How to read & write to a 25aa1024 (1 Mbit SPI Bus Serial EEPROM) via 16F88


Closed Thread
Results 1 to 37 of 37
  1. #1
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default How to read & write to a 25aa1024 (1 Mbit SPI Bus Serial EEPROM) via 16F88

    I'm a newb to all of this and I bought PBP so I wouldn't have to learn assembly but I may have been wrong.

    From what I can gather bit banging in PBP may be the only way to do it but I was hoping that maybe there may be another way.

    For example:
    Would it be possible to bit bang just the initial WRITE ENABLE SEQUENCE (WREN) of it then switch to I2C for the address/data portion and finally bit bang the WRITE DISABLE SEQUENCE (WRDI)

    or

    If PBP can compile assembly along side of PB and someone would be kind enough to supply me with the some example assembly and coach me through it so I understand it, that would be great too?

    Thanks

  2. #2
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    Well I just ordered the 24AA1025 (1024K I2C™ CMOS Serial EEPROM) and that way I will be able to use PBP's I2C capability.

    However, I would still like to know how to use the 25AA1024 as I have a few lying around now that are just gunna go to waste otherwise.

    Thanks

  3. #3
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    SHIFTIN/SHIFTOUT should work for the 25aa1024. You will need to look at the data sheet for the correct modes and all of that stuff.

    This page has a few example about SHIFTIN/OUT and SPI.
    http://www.melabs.com/resources/samples.htm
    Last edited by mackrackit; - 29th March 2010 at 04:26.
    Dave
    Always wear safety glasses while programming.

  4. #4
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    SHIFTIN/SHIFTOUT should work for the 25aa1024. You will need to look at the data sheet for the correct modes and all of that stuff.

    This page has a few example about SHIFTIN/OUT and SPI.
    http://www.melabs.com/resources/samples.htm
    Thanks for the heads up! I don't know how I missed that sample ,the "spix.bas" to begin with. I guess I just had to scroll down a little more :/

    Seeing how I dont have the time to find this out for a few days... what chip should I expect to be quicker the I2C or the SPI? Both will be running off of a 4 MHz clock.

  5. #5
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    I do not know which is faster, never did a side by side or studied the specs for that.
    Let us know what you find. It will be interesting to see.
    Dave
    Always wear safety glasses while programming.

  6. #6
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default I can't WRITE to the I2C What am I doing wrong?

    I made my address a WORD because the 24AA1025 (1024K I2C™ CMOS Serial EEPROM) has a 2 byte address. So in theory this should work but as you can see the output is reading "0" in every address when it should be reading "5"

    Does my code look right?

    I am unsure of the PAUSE 10ms as I can't find any specs in the data sheet for the amount of time needed after each WRITE cycle. I tried commenting out the delay but still the same results. One would think if the delay was wrong I would still get a "5" in Addr0 at the very least.

    Here is the schematic I used to wire up the 24AA1025 to my 16F88:
    http://melabs.com/resources/pbpmanual/5_30-5_31.htm

    Here is the code:
    Code:
    SO      con     0                       ' Define serial output pin
    T2400   con     0                       ' Set serial mode
    DPIN    var     PORTA.0                 ' I2C data pin
    CPIN    var     PORTA.1                 ' I2C clock pin
    B0      var     WORD                    ' Address
    B1      var     byte                    ' Data from first address read
    B2      var     byte                    ' Data from second address read
    B3      var     byte                    ' Second Address
    
       For B0 = 0 To 15                                    ' Loop 16 times
          I2CWRITE DPIN,CPIN,$A0,B0,[5]                    ' Write a "5" to each location
          Pause 10                                         ' Delay 10ms after each write
       Next B0
    
    loop:  
     
       For B0 = 0 To 15 step 2                                          ' Loop 8 times
       high 3                                                           ' LED on to signify a Read in progress
          I2CREAD DPIN,CPIN,$A0,B0,[B1,B2]                              ' Read 2 locations in a row
          B3 = B0 + 1                                                   ' Create second address for print
          Serout SO,T2400,["Addr",#B0,":",#B1,13,10,"Addr",#B3,":",#B2,13,10]  ' Print 2 locations
          B3 = 0                                                        ' Zero out B3 Variable
       low 3                                                            ' LED off to signify no read in progress
       Next B0
    
       Serout SO,T2400,[13,10]             ' Print linefeed
     
       Goto loop
    And here is what I get on Hyperterm:
    Code:
    Addr0:0       
    Addr1:0       
    Addr2:0       
    Addr3:0       
    Addr4:0       
    Addr5:0       
    Addr6:0       
    Addr7:0       
    Addr8:0       
    Addr9:0       
    Addr10:0        
    Addr11:0        
    Addr12:0        
    Addr13:0        
    Addr14:0        
    Addr15:0
    Last edited by wolwil; - 3rd April 2010 at 18:30. Reason: added link to schematic

  7. #7
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Angry Going Nuts!!!

    I simplified everything and have tried everything (even tried swapping out the chip) but I cant get this EEPROM to write anything to it. Here is the new simplified code:

    Code:
    SO      con     0                           ' Define serial output pin
    T2400   con     0                           ' Define serial mode
    cont    CON     %10100000                   ' Define Control byte
    addr    CON     %0000000000000111           ' 2 Byte Address of 7
    B1      VAR     BYTE                        ' Var for data being read
    
    I2CWRITE PORTA.0,PORTA.1,cont,addr,[1]      ' Send the byte 1 to address 7
    
    PAUSE 10                                    ' Wait 10ms for write to complete
    
    I2CREAD PORTA.0,PORTA.1,cont,addr,[B1]      ' Read address 7 into B1
    
    Serout SO,T2400,["Addr",#addr,":",#B1,13,10] ' Print B1's Value in DEC
    Correct me if I'm wrong but the above code should work but it still just reads "0" in hyperterm like this: "Addr7:0"

    I am reading 4.97V from pins 4-8 and I get 4.82V from 4-5 and 4-6 on the 24FC1025 EEPROM so my voltage is within specs. I have checked all continuity on the circuit and they all tone out.

    I don't know what else to do. Please help.

  8. #8
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Angry I found 1 problem with my circuit.

    Pin A2 needed to be tied to VCC not VSS in order for the chip to be enabled. This however has not fixed my problem I am still getting nothing written to it.

  9. #9
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Cool I think I found another issue with the circuit.

    I believe I have the SDA and SCL pins going to the wrong pins on the 16F88. I have them right now going to PORTA.0 for SDA and PORTA.1 for SCL. I believe they need to be set as PORTB.1 for SDA and PORTB.4 for SCL with the 16F88. I will try this tonight and post my findings.

  10. #10
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Unhappy Getting "255" from the read and not "0"

    Well I have new results but still not looking like I am writing to the chip. Now when I read I get 255 for an output and not 0. I don't know if the 24FC1025 is default all 1's or 0's. Here is the new Code:

    Code:
    SO      con     0                           ' Define serial output pin
    T2400   con     0                           ' Define serial mode
    cont    CON     %10100000                   ' Define Control byte
    addr    CON     %0000000000000111           ' 2 Byte Address of 7
    B1      VAR     BYTE                        ' Var for data being read
    
    B1 = 0                                       ' Set B1 to 0 to rule out 255 coming from that
    
    I2CWRITE PORTB.1,PORTB.4,cont,addr,[20]      ' Send the byte 1 to address 7
    
    PAUSE 10                                    ' Wait 10ms for write to complete
    
    I2CREAD PORTB.1,PORTB.4,cont,addr,[B1]      ' Read address 7 into B1
    
    Serout SO,T2400,["Addr",#addr,":",#B1,13,10] ' Print B1's Value in DEC
    Hyperterm is giving me this:
    Code:
    Addr7:255
    Addr7:255
    Addr7:255
    Addr7:255
    Any help would be appreciated

  11. #11
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    Table 2-1 of the data sheet Says this about pin A2
    Non-Configurable Chip Select.
    This pin must be hard wired to
    logical 1 state (VCC). Device
    will not operate with this pin
    left floating or held to logical 0
    (VSS)
    If you are still using the schematic from MeLabs then...

    The other thing I see in the data sheet is the last bit of the control byte sets Read or Write.
    0 = READ
    1 = WRITE
    Code:
    contR    CON     %10100000  
    contW    CON     %10100001
    
    I2CWRITE PORTB.1,PORTB.4,contW,addr,[20]
    PAUSE 10     'Is that long enough?
    I2CREAD PORTB.1,PORTB.4,contR,addr,[B1]
    And you may have to add this but try the above stuff first
    DEFINE I2C_SLOW 1

    But all the above might be a bunch of hooey. I have not used this chip...
    Dave
    Always wear safety glasses while programming.

  12. #12
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Thumbs down Still doesn't work

    If you are still using the schematic from MeLabs then...
    Nope I found that mistake of mine earlier and fixed it

    The other thing I see in the data sheet is the last bit of the control byte sets Read or Write.
    0 = READ
    1 = WRITE
    Yeah this one amazes me with PBP having an I2CREAD and a I2CWRITE command but yet you still have to tell it to READ or WRITE?!?!?!

    Just to clarify I found this under section 5.0 saying that a READ operation should be a 1 and WRITE should be a 0
    The last bit of the control byte defines the operation to
    be performed. When set to a one, a read operation is
    selected, and when set to a zero, a write operation is
    selected.
    PAUSE 10 'Is that long enough?
    Yes I believe so because the 24FC1025 only has a 5ms delay needed

    And you may have to add this but try the above stuff first
    DEFINE I2C_SLOW 1
    I tried it and got the same results, nothing but 255's.

    Do you know if the 24FC1025 is flashed with all 0's or all 1's from the factory? Before I was getting %00000000 from var B1 and now I am getting %11111111 but I want to know if its actually reading that or if its a blip in the coding.

    Here is the updated code:
    Code:
    DEFINE I2C_SLOW 1
    SO      con     0                           ' Define serial output pin
    T2400   con     0                           ' Define serial mode
    contR    CON     %10100001                   ' Define Control byte
    contW    CON     %10100000                   ' Define Control byte
    addr    CON     %0000000000000111           ' 2 Byte Address of 7
    D1      CON     %00000111
    B0      VAR     BYTE                        ' Var for data being read
    B1      VAR     BYTE                        ' Var for 2nd byte being read
    
    b0 = 0
    b1 = 0
    I2CWRITE PORTB.1,PORTB.4,contW,addr,[D1]      ' Send the byte 1 to address 7
    
    PAUSE 10                                    ' Wait 10ms for write to complete
    
    I2CREAD PORTB.1,PORTB.4,contR,addr,[B1,B0]      ' Read address 7 into B1
                                                   ' and address 8 into B0
    
    Serout SO,T2400,["Addr",#addr,":",#B1," and then ",#B0,13,10] ' Print
    I added a 2nd byte to check an address I have not written to and also get a 255 from that but early on in the code I set B1 and B0 to 0 and its getting changed somehow. So either I am reading all 1's from the addresses or the code is screwy.

    PS sorry about the novel here, but its late and I tend to ramble when I'm tired.

    Other notes:
    I am using a 4MHz external clock to run the show if that matters. I will be switching to a 20MHz once I have everything working.

  13. #13
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    I picked up a couple of these 24FC1025 and I am not having any luck either.

    A0 and A1 and WP are connected to VSS.
    A2 connected to VDD.
    10K pull up on SDA and SCL.
    Tried "start/stop" sequence before and after I2C commands...

    Out put to terminal is 0 no matter what.
    Code:
    '  18F6680  24FC1025
        DEFINE OSC 20
        @ __CONFIG    _CONFIG1H, _OSC_HS_1H
        @ __CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
        @ __CONFIG    _CONFIG4L, _LVP_OFF_4L
        
        TRISF = 0
        PORTF = 0
        DEFINE I2C_SLOW 1
        DEFINE I2C_SCLOUT 1
        DPIN    VAR PORTF.6    'I2C DATA PIN
        CPIN    VAR PORTF.7    'I2C CLOCK PIN
        CONTR   CON %10100001  'READ CONTROL
        CONTW   CON %10100000  'WRITE CONTROL
        ADDR    VAR WORD
        DATI    VAR BYTE
        DATO    VAR BYTE
        ADDR = %0000000000000000
        DATO = %11110000
        
        START:
        SEROUT2 PORTB.2, 16572,["TEST",$d,$a]
        PAUSE 1000
        
        HIGH CPIN:HIGH DPIN:LOW DPIN
        I2CWRITE DPIN,CPIN,CONTW,ADDR,[DATO]  
        HIGH CPIN:LOW DPIN:HIGH DPIN
        Pause 10                
    
        HIGH CPIN:HIGH DPIN:LOW DPIN
        I2CREAD DPIN,CPIN,CONTR,ADDR[DATI]        
        HIGH CPIN:LOW DPIN:HIGH DPIN
    
        Serout2 PORTB.2, 16572,["DATA IN ",BIN DATI]       
        SEROUT2 PORTB.2, 16572,[$d,$a]
    
        GOTO START
    Dave
    Always wear safety glasses while programming.

  14. #14
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    I give up...
    Dave
    Always wear safety glasses while programming.

  15. #15
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    I give up...
    Haha! Well at least I learned the problem isn't me

    So does anyone out there know the assembly code to make this work???

  16. #16
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    When I get back tonight I am thinking of do some sort of bit banging, maybe that will work.
    Dave
    Always wear safety glasses while programming.

  17. #17
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166

    Default

    mackrackit, Why are you using 10 k's for the pullup's? I believe the spec. says 4.7K or lower.. Might be the problem....

    Dave Purola,
    N8NTA

  18. #18
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    The data sheet for this part call for 10k at 100 kHz and 2k for 400 kHz and 1 MHz.

    It did not work at the higher speeds so I was trying it at the slow.
    Dave
    Always wear safety glasses while programming.

  19. #19
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    Quote Originally Posted by Dave View Post
    mackrackit, Why are you using 10 k's for the pullup's? I believe the spec. says 4.7K or lower.. Might be the problem....

    Dave Purola,
    N8NTA
    I am using 4.7K. Sorry I forgot to mention that I was doing that different from the schematic I posted.

    Did you get it to work?

  20. #20
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    I have tried several different resistor sizes and still nothing.
    I think I am actually communicating with it as it "ACK" backs at me...
    Here is my current mess...
    Code:
    '  18F6680  24FC1025
        DEFINE OSC 20
        @ __CONFIG    _CONFIG1H, _OSC_HS_1H
        @ __CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
        @ __CONFIG    _CONFIG4L, _LVP_OFF_4L
        
        TRISF = 0
        PORTF = 0
       
        DPIN    VAR PORTF.6    'I2C DATA PIN
        CPIN    VAR PORTF.7    'I2C CLOCK PIN
        CONTR   CON %10100001  'READ CONTROL
        CONTW   CON %10100000  'WRITE CONTROL
        ADDR_HB    VAR BYTE
        ADDR_LB    VAR BYTE
        DATI    VAR BYTE
        DATO    VAR BYTE
        ACK     VAR BIT
        ADDR_HB = %00000000
        ADDR_LB = %00000000
        DATO = %11100000
        CNT VAR BYTE
        CNT = 0
        
        START:CNT = CNT + 1
        GOSUB WRITE_DATA
        PAUSE 100
        GOSUB READ_DATA
        SEROUT2 PORTB.2, 16572,["TEST ",DEC CNT,$d,$a]
        Serout2 PORTB.2, 16572,["DATA IN ",BIN DATI]      
        SEROUT2 PORTB.2, 16572,[$d,$a]
        PAUSE 500
        GOTO START
        
        WRITE_DATA:  ACK=1   :Serout2 PORTB.2, 16572,["ACK ",BIN ACK,$d,$a] 
        GOSUB START_ROM
        SHIFTOUT DPIN,CPIN,1,[CONTW]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        Serout2 PORTB.2, 16572,["ACK ",BIN ACK,$d,$a] 
        SHIFTOUT DPIN,CPIN,1,[ADDR_HB]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[ADDR_LB]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[DATO]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        GOSUB STOP_ROM
        PAUSE 10
        RETURN
        
        READ_DATA:
        GOSUB START_ROM
        SHIFTOUT DPIN,CPIN,1,[CONTR]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[ADDR_HB]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[ADDR_LB]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        GOSUB START_ROM
        SHIFTOUT DPIN,CPIN,1,[CONTR]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTIN DPIN,CPIN,0,[DATI\8]
        GOSUB STOP_ROM
        PAUSE 10
        RETURN
        
        START_ROM:
        HIGH CPIN:HIGH DPIN:LOW DPIN:RETURN
        STOP_ROM:
        HIGH CPIN:LOW DPIN:HIGH DPIN:RETURN
    Dave
    Always wear safety glasses while programming.

  21. #21
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default I made a break through I just don't know what it means :D

    I changed the Control Byte for the read and the write from this:
    Code:
    contR    CON     %10100001                  
    contW    CON     %10100000
    to this:
    Code:
    contR    CON     %10100011                  
    contW    CON     %10100010
    Thinking that because A2 is held high for it to operate then the control bit for A2 should also be a 1... here is the new code:
    Code:
    DEFINE I2C_SLOW 1
    SO      con     0                           ' Define serial output pin
    T2400   con     0                           ' Define serial mode
    contR    CON     %10100011                   ' Define Control byte
    contW    CON     %10100010                   ' Define Control byte
    addr    CON     %0000000000000111           ' 2 Byte Address of 7
    addr2   CON     %0000000000001000           ' 2 Byte Address of 8
    D1      CON     %00000111
    B0      VAR     BYTE                        ' Var for data being read
    B1      VAR     BYTE                        ' Var for data being read
    
    B0 = 0
    B1 = 0
    I2CWRITE PORTB.1,PORTB.4,contW,addr,[D1]      ' Send the byte 1 to address 7
    
    PAUSE 10                                    ' Wait 10ms for write to complete
    
    I2CREAD PORTB.1,PORTB.4,contR,addr,[B1]      ' Read address 7 into B1
    I2CREAD PORTB.1,PORTB.4,contR,addr2,[B0]      ' Read address 8 into B0
    
    Serout SO,T2400,["Addr",#addr,":",#B1," and then Addr",#addr2,":",#B0,13,10] ' Print B1's Value in DEC
    this is the output from hyperterm:
    Code:
    Addr7:2 and then 2
    Like I said I don't know what it means but it sure is different then what I was getting.

    Any thoughts as to why it now is reading a "2" and not 255 or 0??? Its almost like it read the last 2 bits of the write control byte as if the write command wrote the last 2 bits of the control byte to the EEPROM.


    UPDATE:
    I just switched the control byte to be:
    Code:
    contR    CON     %10100001                  
    contW    CON     %10100010
    and got this as an output (Note the "6" in Address 8 to begin and then it get over written to "255" the next go around):
    Code:
    Addr7:2 and then Addr8:6
    Addr7:2 and then Addr8:255
    Addr7:2 and then Addr8:255
    Addr7:2 and then Addr8:255
    Addr7:2 and then Addr8:255
    also I know I'm writing to it because in the example output above I read address 6 with it too (not shown in the code but I added it after posting) and I was reading "255" every time. So this tells me that I am writing a "6" to address 8 but then on the second loop it gets over written/erased to "255" but the "2" in address 7 remains constant and in memory. Now keep in mind that no where in my code do I try to write to address 8 it just happens, more than likely from an over flow from the write to address 7. So basically the byte I am trying to write to 7 gets split into a "2" in address 7 and a "6" in address 8 then address 8 gets overwritten on the 2nd loop to a "255".

    and when I do the control byte like this:
    Code:
    contR    CON     %10100011                  
    contW    CON     %10100000
    I get this (the same as having both A2 bits set to 1):
    Code:
    Addr7:2 and then Addr8:2
    Addr7:2 and then Addr8:2
    Addr7:2 and then Addr8:2
    Last edited by wolwil; - 17th April 2010 at 05:37.

  22. #22
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530

    Default

    Sorry, read the data sheet wrong. Nevermind
    Last edited by ScaleRobotics; - 17th April 2010 at 06:50.

  23. #23
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    Whoops it dawned on me what I am doing by changing that Bit. I guess that my novice understanding of this made me stumble upon the fact that I am now writing and reading from a different Chip Select, but seeing how I only have the one chip I dont understand how its reading/writing chip 01 when it should be chip 00.

    So I guess where I was calling it the A2 bit its actually the A0 bit that I was changing.

  24. #24
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    How do you have pins A0 and A1 connected?

    I have not had a chance to work on this today yet so I do not have any new news.
    Dave
    Always wear safety glasses while programming.

  25. #25
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    Quote Originally Posted by mackrackit View Post
    How do you have pins A0 and A1 connected?

    I have not had a chance to work on this today yet so I do not have any new news.

    Tied to ground.

  26. #26
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166

    Default This one is for Dave...

    mackrackit, You can't use Shiftout and Shiftin for an I2C bus driven part. That is why you had no luck using it with a 24FC1025... It requires the pullup resistor for communicating the ACK signal back to the processor. Shiftout keeps the pin in an active state wghich ever it is... I recently posted code for talking to 24LC1025's here on the forum... Why not just use it for a starting point... I don't remember which thread it was in reply to but I believe it had to do with I2C....

    Dave Purola,
    N8NTA

  27. #27
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    Dave,

    I've searched through all the posts on the 24LC1025 and didn't find any code you posted but I found code that is basically the same as what I have tried already. If you can find the thread you were thinking of that would be great.

    The only thing I have not tried is changing is my pullups from 4.7k to 2k and trying to write to it 1 page at a time but if I cant byte-write to begin with I'm sure the page write will not work either. I will try changing the Pullups tonight and see what happens.

  28. #28
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    I got the idea for shifting here.
    http://www.rentron.com/PicBasic/i2c_communication.htm

    Reading back over my code and data sheet I see some things are backwards. Maybe ...

    Never did find that code posting. Found lots of others for different parts.
    Dave
    Always wear safety glasses while programming.

  29. #29
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default Changed the Pullups to 2.2K and still no change

    Everything is the same as before with the new pullup values of 2.2K...back to the drawing board

    I am going to be out of town for the next week so I wont be able to test anything new but I will be on here checking if any new ideas/breakthroughs come up.
    Last edited by wolwil; - 18th April 2010 at 01:24.

  30. #30
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166

    Default

    wolwil, Here it is again incase you didn't find it. Maxpages is set for 1023 x the number of 24LC1025's you have connected. The routine saves the last storage pointer in the last 2 locations of the last 24LC1025. Block is incremented once for each page. Before you start a clean write you would set block to 0 which is the first page. When you want to read back the data then you would call READ_WRITE_BLK1025 and block would have the last address written..

    This routine is rock solid and I use it for accessing 4 x 24LC1025's for a total of over 4 gigabits of memoy to record Azmnuth,Elevation,East/West/Up/Down Sensor data and control flag information for about 2 months at 1 minute intervals... I hope this helps...

    Code:
     
    CNTRL_BYTE    CON    $A0        'CONTROL BYTE FOR 24LC1025 I2C EEPROM MEMORY (A0/A1 USED FOR CHIP SELECT)
    MAX_PAGES    CON    4095    'MAXIMUM MEMORY STORAGE PAGES,(32 BYTES/MINUTE x 4 MINUTES x PAGES = TOTAL MINUTES)
     
    '*********************************************************************
    RW_EEPROM1025:        'READ FROM or WRITE TO SERIAL EEPROM
    '*********************************************************************
        IF READ_WRITE = 1 THEN    'WRITE 128 BYTE BLOCK TO EEPROM
            IF BLOCK <> 0 THEN    'IF STARTING NEW PASS DON'T READ OLD LOCATION
                READ_WRITE = 0    'SET FOR BLOCK READ
                GOSUB READ_WRITE_BLK1025    'READ FROM SERIAL EEPROM NEXT AVAILABLE STORAGE BLOCK
                READ_WRITE = 1    'SET FOR BLOCK WRITE
            ENDIF
            DEVICE = BLOCK / 512    'SELECT WHICH PHYSICAL ADDRESS BOUNDRY & EEPROM
            ADDRESS = BLOCK << 7    'CALCULATE 12C ADDRESS TO STORE DATA TO
            CNTROL_BYTE = CNTRL_BYTE    'COPY CONTROL BYTE
            CNTROL_BYTE.1 = DEVICE.1    'SET LSB OF HARDWARE ADDRESS
            CNTROL_BYTE.2 = DEVICE.2    'SET MSB OF HARDWARE ADDRESS
            CNTROL_BYTE.3 = DEVICE.0    'SET 64K BLOCK BIT
            INTCON.7 = 0    'CLEAR GLOBAL INTERRUPT
            I2CWRITE SDA,SCL,CNTROL_BYTE,ADDRESS,[STR STOR_DATA\128]    'SAVE DATA TO 12C
            WRITEOCCURED = 1
            INTCON.7 = 1    'SET GLOBAL INTERRUPT
            PAUSE 6        'ALLOW TIME FOR I2C WRITE ~5Ms.
            BLOCK = BLOCK + 1    'INCREMENT FOR NEXT AVAILABLE BLOCK TO WRITE
            BLOCK = BLOCK MIN MAX_PAGES    'LIMIT TO n BLOCKS OF 128 BYTES
            GOSUB READ_WRITE_BLK1025    'WRITE TO or READ FROM SERIAL EEPROM LAST STORAGE BLOCK
        ELSE
            DEVICE = BLOCK / 512    'SELECT WHICH PHYSICAL ADDRESS BOUNDRY & EEPROM
            ADDRESS = BLOCK << 7    'CALCULATE 12C ADDRESS TO STORE DATA TO
            CNTROL_BYTE = CNTRL_BYTE    'COPY CONTROL BYTE
            CNTROL_BYTE.1 = DEVICE.1    'SET LSB OF HARDWARE ADDRESS
            CNTROL_BYTE.2 = DEVICE.2    'SET MSB OF HARDWARE ADDRESS
            CNTROL_BYTE.3 = DEVICE.0    'SET 64K BLOCK BIT
            INTCON.7 = 0    'CLEAR GLOBAL INTERRUPT
            I2CREAD SDA,SCL,CNTROL_BYTE,ADDRESS,[STR READ_DATA\128]    'LOAD IN ENTIRE BLOCK
            WRITEOCCURED = 1
            INTCON.7 = 1    'SET GLOBAL INTERRUPT
        ENDIF
        RETURN
     
    '*********************************************************************
    READ_WRITE_BLK1025:    'WRITE TO or READ FROM SERIAL EEPROM NEXT AVAILABLE STORAGE BLOCK
    '*********************************************************************
        ADDRESS = 65534        'POINT TO LAST STORED DATA(WORD) ADDRESS
        DEVICE = MAX_PAGES / 512    'SELECT WHICH PHYSICAL ADDRESS BOUNDRY & EEPROM
        CNTROL_BYTE = CNTRL_BYTE    'COPY CONTROL BYTE
        CNTROL_BYTE.1 = DEVICE.1    'SET LSB OF HARDWARE ADDRESS
        CNTROL_BYTE.2 = DEVICE.2    'SET MSB OF HARDWARE ADDRESS
        CNTROL_BYTE.3 = DEVICE.0    'SET 64K BLOCK BIT
        IF READ_WRITE = 1 THEN
            INTCON.7 = 0    'CLEAR GLOBAL INTERRUPT
            I2CWRITE SDA,SCL,CNTROL_BYTE,ADDRESS,[BLOCK.LOWBYTE,BLOCK.HIGHBYTE]    'WRITE DATA POINTER TO 12C    
            WRITEOCCURED = 1
            INTCON.7 = 1    'SET GLOBAL INTERRUPT
            PAUSE 6        'ALLOW TIME FOR I2C WRITE ~5Ms.
        ELSE
            INTCON.7 = 0    'CLEAR GLOBAL INTERRUPT
            I2CREAD SDA,SCL,CNTROL_BYTE,ADDRESS,[BLOCK.LOWBYTE,BLOCK.HIGHBYTE]    'READ DATA POINTER FROM 12C    
            WRITEOCCURED = 1
            INTCON.7 = 1    'SET GLOBAL INTERRUPT
        ENDIF
        RETURN
    Dave Purola,
    N8NTA
    Last edited by ScaleRobotics; - 14th June 2010 at 01:24. Reason: Added code tags

  31. #31
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    Hi Dave,
    Thanks for posting your code. I also found my problem...

    My problem is "I am a newbe!!!".
    I forgot PORTF.6 on the 18F6680 is an analog pin.
    RTFD RTFD RTFD

    For what it is worth.. When I take care of the analog issue I can read the part with SHIFTIN/OUT. I can not write to the part that way yet. Still have a timing problem I guess. It may not be worth messing with other than an exercise in coding.
    Dave
    Always wear safety glasses while programming.

  32. #32
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    Quote Originally Posted by Dave View Post
    CNTRL_BYTE CON $A0 'CONTROL BYTE FOR 24LC1025 I2C EEPROM MEMORY (A0/A1 USED FOR CHIP SELECT)
    Maybe this is where I am getting confused... you have the control byte being $A0 which is basically saying to write to the 24LC1025 seeing how the read write bit in that is a 0 like this "10100000" but the you say in your comment that the A0/A1 is for chip select...So in this following line of code where I have the $A0 is that the 8 bit control byte or just the Chip Select portion of it???

    Code:
    I2CREAD PORTB.1,PORTB.4,$A0,addr,[B1]
    See I thought if I wanted to write to chip select A1 I needed to use $A2 or in binary like this %10100010 and if I wanted to read from it I needed to use $A3 or in binary like this %10100011.

    Every combination to read and write to all 4 Chips:

    %10100000 or $A0 = Write to A0 (Pins A0 & A1 Tied Low)
    %10100001 or $A1 = Read from A0
    %10100010 or $A2 = Write to A1 (Pins A0 Tied Low & A1 Tied High)
    %10100011 or $A3 = Read from A1
    %10100100 or $A4 = Write to A2 (Pins A0 Tied High & A1 Tied Low)
    %10100101 or $A5 = Read from A2
    %10100110 or $A6 = Write to A3 (Pins A0 and A1 Tied High)
    %10100111 or $A7 = Read from A3

    So with me having both A0 and A1 Pins Tied to ground I should be using the first 2 options when trying to read/write to the chip or am I just way off on this???

    Am I incorrect in my thinking of what PBP is calling the Control Byte???

  33. #33
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    10100000
    Is the R/W bit. Leave it as "0" and PBP takes care of parsing it to a "1" if needed.

    10100000
    Are the A0 and A1 bits. If pins A0 and A1 are connected to the zero rail leave as zero. Mixing and matching on or the other or both gives the four combination's for up to four chips on the same bus.

    10100000
    Is the bit to set to read or write to the first or second block.
    Dave
    Always wear safety glasses while programming.

  34. #34
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default Just for fun...

    Here is how to read and write to a Serial EEPROM using SHIFTIN/SHIFTOUT.
    Using a 24FC1025.

    Why???? Why not???

    I have the DATA and CLOCK pins pulled up with 2.7k resistors.
    Follow the code with the data sheet to understand what is going on.
    Code:
    DEFINE OSC 20
    
    DPIN    VAR PORTB.2    'I2C DATA PIN
    CPIN    VAR PORTB.1    'I2C CLOCK PIN
    CONT1   CON %10100001  'READ CONTROL
    CONT0   CON %10100000  'WRITE CONTROL
    ADDR_HB   VAR BYTE
    ADDR_LB    VAR BYTE
    DATOW       VAR BYTE
    ACK            VAR BIT
    ADDR_HB = 0'%00000000
    ADDR_LB = 0'%00000000
    DATOW    VAR BYTE
    CNT VAR BYTE
    CNT = 0
    
    START:
        CNT = CNT + 1
        DATOW = 245
        GOSUB WRITE_DATA
        PAUSE 10
        GOSUB READ_DATA
        LCDOUT $FE,1,"TEST ",DEC CNT
        lcdout $FE,$C0,"DATA IN ",DEC DATI
        lcdout $FE,$90,"LB ",DEC ADDR_LB
        PAUSE 250
        GOTO START
        
        WRITE_DATA:     
        ADDR_LB = ADDR_LB + 1
        GOSUB START_ROM
        SHIFTOUT DPIN,CPIN,1,[CONT0]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[ADDR_HB]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[ADDR_LB]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[DATOW\8]      
        SHIFTOUT DPIN,CPIN,1,[%1\1]
        GOSUB STOP_ROM
        PAUSE 10
        RETURN
        
        READ_DATA: 
        GOSUB START_ROM
        SHIFTOUT DPIN,CPIN,1,[CONT0]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[ADDR_HB]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTOUT DPIN,CPIN,1,[ADDR_LB]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        GOSUB START_ROM
        SHIFTOUT DPIN,CPIN,1,[CONT1]
        SHIFTIN DPIN,CPIN,0,[ACK\1]
        SHIFTIN DPIN,CPIN,0,[DATI\8]
        SHIFTOUT DPIN,CPIN,1,[%1\1]
        GOSUB STOP_ROM
        PAUSE 10
        RETURN
        
        START_ROM:
        HIGH CPIN:HIGH DPIN:LOW DPIN:RETURN
        STOP_ROM:
        HIGH CPIN:LOW DPIN:HIGH DPIN:RETURN
    Make sure you have ANALOG turned off!!
    Dave
    Always wear safety glasses while programming.

  35. #35
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default

    Thanks for the code guys! I will try it out on sunday when I get back.

  36. #36
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Default Mackrackit your code works :D

    Well I was able to get your code to work. I noticed when I was reading before using the I2CREAD I was getting all 255's and now I am reading using your code and still getting all 255's where ther is no data written so that is telling me that I was getting the I2CREAD to work before. I am now reading through all memory locations looking for the data I wrote to it before using the I2CWRITE command to try and figure out where it wrote it and why. Once this finishes I will post my findings and thoughts.

    Thanks again for the code.

    PS:
    I have not tried Dave's code yet

    UPDATE:
    I found the written data from my old code in Block 1 of the EEPROM. I am going to go back to the old code I had and try and make it work. I will post my findings
    Last edited by wolwil; - 25th April 2010 at 23:32.

  37. #37
    Join Date
    Mar 2010
    Location
    Minnesota, USA
    Posts
    41

    Thumbs up Finally got it to work!!!

    First and foremost Thank You, Thank You, Thank You for all of your help guys I really do appreciate it.

    Here is the working Code:
    Code:
    ' Define serial output pin
    SO      con     0 
    
    ' Define serial mode                          
    T2400   con     0                           
    
    ' 2 Byte Address Vars
    addr1   var     word                       
    addr2   var     word                       
    addr3   var     word                        
    
    ' Vars for data being written
    D1      Var     Byte                        
    D2      Var     Byte                      
    D3      Var     Byte                        
    
    ' Vars for data being read
    B1      VAR     BYTE                       
    B2      VAR     BYTE                       
    B3      VAR     BYTE                        
    
    ' Set Data Bytes
    D1 = 7                                      
    D2 = 6
    D3 = 5
    
    ' Set Address Bytes
    addr1 = 1
    addr2 = 2
    addr3 = 3
    
    I2CWRITE PORTB.1,PORTB.4,$A0,addr1,[D1]      ' Write a 1 to address 1
    PAUSE 10                                     ' Wait 10ms for write to complete
    I2CWRITE PORTB.1,PORTB.4,$A0,addr2,[D2]      ' Write a 2 to address 2
    PAUSE 10                                     ' Wait 10ms for write to complete
    I2CWRITE PORTB.1,PORTB.4,$A0,addr3,[D3]      ' Write a 3 to address 3
    PAUSE 10                                     ' Wait 10ms for write to complete
    
    I2CREAD PORTB.1,PORTB.4,$A0,addr1,[B1]      ' Read address 1 into B1
    I2CREAD PORTB.1,PORTB.4,$A0,addr2,[B2]      ' Read address 2 into B2
    I2CREAD PORTB.1,PORTB.4,$A0,addr3,[B3]      ' Read address 3 into B3
    
    Serout SO,T2400,["Addr",#addr1,":",#B1," and then Addr",#addr2,":",#B2," and then Addr",#addr3,":",#B3,13,10] ' Print B1's Value in DEC
    and it's out putting this to Hyperterm:
    Code:
    Addr1:7 and then Addr2:6 and then Addr3:5
    Addr1:7 and then Addr2:6 and then Addr3:5
    Addr1:7 and then Addr2:6 and then Addr3:5
    The problem I had in the beginning was I had the SDA/SCL Pins wrong and I did not have the A2 pin Tied to +5V but after correcting those I had my control byte misunderstood and thats why it would not work. After changing the control byte back to $A0 with the A2 held High and the propper pins chosen for SDA and SCL it now works like it should.

    I hope this thread saves everyone a ton of time in the future with these chips I know I sure learned a ton from this little experiance
    Last edited by wolwil; - 26th April 2010 at 00:58.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts