|
|
View previous topic :: View next topic |
Author |
Message |
Jerry507
Joined: 23 Jun 2004 Posts: 3
|
Atmel Dataflash problems |
Posted: Thu Jul 29, 2004 10:52 am |
|
|
Hello,
I am attempting to use a piece of Atmel AT45DB041B flash memory with a PIC18F452 and I'm running into a few problems.
After some work, I've gotten the SPI working properly. I can read status bits off the memory, as well as write to and read from either buffer. However, I am (seemingly) unable to write to the main flash memory or read back from it. If I write to the buffer, and then use to buffer to main memory command, and then use a continuous read starting at the address I wrote to buffer to all I get are 1's. If I initiate the command, and then immediately read the status bit, the status bit indicates the device is busy. Checking the status bit again after several ms (I usually use 20, just to be safe) indicates the device is ready again.
I've looked through the datasheet about a zillion times, and went over the App note from Atmel, as well as reading some code I found on these forums. They all appear to do exactly what I do! As you might imagine, this is getting quite frustrating. I've ordered some different flash memory to use for this project, but my curiosity is keeping me working on this Atmel memory just to figure out what's wrong. Any insight would be greatly appreciated. Following are the functions I'm using to interact with the memory:
#define CS_PIN PIN_A1
void b1topage(long destpage)
{
output_low(CS_PIN);
spi_write(0x83);
spi_write(destpage>>7);
spi_write(destpage<<1);
spi_write(0x00); // don't cares
output_high(CS_PIN);
}
void b1write(char data, long bufferaddr)
{
output_low(CS_PIN);
spi_Write(0x84);
spi_write(0x00); // Don't cares
spi_write(bufferaddr>>8);
spi_write(make8(bufferaddr,0));
spi_write(data);
output_high(CS_PIN);
}
void contread(long startpage) // Continuous read mode
{
output_low(CS_PIN);
spi_write(0xE8);
spi_write(startpage>>7);
spi_write(startpage<<1);
spi_write(0x00);
spi_write(0x00);
spi_write(0x00);
spi_write(0x00);
spi_write(0x00);
}
void b1read(long startbyte)
{
output_low(CS_PIN);
spi_write(0xD4);
spi_write(0x00);
spi_write(startbyte>>8);
spi_write(make8(startbyte,0));
spi_write(0x00);
}
void pageread(long startpage)
{
output_low(CS_PIN);
spi_write(0xD2);
spi_write(startpage>>7);
spi_write(startpage<<1);
spi_write(0x00);
spi_write(0x00);
spi_write(0x00);
spi_write(0x00);
spi_write(0x00);
}
void closeread()
{
output_high(CS_PIN);
}
char readstatus()
{
char status;
output_low(CS_PIN);
spi_write(0x57);
status=spi_read(0x00);
output_high(CS_PIN);
return status;
}
If you need anything else from my code, just let me know and I'll post it up. I did not feel anything else was pertinent to my problem, but I'm willing to do anything to solve this problem. Thanks in advance. |
|
|
adrian
Joined: 08 Sep 2003 Posts: 92 Location: Glasgow, UK
|
|
Posted: Fri Jul 30, 2004 5:26 am |
|
|
I assume that you havn't grounded the WR# pin that write protects the first 256 pages? |
|
|
dvsoft
Joined: 28 Nov 2003 Posts: 46
|
|
Posted: Fri Jul 30, 2004 7:23 am |
|
|
Boujour,
i use the Atmel AR45DB321B with a PIC18F452 without problem.
My driver
//---------------------------------------------------------------------------
// Copyright (c) DVSoft 2004
// email dvsoft@club-internet.fr
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation.
//
// This program is distributed in the hope it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANDIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// Originale Unit Name : DTFService.c
// Author : Alain
// Date : 15-Avril-2004
// Project : YA1-LOGGER-V3
// Version : 0.9.0.1
// Revision :
//
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Dataflash Config
//
const int16 DTFBlockSize = 512; // DTF block Size
const int16 DTFPageSize = 528; // DTF Page Size
const int16 DTFNbrPage = 8192; // DTF Nb Page
//---------------------------------------------------------------------------
// Dataflash Macro
// the PIC18F452 running at 10Mhz with PPL*4 are to fast for the
// DataFlash so wait some cycle for correct operation
//
#define DTFSelect()\
output_low(DTF_CS);\
delay_cycles(3)
#define DTFUnSelect()\
output_high(DTF_CS);\
delay_cycles(3)
#define DTFIsReady() (input(DTF_READY))
//---------------------------------------------------------------------------
// DataFlash PageCount
//
int16 DTFPageCnt;
#byte DTFPageCnt_L=DTFPageCnt
#byte DTFPageCnt_H=DTFPageCnt+1
//---------------------------------------------------------------------------
// DataFlash ByteCount
//
int16 DTFByteCnt;
#byte DTFByteCnt_L=DTFByteCnt
#byte DTFByteCnt_H=DTFByteCnt+1
//---------------------------------------------------------------------------
// DataFlash Address
//
int16 DTFAddress;
#byte DTFAddress_L=DTFAddress
#byte DTFAddress_H=DTFAddress+1
//---------------------------------------------------------------------------
// DataFlash Dump PageCnt
//
int16 DTFDumpPageCnt;
//---------------------------------------------------------------------------
// DataFlash Full Flags
//
BOOLEAN DTFFull;
//---------------------------------------------------------------------------
// DataFlash Buffer Select
//
BOOLEAN DTF_Buffer_2_Active;
//---------------------------------------------------------------------------
#separate
int8 DTFReadStatus(void)
{
int8 Status;
//--- Select
DTFSelect();
//--- Command Read Status
spi_write(0x57);
//--- Status Result
Status = spi_read(0);
//--- Unselect
DTFUnSelect();
return (Status);
}
//---------------------------------------------------------------------------
#separate
void DTFPageToRam(int16 PageNum)
{
//--- Active buffer to main memory page
DTFAddress = (PageNum << 2);
while (!DTFIsReady());
//--- Select
DTFSelect();
//--- Buffer 2 is Active Buffer
if (DTF_Buffer_2_Active) {
//--- Memory Page To Buffer 1
spi_write(0x53);
//--- Set Buffer 1 Active
DTF_Buffer_2_Active = FALSE;
}// End IF
//--- Buffer 1 is Active Buffer
else {
//--- Memory Page To Buffer 2
spi_write(0x55);
//--- Set Buffer 2 Active
DTF_Buffer_2_Active = TRUE;
}// End Else
//--- 7 high address bits
spi_write(DTFAddress_H);
//--- 6 low address bits
spi_write(DTFAddress_L);
//--- don't care 8 bits
spi_write(0x00);
//--- Unselect
DTFUnSelect();
}
//---------------------------------------------------------------------------
#separate
void DTFRAMToPage(int16 PageNum)
{
//--- Active buffer to main memory page
DTFAddress = (PageNum << 2);
//--- Wait DTF_Ready
while (!DTFIsReady());
//--- Select
DTFSelect();
//--- Use Buffer 2 ?
if (DTF_Buffer_2_Active) {
//--- Buffer 2 To PAGE With Built In erase
spi_write(0x86);
//--- Set Buffer 1 Active
DTF_Buffer_2_Active = FALSE;
}// End IF
else {
//--- Buffer 1 To PAGE With Built In erase
spi_write(0x83);
//--- Set Buffer 2 Active
DTF_Buffer_2_Active = TRUE;
}// End ELse
//--- 7 high address bits
spi_write(DTFAddress_H);
//--- 6 low address bits
spi_write(DTFAddress_L);
//--- don't care 8 bits
spi_write(0x00);
//--- Unselect
DTFUnSelect();
}
//---------------------------------------------------------------------------
// Initialisation du Dump commande 'I'
//
#separate
void DTFInitDump(void)
{
//--- First Page
DTFDumpPageCnt = 0;
//--- Load in memeory buffer
DTFPageToRam(DTFDumpPageCnt);
}
#separate
//---------------------------------------------------------------------------
// Selection de la page suivants command 'N'
// return:
// 0 si fin la derniere page enregistrée est passé
// 1 si il reste des pages a lire
//
int DTFDumpNextPage(void)
{
//--- Selection de la page Suivante si < au nombre de pages dispo
DTFDumpPageCnt++;
if (DTFDumpPageCnt < DTFPageCnt) {
//--- Chargement en memoire de la page
DTFPageToRam(DTFDumpPageCnt);
//--- OK
return 1;
}// End If
//--- Fin
return 0;
}
//---------------------------------------------------------------------------
// Dump du packet courrant commande 'D'
//
#separate
void DTFDumpPacket(void)
{
int8 TxBuffer;
int16 ByteCnt;
//--- Wait DTF_Ready
while (!DTFIsReady());
//--- Initialisation
DTFSelect();
//--- Buffer 2 is Active ?
if (DTF_Buffer_2_Active)
spi_write(0x56);
//--- Buffer 1 is Active
else
spi_write(0x54);
//--- 8 Dont'care Byte
spi_write(0x00);
//--- High Byte address
spi_write(0x00);
//--- Low Byte address
spi_write(0x00);
//--- 8 Dont'care Byte
spi_write(0x00);
//--- Byte Count
ByteCnt = DTFPageSize;
//--- Load In Buffer
do {
//--- Dump the current page
TxBuffer = spi_read(0);
putc(TxBuffer);//printf("%c",TxBuffer);
} while (--ByteCnt);
//--- Unselect
DTFUnSelect();
}
//---------------------------------------------------------------------------
#separate
void DTFServiceStart(void)
{
int8 Status;
//--- Setup du SPI
setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_4|SPI_SAMPLE_AT_END);
//--- Buffer 1 Is Active Buffer
DTF_Buffer_2_Active = FALSE;
//--- Lecture du Status de la DataFlash
DTFReadStatus();
Status = DTFReadStatus();
//--- Status OK ?
if (Status & 0x80) {
//--- DataFlash FULL
DTFFull = (DTFPageCnt == DTFNbrPage);
//--- First Word
DTFByteCnt = 0;
//--- Dump page Count
DTFDumpPageCnt = 0;
//--- DataFalsh OK
DTFServiceRun = TRUE;
}// End If
else
//--- DataFlash HS
DTFServiceRun = FALSE;
}
//---------------------------------------------------------------------------
// Specifique function for YA1-Logger-V2
//
#separate
void DTFWriteToFlash(int8 Data)
{
//--- Service RUN
if (!DTFServiceRun)
return;
//--- DTF Full
if (DTFFull)
return;
//--- Wait Ready
while (!DTFIsReady());
//--- Start Write Ram
DTFSelect();
//--- Write To Buffer 1 ?
if (DTF_Buffer_2_Active)
spi_write(0x87);
//--- Write to Buffer 2
else
spi_write(0x84);
//--- 8 Don't care Bit
spi_write(0x00);
//--- High Byte address
spi_write(DTFByteCnt_H);
//--- Low Byte address
spi_write(DTFByteCnt_L);
//--- Write The Value
spi_write(Data);
//--- UnSelect
DTFUnSelect();
//--- Next Word Address In DataFlash
DTFByteCnt++;
//--- Last page Byte ?
if (DTFByteCnt >= DTFPageSize) {
//--- WriteRam Start Addresse
DTFByteCnt = 0;
//--- RAM To Memory page with builtin erase
DTFRAMToPage(DTFPageCnt);
//--- Next Page
DTFPageCnt++;
//--- Store the Last Page Value in PIC eeprom
erase_program_eeprom(DTFPageCntRomAddress);
write_program_eeprom(DTFPageCntRomAddress,DTFPageCnt);
//--- Last Page ?
if (DTFPageCnt >= DTFNbrPage)
DTFFull = TRUE;
}// End IF
}
//--------------------------------------------------------------------------- |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|