English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 20 September 2021, 03:47   #41
modrobert
old bearded fool
 
modrobert's Avatar
 
Join Date: Jan 2010
Location: Bangkok
Age: 56
Posts: 775
Quote:
Originally Posted by saimo View Post
For the details, check out the meticulous comments in the code itself.
And, yes, my routines are used exclusively when the OS is off (that's the whole point: I need the routines precisely because the OS is off/trashed)
Yes, I did check your code, looks professional, easy to follow. I have worked with code to access I2C before, both in hardware (VHDL) and software.

My point was more about the reason C= turns off interrupts completely with Disable() before accessing NVRAM, perhaps there is some conflict which is happening when you run with interrupts enabled?

So far these functions I checked in the library call Disable() in the beginning and Enable() towards the end:

GetCopyNV()
StoreNV()
DeleteNV()
GetNVList()

When you use the term "OS off/trashed" I assume you mean Forbid(), which is not the same as turning off all interrupts, it only disables multitasking.
modrobert is offline  
Old 20 September 2021, 13:21   #42
saimo
Registered User
 
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 787
Quote:
Originally Posted by modrobert View Post
I have worked with code to access I2C before, both in hardware (VHDL) and software.
That's a great help. This is the first time for me, instead.

Quote:
My point was more about the reason C= turns off interrupts completely with Disable() before accessing NVRAM, perhaps there is some conflict which is happening when you run with interrupts enabled?
The first thing that comes to mind is ensuring that timings don't get disrupted, but in the datasheet there's nothing that suggests that operations should be obligatorily done in a certain amount of time (i.e. stretching the clock isn't an issue, while shortening it is) - so, I'd exclude this.
Maybe it's related to Akiko (seems unlikely to me, though)?
Or it could be just a safety measure to prevent corruption due to misbehaving tasks or even parallel attempts at accessing the NVRAM.

Quote:
When you use the term "OS off/trashed" I assume you mean Forbid(), which is not the same as turning off all interrupts, it only disables multitasking.
Nope, I mean Disable(), no interrupt enabled afterwards and possibly completely trashed OS (due to need of RAM). The only thing my code doesn't do (yet) is executing the routines in supervisor / level 7 interrupts mode to exclude also interference by NMIs potentially generated by add-on hardware.
saimo is offline  
Old 20 September 2021, 14:34   #43
modrobert
old bearded fool
 
modrobert's Avatar
 
Join Date: Jan 2010
Location: Bangkok
Age: 56
Posts: 775
Quote:
Originally Posted by saimo View Post
Nope, I mean Disable(), no interrupt enabled afterwards and possibly completely trashed OS (due to need of RAM). The only thing my code doesn't do (yet) is executing the routines in supervisor / level 7 interrupts mode to exclude also interference by NMIs potentially generated by add-on hardware.
Aha, OK, my mistake. I thought you used the CIA timer, but noticed now you only read the address to cause a predictable delay.
modrobert is offline  
Old 20 September 2021, 18:54   #44
saimo
Registered User
 
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 787
No problem!
saimo is offline  
Old 23 September 2021, 17:28   #45
saimo
Registered User
 
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 787
I have updated the test archive: the executable in this one executes the routines in level 7 interrupt mode, so that nothing could ever interfere - but, honestly, I don't think this changes anything...
saimo is offline  
Old 04 March 2022, 16:09   #46
saimo
Registered User
 
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 787
I have now returned to this. Given the war, I'd really like to have SkillGrid v1.1 out as soon as possible (and if I get the green light from RGCD, it will be donationware for Ukraine), so I must get rid of this last issue.

I have:
* meticulously re-inspected the code once again;
* touched up the comments a little bit and added a few more equrs for better readability;
* re-checked the timings;
* checked that the protocol is implemented correctly by analyzing the log produced by WinUAE for a read whole-NVRAM-read operation;
* ran the tests suite (always getting perfect results).

Unfortunately, I still couldn't get tests done on a real Amiga CD32.

The log looks fine...

Code:
;Get ready.

50-235 [531 126-210]: Data read: c0             nvm_initialize
50-235 [531 132-210]: Direction write: 00->c0   nvm_initialize

;Generate START condition.

50-235 [531 010-211]: I2C START
50-235 [531 010-211]: Data write: c0->80 (80)   nvm_ReadBytes / StartWrite / StartOperation / GenerateSTART / PullSDALow

;Send device address for write operation ($a0).

50-235 [531 084-211]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 117-211]: Data write: 00->40 (40)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit
50-235 [531 138-211]: Data write: 40->c0 (c0)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 173-211]: Data write: c0->40 (40)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 186-211]: Data write: 40->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit
50-235 [531 208-211]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 016-212]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 033-212]: Data write: 00->40 (40)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit
50-235 [531 056-212]: Data write: 40->c0 (c0)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 091-212]: Data write: c0->40 (40)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 108-212]: Data write: 40->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit
50-235 [531 130-212]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 161-212]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 178-212]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit
50-235 [531 196-212]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 008-213]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 017-213]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit
50-235 [531 039-213]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 074-213]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 091-213]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit
50-235 [531 113-213]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 144-213]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 161-213]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit
50-235 [531 179-213]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 193-213]: Direction write: c0->80   nvm_ReadBytes / StartWrite / StartOperation / SendByte
50-235 [531 219-213]: Data write: 80->00 (40)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 032-214]: I2C device address 0xa0
50-235 [531 032-214]: Data write: 40->80 (c0)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLHigh
50-235 [531 044-214]: Data read: 00             nvm_ReadBytes / StartWrite / StartOperation / SendByte
50-235 [531 044-214]: Direction write: 80->c0   nvm_ReadBytes / StartWrite / StartOperation / SendByte

;Send start address ($00).

50-235 [531 082-214]: Data write: c0->00 (00)   nvm_ReadBytes / StartWrite / SendByte / PullSCLLow
50-235 [531 099-214]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / SendByte / SendBit
50-235 [531 121-214]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / SendByte / SendBit / PullSCLHigh
50-235 [531 152-214]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / SendByte / PullSCLLow
50-235 [531 169-214]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / SendByte / SendBit
50-235 [531 187-214]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / SendByte / SendBit / PullSCLHigh
50-235 [531 226-214]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / SendByte / PullSCLLow
50-235 [531 009-215]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / SendByte / SendBit
50-235 [531 030-215]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / SendByte / SendBit / PullSCLHigh
50-235 [531 065-215]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / SendByte / PullSCLLow
50-235 [531 082-215]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / SendByte / SendBit
50-235 [531 104-215]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / SendByte / SendBit / PullSCLHigh
50-235 [531 135-215]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / SendByte / PullSCLLow
50-235 [531 152-215]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / SendByte / SendBit
50-235 [531 170-215]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / SendByte / SendBit / PullSCLHigh
50-235 [531 204-215]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / SendByte / PullSCLLow
50-235 [531 217-215]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / SendByte / SendBit
50-235 [531 008-216]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / SendByte / SendBit / PullSCLHigh
50-235 [531 043-216]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / SendByte / PullSCLLow
50-235 [531 056-216]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / SendByte / SendBit
50-235 [531 078-216]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / SendByte / SendBit / PullSCLHigh
50-235 [531 113-216]: Data write: 80->00 (00)   nvm_ReadBytes / StartWrite / SendByte / PullSCLLow
50-235 [531 130-216]: Data write: 00->00 (00)   nvm_ReadBytes / StartWrite / SendByte / SendBit
50-235 [531 152-216]: Data write: 00->80 (80)   nvm_ReadBytes / StartWrite / SendByte / SendBit / PullSCLHigh
50-235 [531 160-216]: Direction write: c0->80   nvm_ReadBytes / StartWrite / SendByte
50-235 [531 183-216]: Data write: 80->00 (40)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 218-216]: I2C device address 0x00 (Address 0000)
50-235 [531 218-216]: Data write: 40->80 (c0)   nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLHigh
50-235 [531 008-217]: Data read: 00             nvm_ReadBytes / StartWrite / StartOperation / SendByte
50-235 [531 008-217]: Direction write: 80->c0   nvm_ReadBytes / StartWrite / StartOperation / SendByte

;Pull SDA high (it's low because the EEPROM sent an ACK) to allow another START condition).

50-235 [531 035-217]: Data write: c0->00 (00)   nvm_ReadBytes / PullSCLLow
50-235 [531 046-217]: Data write: 00->40 (40)   nvm_ReadBytes / PullSDAHigh
50-235 [531 076-217]: Data write: 40->c0 (c0)   nvm_ReadBytes / PullSCLHigh

;Generate (RE)START condition.

50-235 [531 139-217]: I2C START
50-235 [531 139-217]: Data write: c0->80 (80)   nvm_ReadBytes / StartOperation / GenerateSTART / PullSDALow

;Send device address for read operation ($a1).

50-235 [531 201-217]: Data write: 80->00 (00)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-235 [531 218-217]: Data write: 00->40 (40)   nvm_ReadBytes / StartOperation / SendByte / SendBit
50-235 [531 013-218]: Data write: 40->c0 (c0)   nvm_ReadBytes / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 044-218]: Data write: c0->40 (40)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-235 [531 061-218]: Data write: 40->00 (00)   nvm_ReadBytes / StartOperation / SendByte / SendBit
50-235 [531 079-218]: Data write: 00->80 (80)   nvm_ReadBytes / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 113-218]: Data write: 80->00 (00)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-235 [531 126-218]: Data write: 00->40 (40)   nvm_ReadBytes / StartOperation / SendByte / SendBit
50-235 [531 144-218]: Data write: 40->c0 (c0)   nvm_ReadBytes / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 183-218]: Data write: c0->40 (40)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-235 [531 192-218]: Data write: 40->00 (00)   nvm_ReadBytes / StartOperation / SendByte / SendBit
50-235 [531 214-218]: Data write: 00->80 (80)   nvm_ReadBytes / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 022-219]: Data write: 80->00 (00)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-235 [531 039-219]: Data write: 00->00 (00)   nvm_ReadBytes / StartOperation / SendByte / SendBit
50-235 [531 061-219]: Data write: 00->80 (80)   nvm_ReadBytes / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 092-219]: Data write: 80->00 (00)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-235 [531 109-219]: Data write: 00->00 (00)   nvm_ReadBytes / StartOperation / SendByte / SendBit
50-235 [531 127-219]: Data write: 00->80 (80)   nvm_ReadBytes / StartOperation / SendByte / SendBit / PullSCLHigh
50-235 [531 161-219]: Data write: 80->00 (00)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-235 [531 174-219]: Data write: 00->00 (00)   nvm_ReadBytes / StartOperation / SendByte / SendBit
50-235 [531 192-219]: Data write: 00->80 (80)   nvm_ReadBytes / StartOperation / SendByte / SendBit / PullSCLHigh
50-236 [531 000-220]: Data write: 80->00 (00)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-236 [531 013-220]: Data write: 00->40 (40)   nvm_ReadBytes / StartOperation / SendByte / SendBit
50-236 [531 035-220]: Data write: 40->c0 (c0)   nvm_ReadBytes / StartOperation / SendByte / SendBit / PullSCLHigh
50-236 [531 051-220]: Direction write: c0->80   nvm_ReadBytes / StartOperation / SendByte
50-236 [531 070-220]: Data write: c0->40 (40)   nvm_ReadBytes / StartOperation / SendByte / PullSCLLow
50-236 [531 105-220]: Data write: 40->c0 (c0)   nvm_ReadBytes / StartOperation / SendByte / PullSCLHigh
50-236 [531 121-220]: Data read: 00             nvm_ReadBytes / StartOperation / SendByte
50-236 [531 121-220]: Direction write: 80->c0   nvm_ReadBytes / StartOperation / SendByte

;Read byte #0.

50-236 [531 138-220]: Direction write: c0->80   nvm_ReadBytes
50-236 [531 164-220]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-236 [531 200-220]: I2C RX byte 0000 0x00
50-236 [531 200-220]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-236 [531 217-220]: Data read: 00             nvm_ReadBytes
50-236 [531 023-221]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-236 [531 058-221]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-236 [531 070-221]: Data read: 00             nvm_ReadBytes
50-236 [531 098-221]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-236 [531 133-221]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-236 [531 149-221]: Data read: 00             nvm_ReadBytes
50-236 [531 173-221]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-236 [531 208-221]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-236 [531 224-221]: Data read: 00             nvm_ReadBytes
50-236 [531 021-222]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-236 [531 056-222]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-236 [531 072-222]: Data read: 00             nvm_ReadBytes
50-236 [531 096-222]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-236 [531 131-222]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-236 [531 147-222]: Data read: 00             nvm_ReadBytes
50-236 [531 171-222]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-236 [531 206-222]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-236 [531 222-222]: Data read: 00             nvm_ReadBytes
50-236 [531 019-223]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-236 [531 054-223]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-236 [531 070-223]: Data read: 00             nvm_ReadBytes
50-236 [531 077-223]: Direction write: 80->c0   nvm_ReadBytes
50-236 [531 099-223]: Data write: c0->00 (00)   nvm_ReadBytes / PullSCLLow
50-236 [531 121-223]: Data write: 00->00 (00)   nvm_ReadBytes / SendBit
50-236 [531 144-223]: I2C ACKED
50-236 [531 144-223]: Data write: 00->80 (80)   nvm_ReadBytes / SendBit / PullSCLHigh

;Read other 1023 bytes.

50-236 [531 165-223]: Direction write: c0->80
50-236 [531 184-223]: Data write: 80->00 (40)
50-236 [531 218-223]: I2C RX byte 0001 0x56
50-236 [531 218-223]: Data write: 40->80 (c0)
50-236 [531 226-223]: Data read: 00
50-236 [531 026-224]: Data write: c0->00 (40)
50-236 [531 056-224]: Data write: 40->80 (c0)
50-236 [531 064-224]: Data read: c0
50-236 [531 092-224]: Data write: c0->40 (40)
50-236 [531 127-224]: Data write: 40->c0 (c0)
50-236 [531 139-224]: Data read: 00
50-236 [531 167-224]: Data write: c0->00 (40)
50-236 [531 202-224]: Data write: 40->80 (c0)
50-236 [531 218-224]: Data read: c0
50-236 [531 015-225]: Data write: c0->40 (40)
50-236 [531 050-225]: Data write: 40->c0 (c0)
50-236 [531 066-225]: Data read: 00
50-236 [531 090-225]: Data write: c0->00 (40)
50-236 [531 125-225]: Data write: 40->80 (c0)
50-236 [531 141-225]: Data read: c0
50-236 [531 165-225]: Data write: c0->40 (40)
50-236 [531 200-225]: Data write: 40->c0 (c0)
50-236 [531 216-225]: Data read: c0
50-236 [531 013-226]: Data write: c0->40 (40)
50-236 [531 048-226]: Data write: 40->c0 (c0)
50-236 [531 064-226]: Data read: 00
50-236 [531 066-226]: Direction write: 80->c0
50-236 [531 088-226]: Data write: c0->00 (00)
50-236 [531 105-226]: Data write: 00->00 (00)
50-236 [531 128-226]: I2C ACKED
50-236 [531 128-226]: Data write: 00->80 (80)

...

50-517 [541 211-043]: Data read: 00
50-517 [541 011-044]: Data write: c0->00 (40)
50-517 [541 041-044]: Data write: 40->80 (c0)
50-517 [541 049-044]: Data read: 00
50-517 [541 076-044]: Data write: c0->00 (40)
50-517 [541 107-044]: Data write: 40->80 (c0)
50-517 [541 119-044]: Data read: 00
50-517 [541 147-044]: Data write: c0->00 (40)
50-517 [541 182-044]: Data write: 40->80 (c0)
50-517 [541 194-044]: Data read: 00
50-517 [541 222-044]: Data write: c0->00 (40)
50-517 [541 030-045]: Data write: 40->80 (c0)
50-517 [541 046-045]: Data read: 00
50-517 [541 070-045]: Data write: c0->00 (40)
50-517 [541 105-045]: Data write: 40->80 (c0)
50-517 [541 121-045]: Data read: 00
50-517 [541 145-045]: Data write: c0->00 (40)
50-517 [541 180-045]: Data write: 40->80 (c0)
50-517 [541 196-045]: Data read: 00
50-517 [541 220-045]: Data write: c0->00 (40)
50-517 [541 028-046]: Data write: 40->80 (c0)
50-517 [541 044-046]: Data read: 00
50-517 [541 046-046]: Direction write: 80->c0
50-517 [541 068-046]: Data write: c0->00 (00)
50-517 [541 085-046]: Data write: 00->00 (00)
50-517 [541 108-046]: I2C ACKED
50-517 [541 108-046]: Data write: 00->80 (80)

;Read last byte.

50-517 [541 124-046]: Direction write: c0->80   nvm_ReadBytes
50-517 [541 143-046]: Data write: 80->00 (40)   nvm_ReadBytes / PullSCLLow
50-517 [541 177-046]: I2C RX byte 03FF 0x00
50-517 [541 177-046]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-517 [541 185-046]: Data read: 00             nvm_ReadBytes
50-517 [541 212-046]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-517 [541 015-047]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-517 [541 023-047]: Data read: 00             nvm_ReadBytes
50-517 [541 050-047]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-517 [541 081-047]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-517 [541 093-047]: Data read: 00             nvm_ReadBytes
50-517 [541 121-047]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-517 [541 156-047]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-517 [541 168-047]: Data read: 00             nvm_ReadBytes
50-517 [541 196-047]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-517 [541 004-048]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-517 [541 020-048]: Data read: 00             nvm_ReadBytes
50-517 [541 044-048]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-517 [541 079-048]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-517 [541 095-048]: Data read: 00             nvm_ReadBytes
50-517 [541 119-048]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-517 [541 154-048]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-517 [541 170-048]: Data read: 00             nvm_ReadBytes
50-518 [541 194-048]: Data write: c0->00 (40)   nvm_ReadBytes / PullSCLLow
50-518 [541 002-049]: Data write: 40->80 (c0)   nvm_ReadBytes / PullSCLHigh
50-518 [541 018-049]: Data read: 00             nvm_ReadBytes
50-518 [541 020-049]: Direction write: 80->c0   nvm_ReadBytes
50-518 [541 042-049]: Data write: c0->00 (00)   nvm_ReadBytes / PullSCLLow
50-518 [541 059-049]: Data write: 00->40 (40)   nvm_ReadBytes / SendBit
50-518 [541 082-049]: I2C NACKED
50-518 [541 082-049]: Data write: 40->c0 (c0)   nvm_ReadBytes / SendBit / PullSCLHigh

;Generate STOP condition

50-518 [541 122-049]: Data write: c0->40 (40)   GenerateSTOP / PullSCLLow
50-518 [541 141-049]: Data write: 40->00 (00)   GenerateSTOP / PullSDALow
50-518 [541 171-049]: Data write: 00->80 (80)   GenerateSTOP / PullSCLHigh
50-518 [541 214-049]: I2C STOP
50-518 [541 214-049]: Data write: 80->c0 (c0)   GenerateSTOP / PullSDAHigh
... but there's one thing (in bold) that escapes me:

50-235 [531 193-213]: Direction write: c0->80 nvm_ReadBytes / StartWrite / StartOperation / SendByte
50-235 [531 219-213]: Data write: 80->00 (40) nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLLow
50-235 [531 032-214]: I2C device address 0xa0
50-235 [531 032-214]: Data write: 40->80 (c0) nvm_ReadBytes / StartWrite / StartOperation / SendByte / PullSCLHigh
50-235 [531 044-214]: Data read: 00 nvm_ReadBytes / StartWrite / StartOperation / SendByte

The excerpt is from the end of a write operation that sends the device address to the EEPROM and corresponds to the code that reads the ACK received from it (the same happens for all the other byte send operations).
This is what happens:
1. SDA gets set to input;
2. SCL gets pulled low to start a cycle;
3. SCL gets pulled high to end the cycle;
4. SDA gets read.

The strange thing is, if I'm interpreting 80->00 (40) correctly, that when SCL gets pulled low (80->00 = SCL was high, SDA was low and then both became low), SDA becomes high for a moment (40). Then, after the cycle completes (and, in the real world, SDA is stable), SDA reads correctly low (0 = ACK). Is that a sign that something's wrong in my code or is it an emulation quirk (there's no mention of such behaviour in the datasheet)?

Latest revision of the code attached here.

Last edited by saimo; 06 March 2022 at 00:58. Reason: Removed attachment, as I've posted a newer version in the next post.
saimo is offline  
Old 06 March 2022, 00:57   #47
saimo
Registered User
 
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 787
Maybe (just maybe), I've found (and fixed) something crucial, precisely about the part I highlighted in the previous post.

For sending the ACK/NACK after reading, I was doing this:
1. make SDA output
2. pull SCL low
3. drive SDA as needed
4. pull SCL high

For receiving the ACK/NACK after writing, I was doing this:
1. make SDA input
2. pull SCL low
3. pull SCL high
4. read SDA

The ATMEL datasheet doesn't mention anything specific about that.

The official I2C specifications (UM10204 by NXP) say: "The Acknowledge signal is defined as follows: the transmitter releases the SDA line during the acknowledge clock pulse so the receiver can pull the SDA line LOW and it remains stable LOW during the HIGH period of this clock pulse (see Figure 4)."

That clearly says that the SDA line must not be released before the acknowledge cycle (like I was doing). However, if I inverted steps 1 and 2, things wouldn't work also in WinUAE (I had already discovered this moons ago, but now I've double-checked). The only option that remained was to start the cycle and release the line at the same time. In fact, I've found in the much better and richer datasheet of the same chip by Microchip this: "An ACK is accomplished by the transmitting device first releasing the SDA line at the falling edge of the eighth clock cycle followed by the receiving device responding with a logic ‘0’ during the entire high period of the ninth clock cycle" - and that is also accompanied by this nice diagram that leaves no leeway to interpretation:




After I changed the code (attached), I updated both SkillGrid and the test suite to check whether they'd still produce correct results - and they did. If anyone can and wants to give it a go, the test suite is still available from https://www.retream.com/_temporary/NVRAMRTS.lha. I hope the friend of mine who has the suitable machine for testing will be able to run the tests soonish.

Last edited by saimo; 07 March 2022 at 17:07. Reason: Removed attachment, as I've added an update version in the next post.
saimo is offline  
Old 07 March 2022, 17:06   #48
saimo
Registered User
 
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 787
Minor improvements after checking the NXP documentation and the Microchip datasheet:
* removed the START/STOP conditions after the fallback reset (it didn't make sense already, but I had tried to stay faithful to ATMEL's datasheet);
* shortened the delay before generating the START condition (it was too long for a restart and the appropriate delay was already applied by GenerateSTOP()).
Both these changes should not have any relevance to whether the code works or not, as the fallback reset probably is never executed and the other change only improves performance in a negligible way.
It looks my friend might run the test shortly... crossing fingers...
Attached Files
File Type: s NVRAM.s (23.0 KB, 29 views)

Last edited by saimo; 05 May 2022 at 19:42.
saimo is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Extend CD32 NVRAM? Amiga1992 Hardware mods 41 16 December 2018 14:59
CD32 NVRAM management Amiga1992 support.Hardware 9 20 February 2012 13:27
Access CD32-NVRam from Shell Retro1234 support.Other 3 08 August 2010 11:50
CD32 nvram file...? Christian support.WinUAE 11 13 December 2006 22:25
Cd32 Nvram Phantomz request.Apps 5 16 March 2003 21:09

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 06:26.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.07987 seconds with 16 queries