'Rabbit_3.bas
'
'Interface with Z-World SF1010 serial flash expansion card (4MB).
'
'This program writes 528 bytes to buffer 1, then to the main memory, 
'(built in erase) and the reads them back continuosly using main 
'memory page read mode. '8-bit serial output on MOSI and 8-bit serial 
'input on MOSI 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 B1ToM_Write as Byte = bx10000011
Const M_Read as Byte = bx11010010

Sub Main()
  Dim BAddress as Integer, P_Address as Integer
  Dim Data as Byte  
  
  Call OpenSerialPort (1, 19200)

  For BAddress = 0 to 527			'Write data to Buffer 1
    Data = CByte((BAddress MOD 10) + 2) 
    Call WriteB1 (BAddress, Data)
  Next
  
  P_Address = 0 
  Call B1ToMem(P_Address)			'Transfer data from Buffer 1 to Memory
  
  For BAddress = 0 to 527			'Read data from Main Memory
    Data = ReadMem (P_Address, 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
End Sub

Sub WriteB1 (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, B1_Write)	'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 B1ToMem (ByVal Address as Integer)
  Dim DCare as Byte, Addr_Hi as byte, Addr_Lo as byte, Temp as byte
  Dim N as integer

  Temp = CByte(CByte(Address\256) AND bx00011111)
  For N = 1 to 3
    Temp = Temp * 2
  Next
  Addr_Hi = Temp
  Addr_Lo = Cbyte (Address 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, B1ToM_Write)	'Send Buffer 1 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)
End Sub

Function ReadMem (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)
  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, M_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
    Call ShiftOut (MOSI, SPI_CLK, 8, DCare)
  Next
 
  Val = ShiftIn (MISO, SPI_CLK, 8)			'Read data byte
  ReadMem = (Val XOR bx11111111)			'Invert data byte (Rabbit Semi Board does this)

  Call PutPin (SPI_CS, 1) 	'Bring CS High to end session
End Function