LM3S8962의 I2C 인터페이스에 대하여 알아본다.

우선 Luminary 홈페이지에서 LM3S8962 Datasheet를 다운 받는다.
Link : http://www.luminarymicro.com/products/LM3S8962.html#Datasheet

위의 링크에서 datasheet 및 각종 App Note, Software tool 등을 다운 받을 수 있다.

Datasheet를 토대로 LM3S8962 I2C 인터페이스에 대하여 분석해 보도록 한다.



Inter-Integrated Circuit (I2C) Interface
I2C 버스는 two-wire를 통해 양방향 데이터 통신을 제공하고 serial memory, networking devices, LCDs, tone generators 등과 같은 외부 디바이스와 interface 된다. i2C 버스는 또한 system testing과 제품 개발과 제조를 위한 diagnostic 목적으로 사용된다. LM3S8962 마이크로컨트롤러는 하나의 I2C 모듈을 가지고 있고 버스에서 다른 I2C 내부 동작을 가능하게 된다.

Stellaris I2C 인터페이스는 다음과 특징을 가지고 있다.

I2C 버스에서 Device는 master 나 slave로 지정된다.
    - master나 slave로서 데이터 송수신을 제공한다. 
    - master와 slave 동작은 동시에 동작한다
4개의 I2C 모드
    - Master transmit
    - Master receive
    - Slave transmit
    - Slave receive
■ 두개의 전송 속도 : Standard(100 Kbps), Fast(400 Kbps)
Master와 Slave interrupt generation
   - Master는 transmit 또는 receive 동작 완료할 때 interrupt를 발생한다. 
   - Slave는 master에 의해 데이터가 보내졌거나 요청되었을 때 인터럽트가 발생한다.
Master with arbitration and clock synchronization, multimaster support, and 7-bit addressing mode


1. Block Diagram



2. Functional Description
I2C 모듈은 독립된 peripherals로 동작하는 master와 slave로 구성된다. SDA와 SCL 핀은 양방햔 open-drain pads와 연결되어야만 한다. 전형적인 I2C 버스 configuration 은 아래 그림과 같다.

2.1 I2C Bus Functional Overview
I2C 버스는 단지 2개의 신호 SDA, SCL 만을 사용한다. Stellaris microcontroller에서는 I2CSDA, I2CSCL이라고 불린다.
SDA는 양방향 시리얼 데이터 라인이고 SCL은 양방향 시리얼 클럭라인이다. 버스는 두 신호 모두 High일때 idle 상태이다.

I2C 머스에서  모든 transaction은 9비트이다. 8비트의 데이터과 단일 응답 비트로 구성된다. 전송마다 byte의 수는 제한이 없지만, 각 byte는 응답비트가 따라와야 하며, 데이터는 MSB부터 전송되어야 한다. receiver가 another complete byte를 수신할 수 없을 때, receiver는 SCL 라인을 low 상태로 만들고, transmitter를 강제로 wati state 로 만든다.  receiver가 clock SCL을 방출할 때 데이터 전송은 계속된다.

2.1.1 START and STOP Conditions
I2C 버스의 프로토콜은 transaction을 start하고 end하기 위한 두가지 상태를 정의한다. : START와 STOP이다. SCL이 High인 동안 SDA 라인이 High에서 Low로 바뀌면 START 조건으로 정의 된다. 그리고 SCL 이 High인 동안 SDA 라인에서 Low에서 High로 바뀌면 STOP 조건으로 정의된다. 버스는 START 조건 후에 busy가 되고, STOP 조건 후에는 free가 된다.

2.1.2 Data Format with 7-Bit Address
데이터 전송은 아래 그림에서 보여지는 format을 따른다. START 조건 후에, slave address는 보내진다. 이 address는 7-bit의 길이 다음에 data의 방향을 비트인 여덟번째 비트가 따라온다(R/S bit in the I2CMSA register). zero는 전송동작(send)를 나타내고, 1은 데이타를 위한 요청(receive)을 나타낸다. 데이터 전송은 항상 master에 의해 발생하는 STOP 조건으로 종료된다.  그러나 master는 repeated START 조건을 발생함으로써 버스에서 다른 device와 같이 통신을 초기화 할 수 있다. STOP 조건의 발생하지 않고도 다른 slave를 addressing 할 수도 있다. 송/수신 format의 여러 조합은 단일 전송안에 가능하게 한다.

처음 byte의 첫 7 비트는 slave address를 구성한다. 여덟번째 비트는 message의 방향을 결정한다. 첫번째 byte의 R/S position에서 0은 master가 선택된 slave에 데이터를 write(send)할 것을 의미한다. 1은 master가 slave로부터 데이터를 수신할 것이라는 것을 의미한다.

2.1.3 Data Validity
SDA 라인에서의 데이터는 clock의 high 주기 동안 안정적이어야만 한다. 그리고 데이터 라인은 오로지 SCL이 Low일 때만 변하게 된다.

2.1.4 Acknowledge
모든 bus transaction은 master에서 발생되는 요구된 응답 클럭 사이클을 가지고 있다. 응답 사이클 동안 전송하는 쪽(which can be the master or slave)은 SDA line을 내본낸다. transaction을 응답하기 위해 수신하는 쪽은 응답 클럭 사이클 동안 SDA를 pull down해야 한다. 응답 사이클 동안 수신하는 쪽에 의해 보내지는 데이터는 data validity 요구사항을 따라야만 한다.

slave receiver가 slave address를 응답하지 못할 때, SDA는 slave에 의해 High로 남아 있어야만 한다. 그래야 master는 STOP 조건을 발생할 수있고 현재 전송을 취소할 수 있다. 만약 master device가 전송하는 동안 receiver로서 동작하고 있다면, 그것은 slave에 의해 만들어진 각각의 전송에 응답하기 위한 책임을 가질 수 있다. master가 전송에서 byte 수를 제어하기 때문에, 그것은 마지막 data byte에서 응답을 발생하지 않음으로서 slave transmitter에게 데이터의 끝이라는 신호를 준다. slave transmitter는 그때 master에게 STOP 또는  repeated START 조건을 발생하도록 허락하기 위해 SDA를 release해야 한다.

2.1.5 Arbitration
master는 bus가 idle상태라면 전송을 시작할 수 도 있다. START 조건의 최소 hold time을 가지고 START 조건을 발생시키는 것을 두 개 이상의 master에서 가능하다. 이 경우에 arbitration scheme은 SCL이 High인 동안 SDA 라인에서 이루어진다. arbitration 동안, 다른 master가 0을 전송하는 동안 SDA에서 '1'이 되도록 경쟁하는 master device 중 첫번째는 데이터의 출력 상태를 switch off 할 것이고 bus가 다시 idle 상태가 될때 까지 물러나 있을 것이다.

Arbitration은 여러개의 비트를 발생할 수 있다. 그것의 첫번째 stage는 address 비트의 비교이다, 만약 양쪽 master 모두 같은 device를 접근하려고 시도하면, arbitration은 data bit의 비교를 계속한다.



2.2 Available Speed Modes
I2C clock rate는 CLK_PRD, TIMER_PRD, SCL_LP, SCL_HP parameter에 의해 결정된다.

여기서 :
CLK_PRD : system clock period
SCL_LP : SCL의 low phase(fixed at 6)
SCL_LP : SCL의 high phase(fixed at 4)
TIMER_PRD : I2C Master Timer Period (I2CMTPR) register에서 프로그램된 값

I2C clock 주기는 다음 식으로 계산된다.
SCL_PERIOD = 2*(1 + TIMER_PRD)*(SCL_LP + SCL_HP)*CLK_PRD

예를들어,
CLK_PRD = 50 ns
TIMER_PRD = 2
SCL_LP=6
SCL_HP=4
yields a SCL frequency of:
1/T = 333 Khz

아래 테이블은 타이머 주기, 시스템 클럭, 스피드 모드의 예시를 보여준다. (Standard or Fast).



2.3 Interrupts
아래 조건들이 관찰되었을 때 I2C는 인터럽트를 발생할 수 있다.

■ Master transaction completed
■ Master transaction error
■ Slave transaction received
■ Slave transaction requested

I2C master와 I2C slave 모듈은 분리된 interrupt signal을 가지고 있다. 양 쪽 모듈이 여러개의 조건에 의한 인터럽트를 발생할 수 있는 동안 단지 하나의 인터럽트 신호가 interrupt controller로 보내진다.

2.3.1 I2C Master Interrupts
I2C master 모듈은 transaction이 완료되거나, error가 transaction 동안 발생했을 때, 인터럽트를 발생한다. I2C master 인터럽트를 enable하기 위해, 소프트웨어는 I2C Master Interrupt Mask (I2CMIMR) register에 '1'을 write해야 한다. 인터럽트 조건이 발생했을 때, 소프트웨어는 I2C Master Control/Status (I2CMCS) register에서 ERROR 비트를 확인해야 한다. 이것은 error가 마지막 transaction 동안 발생하지 않았다는 것을 증명하기 위해서이다. error 조건은 마지막 transaction이 slave에 의해 응답하지 않았다면 asserted 된다. 또한 master가 다른 master로 arbitration을 잃었기 때문에 bus의 ownership을 포기하도록 강제되었을 경우에도 error 조건은 asserted 된다.  error가 감지되지 않았다면, application은 전송을 게속할 수 있다. 인터럽트는 I2C Master Interrupt Clear (I2CMICR) register에 '1'을write 함으로써 clear 된다.
applicaiton이 인터럽트의 사용을 요구하지 않는다면, raw interurpt status는 항상 I2C Master Raw Interrupt Status (I2CMRIS) register를 통해 확인할 수 있다

2.3.2 I2C Slave Interrupts
slave 모듈은 데이터가 수신되었거나 요청되었을 때 인터럽트를 발생할 수 있다. 이 인터럽트는 I2C Slave Interrupt Mask (I2CSIMR) register에서 DATAIM 비트에 '1'을 write함으로서 enable 된다. 소프트웨어는 모듈이 I2C Slave Data (I2CSDR) register로부터 데이터를 write(transmit) 또는 read(receive) 해야만 하는지를 결정한다. 이것은 I2C Slave Control/Status (I2CSCSR) register의 RREQ, TREQ 비트를 확인함으로써 이루어진다. 만약 slave 모듈이 receive 모드에 있고 전송의 첫번째 byte가 수신되었다면, FBR 비트는 RREQ와 함께 set 된다. 인터럽트는 I2C Slave Interrupt Clear (I2CSICR) register에서 DATAIC 비트에 1dmf write함으로써 clear된다.

만약 application에서 인터럽트의 사용을 요구하지 않는다면, raw interrupt status는 항상 I2C Slave Raw Interrupt Status (I2CSRIS) register를 통해 확인할 수 있다.

2.4 Loopback Operation
I2C 모듈은 진단 및 debug 작업을 위해 내부 loopback 모드로 바뀔 수 있다. 이것은 I2C Master Configuration I2CMCR) register에서 LPBK 비트를 셋팅함으로써 이루어진다. loopback 모드에서 SDA, SCL 신호는 함께 묶인다.

2.5 Command Sequence Flow Charts
이 setcion은 master나 slave 모두 양쪽에서 여러개의 I2C 전송 타입을 수행하기 위해 요구되는 단계를 자세히 설명한다.

2.5.1 I2C Master Command Sequences
아래의 그림은 I2C master에서 사용할 수 있는 command sequence를 나타낸다.






2.5.2 I2C Slave Command Sequences
아래 그림은 I2C slave에서 사용할 수 있는 command sequence를 나타낸다.



3. Initialization and Configuration
아래의 예시는 master에서 단일 byte를 전송하기 위해 I2C module을 configure하는 방법을 보여준다.
이것은 system clock이 20MHZ라고 가정한다.

(1) System Control 모듈에서 RCGC1 레지스터에 0x0000.1000의 값을 writing함으로써 I2C clock을 enable한다.

(2) System Control 모듈에서 RCGC2 레지스터를 통해 적절한 GPIO의 clock을 enable 한다.

(3) GPIO 모듈에서, GPIOAFSEL 레지스터를 사용함으로써 alternate function을 위한 적절한 pin을 enable 한다.

(4) I2CMCR 레지스터에 0x0000.0020의 값을 writing함으로써 I2C Master를 초기화 한다.

(5) 정확한 값을 I2CMTPR 레지스터에 writing함으로써 희망하는 SCL clock speed를 100 Kbps로 설정한다. 
     I2CMTPR 레지스터에 쓰여진 값은 하나의 SCL clock 주기에서 시스템 클럭 주기의 수를 나타낸다. TPR 값은 다음
    수식에 의해 결정된다.

    TPR = (System Clock / (2 * (SCL_LP + SCL_HP) * SCL_CLK)) - 1;
    TPR = (20MHz / (2 * (6 + 4) * 100000)) - 1;
    TPR = 9
 
    I2CMTPR 레지스터에 0x0000.0009의값을 write 한다. 

(6) master의 slave address를 명시하고 다음 동작은 I2CMSA 레지스터에 0x0000.0076의 값을 write함으로써 Send 될
    것이라고 명시한다.   이것은 0x3B로 slave address를 설정한다.

(7) 희망하는 데이터를 I2CMDR에 writing함으로써 데이터 레지스터에서 보내지기 위한 데이터를 위치시킨다.

(8) I2CMCS 레지스터에 0x0000.0007 의 값을 writing함으로써 Master로부터 Slave로 데이터의 단일 byte 전송을
    초기화
한다.

(9) I2CMCS 레지스터의 BUSBSY비트가 clear 될때까지 polling함으로써 전송이 완료될 때까지 기다린다.


4. Register Map
아래의 테이블은 I2C 레지스트터를 list한다. 모든 address는 I2C base address와 관련되어 주어진다.

■ I2C Master 0: 0x4002.0000
■ I2C Slave 0: 0x4002.0800




5. API Functions



I2CMasterInitExpClk - I2C Master Block을 초기화한다.
master를 위한 bus speed를 설정하고, I2C Master block을 enable 한다.
        bFast : true -> transfer data at 400kbps                                            
        bFast : otherwise -> transfer data at 100kbps


I2CMasterEnable - I2C Master block를 enable한다.

I2CMasterDisable - I2C master  block를 disable 한다.

I2CMasterSlaveAddrSet - transction을 초기화할 때 bus에서 I2C master를 위치시킬 address를 설정한다.
        bReceive : true -> I2C Master가 slave로부터 read하도록 초기화 
        bReceive : otherwise -> I2C Master가 slave로 write하도록 초기화

I2CMasterDataPut - I2C Master로부터 1 byte를 전송한다.
이 함수는 I2C Master Data Register로 제공된 데이터를 넣게된다.

I2CMasterDataGet - I2C Master로 보내진 1 byte를 수신한다.
이 함수는 I2C Master Data Register로부터 1byte data를 read한다.

I2CMasterControl - I2C Master module의 상태를 제어한다.
이 함수는 Master module send/receive 동작의 상태를 제어하기 위해 사용된다.

I2CMasterBusy - I2C Master가 busy인지 아닌지를 나타낸다.
이 함수는 I2C Master가 data를 전송/수신 중 인지 여부를 나타낸다.

I2CMasterBusy - I2C bus 가  busy인지 아닌지를 나타낸다.
이 함수는  I2C bus의  busy여부를 return한다. multi-master 환경에서 다른 master 가 현재 bus에서 사용되는지를 결정하기 위해 사용된다.

I2CMasterErr - I2C Master module의 errt 상태를 얻어온다.
이 함수는 Master module send/receive 동작의 error 상태를 얻어오는 데 사용한다.

I2CMasterIntEnable - I2C Master interrupt suorce를  enable한다.

I2CMasterIntDisable - I2C Master interrupt source를 disable 한다.

I2CMasterIntStatus - 현재 I2C Master interrupt 상태를 얻어온다.
processor를 반영하도록 허락된 raw interrupt 상태나 interrupt 상태가 return 될 수 있다.
        bMasked : false -> raw interrupt status가 요청됨.
        bMasteed : true -> interrupt status가 요청됨.

I2CMasterIntClear - I2C Master interrupt source를 clear한다.
I2C Master interrupt source가 clear되고 더이상 assert 되지 않는다. 이것은 exit 후에 즉시 다시 호출되도록 하기위해 interrupt handler 내에서 수행되어야 한다.



I2CSlaveInit - I2C slave block을 초기화한다.
I2C block을 성공적으로 초기화하면, 이 함수는 slave address를 설정하고, I2C slave block을 enable하게 된다.
ucSlaveAddr은 I2C master에 의해 보내진 slave address와 비교될 값이다.

I2CSlaveEnable - I2C Slave block 을 enable 한다.

I2CSlaveDisable - I2C Slave block을 disable 한다.

I2CSlaveStatus - I2C Slave module 상태를 가져온다.
이 함수는 master 로부터 요청된 동작을 return 한다.
    I2C_SLAVE_ACT_NONE : I2C Slave modue 요청된 어떤 동작도 없다.
    I2C_SLAVE_ACT_RREQ : I2C master가 I2C Slave module로 데이터를 보냈다.
    I2C_SLAVE_ACT_TREQ : I2C master가 I2C Slave module이 data를 보내도록 요청했다.
    I2C_SLAVE_ACT_RREQ_FBR : I2C master가 I2C slave에게 data를 보내고, slave 자신의 address를 따라 첫번째 
                                                byte가 수신되었다. 

I2CSlaveDataGet - I2C slave로 보내진 1 byte를 수신한다.
이 함수는 I2C Slave Data Register로부터 1 byte의 data를 읽는다.

I2CSlaveDataPut - I2C Slave로부터 1 byte을 전송한다.
이 함수는 I2C Slave Data Register로 제공된 data를 넣는다.


I2CSlaveIntEnable - I2C Slave interrupt source를 enable한다.

I2CSlaveIntDisable - I2C Salve interrupt source를 disable한다.

I2CSlaveIntStatus - 현재 I2C Slave interrupt 상태를 얻어온다.
processor를 반영하도록 허락된 raw interrupt 상태 또는 interrupt 상태가 return될 수 있다.
        bMasked : false -> raw interrupt 상태가 요청됨.
        bMasked : true -> interrupt 상태가 요청됨.

I2CSlaveIntClear - I2C Slave interrupt source를 clear한다.
I2C Slave interrupt source는 clear되고 더이상 assert되지 않는다. 이것은 exit 후에 즉시 다시 호출되게 하기 위해 interrupt handler 내에서 수행되어야 한다.

I2CIntRegister - I2C module을 위해 interrupt handler를 등록한다.
이것은 I2C 인터럽트가 발생했을 때 호출될 handler를 설정한다.

I2CIntUnregister - I2C module을 위한 interrupt handler를 등록해제한다.
이 함수는 I2C 인터럽트가 발생했을 때 호출될 handler를 clear할 것이다. interrupt handler에서 interrupt를 mask off하므로 더이상 호출되지 않을 것이다.






Posted by eoseontaek