Akscan 0 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Пытаюсь запустить связку из этой памяти и микроконтроллера AT91RM9200. Инициализация пройдена успешно, id микросхемы я тоже считываю. Также работает считывание страницы. Проблема возникает, когда я пытаюсь записать в память значения. Алгоритм записи следующий: -Имеется буфер unsigned char dataToWrite[31] для записи, первые два байта которого содержат захардкоренные значения 0xAA и 0xBB -Следующие индексы неполностью заполнены данными, байт 20. Незаполненные поля обнулены -Стираю блок, на кототрый я хочу записать данные -Записываю данные -Проверяю статус операции, что она успешна -Читаю данные Проблема в том, что данные читаются не полностью. Считывается заголовок из 0xAA и 0xBB, 2 нулевых байта, и четыре байта с данными. Весь остальной считанный массив заполнен значениями 0xFF Кто-нибудь сталкивался с подобным? Плата работает на частоте 18,43 MHz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба -Имеется буфер unsigned char dataToWrite[31] Проблема в том, что данные читаются не полностью. Считывается заголовок из 0xAA и 0xBB, 2 нулевых байта, и четыре байта с данными. Весь остальной считанный массив заполнен значениями 0xFF Как сейчас указана длинна массива? И действительно ли она передаётся равной 32(31)? Или там почему то сейчас передаётся 8? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Akscan 0 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Как сейчас указана длинна массива? И действительно ли она передаётся равной 32(31)? Или там почему то сейчас передаётся 8? Массив передается весь, с данными, и нулями, размером 31 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Массив передается весь, с данными, и нулями, размером 31Тогда странно. Ибо 0xFF говорит про то что в эти места скорее всего записи не было. И там лежат значения после стирания. Попробуйте эксперимент: передать массив любых чисел кроме нулевых. Т.е. чтобы ни в данных ни в хвосте не было нулей. И напишите что получиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Akscan 0 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Может быть проблема в тактовой частоте? Я прокурил даташит на память, но не нашел(или не заметил) упоминаний о частоте, на которой работает память. Контроллер может слишком быстро писать туда данные? Тогда странно. Ибо 0xFF говорит про то что в эти места скорее всего записи не было. И там лежат значения после стирания. Попробуйте эксперимент: передать массив любых чисел кроме нулевых. Т.е. чтобы ни в данных ни в хвосте не было нулей. И напишите что получиться. Пробовал. Пишется опять же 8 байт, остального нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Где-то путаницы (unsigned char *) <->(int *) не может быть? 32 / sizeof(int) = 8. Попробуйте записать, скажем, 28 байт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Akscan 0 9 ноября, 2016 Опубликовано 9 ноября, 2016 (изменено) · Жалоба Где-то путаницы (unsigned char *) <->(int *) не может быть? 32 / sizeof(int) = 8. Попробуйте записать, скажем, 28 байт. Писал разное количество, и 31 и 26, и т.д. Код функций на инициализацию, чтение, запись, и прочее: Файл memory.c #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 #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); Изменено 9 ноября, 2016 пользователем Akscan Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Если я правильно понимаю этот кусочек пишет 10 байт. Всегда вне зависимости от реально длинны данных. Правда не 8..... for(i = 10;i>0;i--) { WRITE_DATA8(Write[i]); delayNand(1); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Akscan 0 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Если я правильно понимаю этот кусочек пишет 10 байт. Всегда вне зависимости от реально длинны данных. Правда не 8..... for(i = 10;i>0;i--) { WRITE_DATA8(Write[i]); delayNand(1); } Я его менял, когда разные значение писать пробовал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Осциллограф видит все импульсы записи? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Писал разное количество, и 31 и 26, и т.д.Типичный ответ программиста - точный и не несущий никакой полезной информации :) И каков был результат этих записей? Писалось все равно 8? Больше? Меньше? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Akscan 0 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Типичный ответ программиста - точный и не несущий никакой полезной информации :) И каков был результат этих записей? Писалось все равно 8? Больше? Меньше? Ну бывает) Точно 8. Осциллограф видит все импульсы записи? Да, сейчас проверил, импульсы видны все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Да, сейчас проверил, импульсы видны все.Неожиданно. Повторная запись без стирания что даёт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Akscan 0 9 ноября, 2016 Опубликовано 9 ноября, 2016 · Жалоба Неожиданно. Повторная запись без стирания что даёт? Ничего не дает, хотя и пробовал. По даташиту на микросхему, стирание перед записью обязательно. Есть подозрение, что стирание не выполняется, но тогда это выплыло бы в проверке статуса, а она проходит успешно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Akscan 0 10 ноября, 2016 Опубликовано 10 ноября, 2016 · Жалоба Нашелся один косяк в разводке платы. Две ноги запаяны неправильно. Всем большое спасибо за помощь, буду копать дальше. Если что, подниму тему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться