Shop OBEX P1 Docs P2 Docs Learn Events
BS2 To flash — Parallax Forums

BS2 To flash

RockitRocketRockitRocket Posts: 4
edited 2010-05-05 21:27 in BASIC Stamp
Hello Everybody,

I am trying to make my flash memory work with a BS2. The BS2, as you know, runs at 5V. The flash memory, atmel ATDF161A, runs at 3.3V. I have an SPI connection between the two with a level shifter between them. I have tried to write to my flash memory to no avail. I was able to find some code online that referred to writing to an Atmel AT45DB011. Some of you may have read it online before. I know that the two flashes are different and I am trying to figure out where in the code I need to modify to make it work with my flash. I will paste the original code after my message and if anyone can help, please respond back quickly. Before I go, does anyone think it could be the level shifter causing problems? Thanks in advance to anyone who can help. Well, here's the original code I found online:

' Demo of the AT45D0xx
' under control of the Stamp II
' (c) 1999 Tracy Allen, Electronically Monitored Ecosystems.
cmd var byte ' AT45D0xx command, to be sent by the Stamp
page var word ' page of 264 bytes, 1024 pages in the AT45D020
adrs var byte ' which byte on page
' bytes 256-263 not used
ix var byte ' general purpose index
x var byte ' general purpose byte

' here are the connections to hardware control lines:
atcs con 8 ' AT45D0xx chip select line
sck con 9 ' AT45D0xx clock line
sdo con 10 ' AT45D0xx data output line
sdi con 11 ' AT45D0xx data input line
sdip var in11 ' AT45D0xx data status

' here is demo data that will be stored in the dataflash:
msg data "this is a test.. 1.. 2.. 3.."

outs=%0000000111100001
'fedcba9876543210
dirs=%1111011111111111

main:
'
' first write some data to one of the RAM buffers
cmd=$84 ' write to buffer 1 command
adrs=0 ' write at the beginning of the page
gosub sndcmd
for ix=0 to 27 ' 28 byte message
read msg+ix,x ' read it from BS2 eeprom
debug x ' show it on screen
shiftout sdo,sck,msbfirst,[noparse][[/noparse]x\8] ' put it in the AT45D0xx
next
debug cr
high atcs ' finish the command
'
'
' now read back the data from the RAM buffer
cmd=$54 ' read from buffer 1
adrs=0 ' read from the beginning of the page
gosub sndcmd
for ix=0 to 27 ' 28 byte message
shiftin sdi,sck,msbpost,[noparse][[/noparse]x] ' get it from the AT45D0xx
debug x ' show it on screen
next
high atcs ' finish the command
debug cr
'
'
' now erase a flash eeprom page and put the data there
cmd=$83 ' erase flash page & write buffer 1 there
page=5 ' choose page 5 for the demo
debug hex4 page,cr
gosub sndcmd ' do it, erase and program page 5!
high atcs ' finish the command
gosub waitready ' wait for it to finish writing
'pause 20 ' alternative to wait routine, hard pause
'
'
' now read data directly from the flash page
cmd=$52 ' read page direct command
page=5 ' same page as above
adrs=0 ' top of the page
gosub sndcmd
for ix=0 to 27 ' read 28 bytes
shiftin sdi,sck,msbpost,[noparse][[/noparse]x\8]
debug x
next
high atcs ' finish the command
debug cr,cr
'
pause 1000
end ' end of the demo program

'
' subroutine sends the command
' some commands require more bytes than others
' some commands require a lot of extra clocking bits
' This routine asserts chip select, but it is up to the
' calling routine to bring the chip select back high.
sndcmd:
low atcs
shiftout sdo,sck,msbfirst,[noparse][[/noparse]cmd\8,page<<1\16,adrs\8]
if cmd>$56 then sndend
shiftout sdo,sck,msbfirst,[noparse][[/noparse]0\8]
if cmd>$52 then sndend
shiftout sdo,sck,msbfirst,[noparse][[/noparse]0\16,0\8]
sndend:
return


'
' subroutine waits for the chip to finish writing to flash page
' it has a timeout loop
' note that it is necessary to wait before starting another
' write to the flash
' however, the program could start sending data to the
' alternate RAM buffer #2 even while the write is in progress.
waitready:
low atcs
shiftout sdo,sck,msbfirst,[noparse][[/noparse]$ae\9]
ix=255
wr1:
pause 1
ix=ix-1
if sdip-1*ix then wr1
high atcs
if ix=0 then error
return

error:
debug "dataflash write error",cr
return

Comments

  • Tracy AllenTracy Allen Posts: 6,662
    edited 2010-05-03 07:04
    Atmel at some point added a letter to the part number (a "D" at the end) and tweaked some of the commands and internal operations. A change is needed in the waitReady routine, as follows. Or try replacing the waitReady routine with a simple PAUSE 16.
    ' ----------------
    waitReady:
    ' wait for the ready-busy\ bit (bit 7 of status register) to go high
    ' variable ix is a timeout counter
      LOW ATcs
        SHIFTOUT sdo,sck,MSBFIRST,[noparse][[/noparse]$d7]    ' status command 
        FOR ix=255 TO 0
          SHIFTIN  sdi,sck,MSBPRE,[noparse][[/noparse]x]          ' read status byte repeatedly, has to be inside the loop
          IF x.BIT7 THEN EXIT                    '  until bit7 goes high when done
        NEXT
      HIGH ATcs
      IF ix=0 THEN error                        ' or times out
      RETURN
    



    Furthermore, Atmel retired the $52 command (for reading data with MSBPOST modifier) and suggests using command $E2 instead (used with the MSBPRE modifier). The old command may still work, but if not, the program will require several adjustments.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • RockitRocketRockitRocket Posts: 4
    edited 2010-05-04 21:07
    I tried using your waitready command and the hard pause, nothing. But, I was able to write to the flash a character of 99 in hex using:

    shiftout 4,5,msbfirst,[noparse][[/noparse]$02\8, 0\16, 0\8, 72\9, 99\8] 'pin 4 is our data out and pin 5 is our clock, the rest is a string from the data sheet to write to a page

    This was great to see, but when I tried to change the hex value coming out, it wouldn't change. I don't know what the problem is, and I'm trying to understand this basic stamp environment. It doesn't seem too hard at first, but it can get confusing. I've read through a lot of your website, good stuff. The Earth Measurement pdf link is dead, BTW.

    Any help would be appreciated to help us write and read to our flash. Below I have attached a link to the Atmel flash we are using. Thanks.

    http://www.atmel.com/dyn/resources/prod_documents/doc3640.pdf
  • RockitRocketRockitRocket Posts: 4
    edited 2010-05-05 21:27
    Ok, I've tried some other things. I've read the Atmel datasheet and tried to implement the opcodes and such as atmel wants in the coding. Everything seems to work until I attempt to read from my flash memory. This seems to fail. I always return a value of 6 for some odd reason. I'll paste the code I'm using now. Be warned though, it is in very early stages and doesn't include any loops or protections. BTW, it still includes some of your initializations at the beginning. Thanks in advance for any help.

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}


    ' Demo of the AT45D0xx
    ' under control of the Stamp II
    ' (c) 1999 Tracy Allen, Electronically Monitored Ecosystems.
    cmd VAR Byte ' AT45D0xx command, to be sent by the Stamp
    page VAR Word ' page of 264 bytes, 1024 pages in the AT45D020
    adrs VAR Byte ' which byte on page
    dat VAR Byte 'data in
    stat VAR Byte 'status register

    ix VAR Byte ' general purpose index
    x VAR Byte ' general purpose byte

    ' here are the connections to hardware control lines:
    cs PIN 3 ' chip SELECT line
    clk PIN 5 ' clock line
    so PIN 4 ' data output line
    si PIN 6 ' data input line
    sip VAR IN11 ' AT45D0xx data status

    ' here is demo data that will be stored in the dataflash:
    msg DATA "this is a test.. 1.. 2.. 3.."

    'OUTS=%0000000111100001
    'fedcba9876543210
    'DIRS=%1111011111111111

    'GOSUB status
    'GOSUB unprotect
    'GOSUB status
    ''GOSUB sector_protect
    GOSUB wrt
    GOSUB status
    GOSUB disable
    GOSUB status
    GOSUB rd
    GOSUB status
    END

    status:
    '
    'check the status register
    cmd = $05 'opcode for checking status

    LOW cs 'CS low
    SHIFTOUT so, clk, MSBFIRST, [noparse][[/noparse]cmd\8] 'checks status, looking for 0 on bit7
    SHIFTIN si, clk, MSBFIRST, [noparse][[/noparse]stat\8]

    HIGH cs
    'DEBUG HOME
    DEBUG CR, BIN8 stat
    RETURN

    unprotect:
    '
    'performing a global unprotect of flash
    cmd = $06 'opcode for write enable
    LOW cs 'CS low
    SHIFTOUT so, clk, MSBFIRST, [noparse][[/noparse]cmd\8] 'sets WEL bit to 1 in status register
    HIGH cs 'CS high

    cmd = $01 'opcode for global unprotect
    dat = $00 'sets the status at unprotect
    LOW cs
    SHIFTOUT so, clk, MSBFIRST, [noparse][[/noparse]cmd\8, dat\8]
    HIGH cs
    RETURN

    wrt:
    '
    'write to address in seq. mode
    cmd = $06 'opcode for write enable
    dat = $01
    LOW cs 'CS low
    SHIFTOUT so, clk, MSBFIRST, [noparse][[/noparse]cmd\8] 'sets WEL bit to 1 in status register
    HIGH cs 'CS high

    cmd = $AF 'opcode for sequential mode
    LOW cs
    SHIFTOUT so, clk, MSBFIRST, [noparse][[/noparse]cmd\8, 0\16, 0\8, dat\8] 'writing hex 99 to address 00
    HIGH cs
    RETURN

    disable:
    '
    'disable write
    cmd = $04
    LOW cs
    SHIFTOUT so, clk, MSBFIRST, [noparse][[/noparse]cmd\8]
    HIGH cs
    RETURN

    rd:
    '
    'read from memory
    cmd = $03
    LOW cs
    SHIFTOUT so, clk, MSBFIRST, [noparse][[/noparse]cmd\8, 0\16, 0\8]
    SHIFTIN si, clk, MSBFIRST, [noparse][[/noparse]adrs\8]
    HIGH cs
    DEBUG CR, dec adrs

    RETURN
Sign In or Register to comment.