|
Запись данных во Flash Sam7s256 |
|
|
|
Jun 21 2009, 17:55
|
Группа: Участник
Сообщений: 11
Регистрация: 21-06-09
Пользователь №: 50 508

|
Доброго времени суток. Помогите решить такую проблему. Не могу разобраться как записать данные во флеш. Функционал - прием данных с USART запись в постоянную память, выдача по требованию. Все прекрасно работает с RAM - данные получаются и выдаются, но естественно сброс по питанию все обнуляет. С помошью SAM-BA залил прошивку, все работает из флеши и выполняется в RAM но как записывать пользовательские данные? Судя по даташиту необходимо поместить данные в буфер-защелку, после чего запись команд в регистр EFC для операции со страницей №такой то. Где этот буфер определяется? по регистрам не нашел.
Второй вопрос как определить где закончится программа - с какого момента можно будет записать данные (флеш с 0х00100000 без ремапа начинается) Не бейте сильно в электронике почти полный нуб) пока освоил инициализацию, прерывания и com
|
|
|
|
|
Jun 22 2009, 21:58
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Spoofing @ Jun 21 2009, 21:55)  Судя по даташиту необходимо поместить данные в буфер-защелку, после чего запись команд в регистр EFC для операции со страницей №такой то. Где этот буфер определяется? по регистрам не нашел. просто пишите в флеш на те места куда хотели записать, буфер там кольцевой, поэтому старшие разряды просто обрежет, ну или обрезайте сами по границе страницы, регистры здесь не задействованны... Цитата Второй вопрос как определить где закончится программа - с какого момента можно будет записать данные (флеш с 0х00100000 без ремапа начинается) Это уже зависит от применяемого компилятора, нужно редактировать какой-нить файл отвечающий за распределение памяти.
|
|
|
|
|
Jun 23 2009, 15:44
|
Группа: Участник
Сообщений: 11
Регистрация: 21-06-09
Пользователь №: 50 508

|
Возможности проверить на железке дома нет. Но вроде бы компилится без ошибок. Есть замечания по коду? Код AT91PS_MC f_pMC = AT91C_BASE_MC;
int flash_write_page(int* addr, int* data, unsigned int size_data) { int page; unsigned int i = 0, count=0; int * Flash; Flash = (int*)addr; page = ((int)addr >> 8); for (i=0;(i<size_data)&&(i<255); Flash++,count++,i += 4) { *Flash= data[count]; } f_pMC->MC_FCR = (0x5a << 24) | (page << 8) | AT91C_MC_FCMD_START_PROG;
while(!( f_pMC->MC_FSR) & AT91C_MC_FRDY);
if((f_pMC->MC_FSR & AT91C_MC_LOCKE) || (f_pMC->MC_FSR & AT91C_MC_PROGE)) { return -1; } return 0; } вызов функции Код //Write Flash s_pAIC->AIC_IDCR = NU1; flash_write_page (data_real,buff_ssc,32); s_pAIC->AIC_IECR = iMask; data_real - начальный адрес области данных (пока фиксированный вручную)
|
|
|
|
|
Jun 23 2009, 15:54
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Не забудьте в MC_FMR записать корректные значения. Цитата(Spoofing @ Jun 23 2009, 19:44)  Код while(!( f_pMC->MC_FSR) & AT91C_MC_FRDY);
if((f_pMC->MC_FSR & AT91C_MC_LOCKE) || (f_pMC->MC_FSR & AT91C_MC_PROGE)) { return -1; } return 0; Здесь потеряете биты ошибок в MC_FSR. Цитата(Spoofing @ Jun 23 2009, 19:44)  Код while(!( f_pMC->MC_FSR) & AT91C_MC_FRDY); Здесь скобки стоят неправильно.
|
|
|
|
|
Jun 23 2009, 17:40
|
Группа: Участник
Сообщений: 11
Регистрация: 21-06-09
Пользователь №: 50 508

|
Код p_pMC->MC_FMR = 0x24<<16; во время начальной инициализации Цитата Здесь скобки стоят неправильно. спасибо, пропустил) Цитата Здесь потеряете биты ошибок в MC_FSR. точно) вот так будет лучше Код int temp; while(!((temp=f_pMC->MC_FSR) & AT91C_MC_FRDY)); if((temp & AT91C_MC_LOCKE) || (temp & AT91C_MC_PROGE)) { return -1; } По вопросу размещения кода \данных - размещение можно только жестко задать областями или как то динамически? Скорее всего в конце проекта можно будет сказать какого размера код и писать данные дальше, но как то не красиво
|
|
|
|
|
Jun 23 2009, 18:10
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Spoofing @ Jun 23 2009, 21:40)  Код p_pMC->MC_FMR = 0x24<<16; во время начальной инициализации Понятно, на 24МГц работаете? Цитата(Spoofing @ Jun 23 2009, 21:40)  По вопросу размещения кода \данных - размещение можно только жестко задать областями или как то динамически? Скорее всего в конце проекта можно будет сказать какого размера код и писать данные дальше, но как то не красиво Обычно можно выпытать у линкера, где кончается программа.
|
|
|
|
|
Jun 23 2009, 19:21
|
Группа: Участник
Сообщений: 11
Регистрация: 21-06-09
Пользователь №: 50 508

|
Цитата Понятно, на 24МГц работаете? пока на отладочной плате, а потом кварц на 18.462
Сообщение отредактировал Spoofing - Jun 23 2009, 19:22
|
|
|
|
|
Jun 24 2009, 15:20
|
Группа: Участник
Сообщений: 11
Регистрация: 21-06-09
Пользователь №: 50 508

|
При прогоне на плате возникли такие проблемы: Если функцию записи проходить по шагам то все прекрасно, обычном запуске вешается на ожидании Код while(!((temp=f_pMC->MC_FSR) & AT91C_MC_FRDY)); бит не устанавливается, при остановке вываливаюсь на строку Код PAbt_Handler B PAbt_Handler в SAM.s В регистре отложенный прерываний висит 01 - fiq хотя я их не использую и перед вызовом функции записи все прерывания запрещены. Хз если бы проблемы были в отсутсвии обработчика то выкидывало бы на Код FIQ_Handler B FIQ_Handler Код #include "board.h" AT91PS_MC f_pMC = AT91C_BASE_MC; int flash_write_page(int addr, char *data, int size_data) { int i = 0, page, temp; int *Flash, *data_temp; Flash = (int*)addr; data_temp= (int*) data; page = (int)((addr - (int)AT91C_IFLASH)>> 8);
for (i=0;(i<size_data)&&(i<255); Flash++,data_temp++,i += 4) { *Flash =*data_temp; } f_pMC->MC_FCR = (0x5a << 24) | (page << 8) | AT91C_MC_FCMD_START_PROG; while(!((temp=f_pMC->MC_FSR) & AT91C_MC_FRDY)); if((temp & AT91C_MC_LOCKE) || (temp & AT91C_MC_PROGE)) { return -1; } return 0; }
Сообщение отредактировал Spoofing - Jun 24 2009, 15:21
|
|
|
|
|
Jun 24 2009, 15:47
|
Группа: Участник
Сообщений: 11
Регистрация: 21-06-09
Пользователь №: 50 508

|
Для выполнения функции из RAM достаточно добавить Код __ramfunc int flash_write_page(int addr, char *data, int size_data) или необходимо еще что то править?
|
|
|
|
|
Jun 24 2009, 18:04
|

Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369

|
Не мучийся вот: CODE //*---------------------------------------------------------------------------- //* ATMEL Microcontroller Software Support - ROUSSET - //*---------------------------------------------------------------------------- //* The software is delivered "AS IS" without warranty or condition of any //* kind, either express, implied or statutory. This includes without //* limitation any warranty or condition with respect to merchantability or //* fitness for any particular purpose, or against the infringements of //* intellectual property rights of others. //*---------------------------------------------------------------------------- //* File Name : Flash.c //* Object : Flash routine //* Creation : JPP 30/Jun/2004 //* Modif : JPM 16/Nov/2004 Flash write status //*----------------------------------------------------------------------------
// Include Standard files #include <hardware.h> #include <flash.h>
#define false 0 #define true 1
//*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Init //* \brief Flash init //*---------------------------------------------------------------------------- void AT91F_Flash_Init (void) { //* Set number of Flash Waite sate // SAM7S64 features Single Cycle Access at Up to 30 MHz // if MCK = 47923200, 50 Cycles for 1 µseconde ( field MC_FMR->FMCN) AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(50 <<16)) | AT91C_MC_FWS_1FWS; }
//*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Ready //* \brief Wait the flash ready //*---------------------------------------------------------------------------- __ramfunc int AT91F_Flash_Ready (void) { unsigned int status; status = 0;
//* Wait the end of command while ((status & AT91C_MC_FRDY) != AT91C_MC_FRDY ) { status = AT91C_BASE_MC->MC_FSR; } return status; }
//*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Lock_Status //* \brief Get the Lock bits field status //*---------------------------------------------------------------------------- __ramfunc int AT91F_Flash_Lock_Status(void) { return (AT91C_BASE_MC->MC_FSR & AT91C_MC_FSR_LOCK); } //*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Lock //* \brief Write the lock bit and set at 0 FSR Bit = 1 //* \input page number (0-1023) //* \output Region //*---------------------------------------------------------------------------- __ramfunc int AT91F_Flash_Lock (unsigned int Flash_Lock_Page) { //* set the Flash controller base address AT91PS_MC ptMC = AT91C_BASE_MC;
//* write the flash //* Write the Set Lock Bit command ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_LOCK | (AT91C_MC_PAGEN & (Flash_Lock_Page << 8) );
//* Wait the end of command AT91F_Flash_Ready();
return (AT91F_Flash_Lock_Status()); } //*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Unlock //* \brief Clear the lock bit and set at 1 FSR bit=0 //* \input page number (0-1023) //* \output Region //*---------------------------------------------------------------------------- __ramfunc int AT91F_Flash_Unlock(unsigned int Flash_Lock_Page) { //* Write the Clear Lock Bit command AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_UNLOCK | (AT91C_MC_PAGEN & (Flash_Lock_Page << 8) );
//* Wait the end of command AT91F_Flash_Ready();
return (AT91F_Flash_Lock_Status()); }
//*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Check_Erase //* \brief Check the memory at 0xFF in 32 bits access //*---------------------------------------------------------------------------- __ramfunc int AT91F_Flash_Check_Erase (unsigned int * start, unsigned int size) { unsigned int i; //* Check if flash is erased for (i=0; i < (size/4); i++ ) { if ( start[i] != ERASE_VALUE ) return false; } return true; }
//*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Erase_All //* \brief Send command erase all flash //*---------------------------------------------------------------------------- __ramfunc int AT91F_Flash_Erase_All(void) { //* set the Flash controller base address AT91PS_MC ptMC = AT91C_BASE_MC; //* Write the Erase All command ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_ERASE_ALL; //* Wait the end of command AT91F_Flash_Ready(); //* Check the result return ( (ptMC->MC_FSR & ( AT91C_MC_PROGE | AT91C_MC_LOCKE ))==0); }
//*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Write //* \brief Write in one Flash page located in AT91C_IFLASH, size in 32 bits //* \input Flash_Address: start at 0x0010 0000 size: in byte //*---------------------------------------------------------------------------- __ramfunc int AT91F_Flash_Write( unsigned int Flash_Address ,int size ,unsigned int * buff) { //* set the Flash controller base address AT91PS_MC ptMC = AT91C_BASE_MC; unsigned int i, page, status; unsigned int * Flash; //* init flash pointer Flash = (unsigned int *) Flash_Address; //* Get the Flash page number page = ((Flash_Address - (unsigned int)AT91C_IFLASH ) /FLASH_PAGE_SIZE_BYTE); //* copy the new value for (i=0; (i < FLASH_PAGE_SIZE_BYTE) & (size > 0);i++, Flash++,buff++,size-=4 ){ //* copy the flash to the write buffer ensuring code generation *Flash=*buff; } //* Write the write page command ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | (AT91C_MC_PAGEN & (page <<8)); //* Wait the end of command status = AT91F_Flash_Ready(); //* Check the result if ( (status & ( AT91C_MC_PROGE | AT91C_MC_LOCKE ))!=0) return false; return true; }
//*---------------------------------------------------------------------------- //* \fn AT91F_Flash_Write //* \brief Write in one Flash page located in AT91C_IFLASH, size in byte //* \input Start address (base=AT91C_IFLASH) size (in byte ) and buff address //*---------------------------------------------------------------------------- __ramfunc int AT91F_Flash_Write_all( unsigned int Flash_Address ,int size ,unsigned int * buff) {
int next, status; unsigned int dest; unsigned int * src;
dest = Flash_Address; src = buff; status = true;
while( (status == true) & (size > 0) ) { //* Check the size if (size <= FLASH_PAGE_SIZE_BYTE) next = size; else next = FLASH_PAGE_SIZE_BYTE;
//* Unlock current sector base address - current address by sector size AT91F_Flash_Unlock((dest - (unsigned int)AT91C_IFLASH ) /FLASH_PAGE_SIZE_BYTE);
//* Write page and get status status = AT91F_Flash_Write( dest ,next ,src); // * get next page param size -= next; src += FLASH_PAGE_SIZE_BYTE/4; dest += FLASH_PAGE_SIZE_BYTE; } return status; }
//*---------------------------------------------------------------------------- //* \fn AT91F_NVM_Status //* \brief Get the NVM field status //*---------------------------------------------------------------------------- __ramfunc int AT91F_NVM_Status(void) { return (AT91C_BASE_MC->MC_FSR & AT91C_MC_FSR_MVM); }
//*---------------------------------------------------------------------------- //* \fn AT91F_NVM_Set //* \brief Write the Non Volatile Memory Bits and set at 0 FSR Bit = 1 //*---------------------------------------------------------------------------- __ramfunc int AT91F_NVM_Set (unsigned char NVM_Number) { //* set the Flash controller base address AT91PS_MC ptMC = AT91C_BASE_MC;
//* write the flash //* Write the Set NVM Bit command ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_SET_GP_NVM | (AT91C_MC_PAGEN & (NVM_Number << 8) );
//* Wait the end of command AT91F_Flash_Ready(); return (AT91F_NVM_Status()); } //*---------------------------------------------------------------------------- //* \fn AT91F_NVM_Clear //* \brief Clear the Non Volatile Memory Bits and set at 1 FSR bit=0 //*---------------------------------------------------------------------------- __ramfunc int AT91F_NVM_Clear(unsigned char NVM_Number) { //* set the Flash controller base address AT91PS_MC ptMC = AT91C_BASE_MC;
//* write the flash //* Write the Clear NVM Bit command ptMC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_CLR_GP_NVM | (AT91C_MC_PAGEN & (NVM_Number << 8) );
//* Wait the end of command AT91F_Flash_Ready();
return (AT91F_NVM_Status()); }
//*---------------------------------------------------------------------------- //* \fn AT91F_SET_Security_Status //* \brief Get Flash Security Bit Status //*---------------------------------------------------------------------------- int AT91F_SET_Security_Status (void) { return (AT91C_BASE_MC->MC_FSR & AT91C_MC_SECURITY); }
//*---------------------------------------------------------------------------- //* \fn AT91F_SET_Security //* \brief Set Flash Security Bit //*---------------------------------------------------------------------------- int AT91F_SET_Security (void) { //* write the flash //* Write the Set Security Bit command AT91C_BASE_MC->MC_FCR = ( AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_SET_SECURITY );
//* Wait the end of command AT91F_Flash_Ready();
return (AT91F_SET_Security_Status()); }
//*---------------------------------------------------------------------------- //* ATMEL Microcontroller Software Support - ROUSSET - //*---------------------------------------------------------------------------- //* The software is delivered "AS IS" without warranty or condition of any //* kind, either express, implied or statutory. This includes without //* limitation any warranty or condition with respect to merchantability or //* fitness for any particular purpose, or against the infringements of //* intellectual property rights of others. //*---------------------------------------------------------------------------- //* File Name : Flash.h //* Object : Flash constan description //* Creation : JPP 30/Jun/2004 //* //*----------------------------------------------------------------------------
#ifndef Flash_h #define Flash_h
/*-------------------------------*/ /* Flash Status Field Definition */ /*-------------------------------*/
#define AT91C_MC_FSR_MVM ((unsigned int) 0xFF << 8) // (MC) Status Register GPNVMx: General-purpose NVM Bit Status #define AT91C_MC_FSR_LOCK ((unsigned int) 0xFFFF << 16) // (MC) Status Register LOCKSx: Lock Region x Lock Status
#define ERASE_VALUE 0xFFFFFFFF
/*-----------------------*/ /* Flash size Definition */ /*-----------------------*/ /* 64 Kbytes of Internal High-speed Flash, Organized in 512 Pages of 128 Bytes */
#define FLASH_PAGE_SIZE_BYTE 256 #define FLASH_PAGE_SIZE_LONG 32
#define FLASH_LOCK_BITS_SECTOR 16 #define FLASH_SECTOR_PAGE 32 #define FLASH_LOCK_BITS 16 /* 16 lock bits, each protecting 16 sectors of 32 pages*/ #define FLASH_BASE_ADDRESS 0x00100000 /*------------------------------*/ /* External function Definition */ /*------------------------------*/
/* Flash function */ extern void AT91F_Flash_Init(void); extern int AT91F_Flash_Check_Erase(unsigned int * start, unsigned int size); extern int AT91F_Flash_Erase_All(void); extern int AT91F_Flash_Write( unsigned int Flash_Address ,int size ,unsigned int * buff); extern int AT91F_Flash_Write_all( unsigned int Flash_Address ,int size ,unsigned int * buff);
/* Lock Bits functions */ extern int AT91F_Flash_Lock_Status(void); extern int AT91F_Flash_Lock (unsigned int Flash_Lock); extern int AT91F_Flash_Unlock(unsigned int Flash_Lock);
/* NVM bits functions */ extern int AT91F_NVM_Status(void); extern int AT91F_NVM_Set (unsigned char NVM_Number); extern int AT91F_NVM_Clear(unsigned char NVM_Number);
/* Security bit function */ extern int AT91F_SET_Security_Status (void); extern int AT91F_SET_Security (void);
#endif /* Flash_h */
Причина редактирования: Нарушение п.3.4 Правил форума.
|
|
|
|
|
Jun 24 2009, 20:04
|
Группа: Участник
Сообщений: 11
Регистрация: 21-06-09
Пользователь №: 50 508

|
А смысл от этого монумента если большая часть не нужна?) Лучше сделать подпрограмму записи команды и ожидания флага и вызывать его из функции записи.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|