|
|
  |
Проблема с памятью MT29F16G08 |
|
|
|
Nov 9 2016, 07:00
|
Группа: Участник
Сообщений: 8
Регистрация: 9-11-16
Пользователь №: 94 110

|
Пытаюсь запустить связку из этой памяти и микроконтроллера AT91RM9200. Инициализация пройдена успешно, id микросхемы я тоже считываю. Также работает считывание страницы. Проблема возникает, когда я пытаюсь записать в память значения. Алгоритм записи следующий: -Имеется буфер unsigned char dataToWrite[31] для записи, первые два байта которого содержат захардкоренные значения 0xAA и 0xBB -Следующие индексы неполностью заполнены данными, байт 20. Незаполненные поля обнулены -Стираю блок, на кототрый я хочу записать данные -Записываю данные -Проверяю статус операции, что она успешна -Читаю данные
Проблема в том, что данные читаются не полностью. Считывается заголовок из 0xAA и 0xBB, 2 нулевых байта, и четыре байта с данными. Весь остальной считанный массив заполнен значениями 0xFF
Кто-нибудь сталкивался с подобным?
Плата работает на частоте 18,43 MHz
|
|
|
|
|
Nov 9 2016, 07:56
|
Группа: Участник
Сообщений: 8
Регистрация: 9-11-16
Пользователь №: 94 110

|
Цитата(MegaVolt @ Nov 9 2016, 10:47)  Как сейчас указана длинна массива? И действительно ли она передаётся равной 32(31)? Или там почему то сейчас передаётся 8? Массив передается весь, с данными, и нулями, размером 31
|
|
|
|
|
Nov 9 2016, 08:04
|
Знающий
   
Группа: Свой
Сообщений: 779
Регистрация: 3-01-05
Из: Минск
Пользователь №: 1 783

|
Цитата(Akscan @ Nov 9 2016, 10:56)  Массив передается весь, с данными, и нулями, размером 31 Тогда странно. Ибо 0xFF говорит про то что в эти места скорее всего записи не было. И там лежат значения после стирания. Попробуйте эксперимент: передать массив любых чисел кроме нулевых. Т.е. чтобы ни в данных ни в хвосте не было нулей. И напишите что получиться.
|
|
|
|
|
Nov 9 2016, 08:06
|
Группа: Участник
Сообщений: 8
Регистрация: 9-11-16
Пользователь №: 94 110

|
Может быть проблема в тактовой частоте? Я прокурил даташит на память, но не нашел(или не заметил) упоминаний о частоте, на которой работает память. Контроллер может слишком быстро писать туда данные? Цитата(MegaVolt @ Nov 9 2016, 11:04)  Тогда странно. Ибо 0xFF говорит про то что в эти места скорее всего записи не было. И там лежат значения после стирания.
Попробуйте эксперимент: передать массив любых чисел кроме нулевых. Т.е. чтобы ни в данных ни в хвосте не было нулей. И напишите что получиться. Пробовал. Пишется опять же 8 байт, остального нет.
|
|
|
|
|
Nov 9 2016, 08:28
|
Группа: Участник
Сообщений: 8
Регистрация: 9-11-16
Пользователь №: 94 110

|
Цитата(Сергей Борщ @ Nov 9 2016, 11:19)  Где-то путаницы (unsigned char *) <->(int *) не может быть? 32 / sizeof(int) = 8. Попробуйте записать, скажем, 28 байт. Писал разное количество, и 31 и 26, и т.д. Код функций на инициализацию, чтение, запись, и прочее: Файл memory.c CODE #ifndef AT91RM9200_H #include <AT91RM9200.H> #endif #include "memory.h" #define PAGE_SIZE 2112 extern unsigned char data[PAGE_SIZE]; extern int statusReadPageNand; extern unsigned char writeData[30];
void delayNand(int a) { while(a!=0) { a--; } }
void BOARD_ConfigureNandFlash(void) { // Configure EBI AT91C_BASE_EBI->EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia; // Setup Flash // WSEN = 1 (Wait states are enabled) // NWS = 1 (Number of Wait States) (1 * 16,7 nS) // DBW = 2 (Data Bus Width - 8-bit) AT91C_BASE_SMC2->SMC2_CSR[3] = (AT91C_SMC2_NWS & 1) | AT91C_SMC2_WSEN | AT91C_SMC2_DBW_8; }
void PIO_Configure_CE_RB(void) { //PC14=SMCE - output AT91C_BASE_PIOC->PIO_IDR = AT91C_PIO_PC14; //Disable interrupts AT91C_BASE_PIOC->PIO_PPUDR = AT91C_PIO_PC14; AT91C_BASE_PIOC->PIO_MDDR = AT91C_PIO_PC14; AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC14; AT91C_BASE_PIOC->PIO_PER = AT91C_PIO_PC14;
//SMWE - output AT91C_BASE_PIOC->PIO_MDDR = AT91C_PIO_PC3; AT91C_BASE_PIOC->PIO_PDR = AT91C_PIO_PC3; AT91C_BASE_PIOC->PIO_ASR = AT91C_PIO_PC3; //SMOE - output AT91C_BASE_PIOC->PIO_MDDR = AT91C_PIO_PC1; AT91C_BASE_PIOC->PIO_PDR = AT91C_PIO_PC1; AT91C_BASE_PIOC->PIO_ASR = AT91C_PIO_PC1; //PC15=SMRB - input AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOC; AT91C_BASE_PIOC->PIO_IDR = AT91C_PIO_PC15; //Disable interrupts AT91C_BASE_PIOC->PIO_PPUDR = AT91C_PIO_PC15; AT91C_BASE_PIOC->PIO_IFDR = AT91C_PIO_PC15; AT91C_BASE_PIOC->PIO_ODR = AT91C_PIO_PC15; AT91C_BASE_PIOC->PIO_PER = AT91C_PIO_PC15; }
unsigned char Get_SMRB(void) { unsigned int reg = AT91C_BASE_PIOC->PIO_PDSR;
if ((reg & AT91C_PIO_PC15) == 0) { return 0; } else { return 1; } }
void WaitReady(void) { while (!Get_SMRB()); }
void NandFlash_Reset(void) { // PC14 #CE=0 AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC14; //0 WRITE_COMMAND(COMMAND_RESET); WaitReady(); // PC14 #CE=1 AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 }
int NandFlash_ReadId(void) { unsigned int chipId; unsigned char chipId2;
// PC14 #CE=0 AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC14; //0
WRITE_COMMAND(COMMAND_READID); WRITE_ADDRESS(0); chipId = READ_DATA8; if (chipId == 0x2C) { AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 return 1; } chipId |= READ_DATA8 << 8; chipId |= READ_DATA8 << 16; chipId |= READ_DATA8 << 24; chipId2 = READ_DATA8; // PC14 #CE=1 AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 if(chipId==0) chipId=10; if(chipId2==0) chipId2=10; return chipId; }
void NandFlash_Read(int column, int row, int page, int LUN, int plane) { int column1,column2,row1,row2,row3; int i = 0;
int cycle1,cycle2,cycle3,cycle4,cycle5; cycle1 = column%65536; cycle2 = column>>16;
cycle3 = page; cycle3 |= plane<<7;
cycle4 = row%65536; cycle5 = row>>9; cycle5 |= LUN<<10;
// PC14 #CE=0 AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC14; //0 WRITE_COMMAND(COMMAND_READ_1); WRITE_ADDRESS(cycle1); WRITE_ADDRESS(cycle2);
WRITE_ADDRESS(cycle3); WRITE_ADDRESS(cycle4); WRITE_ADDRESS(cycle5); WRITE_COMMAND(COMMAND_READ_2); WaitReady(); for(i = 0; i<PAGE_SIZE; i++) { data[i] = READ_DATA8; delayNand(1); data[i] |= READ_DATA8 << 8; delayNand(1); data[i] |= READ_DATA8 << 16; delayNand(1); data[i] |= READ_DATA8 << 24; delayNand(1); } // PC14 #CE=1 AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 }
void NandFlash_Write(int column, int row, int page, int LUN, int plane) { // PC14 #CE=0 int column1,column2,row1,row2,row3,i; int cycle1,cycle2,cycle3,cycle4,cycle5; unsigned char * Write; Write = (unsigned char *) writeData;
cycle1 = column%65536; cycle2 = column>>16;
cycle3 = page; cycle3 |= plane<<7;
cycle4 = row%65536; cycle5 = row>>9; cycle5 |= LUN<<10;
AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC14; //0 WRITE_COMMAND(COMMAND_WRITE_1);
WRITE_ADDRESS(cycle1); WRITE_ADDRESS(cycle2);
WRITE_ADDRESS(cycle3); WRITE_ADDRESS(cycle4); WRITE_ADDRESS(cycle5);
for(i = 10;i>0;i--) { WRITE_DATA8(Write[i]); delayNand(1); }
WRITE_COMMAND(COMMAND_WRITE_2); WaitReady(); // PC14 #CE=1 AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 }
unsigned char NandFlash_ReadStatus() { int status; AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC14; //0 WRITE_COMMAND(COMMAND_READ_STATUS); status = READ_DATA8; WaitReady();
AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 return status; }
void NandFlash_EraseBlock(int column, int page, int plane) { unsigned char status; int cycle1,cycle2,cycle3; cycle1 = column%65536; cycle2 = column>>16;
cycle3 = page; cycle3 |= plane<<7;
AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC14; //0 WRITE_COMMAND(COMMAND_ERASE_1); WRITE_ADDRESS(cycle1); WRITE_ADDRESS(cycle2); WRITE_ADDRESS(cycle3); WRITE_COMMAND(COMMAND_ERASE_2); WaitReady(); AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 status = NandFlash_ReadStatus(); } void NandFlash_WriteFF(int column,int row, int page, int LUN, int plane) { // PC14 #CE=0 int column1,column2,row1,row2,row3,i; int cycle1,cycle2,cycle3,cycle4,cycle5; unsigned char * Write; Write = (unsigned char *) writeData;
cycle1 = column%65536; cycle2 = column>>16;
cycle3 = page; cycle3 |= plane<<7;
cycle4 = row%65536; cycle5 = row>>9; cycle5 |= LUN<<10;
AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC14; //0 WRITE_COMMAND(COMMAND_WRITE_1);
WRITE_ADDRESS(cycle1); WRITE_ADDRESS(cycle2);
WRITE_ADDRESS(cycle3); WRITE_ADDRESS(cycle4); WRITE_ADDRESS(cycle5);
for(i = 2112;i>0;i--) { WRITE_DATA8(0xFF); delayNand(1); }
WRITE_COMMAND(COMMAND_WRITE_2); WaitReady(); // PC14 #CE=1 AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC14; //1 }
Файл memory.h CODE #ifndef MEMORY_H #define MEMORY_H #endif #define COMMAND_RESET 0xFF #define COMMAND_READID 0x90 #define COMMAND_READ_1 0x00 #define COMMAND_READ_2 0x30 #define COMMAND_WRITE_1 0x80 #define COMMAND_WRITE_2 0x10 #define COMMAND_ERASE_1 0x60 #define COMMAND_ERASE_2 0xD0 #define COMMAND_READ_STATUS 0x70
/// Address for transferring command bytes to the nandflash. #define BOARD_NF_COMMAND_ADDR 0x40200000 /// Address for transferring address bytes to the nandflash. #define BOARD_NF_ADDRESS_ADDR 0x40400000 /// Address for transferring data bytes to the nandflash. #define BOARD_NF_DATA_ADDR 0x40000000
#define WRITE_COMMAND(command) \ {*((volatile unsigned char *) BOARD_NF_COMMAND_ADDR) = (unsigned char) command;} #define WRITE_ADDRESS(address) \ {*((volatile unsigned char *) BOARD_NF_ADDRESS_ADDR) = (unsigned char) address;} #define WRITE_DATA8(data) \ {*((volatile unsigned char *) BOARD_NF_DATA_ADDR) = (unsigned char) data;} #define READ_DATA8 \ (*((volatile unsigned char *) BOARD_NF_DATA_ADDR)) void BOARD_ConfigureNandFlash(void); void PIO_Configure_CE_RB(void); unsigned char Get_SMRB(void); void WaitReady(void); void NandFlash_Reset(void); int NandFlash_ReadId(void); void NandFlash_Write(int column,int row, int page, int LUN, int plane); void NandFlash_Read(int column,int row, int page, int LUN, int plane); unsigned char NandFlash_ReadStatus(); void NandFlash_EraseBlock(int column, int page, int plane); void NandFlash_WriteFF(int column,int row, int page, int LUN, int plane);
Сообщение отредактировал Akscan - Nov 9 2016, 08:30
|
|
|
|
|
Nov 9 2016, 08:49
|
Знающий
   
Группа: Свой
Сообщений: 779
Регистрация: 3-01-05
Из: Минск
Пользователь №: 1 783

|
Если я правильно понимаю этот кусочек пишет 10 байт. Всегда вне зависимости от реально длинны данных. Правда не 8..... Код for(i = 10;i>0;i--) { WRITE_DATA8(Write[i]); delayNand(1); }
|
|
|
|
|
Nov 9 2016, 08:54
|
Группа: Участник
Сообщений: 8
Регистрация: 9-11-16
Пользователь №: 94 110

|
Цитата(MegaVolt @ Nov 9 2016, 11:49)  Если я правильно понимаю этот кусочек пишет 10 байт. Всегда вне зависимости от реально длинны данных. Правда не 8..... Код for(i = 10;i>0;i--) { WRITE_DATA8(Write[i]); delayNand(1); } Я его менял, когда разные значение писать пробовал
|
|
|
|
|
Nov 9 2016, 10:29
|
Группа: Участник
Сообщений: 8
Регистрация: 9-11-16
Пользователь №: 94 110

|
Цитата(Сергей Борщ @ Nov 9 2016, 12:10)  Типичный ответ программиста - точный и не несущий никакой полезной информации  И каков был результат этих записей? Писалось все равно 8? Больше? Меньше? Ну бывает) Точно 8. Цитата(MegaVolt @ Nov 9 2016, 12:00)  Осциллограф видит все импульсы записи? Да, сейчас проверил, импульсы видны все.
|
|
|
|
|
Nov 9 2016, 13:09
|
Группа: Участник
Сообщений: 8
Регистрация: 9-11-16
Пользователь №: 94 110

|
Цитата(MegaVolt @ Nov 9 2016, 15:52)  Неожиданно. Повторная запись без стирания что даёт? Ничего не дает, хотя и пробовал. По даташиту на микросхему, стирание перед записью обязательно. Есть подозрение, что стирание не выполняется, но тогда это выплыло бы в проверке статуса, а она проходит успешно
|
|
|
|
|
Nov 10 2016, 05:43
|
Группа: Участник
Сообщений: 8
Регистрация: 9-11-16
Пользователь №: 94 110

|
Нашелся один косяк в разводке платы. Две ноги запаяны неправильно. Всем большое спасибо за помощь, буду копать дальше. Если что, подниму тему.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|