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

Проблема с памятью MT29F16G08

Пытаюсь запустить связку из этой памяти и микроконтроллера AT91RM9200. Инициализация пройдена успешно, id микросхемы я тоже считываю. Также работает считывание страницы. Проблема возникает, когда я пытаюсь записать в память значения. Алгоритм записи следующий:

-Имеется буфер unsigned char dataToWrite[31] для записи, первые два байта которого содержат захардкоренные значения 0xAA и 0xBB

-Следующие индексы неполностью заполнены данными, байт 20. Незаполненные поля обнулены

-Стираю блок, на кототрый я хочу записать данные

-Записываю данные

-Проверяю статус операции, что она успешна

-Читаю данные

 

Проблема в том, что данные читаются не полностью. Считывается заголовок из 0xAA и 0xBB, 2 нулевых байта, и четыре байта с данными. Весь остальной считанный массив заполнен значениями 0xFF

 

Кто-нибудь сталкивался с подобным?

 

Плата работает на частоте 18,43 MHz

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


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

-Имеется буфер unsigned char dataToWrite[31]

Проблема в том, что данные читаются не полностью. Считывается заголовок из 0xAA и 0xBB, 2 нулевых байта, и четыре байта с данными. Весь остальной считанный массив заполнен значениями 0xFF

Как сейчас указана длинна массива? И действительно ли она передаётся равной 32(31)? Или там почему то сейчас передаётся 8?

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


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

Как сейчас указана длинна массива? И действительно ли она передаётся равной 32(31)? Или там почему то сейчас передаётся 8?

Массив передается весь, с данными, и нулями, размером 31

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


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

Массив передается весь, с данными, и нулями, размером 31
Тогда странно. Ибо 0xFF говорит про то что в эти места скорее всего записи не было. И там лежат значения после стирания.

 

Попробуйте эксперимент: передать массив любых чисел кроме нулевых. Т.е. чтобы ни в данных ни в хвосте не было нулей. И напишите что получиться.

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


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

Может быть проблема в тактовой частоте? Я прокурил даташит на память, но не нашел(или не заметил) упоминаний о частоте, на которой работает память. Контроллер может слишком быстро писать туда данные?

 

Тогда странно. Ибо 0xFF говорит про то что в эти места скорее всего записи не было. И там лежат значения после стирания.

 

Попробуйте эксперимент: передать массив любых чисел кроме нулевых. Т.е. чтобы ни в данных ни в хвосте не было нулей. И напишите что получиться.

Пробовал. Пишется опять же 8 байт, остального нет.

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


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

Где-то путаницы (unsigned char *) <->(int *) не может быть? 32 / sizeof(int) = 8. Попробуйте записать, скажем, 28 байт.

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


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

Где-то путаницы (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);    

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

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


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

Если я правильно понимаю этот кусочек пишет 10 байт. Всегда вне зависимости от реально длинны данных. Правда не 8.....

 

        for(i = 10;i>0;i--)
        {
            WRITE_DATA8(Write[i]);
            delayNand(1);
        }

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


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

Если я правильно понимаю этот кусочек пишет 10 байт. Всегда вне зависимости от реально длинны данных. Правда не 8.....

 

        for(i = 10;i>0;i--)
        {
            WRITE_DATA8(Write[i]);
            delayNand(1);
        }

Я его менял, когда разные значение писать пробовал

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


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

Писал разное количество, и 31 и 26, и т.д.
Типичный ответ программиста - точный и не несущий никакой полезной информации :) И каков был результат этих записей? Писалось все равно 8? Больше? Меньше?

 

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


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

Типичный ответ программиста - точный и не несущий никакой полезной информации :) И каков был результат этих записей? Писалось все равно 8? Больше? Меньше?

Ну бывает)

Точно 8.

 

Осциллограф видит все импульсы записи?

Да, сейчас проверил, импульсы видны все.

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


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

Да, сейчас проверил, импульсы видны все.
Неожиданно. Повторная запись без стирания что даёт?

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


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

Неожиданно. Повторная запись без стирания что даёт?

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

Есть подозрение, что стирание не выполняется, но тогда это выплыло бы в проверке статуса, а она проходит успешно

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


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

Нашелся один косяк в разводке платы. Две ноги запаяны неправильно.

Всем большое спасибо за помощь, буду копать дальше. Если что, подниму тему.

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


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

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

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

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

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

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

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

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

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

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