본문 바로가기
STM32

CPAL 라이브러리 버그

by irmus 2014. 6. 26.

STM32 MCU를 많이 사용합니다. 개인적으로 잘 만들어진 MCU라 생각하고 있지만 ST의 소프트웨어는 좀 거지같은 면이 있어요. Luminary micro가 이런건 정말 잘 했었는데, TI로 넘어가고나선 그 맛이 사라졌죠 ^^;

여튼 요며칠 STM32F4에서 I2C slave를 구현하는 CPAL 코드조각을 만들려고 하고 있었습니다. I2C master는 예전에 잘 만들어서 잘 쓰고 있는데, DMA 사용하는 slave는 한번도 안해봤더라구요. 마침 필요한 일도 있고 해서 간단하게 예제 하나 만들어야지 하고 시작했는데, 잘 안되네요 이거;;

한 이틀쯤 끙끙거린거 같아요. 문서도 빈약하고 예제는 더 빈약하다보니 내가 잘못하고 있는 건지 이게 원래 안되는 건지 도통 알수가 없었습니다. 이런 경우 대부분은 "내가 잘못하고 있다"로 결론이 난다는 것을 잘 알고 있기 때문에 이틀간 문서읽고 코드 뒤져보고 디버깅돌리고 계속하고 있었습니다만, 이번엔 "CPAL 라이브러리에 버그가 있다"로 결론이 내려졌네요.

DMA 모드로 slave에서 read를 할 때 1 byte만 read 한다면 정상 동작 하지 않습니다. 이를 수정하기 위해서는 cpal_i2c.c 파일에서 I2C_SLAVE_RXNE_Handle() 함수 관련된 #ifdef ~ #endif 를 수정해야 합니다.


위는 ST에서 배포한 CPAL 펌웨어 소스의 cpal_i2c.c 파일 원본입니다. 이걸 아래와 같이 수정해야 합니다.



이 파일에서 I2C_SLAVE_RXNE_Handle로 검색하면 총 3 곳이 나옵니다. 원본에는 모두 #ifdef CPAL_I2C_IT_PROGMODEL 로만 되어 있는데요, 이걸 모두 다 위의 코드 처럼 수정해야 합니다.


STM32에 쓰인 I2C는 DMA 모드에서는 1 byte만 수신할 수가 없습니다. 이를 위해 CPAL 에서는 DMA모드이고 1 byte 수신이라면 라이브러리 내부적으로 인터럽트 모드로 전환해서 처리합니다. 사용자 코드에는 전혀 차이가 없습니다. 이런 자동 전환 작업이 I2C master 코드에는 잘 구현되어 있으나 slave에는 빠져있었습니다. 다행히 크게 건드릴 일은 없고 #ifdef 3곳만 수정해 주면 잘 동작합니다.