Перейти к содержанию
    

SAM7Sxx flash write

Конкретизирую вопрос:

 

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

 

Основная проблема - понять, по какому же адресу будет тот самы буфер: >1Mb или >253Mb, т.е. 0x00300000 ??? и как к нему адресоваться? побайтно, т.е. инкремент абсолютного адреса при записи 32-разрядонго слова идет на 4?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, Hardman!

Интересная получается статистика - из 78 (!!!) просмотревших эту тему только ОДИН вставил свой комментарий.... Видно мало-кто пользует Flash как EEPROM...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот рабочие файлики для 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+9;

AT91F_disable_interrupt();

EFCWrite(0x100000 | TestAddr,(u8*)buf1,8192,0);

AT91F_enable_interrupt();

 

for( i=0;i<8192/4;i++)

if (buf1!=pbuf3)

buf1=0;

 

}

-----------------------------------------------------------------------

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Насчет #define TestAddr 0x0000

- это шутка наверное....? я же именно так и тестировал....а программулина из Flash...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос к sapID.

У Вас конкретно это работает при запуске программы во флэше? Не при отладке, а с отключенным программатором?

Дело в том, что очень давно начал пытаться переписать флэш при работающей программе, но нет данных, что кто-то это сделал. При попытке снять блокировку с флэши (включены ли прерывания или выключены) - контроллер вываливается в какие-то дебри, делее - не работает ничего. Ну хоть программа при этом не стирается.

У меня немного другая задача: переписать полностью программу через уарт. По тому, что нашел я переписываю полностью код из флэши в память. Надо лишь как-то передать управление не на флэш, а на память. Если у кого-то есть решение - хотелось бы посмотреть.

 

Забыл дописать. При исполнении программы из памяти (RAM), пишется что угодно куда угодно.

Но если из флэши, то только можно считывать данные без возможности записи.

Так вот вопрос, вообще есть возможность записи-то?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насчет #define TestAddr 0x0000

- это шутка наверное....? я же именно так и тестировал....а программулина из Flash...

Да недосмотрел. Просто, последний раз отлаживался из RAM.

Тут надо что-то типа:

#define TestAddr 0x0F000

 

У Вас конкретно это работает при запуске программы во флэше? Не при отладке, а с отключенным программатором?

Функция записи должна выполняться из RAM (в даташите это описано). В IAR это прописывается как __ramfunc и сегмент CODE_I должен быть описан в RAM.

Во время записи не должны вызываться прерывания, так как их обработчик обычно во FLASH.

Ну, и есть отличия в размере страниц для разных процов - в примере прописано для AT91SAM7S64 и AT91SAM7S256.

В остальном - все работает. Записывается верхняя часть программы, в конце, если надо, загрузчик на начальных адресах и делается RESET - в конце EFCWrite() есть переход на 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сравнивал свой текст с тем что был предложен. Все сходится. Единственное отличие в отключении прерываний (ну не знаю я как написать процедуру на asm в MULTI, а IARом не хочу пользоваться). Вместо AT91F_disable_interrupt() я просто сбрасывал биты разрешения IRQ и FIQ на С. Скорее всего в этом и есть проблема.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сравнивал свой текст с тем что был предложен. Все сходится. Единственное отличие в отключении прерываний (ну не знаю я как написать процедуру на 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

Изменено пользователем sapID

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что сталкнулся с такими колесами. Пример тот же, но стоит задача записи довольно большого объема во флешь. Суть колес заключается в том, что флаг AT91C_MC_FRDY после команды на запись или не сбрасывается или сбрасывается поздно... поэтому страницы пишутся через одну.....пока просто поставил задержку в 6 мс.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно вопрос по SAM7S256?

 

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

 

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

 

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

 

З.Ы. Пытаюсь программировать в IAR

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для ядра не сущетвует разнаицымежду исполнением из RAM и из flash. Никакие флаги поднимать не нужно, просто происходит обычный вызов подпрограмм по адресам из RAM, при этов в pc загружается 0x002xxxxx .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...