Имеется свой бутлоадер, который при запуске микроконтроллера после филипсовских приблуд получает управление, далее переводит ядро и периферию на частоту ~59 МГц (кварц 14745600 Гц). Затем выполняются проверки и может быть перепрошивка, после чего в конце перед передачей управления в главный проект вся использовавшаяся в бутлоадере периферия приводится в состояние как после сброса. В т.ч. также производится остановка PLL и запись стандартных значений в MAMTIM.
И все было бы хорошо... Но выяснилось, что на некоторых экземплярах микроконтроллеров определенные последовательности заставляют ядро войти в ступор.
Сначала было так:
Код
// release PLL
PLLCFG = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
PLLCON = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
while( (PLLSTAT & BSP_PLL_STATUS_LOCKED) == BSP_PLL_STATUS_LOCKED )
WDT_Reset();
// release MAM
MAMCR = 0;
MAMTIM = 7;
// release VPBDIV
VPBDIV = 0;
VPBDIV = 0;
PLLCFG = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
PLLCON = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
while( (PLLSTAT & BSP_PLL_STATUS_LOCKED) == BSP_PLL_STATUS_LOCKED )
WDT_Reset();
// release MAM
MAMCR = 0;
MAMTIM = 7;
// release VPBDIV
VPBDIV = 0;
VPBDIV = 0;
и после выполнения первого (и/или единственного) VPBDIV = 0 ядро входило в ступор. Причем в отладчике сразу поймать это не удалось. Приходилось ставить точку останова где-нибудь за обнулением VPBDIV, потом делать сброс (не перезапуск отладки, а именно сброс), после чего повторный пуск приводил к ступору. Без отладчика же это могло проявиться, а могло и нет даже на одном и том же микроконтроллере.
Поменял местами "отпускание" MAM и VPBDIV - помогло:
Код
// release PLL
PLLCFG = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
PLLCON = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
while( (PLLSTAT & BSP_PLL_STATUS_LOCKED) == BSP_PLL_STATUS_LOCKED )
WDT_Reset();
// release VPBDIV
VPBDIV = 0;
VPBDIV = 0;
// release MAM
MAMCR = 0;
MAMTIM = 7;
PLLCFG = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
PLLCON = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
while( (PLLSTAT & BSP_PLL_STATUS_LOCKED) == BSP_PLL_STATUS_LOCKED )
WDT_Reset();
// release VPBDIV
VPBDIV = 0;
VPBDIV = 0;
// release MAM
MAMCR = 0;
MAMTIM = 7;
Вроде бы головная боль ушла. Но то на LPC2214 =). Недавно опять всплыло, теперь это новые LPC2138 - не всегда проскакивает участок "отпускания" PLL, в случае "неудачи" - опять ступор:
Код
// release PLL
PLLCFG = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
PLLCON = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
PLLCFG = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
PLLCON = 0;
PLLFEED = 0xAA;
PLLFEED = 0x55;
Получить повторяемость глюка не удалось. Сначала все время уходит в ступор, перезапускаю отладку и пытаюсь выяснить точно, с какой на какую команду отказывается работать. Для этого устанавливаю точку останова на последний PLLFEED = 0x55, пускаю выполнение до нее, потом сброс (без перезапуска отладки), убираю точку останова, далее делаю пуск до точки останова где-нибудь после работы с PLL - впадает в ступор. Однако после нескольких таких раз вдруг ступор ушел. Что ни делал - стирание, выключение, многократный сброс и перезапуск отладки - бесполезно, работает как ни в чем не бывало.
Вопрос собственно в том, какая должна быть последовательность выключения PLL (а заодно и VPB и MAM - на всякий случай)? Как это делать правильно и желательно единообразно для большинства изделий линейки LPC? Везде написано, как это хозяйство включается. А как вЫключать - я не нашел. Может, где-то есть описалово или кто-то сталкивался с проблемой и решил ее - пожалуйста, помогите.
Спасибо.