Flash weirdness when toggling address line a lot

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Flash weirdness when toggling address line a lot
by on (#66186)
We're encountering a problem with an Am29F040B 512KB Flash memory chip. It works fine, except after A15 has been toggled quickly for about 300 msec, with chip select DEasserted and no accesses being made to chip. Then reads return $FF for several hundred msec, then slowly the bits return to what they should be. No other pin causes this. The odd thing is that during this period where reads don't work, I can do the special write sequence to enable Autoselect mode and successfully read the chip ID just fine. After doing this, I write $F0 to reset back to array read mode and get $FF again until the effect wears off. Programming a byte also seems to fail during this cool-off period.

Have tried adding extra bypass capacitors, and putting 1K and 10K resistors in series with A15. Supply voltage stays around 4.95 V when toggling A15 quickly, so it's not causing excessive current drain.

Any ideas on why just this one address pin would behave like that?

by on (#66201)
Are you giving it the /RD, /WR, and /CE signals separately? I know on SRAMs that /WR will over-ride /RD, but I have no idea if that is standardized with flash.

I never had any kind of problem like that, that doesn't sound good. I've used Am29F040B and a non-B version of the chip, as well as some flash chips by other manufacturers and everything always worked as expected.

So I guess A15 is coming out of the MMC1? Maybe there are some weird side-effects.

Here is all my Flash code from the original Squeedo, feel free to use it if it helps (it's pretty straight-forward, and it sounds like the problem could be elsewhere though..).

Code:
autoselect_mode:
        lda #$F0
        sta $8000       ; reset command

        lda #$AA        ; unlock command
        sta $8555
        lda #$55
        sta $82AA

        lda #$90        ; auto-select command
        sta $8555

        lda $8000       ; mfg. id
        sta temp1
        lda $8001       ; device id
        sta temp2

        lda #$F0
        sta $8000       ; reset

        lda temp1
        cmp #1
        bne @xx
        pointer mfg_amd,addr_lo
        jmp mfg_end
@xx:
        cmp #$20
        bne @zz
        pointer mfg_st,addr_lo
        jmp mfg_end
@zz:
        pointer mfg_none,addr_lo
mfg_end:
        lda temp2
        cmp #$A4
        bne @aa
        pointer dev_040,addr_lo2
        jmp dev_end
@aa:
        cmp #$E2
        bne @ba
        pointer dev_040st,addr_lo2
        jmp dev_end
@ba:
        cmp #$20
        bne @bb
        pointer dev_010,addr_lo2
        jmp dev_end
@bb:
        pointer dev_unk,addr_lo2
dev_end:
        rts

msg_maker:      .byte LF,"Flash maker; ",0
mfg_none:       .asciiz "your mom!!"
mfg_amd:        .asciiz "AMD"
mfg_st:         .asciiz "ST"
msg_dev:        .byte LF,"Part #; ",0
dev_040:        .asciiz "Am29F040"
dev_040st:      .asciiz "M29F040B"
dev_010:        .asciiz "29F010"
dev_unk:       .asciiz "Unknown"


sector_erase:           ; have the right bank to erase selected first!
        lda #$AA
        ldy #$55
        ldx #$80

        sta $8555
        sty $82AA
        stx $8555
        sta $8555
        sty $82AA
        lda #$30
        sta $8000
:
        lda $8000
        cmp #$FF
        bne :-

        rts


byte_program:
          stx temp2
          ldx #$AA
          stx $8555
          ldx #$55
          stx $82AA
          ldx #$A0
          stx $8555
          sta (ptr),y    ;(ptr),y
          sta temp_lo

@program_wait:
          lda (ptr),y
          sta count_lo
          lda (ptr),y
          sta count_hi
          and #%01000000
          sta temp3
          lda count_lo
          and #%01000000
          cmp temp3
          beq @program_done
          lda count_hi
          and #%00100000
          and count_lo
          beq @program_wait
          lda (ptr),y
          sta count_lo
          lda (ptr),y
          sta count_hi
          and #%01000000
          sta temp3
          lda count_lo
          and #%01000000
          cmp temp3
          beq @program_done
          lda #$F0
          sta (ptr),y
          ldx temp2
          rts

@program_done:
;              beep
                ldx temp2
                rts

by on (#66204)
Double posting, but if you get stuck and can identify a test case, maybe I can take an MMC1 cart to work and check it out with a scope. I don't know where my MMC1 dev cart is though, so it might have to be part of a game I can get to without seeing the screen.. heh so maybe that's not much help. But I'd like to see more flash carts like this. Down with EPROM! :D

by on (#66207)
Oh man, we found it. The A12 trace had come loose on the board during desoldering or something. A12 is right next to A14 on the Flash, so toggling A14 a lot induced current to A12 via the slight capacitance between the two pins. Man, that was about 18 hours of remote debugging (hardware was a few states away from where I was) and messy jumpering.

Yeah, at first I thought MMC1 issue, timing, etc. then possible bad Flash, misunderstanding about how it works, etc.