English Amiga Board


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

 
 
Thread Tools
Old 25 March 2020, 18:55   #21
phx
Natteravn

phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 1,598
@Bruce: You really have to relax! What's the reason for your harsh tone in most discussions? Did Saimo do anything to you? Is it your ROM code he is talking about?
phx is offline  
Old Yesterday, 01:46   #22
saimo
Registered User
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 267
Back from a little break (dedicated, among other things, to [ Show youtube player ], which provided me with some relaxing distraction from this matter).

I looked again and at a bit further into the log...
Code:
                                                SCL   SDA   operation   cycle
-----------------------------------------------------------------------------

* INITIALIZE

28-077 [98 062-111]: Direction write: 00->c0    o     o
28-077 [98 062-111]: Data write: c0->c0 (c0)    1     1

* START

28-077 [98 108-111]: I2C START
28-077 [98 108-111]: Data write: c0->80 (80)    1     0     start

* ADDRESS MEMORY (for write)

28-077 [98 167-111]: Data write: 80->00 (00)    0     0                 1v
28-077 [98 221-111]: Data write: 00->40 (40)    0     1     
28-077 [98 041-112]: Data write: 40->c0 (c0)    1     1     send 1      1^
28-077 [98 074-112]: Data write: c0->40 (40)    0     1
28-077 [98 104-112]: Data write: 40->00 (00)    0     0
28-077 [98 134-112]: Data write: 00->80 (80)    1     0     send 0      2^
28-077 [98 154-112]: Data write: 80->00 (00)    0     0
28-077 [98 188-112]: Data write: 00->40 (40)    0     1
28-077 [98 219-112]: Data write: 40->c0 (c0)    1     1     send 1      3^
28-077 [98 012-113]: Data write: c0->40 (40)    0     1
28-077 [98 046-113]: Data write: 40->00 (00)    0     0
28-077 [98 073-113]: Data write: 00->80 (80)    1     0     send 0      4^
28-077 [98 102-113]: Data write: 80->00 (00)    0     0
28-077 [98 132-113]: Data write: 00->00 (00)    0     0
28-077 [98 162-113]: Data write: 00->80 (80)    1     0     send 0      5^
28-077 [98 187-113]: Data write: 80->00 (00)    0     0     
28-077 [98 217-113]: Data write: 00->00 (00)    0     0
28-077 [98 020-114]: Data write: 00->80 (80)    1     0     send 0      6^
28-077 [98 040-114]: Data write: 80->00 (00)    0     0
28-077 [98 074-114]: Data write: 00->00 (00)    0     0
28-077 [98 101-114]: Data write: 00->80 (80)    1     0     send 0      7^
28-077 [98 130-114]: Data write: 80->00 (00)    0     0
28-077 [98 160-114]: Data write: 00->00 (00)    0     0
28-077 [98 190-114]: Data write: 00->80 (80)    1     0     send 0      8^

* GET ACK

28-077 [98 218-114]: Direction write: c0->80    o     i
28-077 [98 218-114]: Data write: 80->00 (40)    0     *                 9v

28-077 [98 041-115]: I2C device address 0xa0

28-077 [98 041-115]: Data write: 40->80 (c0)    1     *                 9^
28-077 [98 074-115]: Direction read: 80         o     i     
28-077 [98 074-115]: Data read: 00              *     0     get ACK

* ???

28-077 [98 082-115]: Data write: c0->00 (40)    0     *     ?           10v
28-077 [98 093-115]: Data write: 40->00 (40)    0     *     ?

* ADDRESS OFFSET

28-077 [98 128-115]: Direction write: 80->c0    o     o     
28-077 [98 128-115]: Data write: 40->00 (00)    0     0
28-077 [98 165-115]: Data write: 00->80 (80)    1     0                 10^
28-077 [98 198-115]: Data write: 80->00 (00)    0     0
28-078 [98 005-116]: Data write: 00->00 (00)    0     0
28-078 [98 032-116]: Data write: 00->80 (80)    1     0                 11
28-078 [98 061-116]: Data write: 80->00 (00)    0     0                 
28-078 [98 091-116]: Data write: 00->00 (00)    0     0                 
28-078 [98 121-116]: Data write: 00->80 (80)    1     0                 12
28-078 [98 146-116]: Data write: 80->00 (00)    0     0                 
28-078 [98 176-116]: Data write: 00->00 (00)    0     0                 
28-078 [98 206-116]: Data write: 00->80 (80)    1     0                 13
28-078 [98 226-116]: Data write: 80->00 (00)    0     0                 
28-078 [98 033-117]: Data write: 00->00 (00)    0     0                 
28-078 [98 060-117]: Data write: 00->80 (80)    1     0                 14
28-078 [98 089-117]: Data write: 80->00 (00)    0     0                 
28-078 [98 119-117]: Data write: 00->00 (00)    0     0                 
28-078 [98 149-117]: Data write: 00->80 (80)    1     0                 15
28-078 [98 174-117]: Data write: 80->00 (00)    0     0                 
28-078 [98 204-117]: Data write: 00->00 (00)    0     0                 
28-078 [98 007-118]: Data write: 00->80 (80)    1     0                 16
28-078 [98 027-118]: Data write: 80->00 (00)    0     0                 
28-078 [98 061-118]: Data write: 00->00 (00)    0     0                 
28-078 [98 088-118]: Data write: 00->80 (80)    1     0                 17

28-078 [98 170-118]: I2C device address 0x00 (Address 0000)

* GET ACK

28-078 [98 119-118]: Direction write: c0->80    o     i
28-078 [98 119-118]: Data write: 80->00 (40)    0     0
28-078 [98 170-118]: Data write: 40->80 (c0)    1     0                 18

28-078 [98 207-118]: Direction read: 80
28-078 [98 207-118]: Data read: 00              0     0     get ACK


* RESTART

28-078 [98 211-118]: Data write: c0->00 (40)    0     *                 19v
28-078 [98 001-119]: Direction write: 80->c0    o     o
28-078 [98 001-119]: Data write: 40->c0 (c0)    1     1                 19^ extra cycle
28-078 [98 047-119]: Data write: c0->80 (80)    1     0
28-078 [98 047-119]: I2C START

* ADDRESS MEMORY (for read)

28-078 [98 101-119]: Data write: 80->00 (00)    0     0                 20v
28-078 [98 135-119]: Data write: 00->40 (40)    0     1
28-078 [98 182-119]: Data write: 40->c0 (c0)    1     1                 20^
28-078 [98 215-119]: Data write: c0->40 (40)    0     1                 21v
28-078 [98 018-120]: Data write: 40->00 (00)    0     0                 
28-078 [98 048-120]: Data write: 00->80 (80)    1     0                 21^
28-078 [98 068-120]: Data write: 80->00 (00)    0     0                 22v
28-079 [98 102-120]: Data write: 00->40 (40)    0     1
28-079 [98 133-120]: Data write: 40->c0 (c0)    1     1                 22^
28-079 [98 153-120]: Data write: c0->40 (40)    0     1                 23v
28-079 [98 187-120]: Data write: 40->00 (00)    0     0
28-079 [98 214-120]: Data write: 00->80 (80)    1     0                 23^
28-079 [98 016-121]: Data write: 80->00 (00)    0     0                 24v
28-079 [98 046-121]: Data write: 00->00 (00)    0     0
28-079 [98 076-121]: Data write: 00->80 (80)    1     0                 24^
28-079 [98 101-121]: Data write: 80->00 (00)    0     0                 25v
28-079 [98 131-121]: Data write: 00->00 (00)    0     0
28-079 [98 161-121]: Data write: 00->80 (80)    1     0                 25^
28-079 [98 181-121]: Data write: 80->00 (00)    0     0                 26v
28-079 [98 215-121]: Data write: 00->00 (00)    0     0
28-079 [98 015-122]: Data write: 00->80 (80)    1     0                 26^
28-079 [98 044-122]: Data write: 80->00 (00)    0     0                 27v
28-079 [98 078-122]: Data write: 00->40 (40)    0     1
28-079 [98 105-122]: Data write: 40->c0 (c0)    1     1                 27^

* GET ACK

28-079 [98 137-122]: Direction write: c0->80    o     i
28-079 [98 137-122]: Data write: c0->40 (40)    0     *                 28v
28-079 [98 188-122]: Data write: 40->c0 (c0)    1     *                 28^
28-079 [98 224-122]: Direction read: 80
28-079 [98 224-122]: Data read: 00              0     0     get ACK

* ???

28-079 [98 001-123]: Data write: c0->00 (40)    0     *                 29v
28-079 [98 019-123]: Data write: 40->00 (40)    0     *
28-079 [98 021-123]: Data write: 40->00 (40)    0     *

* READ BYTE 0

28-079 [98 059-123]: I2C RX byte 0000 0x00
28-079 [98 059-123]: Data write: 40->80 (c0)    1     *                 29^
28-079 [98 092-123]: Direction read: 80
28-079 [98 092-123]: Data read: 00
28-079 [98 099-123]: Data write: c0->00 (40)
28-079 [98 122-123]: Data write: 40->80 (c0)                            31^
28-079 [98 143-123]: Direction read: 80
28-079 [98 143-123]: Data read: 00
28-079 [98 147-123]: Data write: c0->00 (40)
28-079 [98 172-123]: Data write: 40->80 (c0)                            32^
28-079 [98 192-123]: Direction read: 80
28-079 [98 192-123]: Data read: 00
28-079 [98 196-123]: Data write: c0->00 (40)
28-079 [98 217-123]: Data write: 40->80 (c0)                            33^
28-079 [98 011-124]: Direction read: 80
28-079 [98 011-124]: Data read: 00
28-079 [98 015-124]: Data write: c0->00 (40)
28-079 [98 040-124]: Data write: 40->80 (c0)                            34^
28-080 [98 060-124]: Direction read: 80
28-080 [98 060-124]: Data read: 00
28-080 [98 064-124]: Data write: c0->00 (40)
28-080 [98 085-124]: Data write: 40->80 (c0)                            35^
28-080 [98 106-124]: Direction read: 80
28-080 [98 106-124]: Data read: 00
28-080 [98 110-124]: Data write: c0->00 (40)
28-080 [98 135-124]: Data write: 40->80 (c0)                            36^
28-080 [98 155-124]: Direction read: 80
28-080 [98 155-124]: Data read: 00
28-080 [98 159-124]: Data write: c0->00 (40)
28-080 [98 180-124]: Data write: 40->80 (c0)                            37^
28-080 [98 201-124]: Direction read: 80
28-080 [98 201-124]: Data read: 00

* SEND ACK

28-080 [98 208-124]: Data write: c0->00 (40)    0     *                 38v
28-080 [98 048-125]: Direction write: 80->c0    o     o
28-080 [98 048-125]: Data write: 40->00 (00)    0     0
28-080 [98 085-125]: I2C ACKED
28-080 [98 085-125]: Data write: 00->80 (80)    1     0                 38^

* ???

28-080 [98 124-125]: Data write: 80->00 (00)    0     0                 39v
28-080 [98 135-125]: Direction write: c0->80    o     i
28-080 [98 135-125]: Data write: 00->00 (40)    0     *
28-080 [98 135-125]: Data write: 40->00 (40)    0     *

* READ BYTE 1

28-080 [98 163-125]: I2C RX byte 0001 0x56
28-080 [98 163-125]: Data write: 40->80 (c0)    1     *                 39^
28-080 [98 184-125]: Direction read: 80
28-080 [98 184-125]: Data read: 00
28-080 [98 188-125]: Data write: c0->00 (40)
28-080 [98 213-125]: Data write: 40->80 (c0)
28-080 [98 006-126]: Direction read: 80
28-080 [98 006-126]: Data read: c0
28-080 [98 010-126]: Data write: c0->00 (40)
28-080 [98 032-126]: Data write: 40->80 (c0)
28-080 [98 057-126]: Direction read: 80
28-080 [98 057-126]: Data read: 00
28-080 [98 065-126]: Data write: c0->00 (40)
28-080 [98 086-126]: Data write: 40->80 (c0)
28-080 [98 107-126]: Direction read: 80
28-080 [98 107-126]: Data read: c0
28-080 [98 111-126]: Data write: c0->00 (40)
28-080 [98 136-126]: Data write: 40->80 (c0)
28-080 [98 157-126]: Direction read: 80
28-080 [98 157-126]: Data read: 00
28-080 [98 161-126]: Data write: c0->00 (40)
28-080 [98 186-126]: Data write: 40->80 (c0)
28-080 [98 206-126]: Direction read: 80
28-080 [98 206-126]: Data read: c0
28-080 [98 210-126]: Data write: c0->00 (40)
28-080 [98 005-127]: Data write: 40->80 (c0)
28-080 [98 030-127]: Direction read: 80
28-080 [98 030-127]: Data read: c0
28-081 [98 038-127]: Data write: c0->00 (40)
28-081 [98 059-127]: Data write: 40->80 (c0)
28-081 [98 080-127]: Direction read: 80
28-081 [98 080-127]: Data read: 00
28-081 [98 084-127]: Data write: c0->00 (40)
28-081 [98 147-127]: Direction write: 80->c0
28-081 [98 147-127]: Data write: 40->00 (00)
28-081 [98 175-127]: I2C ACKED
... and noticed again that after the ACKs some extra-protocol writes are performed (not always in the same way), that the RESTART condition is performed by means of the extra cycle, that sometimes data is set/cleared together with setting the input/output, and that the flood of direction read/writes reported by Toni (and filtered out by the log settings) is due to the fact that all operations are performed as longwords spanning both the data and the direction registers.

(Continued in the next post.)
saimo is offline  
Old Yesterday, 01:56   #23
saimo
Registered User
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 267
(Continued.)

I felt that looking at the log wasn't sufficient to fully understand the logic (and check the timings), so I decided to challenge my sanity and follow the execution from the UAE monitor (for those who find this strange, again, it's a limitation of mine). I couldn't take much, but something came out of it...

Code:
*** initialization
Memwatch 1: break at 00B80030.L  W  C000C000 PC=00E61A12 CPUDW (000)   hh oo

00E61A12 2a85                     MOVE.L D5,(A5) [c000c000]
00E61A14 4a39 00bf e001           TST.B $00bfe001
00E61A1A 4a39 00bf e001           TST.B $00bfe001
00E61A20 4a39 00bf e001           TST.B $00bfe001
00E61A26 4a39 00bf e001           TST.B $00bfe001
00E61A2C 0285 bfff ffff           AND.L #$bfffffff,D5


*** START condition

Memwatch 1: break at 00B80030.L  W  8000C000 PC=00E61A32 CPUDW (000)   hl oo

00E61A32 2a85                     MOVE.L D5,(A5) [0000c000] 8000C000
00E61A34 4a39 00bf e001           TST.B $00bfe001
00E61A3A 4a39 00bf e001           TST.B $00bfe001
00E61A40 4a39 00bf e001           TST.B $00bfe001
00E61A46 4e75                     RTS


*** send byte (address memory)

Memwatch 1: break at 00B80030.L  W  0000C000 PC=00E61ABC CPUDW (000)   ll oo   v

00E61AB4 7207                     MOVE.L #$07,D1
00E61AB6 0285 7fff ffff           AND.L #$7fffffff,D5
00E61ABC 2a85                     MOVE.L D5,(A5) [0000c000] 0000C000
00E61ABE 4a39 00bf e001           TST.B $00bfe001
00E61AC4 4a39 00bf e001           TST.B $00bfe001
00E61ACA 4a39 00bf e001           TST.B $00bfe001
00E61AD0 4a39 00bf e001           TST.B $00bfe001
00E61AD6 0285 bfff ffff           AND.L #$bfffffff,D5

Memwatch 1: break at 00B80030.L  W  4000C000 PC=00E61AEC CPUDW (000)   lh oo

00E61ADC 0085 0000 4000           OR.L #$00004000,D5
00E61AE2 e388                     LSL.L #$01,D0
00E61AE4 6406                     BCC.B #$06 == $00e61aec (T)
00E61AE6 0085 4000 0000           OR.L #$40000000,D5
00E61AEC 2a85                     MOVE.L D5,(A5) [c000c000] 4000C000
00E61AEE 4a39 00bf e001           TST.B $00bfe001
00E61AF4 4a39 00bf e001           TST.B $00bfe001
00E61AFA 4a39 00bf e001           TST.B $00bfe001
00E61B00 4a39 00bf e001           TST.B $00bfe001
00E61B06 0085 8000 0000           OR.L #$80000000,D5

Memwatch 1: break at 00B80030.L  W  C000C000 PC=00E61B0C CPUDW (000)   hh oo   ^

00E61B0C 2a85                     MOVE.L D5,(A5) [c000c000] C000C000
00E61B0E 4a39 00bf e001           TST.B $00bfe001
00E61B14 4a39 00bf e001           TST.B $00bfe001
00E61B1A 4a39 00bf e001           TST.B $00bfe001
00E61B20 51c9 ff94                DBF .W D1,#$ff94 == $00e61ab6 (F)


*** start cycle and set SDA to input

Memwatch 1: break at 00B80030.L  W  00008000 PC=00E61B2A CPUDW (000)   ll oi   v

00E61B24 0285 7fff bfff           AND.L #$7fffbfff,D5
00E61B2A 2a85                     MOVE.L D5,(A5) [c000c000] 00008000
00E61B2C 4a39 00bf e001           TST.B $00bfe001
00E61B32 4a39 00bf e001           TST.B $00bfe001
00E61B38 4a39 00bf e001           TST.B $00bfe001
00E61B3E 4a39 00bf e001           TST.B $00bfe001
00E61B44 4e75                     RTS


*** complete cycle

Memwatch 1: break at 00B80030.L  W  80008000 PC=00E61C10 CPUDW (000)   hl oi   ^

00E61C04 0085 8000 0000           OR.L #$80000000,D5
00E61C0A 0285 ffff bfff           AND.L #$ffffbfff,D5
00E61C10 2a85                     MOVE.L D5,(A5) [00008000] 80008000
00E61C12 7406                     MOVE.L #$06,D2

*** read ACK up to 7 times and then start cycle

Memwatch 0: break at 00B80030.L R   00000000 PC=00E61C26 CPUDR (000)

00E61C14 4a39 00bf e001           TST.B $00bfe001
00E61C1A 4a39 00bf e001           TST.B $00bfe001
00E61C20 4a39 00bf e001           TST.B $00bfe001
00E61C26 2a15                     MOVE.L (A5) [00008000],D5
00E61C28 0805 001e                BTST.L #$001e,D5
00E61C2C 6706                     BEQ.B #$06 == $00e61c34 (F)         if ACK...
00E61C2E 51ca ffe4                DBF .W D2,#$ffe4 == $00e61c14 (F)
00E61C32 600e                     BT .B #$0e == $00e61c42 (T)         if NACK (never happened)...

Memwatch 1: break at 00B80030.L  W  00008000 PC=00E61C3A CPUDW (000)  ll oi    v

00E61C34 0285 7fff ffff           AND.L #$7fffffff,D5
00E61C3A 2a85                     MOVE.L D5,(A5) [00008000] 00008000
00E61C3C 023c 00fe                AND.B #$00fe,CCR
00E61C40 4e75                     RTS

00E61C42 0285 7fff ffff           AND.L #$7fffffff,D5
00E61C48 2a85                     MOVE.L D5,(A5) [00008000]           lh oi    v
00E61C4A 003c 0001                OR.B #$0001,CCR
00E61C4E 4e75                     RTS


*** send offset
*** repeat initialization + START condition
*** address memory


* read byte

Memwatch 1: break at 00B80030.L  W  00008000 PC=00E61B4E CPUDW (000)  ll oi    v

00E61B46 7207                     MOVE.L #$07,D1
00E61B48 0285 ffff bfff           AND.L #$ffffbfff,D5                          ensures SDA is input (no assumption on previous state)
00E61B4E 2a85                     MOVE.L D5,(A5) [c0008000]                    loop here

Memwatch 1: break at 00B80030.L  W  00008000 PC=00E61B56 CPUDW (000)  ll oi    v   no delay

00E61B50 0285 7fff ffff           AND.L #$7fffffff,D5                          loop here
00E61B56 2a85                     MOVE.L D5,(A5) [c0008000]                    to pull SCL low 
00E61B58 4a39 00bf e001           TST.B $00bfe001
00E61B5E 4a39 00bf e001           TST.B $00bfe001
00E61B64 4a39 00bf e001           TST.B $00bfe001
00E61B6A 0085 8000 0000           OR.L #$80000000,D5

Memwatch 1: break at 00B80030.L  W  80008000 PC=00E61B70 CPUDW (000)  hl oi    ^

00E61B70 2a85                     MOVE.L D5,(A5) [c0008000]
00E61B72 4a39 00bf e001           TST.B $00bfe001
00E61B78 4a39 00bf e001           TST.B $00bfe001
00E61B7E 4a39 00bf e001           TST.B $00bfe001

Memwatch 0: break at 00B80030.L R   00000000 PC=00E61B84 CPUDR (000)           read SDA

00E61B84 2415                     MOVE.L (A5) [c0008000],D2
00E61B86 e388                     LSL.L #$01,D0
00E61B88 0802 001e                BTST.L #$001e,D2
00E61B8C 6704                     BEQ.B #$04 == $00e61b92 (F)
00E61B8E 0000 0001                OR.B #$01,D0
00E61B92 51c9 ffbc                DBF .W D1,#$ffbc == $00e61b50 (F)


* start cycle and exit

Memwatch 1: break at 00B80030.L  W  00008000 PC=00E61B9C CPUDW (000)  ll oi    v

00E61B96 0285 7fff ffff           AND.L #$7fffffff,D5
00E61B9C 2a85                     MOVE.L D5,(A5) [c0008000]
00E61B9E 4a39 00bf e001           TST.B $00bfe001
00E61BA4 4a39 00bf e001           TST.B $00bfe001
00E61BAA 4a39 00bf e001           TST.B $00bfe001
00E61BB0 4a39 00bf e001           TST.B $00bfe001
00E61BB6 023c 00fe                AND.B #$00fe,CCR
00E61BBA 4e75                     RTS


*** send ACK and start cycle

Memwatch 1: break at 00B80030.L  W  0000C000 PC=00E61BC8 CPUDW (000)  ll ii    v

00E61BBC 0285 bfff ffff           AND.L #$bfffffff,D5                          set SDA to 0 and to input
00E61BC2 0085 0000 4000           OR.L #$00004000,D5
00E61BC8 2a85                     MOVE.L D5,(A5) [0000c000]
00E61BCA 4a39 00bf e001           TST.B $00bfe001
00E61BD0 4a39 00bf e001           TST.B $00bfe001
00E61BD6 4a39 00bf e001           TST.B $00bfe001
00E61BDC 0085 8000 0000           OR.L #$80000000,D5

Memwatch 1: break at 00B80030.L  W  8000C000 PC=00E61BE2 CPUDW (000)  hl ii    ^

00E61BE2 2a85                     MOVE.L D5,(A5) [0000c000]        
00E61BE4 4a39 00bf e001           TST.B $00bfe001
00E61BEA 4a39 00bf e001           TST.B $00bfe001
00E61BF0 4a39 00bf e001           TST.B $00bfe001
00E61BF6 0285 7fff ffff           AND.L #$7fffffff,D5

Memwatch 1: break at 00B80030.L  W  0000C000 PC=00E61BFC CPUDW (000)  ll ii    v

00E61BFC 2a85                     MOVE.L D5,(A5) [0000c000]
00E61BFE 023c 00fe                AND.B #$00fe,CCR
00E61C02 4e75                     RTS
Things confirmed:
* the code always uses longwords (which, together with the many immediate ANDs/ORs, cause it to be a bit bigger / less efficient than it could be, unless it's mandatory to access both registers at the same time - which would be rather odd, but I don't want to exclude anything);
* additional operations are performed after the ACKs;
* the RESTART is performed by generating STOP condition through the simple initialization executed at the very beginning (this is a consequence of SCL being left low by routines as noted below).

Things discovered:
* receiving ACK is performed is a weird way: after clocking the cycle and waiting for the signal to stabilize, SDA is read up to 7 times consecutively until it reads 0... what for? the signal is already stable, and it isn't going to change since no pulse is sent to the EEPROM, and the datasheet doesn't even contemplate the case of a NACK;
* the extra unexpected writes depend on the fact that the routines use the convention of pulling SCL low (i.e. starting a cycle) before returning: when the next routine begins, it pulls SCL low again (so nothing changes, in practice);
* sometimes data and direction get set at the same time: this could be a good optimization (as it saves a delay each time), but can it be done always?
* delays are irregular (seemingly, without a logic): sometimes they are achived by accessing the CIA A 4 times, sometimes 3 (as if the code relied on the additional delay caused by the execution of the following instructions - which would of course would not work on faster CPUs, but, if the EEPROM is the 5 V version, then actually even just 1 access should always suffice), and in one case there is no delay at all between two consecutive writes (which don't change anything, though);

Side note: the code seems generated by a compiler (especially the part that reads the ACK).

Toni, a question regarding the registers: can they be accessed singularly, and by byte (as the comment in the UAE code suggests)? To be safe, given that it causes no penalty, I'll change my code to access them by word, but I'm wondering if for some reason I should always acccess them both at the same time as the Kernel does.
saimo is offline  
Old Yesterday, 19:09   #24
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 45
Posts: 23,639
Quote:
* receiving ACK is performed is a weird way: after clocking the cycle and waiting for the signal to stabilize, SDA is read up to 7 times consecutively until it reads 0... what for? the signal is already stable, and it isn't going to change since no pulse is sent to the EEPROM, and the datasheet doesn't even contemplate the case of a NACK;
ROM code probably is based on some generic I2C code which has support for extra wait states.

Quote:
Toni, a question regarding the registers: can they be accessed singularly, and by byte (as the comment in the UAE code suggests)? To be safe, given that it causes no penalty, I'll change my code to access them by word, but I'm wondering if for some reason I should always acccess them both at the same time as the Kernel does.
I am quite sure they can be accesses any way possible (byte, word or long). Note that 68020+ does only long accesses if address is 32-bit capable (Akiko AFAIK is) and address is long aligned. So in this case CPU always splits it to 2 back to back word accesses.
Toni Wilen is online now  
Old Yesterday, 20:20   #25
saimo
Registered User
saimo's Avatar
 
Join Date: Aug 2010
Location: Italy
Posts: 267
Quote:
Originally Posted by Toni Wilen View Post
ROM code probably is based on some generic I2C code which has support for extra wait states.
After making the post, I realized that maybe it's a matter of misinterpretation of how the acknowledge polling works or a hack based on the assumption of the duration of the internal write cycle - the due explanation follows.

The EEPROM won't respond with an ACK to the request of starting an operation only when it's internally busy with committing the data written with a previous operation. To initiate any other operation, it is necessary to execute what described at page 7 of the ATMEL datasheet: ACKNOWLEDGE POLLING: Once the internally timed write cycle has started and the EEPROM inputs are disbled, acknowledge polling can be initiated. This involves sending a start condition followed by the device address word. The read/write bit is representative of the operation desired. Only if the internal write cycle has completed will the EEPROM respond with a zero allowing the read or write sequence to continue.

One might be mislead by the word "polling", as the operation doesn't involve just polling the SDA wire, but also generating the start condition and sending the device address each time. The explanation could have been better, but there can't be doubts. By the way, in a previous post I mentioned that the STM datasheet, whose text is quite poor, indeed explains this nicely:



The Kernal code, instead, simply polls the SDA wire 7 times in a row with a delay between the reads of about 4.2 microseconds. This won't work if the EEPROM is busy because it would respond only once (with a NACK) and then, anyway, SDA would never change because SCL is never pulsed. At boot of course this is not a problem since the EEPROM is not busy, but in theory there could be problems afterwards. Maybe this is fixed by SetPatch or maybe the condition never happens because of how the NVRAM is accessed (I didn't analyze the code further, but from the behaviour I had observed also in other occasions, it seems that the NVRAM is re-written entirely every time StoreNV() is called, so the problem could arise only if two access requests are made almost simultaneously, which is very unlikely).

Quote:
I am quite sure they can be accesses any way possible (byte, word or long). Note that 68020+ does only long accesses if address is 32-bit capable (Akiko AFAIK is) and address is long aligned. So in this case CPU always splits it to 2 back to back word accesses.
OK, thanks.



I have adjusted/improved a bit my code (attached here) and also fixed a little bug: I had forgotten to send the NACK after reading the very last byte (but this wasn't the cause of the issues I reported). Now I'm waiting for other tests results.
Attached Files
File Type: s NVRAM.s (12.2 KB, 2 views)
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? Akira Hardware mods 41 16 December 2018 15:59
CD32 NVRAM management Akira support.Hardware 9 20 February 2012 14:27
Access CD32-NVRam from Shell Retro1234 support.Other 3 08 August 2010 12:50
CD32 nvram file...? Christian support.WinUAE 11 13 December 2006 23:25
Cd32 Nvram Phantomz request.Apps 5 16 March 2003 22: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 11:26.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.
Page generated in 0.06375 seconds with 15 queries