nRF52832 개발일지 (6)

치삼이·2021년 7월 27일
0

nRF52832 개발일지

목록 보기
7/8
post-thumbnail

👨‍💻 개발일지 (6) : Nordic SDK로 DWM1001 I2C 통신하기 -1-

이번 시간에는 nRF52832의 I2C을 통해 통신하는 방법에 대해 알아보도록 하겠습니다. 보통 MCU를 이용하는 통신 방법에는 UART, SPI, I2C 세 가지 하드웨어 프로토콜을 많이 사용됩니다. 그 밖에 CAN 같은 차량내부에 많이 쓰이는 프로토콜도 있습니다. 🚘

DWM1001은 내부에는 LIS2DH12TR라는 3축 가속도 센서를 내장하고 있으며, 이 센서에 대한 인터페이스는 I2C 입니다.

1. Two Wire Interface vs Inter-Integrated Circuit 💡

본격적인 Product Specification 분석 전, TWI(Two Wire Interface) I2C 차이를 짚고 넘어 가겠습니다.

몇몇 MCU를 제어하다 보면, I2C 대신 TWI 라는 프로토콜을 사용해 I2C 통신을 하는것을 본적이 있을 겁니다. I2C는 필립스에서 만든 프로토콜이며 TWI는 아트멜에서 만든 프로토콜입니다. 두 프로콜은 버스구성이 같아 TWI에서 사용하는 브로드캐스트 10bit 주소지정 같은 특수한 경우를 제외하면 일반적인 경우는 모두 호환이 됩니다.

2. nRF52832 I2C 확인

nRF52832의 I2C 부분의 Product Specification의 인스턴스 및 관련 레지스터부터 살펴보겠습니다.

  • TWIM — I2C compatible two-wire interface master with EasyDMA.
  • TWIS — I2C compatible two-wire interface slave with EasyDMA
  • TWI — I2C compatible two-wire interface

nRF52832는 I2C는 👆 위에서 언급한 세 가지의 형태의 인스턴스가 존재합니다. SPI와 마찬가지로 I2C 는 DMA를 이용하지 않으면 마스터 모드만 사용할 수 있습니다.

I2C 는 SPI와 마찬가지로 Master Slave 구조를 채택하고 있습니다. 하나의 마스터가 여러 슬레이브를 제어하는 형태가 일반적으로 사용 됩니다. SPI는 SS 혹은 CS 핀으로 슬레이브를 선택하는 반면 I2C 는 주소를 이용해 슬레이브와 통신을 합니다.

I2C 역시 SPI 와 마찬가지로 I2C0 I2C1 I2C2 총 세 가지 인스턴스를 만들 수 있습니다. 물론 숫자가 같으면 리소스 공유도 같이 합니다.

Product Specification의 Table 11: Instantiation table을 보면 SPI 및 SPIM, SPS의 인스턴스는 총 세 가지가 있는데 I2C 레지스터 부분의 Table 126: Instances 에는 0 하고 1 이렇게 두 개 뿐이네요...

Table 11: Instantiation table

Table 126: Instances

어디가 잘못됐는지... 😵

다음으로 I2C 관련 레지스터를 살펴보겠습니다.

다른 주변기기 레지스터와 크게 다를게 없습니다. Interrupt Enable/Disable, PSELSCL, PSELSDA, RXD, TXD 등 SPI 혹은 UART 에서 봤던 레지스터 셋 입니다.

3. Nordic SDK의 I2C

I2C 관련 소스 파일 및 헤더 파일은 nrf_drv_twi.c, nrf_drv_twi.h, nrfx_twi.c, nrfx_twi.h 총 네가지 입니다. 이 모듈 역시 SPI 혹은 UART 처럼 nrf_drv 모듈에서 nrfx 모듈을 호출하여 자료형만 바꿔줍니다. 그러므로 nrfx 모듈에서의 I2C 관려 파일만 살펴 보겠습니다.

우선 nrfx_twi.h 에 있는 nrfx_twi_config_t 입니다. 다른 config 타입에 비해 변수의 갯수가 확실히 적습니다.

typedef struct
{
    uint32_t            scl;                ///< SCL pin number.
    uint32_t            sda;                ///< SDA pin number.
    nrf_twi_frequency_t frequency;          ///< TWI frequency.
    uint8_t             interrupt_priority; ///< Interrupt priority.
    bool                hold_bus_uninit;    ///< Hold pull up state on GPIO pins after uninit.
} nrfx_twi_config_t;

두 번째는 nrfx_twi.c 에 있는 twi_control_block_t 입니다. 실제로 이 타입의 변수를 메모리에 적재하여 I2C 인스턴스를 생성합니다.

typedef struct
{
    nrfx_twi_evt_handler_t  handler;
    void *                  p_context;
    volatile uint32_t       int_mask;
    nrfx_twi_xfer_desc_t    xfer_desc;
    uint32_t                flags;
    uint8_t *               p_curr_buf;
    size_t                  curr_length;
    bool                    curr_tx_no_stop;
    twi_suspend_t           prev_suspend;
    nrfx_drv_state_t        state;
    bool                    error;
    volatile bool           busy;
    bool                    repeated;
    size_t                  bytes_transferred;
    bool                    hold_bus_uninit;
} twi_control_block_t;

4. LIS2DH12TR 3축 가속도 센서

LIS2DH12TR는 ST에서 만든 3축 가속도 센서 입니다. 저전력으로 동작이 가능하며 femto(1e-15)단위로 출력하는 고성능 멤스 센서 입니다. 혹시 더 자세한 스펙이 궁금하다면 아래 데이터 시트를 참고해 주세요.

🔗 LIS2DH12TR

4.1 LIS2DH12TR 인터페이스

LIS2DH12TR는 SPI, I2C 두 가지 타입의 인터페이스가 존재합니다. 두 타입의 인터페이스를 모두 지원하며 어떤 인터페이스를 사용하느냐에 따라 핀의 용도가 바뀌게 됩니다.

👆 위 테이블을 보시면 CS핀의 1/0 구분을 통해 SPI와 I2C를 구분합니다.

DWM1001에서는 I2C 인터페이스를 사용하니 데이터시트 상에서 I2C 부분만 확인하도록 하겠습니다.

LIS2DH12TR는 I2C 인터페이스를 이용할 경우 동시에 두개를 사용하기위해 마지막 두번째 비트를 이용합니다. 기본 주소인 001100에 다음 비트가 0 혹은 1로써 두 센서를 구분하며 마지막 비트인 8번째 비트는 R/W 즉 Read 연산이지 Write 연산이지를 구분하기 위해 사용됩니다.

사실 I2C는 주소가 7bit며 그 다음이 R/W 구분 비트입니다. LIS2DH12TR만의 특징이 아닙니다. 🤣🤣

DWM1001에서는 LIS2DH12TR가 어떻게 연결되어 있는지 확인해 보겠습니다.

CS와 SA0가 VCC_DEV와 접지되어 있습니다. 둘 다 1로 enable 된 상태며, 즉 I2C 인터페이스며 주소 0x19로 설정됬습니다.

4.2 LIS2DH12TR 데이터 교환

이제 마지막으로 LIS2DH12TR가 어떻게 통신하는지 알아보도록 하겠습니다.

Transfer when master is writing one byte to slave

Transfer when master is writing multiple bytes to slave

Transfer when master is receiving (reading) one byte of data from slave

Transfer when master is receiving (reading) multiple bytes of data from slave

LIS2DH12TR의 모든 통신은 마스터가 Write연산을 하는 것 부터 시작합니다. 마스터에서 일련의 비트 시퀀스 00110011을 보낸뒤 레지스터 어드레스를 보내는 과정은 모든 통신에서 같습니다. 다만 그다음에 SR(repeated start)를 통해 다시 Read 연산을 하느냐 혹은 바로 데이터를 보내 Write 연산을 하느냐의 차이가 보입니다.

0개의 댓글