реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> SAM7S установка GPNVM-битов, виснет :(
OlegH
сообщение Aug 7 2010, 14:25
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 186
Регистрация: 14-01-06
Из: Украина, г.Харьков
Пользователь №: 13 168



Делаю проект на SAM7S128 и попутно осваиваю ARM.
Пытаюсь установить GPNVM0 и GPNVM1 биты для включения BrownOut Detector.
Пробую уже по-всякому, и так и сяк - но при выполнении все виснет... Даже WatchDog или J-Link потом не сбрасывает, помогает только выключение питания. Причем сами биты (один или оба) как раз устанавливаются...

Вот код IAR:
Код
__ramfunc void MemDelay(void)
{
  for (volatile int i=0; i<100; i++);
}

__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) | (48 << 16); // 48 MHz
    AT91C_BASE_MC->MC_FCR = (0x5A<<24)|(1<<8)|AT91C_MC_FCMD_SET_GP_NVM;//AT91C_MC_FCMD_SET_GP_NVM;
    MemDelay();
    while ((AT91C_BASE_MC->MC_FSR & 1)==0);
    MemDelay();
    AT91C_BASE_MC->MC_FMR = (AT91C_BASE_MC->MC_FMR & ~AT91C_MC_FMCN) | (48 << 16); // 48 MHz
    AT91C_BASE_MC->MC_FCR = (0x5A<<24)|(0<<8)|AT91C_MC_FCMD_SET_GP_NVM;
    MemDelay();
    while ((AT91C_BASE_MC->MC_FSR & 1)==0);
   __enable_irq();
}



Сама программа во Flash.

EnableBrownOutDetector() вызывается по нажатию кнопки в меню отладочного терминала (DBGU).
Если ходить по шагам, то мертво виснет на записи первой (либо второй - уже точно не помню) команды.
Еще эффект - если SET_GP заменить на CLR_GP, то биты сбрасываются и очень шустро, ничего не виснет.

WatchDog включен примерно на 1 секунду (неужели биты устанавливаются дольше чем 1 секунда?)

Что это может быть ?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 7 2010, 18:53
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Олег Хохлов @ Aug 7 2010, 18:25) *
Что это может быть ?

Есть предположение, что дело в последовательности операций: у вас сначала разрешается сброс от brownout, и только затем сам BOD. Попробуйте сначала установить GPNVM0, а уже потом 1.
Нужды в паузах и расположении кода в RAM в данном случае нет.
Go to the top of the page
 
+Quote Post
OlegH
сообщение Aug 8 2010, 08:50
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 186
Регистрация: 14-01-06
Из: Украина, г.Харьков
Пользователь №: 13 168



Цитата(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();
}

Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 14:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01454 секунд с 7
ELECTRONIX ©2004-2016