This is an interesting observation, Thank you.
I wonder why it still works though!
Funny how sometimes a programming error is undetected by the compiler and then the program runs with unpredictable results and other times it just works!
Mike
Further investigation has revealed why your checksum still worked.... (sorry for the rather brief earlier reply - it was from my mobile phone!). If we use the following code:
This reveals that with i2caddr as a byte, the for/next loop assigns the following values to I2CAddr:Code:I2CAddr Var byte Xray var byte Alpha var byte I2CAddr2 var byte I2CDevice var byte I2cdevice =160 I2CAddr2 = 0 for i2caddr = 0 to 2048 step 16 i2cwrite d1,d2,i2cdevice,i2caddr,[$55] hserout [hex I2CAddr, " "] pause 10 next
0 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0
then stops (whereas as a word continues up to 800 as expected).
So you are actually only writing to a memory address up to F0, but then reading back gives you the correct checksum. However where are you actually writing to memory? - Well the memory assignment by PBP is sequential in alphabetic order, words first then bytes, and the next byte after I2CAddr is in fact I2CDevice in your code, or in my modification, I2CAddr2, as is seen here:
Now the PBP manual states "The Address size sent (byte or word) is determined by the size of the variable that is used. If a byte-sized variable is used for the Address, an 8-bit address is sent. If a word-sized variable is used, a 16-bit address is sent. Be sure to use the proper sized variable for the device you wish to communicate with."Code:_Alpha EQU RAM_START + 018h _I2CAddr EQU RAM_START + 019h _I2CAddr2 EQU RAM_START + 01Ah _I2CDevice EQU RAM_START + 01Bh _Xray EQU RAM_START + 01Ch
I suspect this is in fact not correct and looking at the assembler code that PBP generates, in fact I2CWRITE seems to send a word, using I2CAddr, I2CAddr2 as the (word) address in my example, or the case of your code, actually I2CAddr, I2CDevice (=$A0) which is I suspect somewhere other than you intended in memory!
Peter
Thank you Peter,
I understand the first part of your response but not sure about the second part:
I will continue to read it over and over, some times it takes me a few times to understand.Now the PBP manual states "The Address size sent (byte or word) is determined by the size of the variable that is used. If a byte-sized variable is used for the Address, an 8-bit address is sent. If a word-sized variable is used, a 16-bit address is sent. Be sure to use the proper sized variable for the device you wish to communicate with."
I suspect this is in fact not correct and looking at the assembler code that PBP generates, in fact I2CWRITE seems to send a word, using I2CAddr, I2CAddr2 as the (word) address in my example, or the case of your code, actually I2CAddr, I2CDevice (=$A0) which is I suspect somewhere other than you intended in memory!
Now again I am running into some mystery and I wish I could understand better...
If I run this code:
Then I read the EPROM with Ponyprog and observed everything as expected.Code:i2cdevice =$A0 for i2caddr = 0 to 2048 step 16 i2cwrite d1,d2,i2cdevice,i2caddr,[$01]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$01]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$01]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$08]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$08]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$08]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$21]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$21]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$21]:i2caddr = i2caddr + 1:pause 10 i2cwrite d1,d2,i2cdevice,i2caddr,[$ff]:pause 10 next
Then I rewrote my code by changing:
toCode:for i2caddr = 0 to 2048 step 16and the 3 first line I replaced $01 by $ff.Code:for i2caddr = 0 to 1024 step 16
I was expecting to see half of the memory filled with my changes but it got filled all the way to address $7FF:
The more I test the more I get confused!
Mike
Actually I was wrong about the Addressing - I hadn't noticed you were using a 24C16 - I normally use larger chips - in fact the 24C16 needs a byte for the address. Unfortunately the addressing you require is a little more complex - the 2K memory is organised in 8 x 256 byte blocks and the A10, A9, A8 are conveyed as the lower 3,2,1 bits of the Control byte, and A7-0 in the Address byte - a rewrite of your addressing is needed!
Control Byte: 1010XXX0 where XXX are the high order 3 bits of the address
Address Byte: XXXXXXXX = A7-0
You will need to create the Control byte for each successive write. Get back to me if you need any more help.
Peter
Ok so maybe I need more help.
There is obviously something I don't understand.
Looking at the 24CL16 datasheet:
Based on this I changed the address to word and my understanding is:
Control byte = 1010 000 0 = $A0
I want to write $aa at address $400 so I wrote this code:
I was expecting to see only address $400 showing value $aa but this is the result:Code:i2cdevice =$A0 i2caddr = $400 i2cwrite d1,d2,i2cdevice,i2caddr,[$aa]:pause 10
the value $aa is now showing at address $004 and at every next 16 locations all the way to 2048.
???
Mike
I suggest you use a data array to send your bytes, and then you need to construct the ControlByte and address as in this example:
PeterCode:Dat VAR byte[16] i var word j var Byte SDA var PORTA.2 SCL VAR PORTA.3 CntrB var Byte Addr var byte for i = 0 to 15 lookup i, [$01,$01,$01,$3c,$3c,$3c,$3c,$3c,$3c,$08,$08,$08,$21,$21,$21,$FF], j Dat[i] = j next for i = 0 to $7F0 step 16 'End at 2048-16 = $7F0 CntrB = %10100000 CntrB.3 = i.10 CntrB.2 = i.9 CntrB.1 = i.8 Addr = i.lowbyte i2cwrite SDA,SCL,CntrB,Addr,[str Dat\16] pause 10 next
Bookmarks