Цитата(aaarrr @ Aug 7 2010, 21:53)

Есть предположение, что дело в последовательности операций: у вас сначала разрешается сброс от brownout, и только затем сам BOD. Попробуйте сначала установить GPNVM0, а уже потом 1.
Нужды в паузах и расположении кода в RAM в данном случае нет.
Пробовал и так...... Сначала у меня при зависании устанавливался только один бит, поэтому чтобы во второй раз установить другой, пришлось поменять строчки местами. Задержки добавил на всякий случай, потому что поиском в какой-то теме наткнулся на мнение, что бит занятости контроллера EFC выставляется не всегда.....
В RAM тоже перенес на "попробовать", сначала все было просто во FLASH.
И два раза FMCN настраиваю тоже из подстраховки - сначала было только раз.
Что, BrownOut никто не пользуется ? как его включают ? может это можно сделать какими-то внешними средствами через JTAG,а не программой пользователя ?
Попробовал отключить WatchDog для проверки - не помогло, все равно при попытке установки битов наглухо виснет... Но биты устанавливаются, т.е. виснет судя по всему на второй команде.
Фух, поменял таки назад местами команды установки битов - и ТАКИ ЗАРАБОТАЛО!!! спасибо за подсказку! одной проблемой теперь меньше. Паузы убрал - действительно работает без них. Какой же капризный этот SAM7S....
А вот __ramfunc оказывается нужен обязательно - без него первая же команда что установки, что сброса NVM-бита вызывает зависание и перезагрузку по Watchdog. Возможно, выполнение этих команд блокирует считывание программного кода из FLASH.
Итого работающий код получился таким:
Код
__ramfunc void EnableBrownOutDetector(void)
{
__disable_irq();
while ((AT91C_BASE_MC->MC_FSR & 1)==0);
AT91C_BASE_MC->MC_FMR = (AT91C_BASE_MC->MC_FMR & ~AT91C_MC_FMCN) | (((BOARD_MCK+999999)/1000000) << 16);
AT91C_BASE_MC->MC_FCR = (0x5A<<24)|(0<<8)|AT91C_MC_FCMD_SET_GP_NVM;
while ((AT91C_BASE_MC->MC_FSR & 1)==0);
AT91C_BASE_MC->MC_FMR = (AT91C_BASE_MC->MC_FMR & ~AT91C_MC_FMCN) | (((BOARD_MCK+999999)/1000000) << 16);
AT91C_BASE_MC->MC_FCR = (0x5A<<24)|(1<<8)|AT91C_MC_FCMD_SET_GP_NVM;
while ((AT91C_BASE_MC->MC_FSR & 1)==0);
__enable_irq();
}
__ramfunc void DisableBrownOutDetector(void)
{
__disable_irq();
while ((AT91C_BASE_MC->MC_FSR & 1)==0);
AT91C_BASE_MC->MC_FMR = (AT91C_BASE_MC->MC_FMR & ~AT91C_MC_FMCN) | (((BOARD_MCK+999999)/1000000) << 16);
AT91C_BASE_MC->MC_FCR = (0x5A<<24)|(1<<8)|AT91C_MC_FCMD_CLR_GP_NVM;
while ((AT91C_BASE_MC->MC_FSR & 1)==0);
AT91C_BASE_MC->MC_FMR = (AT91C_BASE_MC->MC_FMR & ~AT91C_MC_FMCN) | (((BOARD_MCK+999999)/1000000) << 16);
AT91C_BASE_MC->MC_FCR = (0x5A<<24)|(0<<8)|AT91C_MC_FCMD_CLR_GP_NVM;
while ((AT91C_BASE_MC->MC_FSR & 1)==0);
__enable_irq();
}