embeded/i2c

i2c mode - tm4c

구차니 2018. 4. 26. 12:31

데이터시트 내용중에

Four I2C modes
– Master transmit
– Master receive
– Slave transmit
– Slave receive 
 

요런게 보이는데, 풀어 쓰다면

마스터 모드 - master가 slave로 전송 / slave가 master로 부터 받기

마스터 모드 - slave가 master로 전송 / master가 slave로 부터 받기

슬레이브 모드 - slave가 master로 전송 / master가 slave로 부터 받기

슬레이브 모드 - master가 slave로 전송 / slave가 master로 부터 받기 

요렇게 해석이 가능하다.


I2C 통신은 아래와 같이 이루어 지는데 Master에 의해서 SCL이 생성되고
마스터에 의해서 통신이 시작되고(START)

마스터가 쓰는 데이터 = 통신할 slave의 주소 + Read/Write(혹은 Receive/Send) 

슬레이브의 응답 = ACK
마스터가 쓰는 데이터 = slave의 register 주소
슬레이브의 응답 = ACK
마스터가 쓰는 데이터 = register의 data
슬레이브의 응답 = ACK

마스터에 의해서 통신이 종료되게 된다.(STOP)


 

I2C 레지스터 관련 내용 





Driverlib에 정의된 내용

#define I2C_MASTER_CMD_SINGLE_SEND                                            \

                                0x00000007

#define I2C_MASTER_CMD_SINGLE_RECEIVE                                         \

                                0x00000007

#define I2C_MASTER_CMD_BURST_SEND_START                                       \

                                0x00000003

#define I2C_MASTER_CMD_BURST_SEND_CONT                                        \

                                0x00000001

#define I2C_MASTER_CMD_BURST_SEND_FINISH                                      \

                                0x00000005

#define I2C_MASTER_CMD_BURST_SEND_STOP                                        \

                                0x00000004

#define I2C_MASTER_CMD_BURST_SEND_ERROR_STOP                                  \

                                0x00000004

#define I2C_MASTER_CMD_BURST_RECEIVE_START                                    \

                                0x0000000b

#define I2C_MASTER_CMD_BURST_RECEIVE_CONT                                     \

                                0x00000009

#define I2C_MASTER_CMD_BURST_RECEIVE_FINISH                                   \

                                0x00000005

#define I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP                               \

                                0x00000004

#define I2C_MASTER_CMD_QUICK_COMMAND                                          \

                                0x00000027

#define I2C_MASTER_CMD_HS_MASTER_CODE_SEND                                    \

                                0x00000013

#define I2C_MASTER_CMD_FIFO_SINGLE_SEND                                       \

                                0x00000046

#define I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE                                    \

                                0x00000046

#define I2C_MASTER_CMD_FIFO_BURST_SEND_START                                  \

                                0x00000042

#define I2C_MASTER_CMD_FIFO_BURST_SEND_CONT                                   \

                                0x00000040

#define I2C_MASTER_CMD_FIFO_BURST_SEND_FINISH                                 \

                                0x00000044

#define I2C_MASTER_CMD_FIFO_BURST_SEND_ERROR_STOP                             \

                                0x00000004

#define I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START                               \

                                0x0000004a

#define I2C_MASTER_CMD_FIFO_BURST_RECEIVE_CONT                                \

                                0x00000048

#define I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH                              \

                                0x00000044

#define I2C_MASTER_CMD_FIFO_BURST_RECEIVE_ERROR_STOP                          \

                                0x00000004


#define I2C_O_MCS               0x00000004  // I2C Master Control/Status 


void

I2CMasterControl(uint32_t ui32Base, uint32_t ui32Cmd)

{

    //

    // Check the arguments.

    //

    ASSERT(_I2CBaseValid(ui32Base));

    ASSERT((ui32Cmd == I2C_MASTER_CMD_SINGLE_SEND) ||

           (ui32Cmd == I2C_MASTER_CMD_SINGLE_RECEIVE) ||

           (ui32Cmd == I2C_MASTER_CMD_BURST_SEND_START) ||

           (ui32Cmd == I2C_MASTER_CMD_BURST_SEND_CONT) ||

           (ui32Cmd == I2C_MASTER_CMD_BURST_SEND_FINISH) ||

           (ui32Cmd == I2C_MASTER_CMD_BURST_SEND_ERROR_STOP) ||

           (ui32Cmd == I2C_MASTER_CMD_BURST_RECEIVE_START) ||

           (ui32Cmd == I2C_MASTER_CMD_BURST_RECEIVE_CONT) ||

           (ui32Cmd == I2C_MASTER_CMD_BURST_RECEIVE_FINISH) ||

           (ui32Cmd == I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP) ||

           (ui32Cmd == I2C_MASTER_CMD_QUICK_COMMAND) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_SINGLE_SEND) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_BURST_SEND_START) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_BURST_SEND_CONT) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_BURST_SEND_FINISH) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_BURST_SEND_ERROR_STOP) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_BURST_RECEIVE_CONT) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH) ||

           (ui32Cmd == I2C_MASTER_CMD_FIFO_BURST_RECEIVE_ERROR_STOP) ||

           (ui32Cmd == I2C_MASTER_CMD_HS_MASTER_CODE_SEND));


    //

    // Send the command.

    //

    HWREG(ui32Base + I2C_O_MCS) = ui32Cmd;



값대로 정렬하면 아래처럼 나오는데

CONT 0x01

START 0x03

STOP 0x04

FINISH 0x05

_SINGLE_ 0x07

로 끝나게 된다.


I2C_MASTER_CMD_BURST_SEND_CONT 0x00000001


I2C_MASTER_CMD_BURST_SEND_START 0x00000003


I2C_MASTER_CMD_BURST_SEND_STOP 0x00000004

I2C_MASTER_CMD_BURST_SEND_ERROR_STOP 0x00000004

I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP 0x00000004

I2C_MASTER_CMD_FIFO_BURST_SEND_ERROR_STOP 0x00000004

I2C_MASTER_CMD_FIFO_BURST_RECEIVE_ERROR_STOP 0x00000004


I2C_MASTER_CMD_BURST_SEND_FINISH 0x00000005

I2C_MASTER_CMD_BURST_RECEIVE_FINISH 0x00000005


I2C_MASTER_CMD_SINGLE_SEND 0x00000007

I2C_MASTER_CMD_SINGLE_RECEIVE 0x00000007


I2C_MASTER_CMD_BURST_RECEIVE_CONT 0x00000009

I2C_MASTER_CMD_BURST_RECEIVE_START 0x0000000b


I2C_MASTER_CMD_HS_MASTER_CODE_SEND 0x00000013


I2C_MASTER_CMD_QUICK_COMMAND 0x00000027

I2C_MASTER_CMD_FIFO_BURST_SEND_CONT 0x00000040

I2C_MASTER_CMD_FIFO_BURST_SEND_START 0x00000042

I2C_MASTER_CMD_FIFO_BURST_SEND_FINISH 0x00000044

I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH 0x00000044

I2C_MASTER_CMD_FIFO_SINGLE_SEND 0x00000046

I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE 0x00000046

I2C_MASTER_CMD_FIFO_BURST_RECEIVE_CONT 0x00000048

I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START 0x0000004a 



+

데이터시트에는 존재하지 않는 오프셋 주소다.. ㄷㄷ

burst mode랑 multibyte랑 다른거 같긴한데 모르겠네..

#define I2C_O_MBLEN             0x00000030  // I2C Master Burst Length

#define I2C_O_MBCNT             0x00000034  // I2C Master Burst Count 


I2CMCS에 write 레지스터는.. 0x10까지만 공개되어 있네?

#define I2C_MCS_BURST           0x00000040  // Burst Enable 


공개가 안된건.. 해당 칩셋에서는 burst mode 사용불가인거 겠지?



state라고 하긴 애매한데

idle(통신을 잡지 않은 상태)

start (SDA,SCL Low, 통신 시작)

transmit(address LSB에 Write)

receive(address LSB에 Read)

stop (통신을 놓음)

repeat start(통신을 놓지 않고 다른 장치나 주소로 통신)

run (ACK 이후에 stop이나 transmit/recieve로 가는 상태)


이러한 상태들이 존재하게 된다.

그림으로 그리려니 참 애매해지네


그런 이유로... i2c 구현시에 함수들이 uart 처럼 단순하지 않고

토막토막 나있는 것으로 보인다.


I2CMasterControl()은

i2c driver의 state machine을 통제하고

i2c 로직에서는

장치 주소와, 데이터를 가지고 있고

state machine의 값을 이용해

어떤식으로 데이터를 보낼지 결정하게 된다.

(그래서 더 복잡한 듯)


+

2018.04.27

그러니까.. 1 byte를 기준으로 보내는데

바이트 별로 설정을 해줘야하고

그 설정에 통신을 끝낼지 이어서 전송을 할게 있는지를 설정해주는게 은근복잡했던 것..