실리콘랩스의 EFR32FG1 시리즈를 개발하고 양산하는 도중, 꽤 많은 생산 불량이 나오기 시작했다.
한 7% 정도... ?
무한 재부팅이 되고, 와치 독을 빼면 어디선가 멈춰서 JTAG도 안되고, 멀쩡한 건 정상 부팅이 되고...
문제를 분석하기 위해 크리스털 발진을 찍어보니 발진을 하는 순간, 리셋이 되었다. 어디인지 보기 위해 디버깅 메시지를 이리저리 추가하니, RAIL_StartRx 함수가 실행되면 다음 리셋이 실행되는 것을 확인했다.
(https://docs.silabs.com/rail/latest/group-receive)
무선 RF 통신을 하는 장비가 통신을 하니 멈춘다니.. 우선 크리스털이 문제인가 해서 교체해 봤으나
문제는 해결되지 않았다. 냉납인가 해서 납땜도 다시 해봤으나, 해결된 건 없었다.
https://www.silabs.com/documents/public/application-notes/an0004.1-efm32-cmu.pdf
위 문서를 보면 HFXO 관련 start-up 및 calibrate 관련 내용이 있어서 프로젝트의 클럭 초기화 부분을 보기로 했다.
bsp_init.c
void BSP_initClocks(void)
{
// --------------------------------
// Initialize HFXO if present
#if BSP_CLK_HFXO_PRESENT
// HFXO
CMU_HFXOInit_TypeDef hfxoInit = BSP_CLK_HFXO_INIT;
int ctune = -1;
#if defined(_DEVINFO_MODXOCAL_HFXOCTUNE_MASK) // Series 1
if ((DEVINFO->MODULEINFO & _DEVINFO_MODULEINFO_HFXOCALVAL_MASK) == 0) {
ctune = DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNE_MASK;
}
#elif defined(_DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK) // Series 2
if ((DEVINFO->MODULEINFO & _DEVINFO_MODULEINFO_HFXOCALVAL_MASK) == 0) {
ctune = DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK;
}
#endif
if ((ctune == -1) && (MFG_CTUNE_EN == 1) && (MFG_CTUNE_VAL != 0xFFFF)) {
ctune = MFG_CTUNE_VAL;
}
#if defined(BSP_CLK_HFXO_CTUNE) && BSP_CLK_HFXO_CTUNE >= 0
if (ctune == -1) {
ctune = BSP_CLK_HFXO_CTUNE;
}
#endif
if (ctune != -1) {
#if defined(_SILICON_LABS_32B_SERIES_1)
hfxoInit.ctuneSteadyState = ctune;
#elif defined(_SILICON_LABS_32B_SERIES_2)
hfxoInit.ctuneXoAna = ctune;
hfxoInit.ctuneXiAna = ctune;
#endif
}
CMU_HFXOInit(&hfxoInit);
SystemHFXOClockSet(BSP_CLK_HFXO_FREQ);
#endif // BSP_CLK_HFXO_PRESENT
|
cs |
위 소스를 보면 CMU_HFXOInit 함수를 통해 HFXO를 초기화하고 있다.
로드 캐패시터 값 ctune을 입력받는데 BSP_CLK_HFXO_CTUNE 값을 사용하는 걸로… 알고 있는데 응?
MFG_CTUNE_VAL이라는 값을 먼저 넣는 것이 보인다. 또 설정하는 값이 있었다고?
위 설정에서는 MFG_CTUNE_EN 이 0으로 되어 있지만 처음엔 1 이었다.
MFG_CTUNE_ADDR는 0x0FE0로 시작하는 걸 보아.. USer Data 영역인 것을 확인했다.
어 그런데.. User Data 영역? 이번 제품은 제품번호와 설정값을 main flash가 아닌 User Data에 쓴다. 이유는 플래쉬를 erase 해도 설정값을 지우지 않기 위해서이다.
정상적인 케이스에는 문제가 없으나, 제품 설정 중 전원이 꺼지면 문제가 되는데..
User Data 영역에 잘못된 값이 저장되는 바람에 MFG_CTUNE_VAL 가 이상한 값이 나오면서 HFXO가
잘못 발진되어 CPU가 멈추는 증상이 나온 것이었다...
원래 저 위치에 값을 쓰지도 않기 때문에 이번 기회에 코드를 삭제해 버렸다.
해당 펌웨어를 다시 다운로드하니 문제가 되던 제품들이 정상 동작하기 시작했다...
DCDC 기능 설정 시에는 Device Info 영역의 데이터 읽어 오면서 왜 HXFO Ctune 값은 User Data 영역에서 읽어 오는지 모르겠다. 말 그대로 사용자 영역인데!!!!!
이번 일로 교훈을 얻은 것은 예제를 그대로 사용하지 말 것!! !!
'개발이야기' 카테고리의 다른 글
[ESP32/idf] Panic, watchdog 이벤트 발생 시 참조할 사항 (1) | 2022.10.14 |
---|---|
펌웨어와 커스텀 부트로더(SRAM과 보안,MPU) (1) | 2022.10.14 |
[안드로이드]BLE SPP와 Bonding (2) | 2022.10.14 |
[ESP32] 블루투스 스피커와 버퍼링 (0) | 2022.10.14 |
펌웨어로 2개의 wav 오디오 믹싱하기 (0) | 2022.03.21 |