'Rabbit_4.Bas
'
'Interface with Z-World SF1010 serial flash expansion card (4MB).
'
'This program provides a virtually continuous write operation
'using both buffers of the Atmel AT45DB321 to program 14 pages.
'
'8-bit serial output on MOSI and 8-bit serial input on MISO uses
'ShiftIn() and ShiftOut() commands.
'
'SPI Modes 0 and 3 are used (data clocked in on rising edge of CLK,
'data clocked out on falling edge of CLK).
'
'copyright, Lisa P. Mickens, Morgan State University, Nov. 2001
Const SPI_CS as Byte = 13 'Definition of BX24 pins
Const SPI_CLK as Byte = 14
Const MOSI as Byte = 15
Const MISO as Byte = 16
Const B1_Write as Byte = bx10000100 'Definition of AT45DB321 commands
Const B2_Write as Byte = bx10000111
Const B1ToMemWrite as Byte = bx10000011
Const B2ToMemWrite as Byte = bx10000110
Const Mem_Read as Byte = bx11010010
Sub Main()
Dim BAddress as Integer, PAddress as Integer, N as Integer
Dim Data as Byte
Call OpenSerialPort (1, 19200)
For N = 1 to 7
Debug.print "Writing B1..."
For BAddress = 0 to 527 'Write data to Buffer 1
Data = CByte((BAddress MOD 10) + N)
Call WriteBuffer (B1_Write,BAddress, Data)
Next
Call CheckStatus() 'Monitor RDY/BUSY
PAddress = 2 * (N - 1) 'pages 0, 2, 4, etc
Call BufferToMem(B1ToMemWrite,PAddress) 'Transfer data from Buffer 1 to Memory
Debug.print "Writing B2..."
For BAddress = 0 to 527 'Write data to Buffer 2
Data = CByte((BAddress MOD 5) + N)
Call WriteBuffer (B2_Write,BAddress, Data)
Next
Call CheckStatus() 'Monitor RDY/BUSY
PAddress = 2 * (N-1) + 1 'pages 1, 3, 5, etc
Call BufferToMem(B2ToMemWrite,PAddress) 'Transfer data from Buffer 2
Next
For PAddress = 0 to 13 'Read data from Main Memory
For BAddress = 0 to 527
Data = ReadMemPage (PAddress, BAddress)
Call PutB(Data)
If (((BAddress+1) MOD 10) <> 0) Then 'Put 10 values to a line
Call PutByte (Asc(" "))
Else
Call NewLine()
End If
Next
Call NewLine()
Next
End Sub
Sub WriteBuffer (byVal Opcode as byte, byVal Address as Integer, ByVal Data as Byte)
Dim DCare as Byte, Addr_Hi as byte, Addr_Lo as byte
DCare = bx00000000 'Don't Care byte
Addr_Hi = CByte((CByte(Address\256) AND bx00000011)) 'Set up address bytes
Addr_Lo = CByte (Address MOD 256)
Call PutPin (SPI_CS, 1) 'Bring CS High
Call PutPin (SPI_CLK, 0) 'Make sure CLK is low
Call PutPin (MOSI, 0) 'Bring MOSI low
Call PutPin (SPI_CS,0) 'Bring CS Low to initiate
Call ShiftOut (MOSI, SPI_CLK, 8, Opcode) 'Send Buffer 1 Write opcode
Call ShiftOut (MOSI, SPI_CLK, 8, DCare) '8 Don't care bits
Call ShiftOut (MOSI, SPI_CLK, 8, Addr_Hi) '6 Don't care bits and 2 Address bits
Call ShiftOut (MOSI, SPI_CLK, 8, Addr_Lo) '8 Address bits
Call ShiftOut (MOSI, SPI_CLK, 8, Data) 'Send data byte
Call PutPin (SPI_CS, 1) 'End session
End Sub
Sub BufferToMem (ByVal Opcode as Byte, ByRef PAddress as Integer)
Dim DCare as Byte, Addr_Hi as byte, Addr_Lo as byte, Temp as byte
Dim N as integer
Temp = CByte(CByte(PAddress\256) AND bx00011111) 'Set up address bytes
For N = 1 to 3
Temp = Temp * 2
Next
Addr_Hi = Temp
Addr_Lo = Cbyte (PAddress MOD 256)
DCare = bx00000000 'Don't Care byte
Call PutPin (SPI_CS, 1) 'Bring CS High
Call PutPin (SPI_CLK, 0) 'Make sure CLK is low
Call PutPin (MOSI, 0) 'Bring MOSI low
Call PutPin (SPI_CS,0) 'Bring CS Low to initiate
Call ShiftOut (MOSI, SPI_CLK, 8, Opcode) 'Send Buffer to Main Memory opcode
Call ShiftOut (MOSI, SPI_CLK, 1, DCare) 'Reserved Bit
Call ShiftOut (MOSI, SPI_CLK, 5, Addr_Hi) '5 Page address bits
Call ShiftOut (MOSI, SPI_CLK, 8, Addr_Lo) '8 Page address bits
Call ShiftOut (MOSI, SPI_CLK, 2, DCare) '2 Don't care bits
Call ShiftOut (MOSI, SPI_CLK, 8, DCare) 'Don't Care byte
Call PutPin (SPI_CS, 1) 'End session
Call Sleep (20) 'Time (20 ms) for page erase and programming
PAddress = PAddress + 1 'Increment Page Address
End Sub
Sub CheckStatus ()
Const StatusRegOC as byte = bx11010111
Dim Val as Byte, Status as Byte, Data as Byte
Call PutPin (SPI_CS, 1) 'Bring CS High
Call PutPin (SPI_CLK, 0) 'Make sure CLK is low
Call PutPin (MOSI, 0) 'Bring MOSI low
Call PutPin (SPI_CS,0) 'Bring CS Low to initiate
Call ShiftOut (MOSI, SPI_CLK, 8, StatusRegOC)
Do
Val = ShiftIn (MISO, SPI_CLK, 8) 'Read status register byte
Data = (Val XOR bx11111111) 'Invert data byte (Rabbit Semi Board does this)
Status = Data AND bx10000000 'Check RDY/Busy Bit
Debug.print "Checking status"
Loop Until Status >= 128
Call PutPin (SPI_CS, 1) 'Bring CS High
End Sub
Function ReadMemPage (ByVal PAddr as Integer, ByVal BAddr as Integer) as Byte
Dim DCare as byte, BAddr_Hi as Byte, BAddr_Lo as Byte, Temp as Byte
Dim PAddr_Hi as byte, PAddr_Lo as Byte, Val as Byte
Dim N as Integer
DCare = bx00000000 'Don't Care byte
Temp = CByte (CByte(BAddr\256) AND bx00000011) 'Set up address bytes
For N = 1 to 6
Temp = Temp * 2
Next
BAddr_Hi = Temp
BAddr_Lo = CByte (BAddr MOD 256)
Temp = CByte (CByte(PAddr\256) AND bx00011111)
For N = 1 to 3
Temp = Temp * 2
Next
PAddr_Hi = Temp
PAddr_Lo = CByte (PAddr MOD 256)
Call PutPin (SPI_CS, 1) 'Bring CS High
Call PutPin (SPI_CLK, 0) 'Make sure CLK is low
Call PutPin (MOSI, 0) 'Bring MOSI low
Call PutPin (SPI_CS,0) 'Bring CS Low to initiate
Call ShiftOut (MOSI, SPI_CLK, 8, Mem_Read) 'Send Main Memory Page Read opcode
Call ShiftOut (MOSI, SPI_CLK, 1, DCare) 'Reserved Bit
Call ShiftOut (MOSI, SPI_CLK, 5, PAddr_Hi) '5 Page address bits
Call ShiftOut (MOSI, SPI_CLK, 8, PAddr_Lo) '8 Page address bits
Call ShiftOut (MOSI, SPI_CLK, 2, BAddr_Hi) '2 Byte address bits
Call ShiftOut (MOSI, SPI_CLK, 8, BAddr_Lo) '8 Byte address bits
For N = 1 to 4 '32 don't care bits
Call ShiftOut (MOSI, SPI_CLK, 8, DCare)
Next
Val = ShiftIn (MISO, SPI_CLK, 8) 'Read data byte
ReadMemPage = (Val XOR bx11111111) 'Invert data byte (Rabbit Semi Board does this)
Call PutPin (SPI_CS, 1) 'Bring CS High to end session
End Function