SPI DataFlash Library: Unterschied zwischen den Versionen

Aus ProjectWiki
Wechseln zu:Navigation, Suche
K
K (Donate)
 
(7 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 
== Overview ==
 
== Overview ==
 
This library reads/writes Atmel AT25DF-compatible SPI DataFlash ICs (ex. Spansion S25FL) through either a SW or HW SPI interface.
 
This library reads/writes Atmel AT25DF-compatible SPI DataFlash ICs (ex. Spansion S25FL) through either a SW or HW SPI interface.
The sample serves also as Firmware for the DataFlash Programmer application to initially write data into the memory.
+
The sample serves also as Firmware for the DataFlash Programmer application to write data to the memory.
 
It uploads a list of any type of files, image files are converted on the fly to the uncompressed 16-Bit color BIN format. To access the stored information, an include file with all the neccessary constants (memory position, size, image width & height) is generated.
 
It uploads a list of any type of files, image files are converted on the fly to the uncompressed 16-Bit color BIN format. To access the stored information, an include file with all the neccessary constants (memory position, size, image width & height) is generated.
  
The library has been developed and tested using an XMega-A1 Xplain board with a Spansion S25FL032P (32Mbit) dataflash mounted on it (U502!).
+
The library has been developed and tested using an XMega-A1 Xplained board with a Spansion S25FL032P (32Mbit) dataflash mounted on it.
 +
 
 +
 
 +
[http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=12892 Forum thread]
  
  
Zeile 11: Zeile 14:
 
Include the library. Set the options above the $include statement, needs the new Submode.
 
Include the library. Set the options above the $include statement, needs the new Submode.
 
<pre>Config Submode = New
 
<pre>Config Submode = New
 +
  
 
Const Flash_port_spi = PORTC
 
Const Flash_port_spi = PORTC
Zeile 61: Zeile 65:
  
 
=== Options ===
 
=== Options ===
Options and settings need to be set before the $include-statement, every setting has a default value that will be used if not specified otherwise. (in the list below the default values are shown).
+
Options and settings need to be set before the $include-statement, every setting has a default value that will be used if not specified otherwise. (in the list below the default values for the ATXMega are shown, values for ATMega are written in brackets () if applicable).
 +
 
  
 
Set to true to use software SPI instead of hardware modules, any GPIOs will work.
 
Set to true to use software SPI instead of hardware modules, any GPIOs will work.
 
<pre>Const Flash_use_soft_spi = False</pre>
 
<pre>Const Flash_use_soft_spi = False</pre>
 +
  
 
False only configures the SS pin, does not enable and configure the SPI interface, this needs to be done manually (useful if the memory shares the SPI interface with other hardware).
 
False only configures the SS pin, does not enable and configure the SPI interface, this needs to be done manually (useful if the memory shares the SPI interface with other hardware).
 
<pre>Const Flash_init_spi = True</pre>
 
<pre>Const Flash_init_spi = True</pre>
 +
  
 
Sets the port of the SPI interface.
 
Sets the port of the SPI interface.
<pre>Const Flash_port_spi = Portc</pre>
+
<pre>Const Flash_port_spi = Portc (Portb)</pre>
 +
 
  
 
Set the SPI pins (CS, CLK, SDO and SDI are set to the hardware SPI pins by default)
 
Set the SPI pins (CS, CLK, SDO and SDI are set to the hardware SPI pins by default)
<pre>Const Flash_pin_cs = 4</pre>
+
<pre>Const Flash_pin_cs = 4 (0)</pre>
<pre>Const Flash_pin_clk = 7</pre>
+
<pre>Const Flash_pin_clk = 7 (1)</pre>
<pre>Const Flash_pin_sdo = 5</pre>
+
<pre>Const Flash_pin_sdo = 5 (2)</pre>
<pre>Const Flash_pin_sdi = 6</pre>
+
<pre>Const Flash_pin_sdi = 6 (3)</pre>
 +
 
  
 
(HW SPI) If the memory's SS signal is not connected to the HW SPI CS pin, the correct pin needs to be set:
 
(HW SPI) If the memory's SS signal is not connected to the HW SPI CS pin, the correct pin needs to be set:
 
<pre>Const Flash_port_ss = Flash_port_spi</pre>
 
<pre>Const Flash_port_ss = Flash_port_spi</pre>
 
<pre>Const Flash_pin_ss = Flash_pin_cs</pre>
 
<pre>Const Flash_pin_ss = Flash_pin_cs</pre>
 +
  
 
Enable the status LED. Active during ongoing transmissions.
 
Enable the status LED. Active during ongoing transmissions.
 
<pre>Const Flash_enable_statusled = False</pre>
 
<pre>Const Flash_enable_statusled = False</pre>
 +
  
 
Invert the status LED (active low)
 
Invert the status LED (active low)
 
<pre>Const Flash_invert_statusled = False</pre>
 
<pre>Const Flash_invert_statusled = False</pre>
 +
  
 
Set the pin of the status LED
 
Set the pin of the status LED
<pre>Flash_statusled Alias Porte.0</pre>
+
<pre>Flash_statusled Alias Porte.0 (Porta.0)</pre>
<pre>Flash_statusled Alias Porta.0</pre>
 
  
  
Zeile 100: Zeile 111:
  
 
== Sample ==
 
== Sample ==
 +
This sample also serves as firmware to program the memory with the DataFlash Programmer application, works for both ATMega and ATXmega devices.
 
<pre>$regfile = "xm128a1def.dat"
 
<pre>$regfile = "xm128a1def.dat"
 +
'$regfile = "m128def.dat"
 
$crystal = 32000000
 
$crystal = 32000000
 
$hwstack = 64
 
$hwstack = 64
 
$swstack = 64
 
$swstack = 64
 
$framesize = 64
 
$framesize = 64
 +
 
Config Submode = New
 
Config Submode = New
 
 
Const False = 0
 
Const False = 0
 
Const True = 1
 
Const True = 1
$include "XMegaPll.inc"
 
  
Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
+
' XMega settings
Open "COM1:" For Binary As #1
+
#if _xmega = True
 +
  ' sets the clock frequency using the PLL with the internal 2MHz oscillator
 +
  $include "XMegaPll.inc"
 +
 
 +
  ' Host communication
 +
  Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
 +
 
 +
  ' use the watchdog for communication timeouts
 +
  Config Watchdog = 1000
 +
 
 +
  ' Xplained DataFlash SS
 +
  Const Flash_port_ss = Portq
 +
  Const Flash_pin_ss = 2
 +
 
 +
' ATMega settings
 +
#else
 +
  ' Host communication
 +
  $baud = 115200
 +
  Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
  
' use the watchdog for communication timeouts
+
  ' use the watchdog for communication timeouts
Config Watchdog = 1000
+
  Config Watchdog = 1024
 +
#endif
  
 +
Open "COM1:" For Binary As #1
  
Const Flash_port_ss = Portq                                                    ' Xplained DataFlash SS
+
Const Flash_enable_statusled = True                                             '
Const Flash_pin_ss = 2
 
Const Flash_enable_statusled = True
 
 
$include "SPI-Flash.inc"
 
$include "SPI-Flash.inc"
  
 
Dim Flashbuffer(256) As Byte
 
Dim Flashbuffer(256) As Byte
 
Dim Shakedhands As Boolean
 
Dim Shakedhands As Boolean
Dim Tempbyte As Byte , Tempword As Word , Tempdword As Dword
+
Dim Sector As Byte , Page As Word , Address As Dword
  
 
Flash_init
 
Flash_init
Zeile 131: Zeile 161:
 
Do
 
Do
 
   ' wait for command
 
   ' wait for command
   Inputbin #1 , Tempbyte
+
   Inputbin #1 , Sector
   Select Case Tempbyte
+
   Select Case Sector
  
 
   ' Handshake/Exit
 
   ' Handshake/Exit
Zeile 143: Zeile 173:
 
       Reset Watchdog
 
       Reset Watchdog
 
       Start Watchdog
 
       Start Watchdog
       Inputbin #1 , Tempbyte                                                   ' read sector address
+
       Inputbin #1 , Sector                                                   ' read sector address
 
       Stop Watchdog
 
       Stop Watchdog
       If Shakedhands = True Then Flash_sector_erase Tempbyte
+
       If Shakedhands = True Then Flash_sector_erase Sector
       Printbin #1 , &HF0
+
       Printbin #1 , &HF0                                                       ' ack
  
 
   ' erase whole memory
 
   ' erase whole memory
 
   Case &H02:
 
   Case &H02:
 
       If Shakedhands = True Then Flash_bulk_erase
 
       If Shakedhands = True Then Flash_bulk_erase
       Printbin #1 , &HF0
+
       Printbin #1 , &HF0                                                       ' ack
  
 
   ' write a page (256 Bytes, address bits 23..8)
 
   ' write a page (256 Bytes, address bits 23..8)
Zeile 157: Zeile 187:
 
       Reset Watchdog
 
       Reset Watchdog
 
       Start Watchdog
 
       Start Watchdog
       Inputbin #1 , Tempword                                                   ' read page address
+
       Inputbin #1 , Page                                                   ' read page address
 
       Inputbin #1 , Flashbuffer(1) ; 256                                        ' read 256 bytes page data
 
       Inputbin #1 , Flashbuffer(1) ; 256                                        ' read 256 bytes page data
 
       Stop Watchdog
 
       Stop Watchdog
       Swap Tempword
+
       Swap Page
       If Shakedhands = True Then Flash_write_page Tempword , Flashbuffer(1)
+
       If Shakedhands = True Then Flash_write_page Page , Flashbuffer(1)
       Printbin #1 , &HF0
+
       Printbin #1 , &HF0                                                       ' ack
  
 
   ' read a page (256 Bytes, address bits 23..8)
 
   ' read a page (256 Bytes, address bits 23..8)
Zeile 168: Zeile 198:
 
       Reset Watchdog
 
       Reset Watchdog
 
       Start Watchdog
 
       Start Watchdog
       Inputbin #1 , Tempword                                                   ' read page address
+
       Inputbin #1 , Page                                                   ' read page address
 
       Stop Watchdog
 
       Stop Watchdog
       Swap Tempword
+
       Swap Page
       Tempdword = Tempword
+
       Address = Page
       Shift Tempdword , Left , 8
+
       Shift Address , Left , 8
       If Shakedhands = True Then Flash_read Tempdword , Flashbuffer(1) , 256
+
       If Shakedhands = True Then Flash_read Address , Flashbuffer(1) , 256
 
       Printbin #1 , Flashbuffer(1) ; 256                                        ' write page data
 
       Printbin #1 , Flashbuffer(1) ; 256                                        ' write page data
  
Zeile 228: Zeile 258:
 
== DataFlash Programmer ==
 
== DataFlash Programmer ==
 
The SPI DataFlash Programmer application allows in-circuit programming of the memory over a serial connection. It uploads any types of files, images files (BMP, JPG, PNG, TIFF) can be converted to the uncompressed 16 Bit color BIN format on the fly when writing the data (standard).
 
The SPI DataFlash Programmer application allows in-circuit programming of the memory over a serial connection. It uploads any types of files, images files (BMP, JPG, PNG, TIFF) can be converted to the uncompressed 16 Bit color BIN format on the fly when writing the data (standard).
[[File:SpiDataFlashProgrammer.jpg|frameless|SPI DataFlash Programmer application]]
+
[[File:SpiDataFlashProgrammer.jpg|SPI DataFlash Programmer application]]
 +
 
 
To use this application, the sample from above has to be programmed in the microcontroller, set up the SPI and the USART interface correctly.
 
To use this application, the sample from above has to be programmed in the microcontroller, set up the SPI and the USART interface correctly.
 
On the left side, choose the files to upload, rearrange them as you need and choose whether to convert image files to BIN by checking the box (initially checked for images) or upload them as they are by unchecking (does not affect other file types).
 
On the left side, choose the files to upload, rearrange them as you need and choose whether to convert image files to BIN by checking the box (initially checked for images) or upload them as they are by unchecking (does not affect other file types).
Zeile 237: Zeile 268:
 
"Write to file..." writes the resulting data stream into a binary file instead of programming a memory.
 
"Write to file..." writes the resulting data stream into a binary file instead of programming a memory.
 
At least, a file list in .txt format (one file path per line), containing the files to write, can be saved or loaded.
 
At least, a file list in .txt format (one file path per line), containing the files to write, can be saved or loaded.
 
 
== Donate ==
 
This Software is [http://en.wikipedia.org/wiki/Donationware Donationware].
 
<paypal>1</paypal>
 
[[About|See here]] for more informations
 
  
  
 
== Download ==
 
== Download ==
 
* [http://www.braunecker.at/downloads/dataflash/SpiFlash.zip SPI DataFlash Library 1.0]
 
* [http://www.braunecker.at/downloads/dataflash/SpiFlash.zip SPI DataFlash Library 1.0]

Aktuelle Version vom 31. August 2017, 03:18 Uhr

Overview

This library reads/writes Atmel AT25DF-compatible SPI DataFlash ICs (ex. Spansion S25FL) through either a SW or HW SPI interface. The sample serves also as Firmware for the DataFlash Programmer application to write data to the memory. It uploads a list of any type of files, image files are converted on the fly to the uncompressed 16-Bit color BIN format. To access the stored information, an include file with all the neccessary constants (memory position, size, image width & height) is generated.

The library has been developed and tested using an XMega-A1 Xplained board with a Spansion S25FL032P (32Mbit) dataflash mounted on it.


Forum thread


How to use

Include the library. Set the options above the $include statement, needs the new Submode.

Config Submode = New


Const Flash_port_spi = PORTC
$include "SpiFlash.inc"


Init the DataFlash SPI interface

Sub Flash_init()


Read the 81 Bytes JEDEC RDID information

Sub Flash_get_info(byref Spiflashbuffer() As Byte)


Disable the SPI interface

Sub Flash_stop()


Erase a sector (64Kb block, upper 8 Bit of 24 Bit byte adress). The memory has to be erased (set to &HFF) before writing data.

Sub Flash_sector_erase(byval Sector As Byte)


Erase the whole memory

Sub Flash_bulk_erase()


Writes a page to the memory (256 Bytes) to a specified page adress (upper 16 Bit of 24 Bit byte adress).

Sub Flash_write_page(byval Address As Word , Byref Pagedata() As Byte)


Reads a block of data starting from the 24 Bit adress

Sub Flash_read(byval Address As Dword , Byref Spiflashbuffer() As Byte , Byval Length As Word)


Reads a block of data from the flash memory to an SRAM adress

Sub Flash_readto(byval Sourceaddress As Dword , Byval Destinationaddress As Dword , Byval Length As Dword)


Start an asynchronous read sequence. Data can be read byte-wise from the 24 Bit start adress until Flash_endread() is called.

Sub Flash_beginread(byval Address As Dword)


Reads a Byte (needs Flash_beginread() first)

Function Flash_readbyte() As Byte


Stop a read sequence

Sub Flash_endread()


Options

Options and settings need to be set before the $include-statement, every setting has a default value that will be used if not specified otherwise. (in the list below the default values for the ATXMega are shown, values for ATMega are written in brackets () if applicable).


Set to true to use software SPI instead of hardware modules, any GPIOs will work.

Const Flash_use_soft_spi = False


False only configures the SS pin, does not enable and configure the SPI interface, this needs to be done manually (useful if the memory shares the SPI interface with other hardware).

Const Flash_init_spi = True


Sets the port of the SPI interface.

Const Flash_port_spi = Portc (Portb)


Set the SPI pins (CS, CLK, SDO and SDI are set to the hardware SPI pins by default)

Const Flash_pin_cs = 4 (0)
Const Flash_pin_clk = 7 (1)
Const Flash_pin_sdo = 5 (2)
Const Flash_pin_sdi = 6 (3)


(HW SPI) If the memory's SS signal is not connected to the HW SPI CS pin, the correct pin needs to be set:

Const Flash_port_ss = Flash_port_spi
Const Flash_pin_ss = Flash_pin_cs


Enable the status LED. Active during ongoing transmissions.

Const Flash_enable_statusled = False


Invert the status LED (active low)

Const Flash_invert_statusled = False


Set the pin of the status LED

Flash_statusled Alias Porte.0 (Porta.0)


Electrical connection

SPI DataFlash connection schematic

Only a handful small components are needed to connect the memory. The status LED is optional.


Sample

This sample also serves as firmware to program the memory with the DataFlash Programmer application, works for both ATMega and ATXmega devices.

$regfile = "xm128a1def.dat"
'$regfile = "m128def.dat"
$crystal = 32000000
$hwstack = 64
$swstack = 64
$framesize = 64

Config Submode = New
Const False = 0
Const True = 1

' XMega settings
#if _xmega = True
   ' sets the clock frequency using the PLL with the internal 2MHz oscillator
   $include "XMegaPll.inc"

   ' Host communication
   Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8

   ' use the watchdog for communication timeouts
   Config Watchdog = 1000

   ' Xplained DataFlash SS
   Const Flash_port_ss = Portq
   Const Flash_pin_ss = 2

' ATMega settings
#else
   ' Host communication
   $baud = 115200
   Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

   ' use the watchdog for communication timeouts
   Config Watchdog = 1024
#endif

Open "COM1:" For Binary As #1

Const Flash_enable_statusled = True                                             '
$include "SPI-Flash.inc"

Dim Flashbuffer(256) As Byte
Dim Shakedhands As Boolean
Dim Sector As Byte , Page As Word , Address As Dword

Flash_init

Do
   ' wait for command
   Inputbin #1 , Sector
   Select Case Sector

   ' Handshake/Exit
   Case &HAA:
      Shakedhands = Not Shakedhands                                             ' some kind of accidental write protection
      Printbin #1 , &HF0                                                        ' ack

   ' erase a sector (address bits 23..16)
   Case &H01:
      Reset Watchdog
      Start Watchdog
      Inputbin #1 , Sector                                                    ' read sector address
      Stop Watchdog
      If Shakedhands = True Then Flash_sector_erase Sector
      Printbin #1 , &HF0                                                        ' ack

   ' erase whole memory
   Case &H02:
      If Shakedhands = True Then Flash_bulk_erase
      Printbin #1 , &HF0                                                        ' ack

   ' write a page (256 Bytes, address bits 23..8)
   Case &H03:
      Reset Watchdog
      Start Watchdog
      Inputbin #1 , Page                                                    ' read page address
      Inputbin #1 , Flashbuffer(1) ; 256                                        ' read 256 bytes page data
      Stop Watchdog
      Swap Page
      If Shakedhands = True Then Flash_write_page Page , Flashbuffer(1)
      Printbin #1 , &HF0                                                        ' ack

   ' read a page (256 Bytes, address bits 23..8)
   Case &H04:
      Reset Watchdog
      Start Watchdog
      Inputbin #1 , Page                                                    ' read page address
      Stop Watchdog
      Swap Page
      Address = Page
      Shift Address , Left , 8
      If Shakedhands = True Then Flash_read Address , Flashbuffer(1) , 256
      Printbin #1 , Flashbuffer(1) ; 256                                        ' write page data

   ' read the device ID data (81 Bytes)
   Case &H05:
      If Shakedhands = True Then Flash_get_info Flashbuffer(1)
      Printbin #1 , Flashbuffer(1) ; 81

   End Select
Loop


Application example (XMega-A1 Xplained)

Load all data from flash memory to the extended SRAM memory for faster access:

$regfile = "xm128a1def.dat"
$crystal = 32000000
$hwstack = 64
$swstack = 64
$framesize = 64
Config Submode = New

Const False = 0
Const True = 1

' use the XMega PLL clock system to set the desired system clock frequency
$include "XMegaPll.inc"

'the XPLAIN has a 64 MBit SDRAM which is 8 MByte, it is connected in 3 port, 4 bit databus mode
'in the PDF of the SDRAM you can see it is connected as 16 Meg x 4. Refreshcount is 4K and the row address is A0-A11, column addressing is A0-A9
$xramsize = 8388608                                                             ' 8 MByte
Config Xram = 3port , Sdbus = 4 , Sdcol = 10 , Sdcas = 3 , Sdrow = 12 , Refresh = 500 , Initdelay = 3200 , Modedelay = 2 , Rowcycledelay = 7 , Rowprechargedelay = 7 , Wrdelay = 1 , Esrdelay = 7 , Rowcoldelay = 7 , Modesel3 = Sdram , Adrsize3 = 8m , Baseadr3 = &H0000
'the config above will set the port registers correct. it will also wait for Ebi_cs3_ctrlb.7
Const Xramstart = _hwstackstart + 1                                             ' the address where XRAM data space starts
Const Xramend = Xramstart + _xramsize                                           ' end address

'Const Flash_use_soft_spi = True                                                  ' uncomment to use SW SPI (works on any GPIO)
Const Flash_port_ss = Portq                                                     ' set to select a different pin as SS instead of the dedicated HW SPI module's
Const Flash_pin_ss = 2
$include "SPI-Flash.inc"                                                        ' include the library
$include "DataFlashFiles.inc"                                                   ' include the file info constants written by the DataFlash Programmer application
Const Xramdataend = Xramstart + Flash_totalsize                                 ' calculate the start of free SRAM memory after loading the data from the flash memory

Dim Sram_file_address As Dword

' load all the data stored in the flash memory into the extended SRAM memory for faster access
Flash_init                                                                      ' init the SPI interface
Flash_readto 0 , Xramstart , Flash_totalsize                                    ' load all data at once into the SRAM
Flash_stop                                                                      ' stop the SPI interface

' the file addresses are now calculated as follows:
Sram_file_address = Xramstart + Flash_myfile_bin


DataFlash Programmer

The SPI DataFlash Programmer application allows in-circuit programming of the memory over a serial connection. It uploads any types of files, images files (BMP, JPG, PNG, TIFF) can be converted to the uncompressed 16 Bit color BIN format on the fly when writing the data (standard). SPI DataFlash Programmer application

To use this application, the sample from above has to be programmed in the microcontroller, set up the SPI and the USART interface correctly. On the left side, choose the files to upload, rearrange them as you need and choose whether to convert image files to BIN by checking the box (initially checked for images) or upload them as they are by unchecking (does not affect other file types). Select the correct port and baudrate for the communication to the device, the "R" button refreshes the available serial port list. During the programming process, the File addresses include file is written, which contains information about the stored files (start address, size, width & height for images) as constants. Because page writes can't change 0's to 1's, the memory needs to be erased (sets everything to 1) before writing data to it. Erasing is done sector-wise, which are 64Kb blocks. This is done automatically during programming process for each sector containing pages to write. You can skip this sector-erasing by ticking the checkbox, only page writes are executed. Bulk erase could be used instead, this erases the whole memory at once (takes a while). If the DataFlash device supports the JEDEC RDID command (likely), "Read Flash Info" displays these informations. "Write to file..." writes the resulting data stream into a binary file instead of programming a memory. At least, a file list in .txt format (one file path per line), containing the files to write, can be saved or loaded.


Download