1 |
69 |
zero_gravi |
<<<
|
2 |
|
|
:sectnums:
|
3 |
|
|
== Programming an External SPI Flash via the Bootloader
|
4 |
|
|
|
5 |
|
|
The default processor-internal NEORV32 bootloader supports automatic booting from an external SPI flash.
|
6 |
|
|
This guide shows how to write an executable to the SPI flash via the bootloader so it can be automatically
|
7 |
|
|
fetched and executed after processor reset. For example, you can use a section of the FPGA bitstream configuration
|
8 |
|
|
memory to store an application executable.
|
9 |
|
|
|
10 |
|
|
[NOTE]
|
11 |
|
|
This section assumes the _default_ configuration of the NEORV32 bootloader.
|
12 |
|
|
See section <<_customizing_the_internal_bootloader>> on how to customize the bootloader and its setting
|
13 |
|
|
(for example the SPI chip-select port, the SPI clock speed or the flash base address for storing the executable).
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
:sectnums:
|
17 |
|
|
=== SPI Flash
|
18 |
|
|
|
19 |
|
|
The bootloader can access an SPI compatible flash via the processor top entity's SPI port. By default, the flash
|
20 |
|
|
chip-select line is to `spi_csn_o(0)` and uses 1/8 of the processor's main clock as clock frequency.
|
21 |
|
|
The SPI flash has to support single-byte read and write, 24-bit addresses and at least the following standard commands:
|
22 |
|
|
|
23 |
|
|
* READ `0x03`
|
24 |
|
|
* READ STATUS `0x05`
|
25 |
|
|
* WRITE ENABLE `0x06`
|
26 |
|
|
* PAGE PROGRAM `0x02`
|
27 |
|
|
* SECTOR ERASE `0xD8`
|
28 |
|
|
* READ ID `0x9E`
|
29 |
|
|
|
30 |
|
|
Compatible (FGPA configuration) SPI flash memories are for example the "Winbond W25Q64FV2 or the "Micron N25Q032A".
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
:sectnums:
|
34 |
|
|
=== Programming an Executable
|
35 |
|
|
|
36 |
|
|
[start=1]
|
37 |
|
|
. At first, reset the NEORV32 processor and wait until the bootloader start screen appears in your terminal program.
|
38 |
|
|
. Abort the auto boot sequence and start the user console by pressing any key.
|
39 |
|
|
. Press u to upload the executable that you want to store to the external flash:
|
40 |
|
|
|
41 |
|
|
[source]
|
42 |
|
|
----
|
43 |
|
|
CMD:> u
|
44 |
|
|
Awaiting neorv32_exe.bin...
|
45 |
|
|
----
|
46 |
|
|
|
47 |
|
|
[start=4]
|
48 |
|
|
. Send the binary in raw binary via your terminal program. When the upload is completed and "OK"
|
49 |
|
|
appears, press `p` to trigger the programming of the flash (do not execute the image via the `e`
|
50 |
|
|
command as this might corrupt the image):
|
51 |
|
|
|
52 |
|
|
[source]
|
53 |
|
|
----
|
54 |
|
|
CMD:> u
|
55 |
|
|
Awaiting neorv32_exe.bin... OK
|
56 |
|
|
CMD:> p
|
57 |
|
|
Write 0x000013FC bytes to SPI flash @ 0x00800000? (y/n)
|
58 |
|
|
----
|
59 |
|
|
|
60 |
|
|
[start=5]
|
61 |
|
|
. The bootloader shows the size of the executable and the base address inside the SPI flash where the
|
62 |
|
|
executable is going to be stored. A prompt appears: Type `y` to start the programming or type `n` to
|
63 |
|
|
abort.
|
64 |
|
|
|
65 |
|
|
[TIP]
|
66 |
|
|
Section <<_customizing_the_internal_bootloader>> show the according C-language `define` that can be modified
|
67 |
|
|
to specify the base address of the executable inside the SPI flash.
|
68 |
|
|
|
69 |
|
|
[source]
|
70 |
|
|
----
|
71 |
|
|
CMD:> u
|
72 |
|
|
Awaiting neorv32_exe.bin... OK
|
73 |
|
|
CMD:> p
|
74 |
|
|
Write 0x000013FC bytes to SPI flash @ 0x08000000? (y/n) y
|
75 |
|
|
Flashing... OK
|
76 |
|
|
CMD:>
|
77 |
|
|
----
|
78 |
|
|
|
79 |
|
|
[NOTE]
|
80 |
|
|
The bootloader stores the executable in **little-endian** byte-order to the flash.
|
81 |
|
|
|
82 |
|
|
[start=6]
|
83 |
|
|
. If "OK" appears in the terminal line, the programming process was successful. Now you can use the
|
84 |
|
|
auto boot sequence to automatically boot your application from the flash at system start-up without
|
85 |
|
|
any user interaction.
|