Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SAM7Sxx flash write
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
nameless
Да где же там этот INTERNAL LATCH BUFFER ???
И какой он длины... вот бы рабочий примерчик....
nameless
Конкретизирую вопрос:

нет ли у кого конкретных рекоммендаций по программированию внутренней Flash SAM7S64

Основная проблема - понять, по какому же адресу будет тот самы буфер: >1Mb или >253Mb, т.е. 0x00300000 ??? и как к нему адресоваться? побайтно, т.е. инкремент абсолютного адреса при записи 32-разрядонго слова идет на 4?
Hardman
Посмотри на www.at91.com вроде попадался пример
nameless
Спасибо, Hardman!
Интересная получается статистика - из 78 (!!!) просмотревших эту тему только ОДИН вставил свой комментарий.... Видно мало-кто пользует Flash как EEPROM...
sapID
Вот рабочие файлики для AT91SAM7S64 и AT91SAM7S256.
Прицепить файлами не дал форум...

EFC.h:
-----------------------------------------------------------------------

#ifndef _EFC_h
#define _EFC_h

#include "TypesDef.h"

// Запись чего-нибудь во внутреннюю FLASH процессора
// За один раз пишется/читается не больше EFC_PAGE_SIZE

// AT91SAM7S64
// с 0x00100000 до 0x00110000
#define EFC_PAGE_SIZE 128
#define EFC_PAGE_COUNT 512
#define EFC_PagesInTheLockRegion 32

// AT91SAM7S256
// с 0x00100000 до 0x00140000
/*
#define EFC_PAGE_SIZE 256
#define EFC_PAGE_COUNT 1024
#define EFC_PagesInTheLockRegion 64
*/

#define EFC_PAGE_SIZE_UINT (EFC_PAGE_SIZE/4) // Количество unsigned int


void EFC_Init(void);

// adr начинается с 0x00100000 и должен быть выровнен на EFC_PAGE_SIZE
// pbuf д.б. размером EFC_PAGE_SIZE_UINT int
// Слишком часто не писать, так как ресурс - 10000 записей
// Пишется со стиранием блока. Если блок залочен, сбрасывает LOCK
// В начало FLASH не писать, так как там лежит программа :-)
// При записи не должны вызываться прерывания, так как они исполняются из FLASH
// То есть где надо, обрамлять AT91F_disable_interrupt();EFC_WritePage();AT91F_enable_interrupt();
__ramfunc u32 EFC_WritePage(u32 adr, u32 *pbuf);

// Писать большой блок и, если надо, Reset
__ramfunc void EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset);


// EFC_ReadPage можно не делать, а сразу мапить структуру по ссылке на память
// (см. TestEFC() pbuf3[] )
u32 EFC_ReadPage(u32 adr, u32 *pbuf);

void TestEFC(void);

#endif
-----------------------------------------------------------------------



EFC.cpp:
-----------------------------------------------------------------------

#include "BoardAdd.h"
#include "EFC.h"

__ramfunc void EFC_Init(void)
{
while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)) ;
AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(100 <<16)) | AT91C_MC_FWS_1FWS ;
while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)) ;
}


// adr начинается с 0x00100000
// pbuf д.б. размером EFC_PAGE_SIZE
__ramfunc u32 EFC_WritePage(u32 adr, u32 *pbuf)
{
unsigned int *pflash;
unsigned int page;
unsigned int region;
unsigned int i;

pflash = (unsigned int *)adr;
page = (adr & 0x3FFFF)/EFC_PAGE_SIZE;
region = (page/EFC_PagesInTheLockRegion);

EFC_Init();

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)) ;

return 1;
}


__ramfunc void EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset)
{
u32 l;
if (NeedReset) {
l=0;
}
l=0;
while (l<Len) {
EFC_WritePage(adr, (u32*)&(pbuf[l]));
l+=EFC_PAGE_SIZE;
adr+=EFC_PAGE_SIZE;
}
if (NeedReset) {
__asm("sub r0, r0,r0;");
__asm("bx r0;");
}
}



// adr начинается с 0x00100000
// pbuf д.б. размером EFC_PAGE_SIZE
__ramfunc u32 EFC_ReadPage(u32 adr, u32 *pbuf)
{
unsigned int *pflash = (unsigned int *)adr;
unsigned int i;

EFC_Init();

for (i = 0; i < EFC_PAGE_SIZE_UINT; i++)
*(pbuf + i) = *(pflash + i );

return 1;
}




void TestEFC(void)
{

unsigned int buf1[8192/4];
int i;

#define TestAddr 0x0000
unsigned int *pbuf3=(unsigned int *)TestAddr;

//AT91C_BASE_MC->MC_FCR = (0x5A << 24) | AT91C_MC_FCMD_ERASE_ALL;
//while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)) ;

for(i=0;i<8192/4;i++)
buf1[i]=i+9;
AT91F_disable_interrupt();
EFCWrite(0x100000 | TestAddr,(u8*)buf1,8192,0);
AT91F_enable_interrupt();

for( i=0;i<8192/4;i++)
if (buf1[i]!=pbuf3[i])
buf1[i]=0;

}
-----------------------------------------------------------------------
nameless
Спасибо огромное

Насчет #define TestAddr 0x0000
- это шутка наверное....? я же именно так и тестировал....а программулина из Flash...
klesin
Вопрос к sapID.
У Вас конкретно это работает при запуске программы во флэше? Не при отладке, а с отключенным программатором?
Дело в том, что очень давно начал пытаться переписать флэш при работающей программе, но нет данных, что кто-то это сделал. При попытке снять блокировку с флэши (включены ли прерывания или выключены) - контроллер вываливается в какие-то дебри, делее - не работает ничего. Ну хоть программа при этом не стирается.
У меня немного другая задача: переписать полностью программу через уарт. По тому, что нашел я переписываю полностью код из флэши в память. Надо лишь как-то передать управление не на флэш, а на память. Если у кого-то есть решение - хотелось бы посмотреть.

Забыл дописать. При исполнении программы из памяти (RAM), пишется что угодно куда угодно.
Но если из флэши, то только можно считывать данные без возможности записи.
Так вот вопрос, вообще есть возможность записи-то?
sapID
Цитата(nameless @ Mar 6 2006, 14:45) *
Насчет #define TestAddr 0x0000
- это шутка наверное....? я же именно так и тестировал....а программулина из Flash...

Да недосмотрел. Просто, последний раз отлаживался из RAM.
Тут надо что-то типа:
#define TestAddr 0x0F000

Цитата(klesin @ Mar 8 2006, 20:16) *
У Вас конкретно это работает при запуске программы во флэше? Не при отладке, а с отключенным программатором?

Функция записи должна выполняться из RAM (в даташите это описано). В IAR это прописывается как __ramfunc и сегмент CODE_I должен быть описан в RAM.
Во время записи не должны вызываться прерывания, так как их обработчик обычно во FLASH.
Ну, и есть отличия в размере страниц для разных процов - в примере прописано для AT91SAM7S64 и AT91SAM7S256.
В остальном - все работает. Записывается верхняя часть программы, в конце, если надо, загрузчик на начальных адресах и делается RESET - в конце EFCWrite() есть переход на 0.
klesin
Сравнивал свой текст с тем что был предложен. Все сходится. Единственное отличие в отключении прерываний (ну не знаю я как написать процедуру на asm в MULTI, а IARом не хочу пользоваться). Вместо AT91F_disable_interrupt() я просто сбрасывал биты разрешения IRQ и FIQ на С. Скорее всего в этом и есть проблема.
sapID
Цитата(klesin @ Mar 12 2006, 17:19) *
Сравнивал свой текст с тем что был предложен. Все сходится. Единственное отличие в отключении прерываний (ну не знаю я как написать процедуру на asm в MULTI, а IARом не хочу пользоваться). Вместо AT91F_disable_interrupt() я просто сбрасывал биты разрешения IRQ и FIQ на С. Скорее всего в этом и есть проблема.


AT91F_enable_interrupt и AT91F_disable_interrupt написаны на ассемблере в файле *.s
В С они подключаются через extern

extern void AT91F_enable_interrupt(void);
extern void AT91F_disable_interrupt(void);



#define IRQ_MASK 0x00000080
#define FIQ_MASK 0x00000040
#define INTs_MASK (IRQ_MASK | FIQ_MASK)

;---------------------------------------------------
; \fn extern void AT91F_enable_interrupt(void)
; \brief Enable Core interrupt
;---------------------------------------------------

PUBLIC AT91F_enable_interrupt
CODE32 ; Always ARM mode after exeption
AT91F_enable_interrupt
mrs r0, CPSR
bic r0, r0, #INTs_MASK
msr CPSR_c, r0
bx lr

;---------------------------------------------------
; \fn extern void AT91F_disable_interrupt(void)
; \brief Disable Core interrupt
;---------------------------------------------------

PUBLIC AT91F_disable_interrupt
CODE32 ; Always ARM mode after exeption
AT91F_disable_interrupt
mrs r0, CPSR
orr r0, r0, #INTs_MASK
msr CPSR_c, r0
mrs r0, CPSR
ands r0, r0, #INTs_MASK
beq AT91F_disable_interrupt
bx lr
nameless
Только что сталкнулся с такими колесами. Пример тот же, но стоит задача записи довольно большого объема во флешь. Суть колес заключается в том, что флаг AT91C_MC_FRDY после команды на запись или не сбрасывается или сбрасывается поздно... поэтому страницы пишутся через одну.....пока просто поставил задержку в 6 мс.

Есть ли какие предложения ???
Redaer
Можно вопрос по SAM7S256?

Стоит задача:

Программа работает из flash, при поступлении определенного сигнала по радиоканалу, flash должна скопировать кусок себя в RAM и запустить эту свою часть из нее.

Вопрос: как передать управление из flash в RAM? Для этого нужно какие-то флаги поднимать?

З.Ы. Пытаюсь программировать в IAR
SpiritDance
Для ядра не сущетвует разнаицымежду исполнением из RAM и из flash. Никакие флаги поднимать не нужно, просто происходит обычный вызов подпрограмм по адресам из RAM, при этов в pc загружается 0x002xxxxx .
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.