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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> работа с внутренней флэш, AT91SAM7X256
Dron_Gus
сообщение Jul 12 2007, 12:12
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Отладчик в таких ситуациях может только мешать. Советую попробовать без него.


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
Annuta
сообщение Jul 12 2007, 13:33
Сообщение #17


Участник
*

Группа: Новичок
Сообщений: 42
Регистрация: 26-04-07
Из: Смоленск
Пользователь №: 27 333



Спасибо, Dron_Gus!... да именно из-за этого плата и перегружалась... Теперь не перегружаеься... но и не работает.... sad.gif
Код
__ramfunc int EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset)
{
    u32 l;
    unsigned int *pflash;
    unsigned int page;
    unsigned int region;
    unsigned int i;  

    l=0;    
    while (l<Len)
    {    
          pflash = (unsigned int *)adr;
          page = (adr & 0x3FFFF)/EFC_PAGE_SIZE;
          region = (page/EFC_PagesInTheLockRegion);      
      
      if (AT91C_BASE_MC->MC_FSR & (region << 16))
      {
          // lock set, clear it
          AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(50 <<16)) | AT91C_MC_FWS_2FWS;
          AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (region << 8 ) |AT91C_MC_FCMD_UNLOCK;
      }
      while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
      
      for (i = 0; i < EFC_PAGE_SIZE_UINT; i++)
           *(pflash + i ) = *(pbuf + i);      
      
      AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (page << 8 ) |AT91C_MC_FCMD_START_PROG;
      while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
      
        l+=EFC_PAGE_SIZE;
        adr+=EFC_PAGE_SIZE;
    }
    
    if (NeedReset)
    {
      __asm("sub r0, r0,r0;");
      __asm("bx r0;");
    }
    
    return (Len * AT91C_IFLASH_PAGE_SIZE);
}

вот - делаю как... Прошивка доходит до волшебной строчки
AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (page << 8 ) |AT91C_MC_FCMD_START_PROG;
... и всё... дальше... тормоз!... Возвращает "0" .. естевтсвенно...


--------------------
Из комбинации лени и логики - получается программист! /народная мудрость/
Go to the top of the page
 
+Quote Post
AlexBoy
сообщение Jul 12 2007, 14:59
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 205
Регистрация: 19-12-05
Из: Kiev
Пользователь №: 12 394



Цитата(Annuta @ Jul 12 2007, 16:33) *
вот - делаю как... Прошивка доходит до волшебной строчки
AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (page << 8 ) |AT91C_MC_FCMD_START_PROG;
... и всё... дальше... тормоз!... Возвращает "0" .. естевтсвенно...


в это фрагменте ошибочка, pbuf у вас объявлен как "u8 *pbuf" соответственно читается по 1 байту а пишется по 4. pbuf должен быть "unsigned int *" или заведите локальную переменную и сделайте преобразование к этому типу.
Код
for (i = 0; i < EFC_PAGE_SIZE_UINT; i++)
           *(pflash + i ) = *(pbuf + i);
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 12 2007, 18:21
Сообщение #19


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

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



В функцию EFCWrite(); передается адрес 0x0030000 - область ОЗУ после ремапа, причем получается 196 608 байт, хотя у этого контроллера 64 кб ОЗУхи

или я не прав?
Go to the top of the page
 
+Quote Post
AlexBoy
сообщение Jul 13 2007, 09:27
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 205
Регистрация: 19-12-05
Из: Kiev
Пользователь №: 12 394



Цитата(Timofey @ Jul 12 2007, 21:21) *
В функцию EFCWrite(); передается адрес 0x0030000 - область ОЗУ после ремапа, причем получается 196 608 байт, хотя у этого контроллера 64 кб ОЗУхи

или я не прав?

прав на 100%
#define TestAddr 0x0030000
при вызове EFCWrite(adr, pbuf, Len, NeedReset) adr должен показывать на адрес внутри флеша
#define AT91C_IFLASH ((char *)0x00100000) // Internal FLASH base address
#define AT91C_IFLASH_SIZE ((unsigned int) 0x00040000) // Internal FLASH size in byte (256 Kbytes)
причем не на начало, чтобы не стереть программу, можно так:
Код
#define TestAddr (AT91C_IFLASH+AT91C_IFLASH_SIZE-sizeof(buf1))


To Annuta: Полезно иногда заглядывать в файл AT91SAM7X256.h, там все константы описаны, чтоб не делать таких ошибок с размещением.
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 13 2007, 09:36
Сообщение #21


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

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(AlexBoy @ Jul 13 2007, 15:27) *
To Annuta: Полезно иногда заглядывать в файл AT91SAM7X256.h, там все константы описаны, чтоб не делать таких ошибок с размещением.
Она просто учится smile.gif Про ремап я просто забыл сообщить smile.gif
Go to the top of the page
 
+Quote Post
Annuta
сообщение Jul 13 2007, 10:20
Сообщение #22


Участник
*

Группа: Новичок
Сообщений: 42
Регистрация: 26-04-07
Из: Смоленск
Пользователь №: 27 333



Получилось!!! Спасибо БОЛЬШОЕ всем за помощь!!! smile.gif


--------------------
Из комбинации лени и логики - получается программист! /народная мудрость/
Go to the top of the page
 
+Quote Post
Waso
сообщение Oct 24 2007, 11:00
Сообщение #23


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



Мне в AT91 нужно менять только одно слово во флеше. Обязательно ли для этого читать всю страницу, содержащую слово, менять его и записывать всю страницу обратно? Или можно канибудь проще? Мне не ради простоты а ради удлинения срока службы флеша... (реализую файловую систему. файлы будут больше читаться, писАться - редко, но тем не менее...)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 24 2007, 12:02
Сообщение #24


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Waso @ Oct 24 2007, 14:00) *
Мне в AT91 нужно менять только одно слово во флеше. Обязательно ли для этого читать всю страницу, содержащую слово, менять его и записывать всю страницу обратно?
Если менять с единиц на нолики - не обязательно. Если с ноликов на единицы - да, обязательно. Причем не обязательно читать-менять-писать. Достаточно прочитать и записать в теневой буфер всю страницу, а потом сверху в буфер дописать изменяемые данные:
Код
    volatile uint32_t* pTmp = (uint32_t*)((uint32_t)&Config_flash & ~0x7F);
    uint32_t* pSegmentEnd = (uint32_t*)(((uint32_t)&Config_flash & ~0x7F) + 128);
    while(pTmp < pSegmentEnd) // copy to shadow buffer
    {
        uint32_t Data = *pTmp;
        *pTmp++ = Data;
    }
    uint32_t *pSrc = (uint32_t*)&TmpConfig;
    uint32_t *pDst = (uint32_t*)&Config_flash;
    while(pDst < (uint32_t*)((config_t*)&Config_flash + 1))
    {
        *pDst++ = *pSrc++;
    }

    Flash::RewritePage((uint32_t const*)&Config_flash);


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_dem
сообщение Oct 24 2007, 12:20
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



сколько же у вас памяти жрет проект, если вы пишете на CPP ?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 24 2007, 15:43
Сообщение #26


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(_dem @ Oct 24 2007, 15:20) *
сколько же у вас памяти жрет проект, если вы пишете на CPP ?
Примерно столько же. А удобства неравненно больше. Обсуждалось неоднократно, хотя бы тут.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Waso
сообщение Oct 25 2007, 03:14
Сообщение #27


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



2 Сергей Борщ. Смысл понятен, но реализация в примере темновата.
Цитата(Сергей Борщ @ Oct 24 2007, 19:02) *
[code] volatile uint32_t* pTmp = (uint32_t*)((uint32_t)&Config_flash & ~0x7F);
uint32_t* pSegmentEnd = (uint32_t*)(((uint32_t)&Config_flash & ~0x7F) + 128);
while(pTmp < pSegmentEnd) // copy to shadow buffer
{
uint32_t Data = *pTmp;
*pTmp++ = Data;
}
Разве ~0x7F не равно 0x80 ? Каков смысл такой записи как у Вас?
Тело цикла while тоже кажется избыточным моему неопытному глазу: Сначала присваиваем переменной Data то, на что указывает pTmp, затем, если я правильно понимаю работу постинкремента, сначала присваиваем тому на что указывает pTmp значение Data и после этого увеличиваем сам адрес указателя. Зачем кидать туда-сюда значение *pTmp ?? wacko.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 25 2007, 07:44
Сообщение #28


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Waso @ Oct 25 2007, 06:14) *
Разве ~0x7F не равно 0x80 ? Каков смысл такой записи как у Вас?
Нет, не равно. ~0x7F для ARM равно 0xFFFFFF80. Вот и вы попались. Вообще-то совсем правильно было бы ~0x7FULL, тогда такая запись обнуляла бы 5 младших бит в любой целочисленной переменной. Но я пока не выработал в себе такую привычку, наверное пора начинать.
Цитата(Waso @ Oct 25 2007, 06:14) *
Зачем кидать туда-сюда значение *pTmp ?
Tmp объявлен как volatile *. Без временной переменной получили бы warning компилятора о непредсказуемом порядке доступа к volatile (IAR выдает его всегда, если в выражении встречается более одной volatile-переменной). Без volatile компилятор имел бы полное право выкинуть весь цикл.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Angle
сообщение Nov 21 2007, 09:10
Сообщение #29


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 8-08-07
Из: Екатеринбург
Пользователь №: 29 638



У меня такая проблема не могу записать во внутреннюю флэш.
Контроллер AT91SAM7A3, компилятор Keil.
В настройках проекта Оptions->Target ограничил размер ROM с 0x40000 до 0x30000

Кусок кода
Код
void EFC_Init(void)
{ unsigned long clkus;
    
// Calculate Flash Microsecond Cycle Number - Approximate (no Library Code)
//clkus = (1074*(clk >> 10)) >> 20;            // Master Clock Cycles in 1.0us
  clkus = (1611*(MCK >> 10)) >> 20;            // Master Clock Cycles in 1.5us
   // Set Flash Microsecond Cycle Number
  // Set Flash Waite State to max. (Single Cycle Access at Up to 30 MHz)
  AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN) & (clkus << 16)) | AT91C_MC_FWS_3FWS;
  AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
}


int EFC_WritePage(DWORD adr, DWORD *pbuf)
{
  
    unsigned int *pflash;
    unsigned int page;
    unsigned int i;  

            
pflash = (unsigned int *)adr;
page = (adr - 0x00100000)/AT91C_IFLASH_PAGE_SIZE;
          
AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_UNLOCK |AT91C_MC_PAGEN & (page << 8));
// Wait until the end of Command
while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_EOL) != AT91C_MC_EOL);

for (i = 0; i <AT91C_IFLASH_PAGE_SIZE/4; i++)   *(pflash + i ) = *(pbuf + i);      

AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG |(AT91C_MC_PAGEN & (page << 8));

  // Wait until the end of Command
  while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_EOP) != AT91C_MC_EOP);

// Check for Errors
  if (AT91C_BASE_MC->MC_FSR & (AT91C_MC_PROGE | AT91C_MC_LOCKE)) return (1);
  return (0);
    }

#define TestAddr AT91C_IFLASH+AT91C_IFLASH_SIZE-AT91C_IFLASH_PAGE_SIZE
BYTE TestEFC(void)
{
DWORD buf1[256];
  int i;
  BYTE result;
  for(i=1;i<=63;i++) buf1[i]=i;
  EFC_Init();  
  result=(BYTE)EFC_WritePage((DWORD)TestAddr,(DWORD*)buf1);
  return     result;
}

Прогамма зависает после выполнения строки кода
Код
while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_EOL) != AT91C_MC_EOL);

В чем может быть причина ?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 21 2007, 11:20
Сообщение #30


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Angle @ Nov 21 2007, 11:10) *
Прогамма зависает после выполнения строки кода
Код
while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_EOL) != AT91C_MC_EOL);

В чем может быть причина ?
Кусочек, пишущий в FCR и ожидающий после этого готовности FSR должен исполняться из ОЗУ.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

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

 


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


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