To my way of thinking, delete the 2nd unnecessary I2CStart in the send routine.
For the receive routine: May need a I2CStop after 1st sending of eeprom address(s) and before the next I2CStart. At least that's the way I did it Also need to resend the eeprom address(s) again after 2nd I2CStart and before sending the eeprom read command. And last, missing I2CStop command at the end. Using the code tags in the message box really helps for future inquiries.
Look up the eeprom routines in the contributor's section here for the work flow. Looks like I may have some extra pin manipulation going on, but that was almost four years ago :=).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have resolved problem modifing the library I2C.h
from
Sub I2CReceive (Out I2CByte, In I2CGetAck = TRUE)
to
Sub I2CReceive (Out I2CByte, In I2CGetAck = FALSE)
because last byte read must get NACK an not ACK
Now my SUB for WRITING or READING single byte at time work fine
There isn't a need to edit the library to change whether a NACK or ACK is needed. If a subroutine parameter has = and a value, that's called the default value. If you don't give GCBASIC a value to put in, it will use the default value. For example, this line:
I2CReceive ee_dati
does not give a value for I2CGetAck, so GCBASIC will use whatever the default value is. However, if you write this:
I2CReceive ee_dati, FALSE
then GCBASIC will see that you have given it a value to use for I2CGetAck, and will set it to FALSE (ie, there is a value given, so GCBASIC will ignore the default value and use whatever you give it.)
I haven't done any experimentation with I2C EEPROM chips, so can't really offer much specific advice. However, from experience with other I2C devices, it is quite common to get a NACK rather than an ACK for the last byte. Also, I think Kent is right about the extra start condition in the write subroutine - the datasheet for the AT24C512 doesn't show a start condition in the middle of the write.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sorry, my bad - looks like there isn't actually an easy way to change I2CGetAck in GCGB. Might have to rethink that.
In the mean time, I think you should be able to trick GCGB by changing "ee_dati" to "ee_dati, FALSE" in the receive icon. When that is converted to GCBASIC code, it should come out correctly (as "I2CReceive ee_dati, FALSE", rather than "I2CReceive ee_dati".)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1) w_cholmondeley thank for your advice to use" I2CReceive ee_dati, FALSE" instead to modify the library.
2) for the second I2Cstart in the middle of sub rand_write maybe I made a mistake with cut/past .
As sone as possible i will apply the changes and check the routines again .
Best regard
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I want to write and read on 24C512 but I have write problem.
I use this part of code is correct ?
;Defines (Constants)
#define EEPROM_WR 0xA0
#define EEPROM_RD 0xA1
#define I2C_MODE Master
#define I2C_DATA PORTA.3
#define I2C_CLOCK PORTA.2
Sub rand_write
I2CStart
I2CSend EEPROM_WR
I2CSend ee_addr_lasthigh
I2CSend ee_addr_lastlow
I2CStart
I2CSend ee_dati
I2CStop
End Sub
Sub rand_read
I2CStart
I2CSend EEPROM_WR
I2CSend ee_addr_inihigh
I2CSend ee_addr_inilow
I2CStart
I2CSend EEPROM_RD
I2CReceive ee_dati
End Sub
Best regard Massimo
To my way of thinking, delete the 2nd unnecessary I2CStart in the send routine.
For the receive routine: May need a I2CStop after 1st sending of eeprom address(s) and before the next I2CStart. At least that's the way I did it Also need to resend the eeprom address(s) again after 2nd I2CStart and before sending the eeprom read command. And last, missing I2CStop command at the end. Using the code tags in the message box really helps for future inquiries.
Look up the eeprom routines in the contributor's section here for the work flow. Looks like I may have some extra pin manipulation going on, but that was almost four years ago :=).
I have resolved problem modifing the library I2C.h
from
Sub I2CReceive (Out I2CByte, In I2CGetAck = TRUE)
to
Sub I2CReceive (Out I2CByte, In I2CGetAck = FALSE)
because last byte read must get NACK an not ACK
Now my SUB for WRITING or READING single byte at time work fine
#define EEPROM_WR 0xA0
#define EEPROM_RD 0xA1
#define I2C_MODE Master
#define I2C_DATA PORTA.3
#define I2C_CLOCK PORTA.2
Dim ee_addr_ini As word alias ee_addr_inihigh , ee_addr_inilow
Dim ee_addr_last As word alias ee_addr_lasthigh , ee_addr_lastlow
Dim ee_dati As byte
Sub rand_write
I2CStart
I2CSend EEPROM_WR
I2CSend ee_addr_lasthigh
I2CSend ee_addr_lastlow
I2CStart
I2CSend ee_dati
I2CStop
End Sub
Sub rand_read
I2CStart
I2CSend EEPROM_WR
I2CSend ee_addr_inihigh
I2CSend ee_addr_inilow
I2CStart
I2CSend EEPROM_RD
I2CReceive ee_dati
I2Cstop
End Sub
NOTE 0xA0 or 0xA1 is for pin A0 A1 A2 of 24C512 to ground (addr 0)
There isn't a need to edit the library to change whether a NACK or ACK is needed. If a subroutine parameter has = and a value, that's called the default value. If you don't give GCBASIC a value to put in, it will use the default value. For example, this line:
I2CReceive ee_dati
does not give a value for I2CGetAck, so GCBASIC will use whatever the default value is. However, if you write this:
I2CReceive ee_dati, FALSE
then GCBASIC will see that you have given it a value to use for I2CGetAck, and will set it to FALSE (ie, there is a value given, so GCBASIC will ignore the default value and use whatever you give it.)
I haven't done any experimentation with I2C EEPROM chips, so can't really offer much specific advice. However, from experience with other I2C devices, it is quite common to get a NACK rather than an ACK for the last byte. Also, I think Kent is right about the extra start condition in the write subroutine - the datasheet for the AT24C512 doesn't show a start condition in the middle of the write.
Sorry, my bad - looks like there isn't actually an easy way to change I2CGetAck in GCGB. Might have to rethink that.
In the mean time, I think you should be able to trick GCGB by changing "ee_dati" to "ee_dati, FALSE" in the receive icon. When that is converted to GCBASIC code, it should come out correctly (as "I2CReceive ee_dati, FALSE", rather than "I2CReceive ee_dati".)
1) w_cholmondeley thank for your advice to use" I2CReceive ee_dati, FALSE" instead to modify the library.
2) for the second I2Cstart in the middle of sub rand_write maybe I made a mistake with cut/past .
As sone as possible i will apply the changes and check the routines again .
Best regard