|
|
View previous topic :: View next topic |
Author |
Message |
janiga
Joined: 10 Apr 2006 Posts: 22
|
SPI EEPROM WRITE PROBLEM, READING SEEMS OK NOT SURE! |
Posted: Sun Apr 22, 2007 8:57 am |
|
|
HELLO,
I AM USING A 16F917 CONNECTED TO 25LC1024 WHICH IS VERY FAMILIAR WITH 25LC640.
I MODDED THE DRIVER SUPPLIED BY CCS AND MODIFIED THE SIZE OF EEPROM TO 131072 AND CHANGED THE FOR LOOPS FROM 32 TO 40 AND 24 TO 32 RESPECTIVELY TO ADD THE ADDITIONAL CLOCK CYCLES. WHEN I DO A READ I GET 255 ON LCD WHICH SEEMS LIKE THATS WHAT SHOULD BE IN MEMORY TO START WITH.
WHEN I WRITE TO IT AND THEN READ, I GET 255. CAN SOMEONE HELP!
THANKS
HERE IS CODE
Code: |
#include "MEM TEST.h"
#include <LCD>
#include <25LC1024.c>
UNSIGNED LONG DATAIN;
void main()
{
setup_adc_ports(sAN0|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_lcd(LCD_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,249,10);
setup_ccp1(CCP_PWM);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
setup_oscillator(False);
WHILE (TRUE)
{
printf(lcd_putc,"\fINIT\nEEPROM");
delay_ms(1500);
init_ext_eeprom();
WRITE_EXT_EEPROM(15,15);
printf(lcd_putc,"\fREAD\nEEPROM");
delay_ms(1500);
DATAIN = read_ext_eeprom(15);
printf(lcd_putc,"\fDATA IS\n%LU",DATAIN);
DELAY_MS(1500);
}
}
|
FUSES
Code: |
#include <16F917.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES MCLR //Master Clear pin enabled
#FUSES NOCPD //No EE protection
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 22, 2007 2:44 pm |
|
|
If you want us to look at the driver, then you need to post it. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Apr 22, 2007 3:59 pm |
|
|
Janiga,
When writing text on the internet please turn of your caps-lock key. Writing text in all capital symbols is hard to read and considered shouting (that is, you are not being nice).
What is your compiler version? |
|
|
janiga
Joined: 10 Apr 2006 Posts: 22
|
help |
Posted: Sun Apr 22, 2007 5:26 pm |
|
|
Compiler ver. 4.018
Driver:
Code: |
// 25LC1024 DRIVER VERSION 1
#ifndef EEPROM_SELECT
#define EEPROM_SELECT PIN_B0
#define EEPROM_CLK PIN_B1
#define EEPROM_DI PIN_B2
#define EEPROM_DO PIN_B4
#endif
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 131072
void init_ext_eeprom() {
output_high(EEPROM_SELECT);
output_low(EEPROM_DI);
output_low(EEPROM_CLK);
}
BOOLEAN ext_eeprom_ready() {
BYTE cmd[1], i, data;
cmd[0] = 0x05; //rdsr opcode
output_low(EEPROM_SELECT);
for(i=1; i<=8; ++i) {
output_bit(EEPROM_DI, shift_left(cmd,1,0));
output_high(EEPROM_CLK); //data latches
output_low(EEPROM_CLK); //back to idle
}
for(i=1; i<=8; ++i) {
output_high(EEPROM_CLK); //data latches
shift_left(&data,1,input(EEPROM_DO));
output_low(EEPROM_CLK); //back to idle
}
output_high(EEPROM_SELECT);
return !bit_test(data, 0);
}
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data) {
BYTE cmd[4];
BYTE i;
BYTE wren;
wren=0x06;
cmd[0]=data;
cmd[1]=address;
cmd[2]=(address>>8);
cmd[3]=0x02;
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<8; ++i)
{
output_bit(EEPROM_DI, shift_left(&wren,1,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
output_low(EEPROM_SELECT);
for(i=0; i<40; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,4,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
}
BYTE read_ext_eeprom(EEPROM_ADDRESS address) {
BYTE cmd[3];
BYTE i,data;
cmd[0]=address;
cmd[1]=(address>>8);
cmd[2]=0x03;
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<32; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,3,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
for(i=0; i<8; ++i)
{
shift_left(&data,1,input(EEPROM_DO));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
return(data);
}
|
and my apologies for the caps. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 22, 2007 6:35 pm |
|
|
Your write routine needs a few corrections.
1. You have defined 'EEPROM_ADDRESS' as a 'long int'. But a 'long int'
is only 16 bits in CCS. You have a 32-bit address. Therefore you
need to define it as an 'int32'.
2. In the 25LC1024, the address field in a write operation consists
of 24 bits (3 bytes) of address. But your 'cmd' array only has
two bytes of address. You need to enlarge the 'cmd' array so
it can hold 5 bytes (instead of the current 4 bytes), and also put
in code to shift the 3rd byte of the address by 16-bits, so it's in
properly loaded into the array.
The read function needs similar fixes as above. |
|
|
janiga
Joined: 10 Apr 2006 Posts: 22
|
25LC1024 driver |
Posted: Sun Apr 22, 2007 9:09 pm |
|
|
Here is the code that seems to be working.
If anyone can elaborate more to this please feel free!
Code: |
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 131072
void init_ext_eeprom() {
output_high(EEPROM_SELECT);
output_low(EEPROM_DI);
output_low(EEPROM_CLK);
}
BOOLEAN ext_eeprom_ready() {
BYTE cmd[1], i, data;
cmd[0] = 0x05; //rdsr opcode
output_low(EEPROM_SELECT);
for(i=1; i<=8; ++i) {
output_bit(EEPROM_DI, shift_left(cmd,1,0));
output_high(EEPROM_CLK); //data latches
output_low(EEPROM_CLK); //back to idle
}
for(i=1; i<=8; ++i) {
output_high(EEPROM_CLK); //data latches
shift_left(&data,1,input(EEPROM_DO));
output_low(EEPROM_CLK); //back to idle
}
output_high(EEPROM_SELECT);
return !bit_test(data, 0);
}
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data) {
BYTE cmd[5];
BYTE i;
BYTE wren;
wren=0x06;
cmd[0]=data;
cmd[1]=address;
cmd[2]=(address>>8);
cmd[3]=(address>>8);
cmd[4]=0x02;
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<8; ++i)
{
output_bit(EEPROM_DI, shift_left(&wren,1,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
output_low(EEPROM_SELECT);
for(i=0; i<40; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,5,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
}
BYTE read_ext_eeprom(EEPROM_ADDRESS address) {
BYTE cmd[4];
BYTE i,data;
cmd[0]=address;
cmd[1]=(address>>8);
cmd[2]=(address>>8);
cmd[3]=0x03;
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<32; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,4,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
for(i=0; i<8; ++i)
{
shift_left(&data,1,input(EEPROM_DO));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
return(data);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 22, 2007 9:45 pm |
|
|
I said this:
Quote: |
You have defined 'EEPROM_ADDRESS' as a 'long int'. But a 'long int'
is only 16 bits in CCS. You have a 32-bit address. Therefore you
need to define it as an 'int32'. |
But you didn't change it. You left it as:
Quote: | #define EEPROM_ADDRESS long int |
I said this:
Quote: | also put in code to shift the 3rd byte of the address by 16-bits,
so it's properly loaded into the array. |
But you did this:
Quote: |
cmd[0]=data;
cmd[1]=address;
cmd[2]=(address>>8);
cmd[3]=(address>>8);
cmd[4]=0x02;
|
|
|
|
janiga
Joined: 10 Apr 2006 Posts: 22
|
OOOPS! |
Posted: Mon Apr 23, 2007 12:29 am |
|
|
Update
Code: |
// 25LC1024 DRIVER VERSION 1
#ifndef EEPROM_SELECT
#define EEPROM_SELECT PIN_A2
#define EEPROM_CLK PIN_A3
#define EEPROM_DI PIN_A4
#define EEPROM_DO PIN_A5
#endif
#define EEPROM_ADDRESS int32
#define EEPROM_SIZE 131072
void init_ext_eeprom() {
output_high(EEPROM_SELECT);
output_low(EEPROM_DI);
output_low(EEPROM_CLK);
}
BOOLEAN ext_eeprom_ready() {
BYTE cmd[1], i, data;
cmd[0] = 0x05; //rdsr opcode
output_low(EEPROM_SELECT);
for(i=1; i<=8; ++i) {
output_bit(EEPROM_DI, shift_left(cmd,1,0));
output_high(EEPROM_CLK); //data latches
output_low(EEPROM_CLK); //back to idle
}
for(i=1; i<=8; ++i) {
output_high(EEPROM_CLK); //data latches
shift_left(&data,1,input(EEPROM_DO));
output_low(EEPROM_CLK); //back to idle
}
output_high(EEPROM_SELECT);
return !bit_test(data, 0);
}
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data) {
BYTE cmd[5];
BYTE i;
BYTE wren;
wren=0x06;
cmd[0]=data;
cmd[1]=address;
cmd[2]=(address>>8);
cmd[3]=(address>>16);
cmd[4]=0x02;
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<8; ++i)
{
output_bit(EEPROM_DI, shift_left(&wren,1,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
output_low(EEPROM_SELECT);
for(i=0; i<40; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,5,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
}
BYTE read_ext_eeprom(EEPROM_ADDRESS address) {
BYTE cmd[4];
BYTE i,data;
cmd[0]=address;
cmd[1]=(address>>8);
cmd[2]=(address>>16);
cmd[3]=0x03;
// Wait until the eeprom is done with a previous write
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
for(i=0; i<32; ++i)
{
output_bit(EEPROM_DI, shift_left(cmd,4,0));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
for(i=0; i<8; ++i)
{
shift_left(&data,1,input(EEPROM_DO));
output_high(EEPROM_CLK);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT);
return(data);
}
|
|
|
|
RolandAldridge
Joined: 26 Mar 2007 Posts: 7 Location: Southern California
|
EEPROMS |
Posted: Thu Apr 26, 2007 3:44 pm |
|
|
A while ago I attempted to use Atmel EEPROMS for data storage. I found that I had to implement the write code as a loop, writing the value, reading it back, and if it didn't work, writing it again until it did work, with a maximum count of about 10 iterations round the loop.
It seems that those EEPROMS anyway just do that - sometimes they simply don't write. A friend of mine agreed that he'd had to do the same.
Nowadays I use a Ramtron ferro-electric device for non-volatile storage and it works just fine.
Roland _________________ Roland Aldridge
www.amio2.com |
|
|
|
|
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
|