CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

SPI EEPROM WRITE PROBLEM, READING SEEMS OK NOT SURE!

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
janiga



Joined: 10 Apr 2006
Posts: 22

View user's profile Send private message

SPI EEPROM WRITE PROBLEM, READING SEEMS OK NOT SURE!
PostPosted: Sun Apr 22, 2007 8:57 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Apr 22, 2007 2:44 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Apr 22, 2007 3:59 pm     Reply with quote

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

View user's profile Send private message

help
PostPosted: Sun Apr 22, 2007 5:26 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Apr 22, 2007 6:35 pm     Reply with quote

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

View user's profile Send private message

25LC1024 driver
PostPosted: Sun Apr 22, 2007 9:09 pm     Reply with quote

Very Happy Smile Very Happy Smile Very Happy Smile Crying or Very sad Crying or Very sad Crying or Very sad Razz

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

View user's profile Send private message

PostPosted: Sun Apr 22, 2007 9:45 pm     Reply with quote

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

View user's profile Send private message

OOOPS!
PostPosted: Mon Apr 23, 2007 12:29 am     Reply with quote

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

View user's profile Send private message Send e-mail Visit poster's website

EEPROMS
PostPosted: Thu Apr 26, 2007 3:44 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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