TMS320F28x Boot ROM Peripheral Reference Guide: Preliminary
TMS320F28x Boot ROM Peripheral Reference Guide: Preliminary
Reference Guide
Preliminary
Texas Instruments Incorporated and its subsidiaries (TI) reserve the right to make corrections,
modifications, enhancements, improvements, and other changes to its products and services at
any time and to discontinue any product or service without notice. Customers should obtain the
latest relevant information before placing orders and should verify that such information is current
and complete. All products are sold subject to TI’s terms and conditions of sale supplied at the
time of order acknowledgment.
TI warrants performance of its hardware products to the specifications applicable at the time of
sale in accordance with TI’s standard warranty. Testing and other quality control techniques are
used to the extent TI deems necessary to support this warranty. Except where mandated by
government requirements, testing of all parameters of each product is not necessarily performed.
TI assumes no liability for applications assistance or customer product design. Customers are
responsible for their products and applications using TI components. To minimize the risks
associated with customer products and applications, customers should provide adequate design
and operating safeguards.
TI does not warrant or represent that any license, either express or implied, is granted under any
TI patent right, copyright, mask work right, or other TI intellectual property right relating to any
combination, machine, or process in which TI products or services are used. Information
published by TI regarding third party products or services does not constitute a license from TI
to use such products or services or a warranty or endorsement thereof. Use of such information
may require a license from a third party under the patents or other intellectual property of that third
party, or a license from TI under the patents or other intellectual property of TI.
Resale of TI products or services with statements different from or beyond the parameters stated
by TI for that product or service voids all express and any implied warranties for the associated
TI product or service and is an unfair and deceptive business practice. TI is not responsible or
liable for any such statements.
Mailing Address:
Texas Instruments
Post Office Box 655303
Dallas, Texas 75265
Contents
4 Bootloader Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4.1 Bootloader Functional Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4.2 Bootloader Device Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
4.2.1 PLL Multiplier Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.2.2 Watchdog Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.2.3 PIE Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.2.4 Reserved Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.3 Bootloader Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.4 Bootloader Data Stream Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.5 General Structure of Source Program Data Stream in 8-Bit Mode . . . . . . . . . . . . . . . . . . 18
4.6 Basic Transfer Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.7 InitBoot Assembly Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.8 SelectBootMode Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.9 SCI_Boot Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.10 Parallel_Boot Function (GPIO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.11 SPI_Boot Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.12 ExitBoot Assembly Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
i
Figures
Figures
1 Memory Map of On-Chip ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Vector Table Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3 Bootloader Flow Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4 F2810/12 Boot ROM Function Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5 Jump to Flash Flow Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6 Flow Diagram of Jump to H0 SARAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
7 Flow Diagram of Jump to OTP Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
8 F2810/12 Boot Loader Basic Transfer Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
9 Overview of InitBoot Assembly Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
10 Overview of the SelectBootMode Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
11 Overview of SCI Boot Loader Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
12 Overview of SCI_Boot Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
13 Overview of SCIA_CopyData Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
14 Overview of SCI_GetWordData Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
15 Overview of Parallel GPIO Boot Loader Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
16 Parallel GPIO Boot loader Handshake Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
17 Parallel GPIO Mode Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
18 Parallel GPIO Mode – Host Transfer Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
19 Overview of Parallel_CopyData Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
20 Parallel GPIO Boot Loader Word Fetch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
21 SPI Loader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
22 Data Transfer From EEPROM Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
23 Overview of SPIA_CopyData Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
24 Overview of SPIA_GetWordData Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
25 ExitBoot Procedure Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
ii
Tables
Tables
1 Memory Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Vector Locations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3 Configuration for Device Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4 GPIO Pin Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5 General Structure Of Source Program Data Stream In 16-Bit Mode . . . . . . . . . . . . . . . . . . . . . 16
6 LSB/MSB Loading Sequence in 8-Bit Data Stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
7 GPIO Pin Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
8 SPI 8-Bit Data Stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
9 CPU Register Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
10 Boot-Loader Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Contents iii
Boot ROM
The Boot ROM is factory programmed with boot loading software. Boot-mode
signals (general purpose I/Os) are used to tell the bootloader software what
mode to use on power up. The TMS320F2810/TMS320F2812 Boot ROM
also contains standard math tables, such as SIN/COS waveforms for use in IQ
math related algorithms.
This guide describes the purpose and features of the bootloader. It also
describes other contents of the device on-chip boot ROM and identifies where
all of the information is located within that memory.
1
Boot ROM Overview
The MPNMC status bit in the XINTFCNF2 register switches the device be-
tween microprocessor and microcomputer mode. When high, XINTF Zone 7
is enabled on the external interface and the internal boot ROM is disabled.
When low, XINTF Zone 7 is disabled from the external interface, and the on-
chip boot ROM memory can be accessed instead. The XMPNMC input signal
is latched into the XINTF configuration register XINTCNF2 on a reset. After re-
set, the state of the XMPNMC input signal is ignored and the user can then
modify the state of this mode in software.
On devices with an XINTF, like the F2812, the XMPNMC input signal is avail-
able externally and therefore, the user can control this signal to boot from the
internal boot ROM or from XINTF Zone 7. On devices without the XINTF, such
as the F2810, XMPNMC is tied low internal to the device and, therefore, boot
ROM is automatically enabled at reset.
The remainder of this document assumes that the XMPNMC input signal is
pulled low at reset to boot from internal ROM unless stated otherwise.
included in the F2810/F2812 Boot ROM. These math tables are taken
from the DSP28x IQ math Library V1.4.
J Sin/Cos Table:
Table size: 644 words
Q format: Q30
Contents: 512 32-bit full Sin or Cos values.
Address: 0x3FF000 – 0x3FF503
This is useful for accurate sin wave generation and 32-bit FFTs. This
can also be used for 16-bit math, just skip over every second value.
J Normalized Inverse Table:
Table size: 528 words
Q format: Q29
Contents: 256 32-bit normalized inverse samples.
This table is used as an initial estimate in the Newton -Raphson in-
verse algorithm. By using a more accurate estimate the convergence
is quicker and hence cycle time is faster.
J Normalized Square Root Table:
Table size: 274 words
Q format: Q30
Contents: 128 32-bit normalized inverse square root samples
Figure 1 shows the memory map of the on-chip ROM for the F2810/12. The
memory block is 4Kx16 in size and is located at 0x3F F000 – 0x3F FFFF in both
program and data space when the MPNMC status bit is low.
Address Contents
0x3F FFBA Boot ROM Version Number
0x3F F000
Math tables
and functions
0x3F FC00
Bootloader
functions
Reset fetched from here when
0x3F FFC0 VMAP=1, XMPNMC=0
Reset vector
64 x 16 CPU vector table Other vectors fetched from here when
0x3F FFFF VMAP=1, MPNMC=0, ENPIE=0
Notes: 1) The VMAP bit is located in Status Register 1 (ST1). On the F2810/12 devices, VMAP is always 1 on reset. It can
be changed after reset by software, however the normal operating mode will be to leave VMAP = 1.
2) On the F2812, XMPNMC is available externally, on the F2810 it is tied low internally. On reset, the state of the
XMPNMC input signal is latched into the MPNMC status bit in the XINTCNF2 register where it can be changed by
software.
3) The ENPIE bit is located in the PIECTRL register. The default state of this bit at reset is 0, which disables the Periph-
eral Interrupt Expansion block (PIE).
The only vector that will normally be handled from the internal boot ROM
memory is the reset vector located at 0x3F FFC0. The reset vector is factory
programmed to point to the InitBoot function. This function starts the boot load
process. A series of checking operations is performed on General Purpose I/O
(GPIO I/O) pins to determine which boot mode to use. This boot mode selec-
tion is described in the next section of this document.
The remaining vectors in the ROM are not used during normal operation on
the F2810/12 devices. After the boot process is complete, the user should ini-
tialize the Peripheral Interrupt Expansion (PIE) vector table and enable the PIE
block. From that point on, all vectors, except reset, will be fetched from the PIE
module and not the CPU vector table shown here.
For TI silicon debug and test purposes the vectors located in the boot ROM
memory point to locations in the M0 SARAM block as described in the following
table. During silicon debug, the user can program the specified locations in M0
with branch instructions to catch any vectors fetched from boot ROM. This is
not required for normal device operation.
INT1 0x3F FFC2 0x00 0042 Reserved 0x3F FFE2 0x00 0062
INT2 0x3F FFC4 0x00 0044 NMI 0x3F FFE4 0x00 0064
INT3 0x3F FFC6 0x00 0046 ILLEGAL 0x3F FFE6 0x00 0066
INT4 0x3F FFC8 0x00 0048 USER1 0x3F FFE8 0x00 0068
INT5 0x3F FFCA 0x00 004A USER2 0x3F FFEA 0x00 006A
INT6 0x3F FFCC 0x00 004C USER3 0x3F FFEC 0x00 006C
INT7 0x3F FFCE 0x00 004E USER4 0x3F FFEE 0x00 006E
INT8 0x3F FFD0 0x00 0050 USER5 0x3F FFF0 0x00 0070
INT9 0x3F FFD2 0x00 0052 USER6 0x3F FFF2 0x00 0072
INT10 0x3F FFD4 0x00 0054 USER7 0x3F FFF4 0x00 0074
INT11 0x3F FFD6 0x00 0056 USER8 0x3F FFF6 0x00 0076
INT12 0x3F FFD8 0x00 0058 USER9 0x3F FFF8 0x00 0078
INT13 0x3F FFDA 0x00 005A USER10 0x3F FFFA 0x00 007A
INT14 0x3F FFDC 0x00 005C USER11 0x3F FFFC 0x00 007C
DLOGINT 0x3F FFDE 0x00 005E USER12 0x3F FFFE 0x00 007E
4 Bootloader Features
This section describes in detail the boot mode selection process, as well as
the specifics of boot loader operation.
The bootloader is used to transfer code from an external source into internal
or external interface (XINTF) memory following power up. This allows code to
reside in slow non-volatile memory externally, and be transferred to high-
speed memory to be executed.
The bootloader uses various GPIO signals to determine which boot mode to
use. The boot mode selection process as well as the specifics of each boot
loader operation are described in the remainder of this document. Figure 3
shows the basic bootloader flow.
Reset
(power-on reset
or warm reset
Silicon sets the following:
PIE disabled (ENPIE–0)
VMAP=1
OBJMODE=0
AMODE=0
MOM1MAP=1
Yes
Boot ROM
Reset vector fetched SelectBootMode Begin execution at
from boot ROM address function EntryPoint as
0x3F FFC0 Boot determined by determined by
Jump to InitBoot the state of selected boot mode
function to start I/O pins
boot process
Note: On the F2810 the XMPNMC input signal is tied low internally on the device, and therefore boot from reset is always from
the internal boot ROM.
At reset, the value of the XMPNMC pin is sampled. The state of this pin deter-
mines whether boot ROM or XINTF Zone 7 is enabled at reset.
If XMPNMC = 1 (Micro-Processor Mode) then Zone 7 is enabled and the reset
vector will be fetched from external memory. In this case the user must insure
that the reset vector points to a valid memory location for code execution. This
option is only available on devices with an XINTF.
If XMPNMC = 0 (Micro-Computer Mode) then the boot ROM memory is en-
abled and XINTF Zone 7 is disabled. In this case, the reset vector is fetched
from the internal boot ROM memory. All devices without an XINTF module
have the XMPNMC signal tied low internal to the device such that the boot
ROM memory is always enabled at reset.
The reset vector in boot ROM redirects program execution to the InitBoot func-
tion. After performing device initialization the boot loader will check the state
of GPIO pins to determine which boot mode the user wants to execute. Options
include: Jump to Flash, Jump to H0 SARAM, Jump to OTP or call one of the
on-chip boot loading routines.
After the selection process and if required boot loading is complete, the proc-
essor will continue execution at an entry point determined by the boot mode
selected. If a boot loader was called, then the input stream loaded by the pe-
ripheral determines this entry address. This data stream is described in sec-
tion 2.4.3. If instead the user chooses to boot directly to Flash, OTP or H0 SA-
RAM, the entry address is predefined for each of these memory blocks.
The following sections discuss in detail the different boot modes available and
the process used for loading data code into the device.
On the 28x devices, when booting from the internal boot ROM (XMPNMC =
0), the device is configured for 28x operating mode by the boot ROM software.
The user is responsible for any additional configuration required.
For example:
- If the user’s application includes C2xLP source, then the user is respon-
sible for configuring the device for C2xLP source compatibility prior to exe-
cution of code generated from C2xLP source.
- If the user instead boots from external memory (MPNMC = 1) then the ap-
plication must configure the device for 28x operating mode or C2xLP
source compatible mode as appropriate.
AMODE 0 0 1
PAGE0 0 0 0
M0M1MAP† 1 1 1
The Boot ROM does not change the state of the PLL. Note that the PLL multi-
plier is not affected by a reset from the debugger. Therefore, a boot that is ini-
tialized from a reset from Code Composer Studiot may be at a different speed
than booting by pulling the external reset line (XRSn) low.
The boot modes will not enable the PIE. It will be left in its default state, which
is disabled.
The first 80 words of the M1 memory block (address 0x400 – 0x450) are re-
served for stack use during the boot load process. If code is bootloaded into
this region there is no error checking to prevent it from corrupting the Boot
ROM stack.
modes and gives brief summary of their functional operation. The state of four
GPIO pins are used to determine the boot mode desired as shown in Table 4.
PU No PU No PU No PU Mode Selected
Notes: 1) PU = pin has an internal pullup No PU = pin does not have an internal pullup
2) Users must take extra care due to any affect toggling SPICLK in order to select a boot mode may have on external
logic.
3) If the boot mode selected is Flash, H0 or OTP, then no external code is loaded by the bootloader.
Reset
InitBoot
Call
SelectBootMode
No
EntryPoint determined
directly from state of
I/O pins
Call
ExitBoot
Begin execution
at EntryPoint
The following boot modes do not call a boot loader. Instead, they jump to a pre-
defined location in memory:
In this mode, the boot ROM software will configure the device for ‘28x op-
eration and then branch directly to location 0x3F 7FF6 in Flash memory.
This location is just before the 128-bit code security module (CSM) pass-
word locations. The user is required to have previously programmed a
branch instruction at location 0x3F 7FF6 that will redirect code execution
to either a custom boot-loader or the application code.
User
SelectBootMode programmed
Jump to
Reset InitBoot Select jump ExitBoot 0x3F 7FF6 branch to
to flash desired
location
- Jump to H0 SARAM
In this mode, the boot ROM software will configure the device for ‘28x opera-
tion and then branch directly to 0x3F 8000; the first address in the H0 SARAM
memory block.
SelectBootMode
Jump to Execution
Reset InitBoot Select jump ExitBoot 0x3F 8000 continues
to HO SARAM
In this mode, the boot ROM software will configure the device for C28x op-
eration and then branch directly to at 0x3D 7800; the first address in the
OTP memory block.
SelectBootMode Execute
Jump to
Reset InitBoot Select jump ExitBoot 0x3D 7800 preprogrammed
to OTP OTP code
In this mode, the boot ROM will load code to be executed into on-chip
memory via the SCI-A port.
In this mode, the boot ROM will load code and data into on-chip memory from
an external EEPROM via the SPI port.
In this mode, the boot ROM uses a GPIO port B to load code and data from
an external source. This mode supports both 8-bit and 16-bit data
streams. Since this mode requires a number of GPIO pins, it would
typically be used for downloading code only for flash programming when
the device is connected to a platform explicitly for flash programming and
not a target board.
The first 16-bit word in the data stream is known as the key value. The key val-
ue is used to tell the boot loader the width of the incoming stream: 8 or 16 bits.
Note that not all boot loaders will accept both 8 and 16-bit streams. Please re-
fer to the detailed information on each loader for the valid data stream width.
For an 8-bit data stream, the key value is 0x08AA and for a 16-bit stream it is
0x10AA. If a boot loader receives an invalid key value, then the load is aborted.
In this case, the entry point for the Flash memory will be used.
The next 8 words are used to initialize register values or otherwise enhance
the boot loader by passing values to it. If a boot loader does not use these val-
ues then they are reserved for future use and the boot loader simply reads the
value and then discards it. Currently only the SPI boot loader uses one word
to initialize registers.
The next 10th and 11th words comprise the 22-bit entry point address. This ad-
dress is used to initialize the PC after the boot load is complete. This address
is most likely the entry point of the program downloaded by the boot loader.
The twelfth word in the data stream is the size of the first data block to be trans-
ferred. The size of the block is defined for both 8 and 16-bit data stream formats
as the number of 16-bit words in the block. For example, to transfer a block of
20 8-bit data values from an 8-bit data stream, the block size would be 0x000A
to indicate 10 16-bit words.
The next two words tell the loader the destination address of the block of data.
Following the size and address will be the 16-bit words that makeup that block
of data.
This pattern of block size/destination address repeats for each block of data
to be transferred. Once all the blocks have been transferred, a block size of
0x0000 signals to the loader that the transfer is complete. At this point the load-
er will return the entry point address to the calling routine which in turn will
cleanup and exit. Execution will then continue at the entry point address as de-
termined by the input data stream contents.
Word Contents
1 10AA (KeyValue for memory width = 16bits)
12 Block size (number of words) of the first block of data to load. If the block size is 0, this
indicates the end of the source program. Otherwise another section follows.
. …
. …
. …
. …
. …
. …
… …
23 LSB: Block size in words of the first block to load. If the block size is 0, this indicates the
end of the source program. Otherwise another block follows. For example, a block size
of 0x000A would indicate 10 words or 20 bytes in the block.
. …
. LSB: Last word of the first block of the source being loaded
. MSB: Last word of the first block of the source being loaded
. …
. …
. LSB: Last word of the second block of the source being loaded
. MSB: Last word of the second block of the source being loaded
. …
. …
. …
. …
. …
. LSB: Last word of the last block of the source being loaded
. MSB: Last word of the last block of the source being loaded
n LSB: 00h
After load has completed the following memory values will have been initial-
ized as follows:
Location Value
0x3F9010 0x0001
0x3F9011 0x0002
0x3F9012 0x0003
0x3F9013 0x0004
0x3F9014 0x0005
0x3F8000 0x7700
0x3F8001 0x7625
PC Begins execution at 0x3F8000
The loader first compares the first value sent by the host against the 16-bit key
value of 0x10AA. If the value fetched does not match then the loader will read
a second value. This value will be combined with the first value to form a word.
This will then be checked against the 8-bit key value of 0x08AA. If the loader
finds that the header does not match either the 8-bit or 16-bit key value, or if
the value is not valid for the given boot mode then the load will abort. In this
case the loader will return the entry point address for the flash will be returned
to the calling routine.
Yes
Yes
8-bit
Read EntryPoint address DataSize
Yes Return
R=0
? EntryPoint
No
Read BlockAddress
Transfer R words of
data from source to
destination
Notes: 1) 8-bit and 16-bit transfers are not valid for all boot modes. Refer to the info specific to a particular boot loader for any
limitations.
2) In 8-bit mode the LSB of the 16-bit word is read first followed by the MSB.
After the dummy read of the CSM password locations, the InitBoot routine calls
the SelectBootMode function. This function will then determine the type of boot
mode desired by the state of certain GPIO pins. Once the boot is complete,
the SelectBootMode function passes back the EntryAddr to the InitBoot func-
tion. InitBoot then calls the ExitBoot routine that then restores CPU registers
to their reset state and exits to the EntryAddr that was determined by the boot
mode.
Init Boot
Initialize device
OBJMODE=1
AMODE=0 Dummy read of
MOM1MAP=1 Call Call
CSM password SelectBootMode ExitBoot
DP=0 locations
OVM=0
SPM=0
SP=0x400
PU No PU No PU No PU Mode Selected
Notes: 1) When booting directly to Flash is assumed that the user has previously programmed a branch statement at 0x3F
7FF6 to redirect program flow as desired.
2) When booting directly to OTP or H0, it is assumed that the user has previously programmed or loaded code starting
at the entry point location.
3) x = don’t care
4) Users must take extra care due to any affect toggling SPICLK in order to select a boot mode may have on external
logic.
5) 5. PU = pin has an internal pull -up resister. No PU = pin does not have an internal pull -up resistor
For a boot mode to be selected, the pins corresponding to the desired boot
mode have to be pulled low until the selection process completes. Note that
the state of the selection pins is not latched at reset - they are sampled some
cycles later in the SelectBootMode function.
The SelectBootMode routine disables the watchdog before calling the SCI,
SPI or Parallel boot loader. If a boot loader is not going to be called, then the
watchdog is left untouched. The boot loaders do not service the watchdog
and assume that it is disabled. Before exiting the SelectBootMode routine
will re -enable the watchdog and reset its timer.
When selecting a boot mode, the pins should be pulled high or low through a
weak pulldown or weak pull -up such that the DSP can drive them to a new
state when required. For example, if you wanted to boot from the SCI one of
the pins you pull low is the SCITXDA pin. This pulldown must be weak so that
when the SCI boot process begins the DSP will be able to properly transmit
through the TX pin. Likewise for the remaining boot mode selection pins.
Users must take extra care if using SPICLK to select a boot mode. Toggling
of this signal may have an affect on external logic and this must be taken into
account.
SelectBootMode
HO Yes Return
boot HO_ENTRY_POINT Direct branch to the
? EntryAddr: 0x3F 8000 HO SARAM block.
No
No
Call
WatchDogDisable
After each data transfer, the DSP will echo back the 8-bit character received
to the host. In this manner, the host can perform checks that each character
was received by the DSP.
SCI_Boot
Read KeyValue
Enable the SCIA TX and
RX pin functionality
Valid No
Setup SCI-A for KeyValue Return
1 stop, 8-bit character, (0x08AA) FLASH_ENTRY_POINT
no parity, use internal ?
SC clock, no loopback,
disable Rx/Tx interrupts
Yes
No Autobaud
lock
?
Return
Yes EntryPoint
SCIA_CopyData
Call SCIA_GetWordData
to read
BlockHeader.BlockSize
BlockSize= Yes
0x0000 Return
?
No
Call SCIA_GetLongData
to read
BlockHeader.DestAddr
Transfer
BlockHeader.BlockSize
words of data from
SCIA port to memory
starting at DestAddr
Data No
SCIA_GetWordData Received
?
Yes
Read LSB
Yes
Read MSB
least significant byte (LSB). In this case, data is read from the lower eight lines
of GPIO port B ignoring the higher byte.
The DSP first signals the host that the DSP is ready to begin data transfer by
pulling the GPIOD6 pin low. The host load then initiates the data transfer by
pulling the GPIOD5 pin low. The complete protocol is shown in the diagram
below:
1 2 3 4 5 6
Host control
GPIOD5
DSP control
GPIOD6
1) The DSP indicates it is ready to start receiving data by pulling the GPIOD6
pin low.
2) The boot loader waits until the host puts data on GPIO port B. The host
signals to the DSP that data is ready by pulling the GPIOD5 pin low.
3) The DSP reads the data and signals the host that the read is complete by
pulling GPIOD6 high.
4) The Boot loader waits until the Host acknowledges the DSP by pulling
GPIOD5 high.
5) The DSP again indicates it is ready for more data by pulling the GPIOD6
pin low.
Parallel_Boot
Valid
Return No KeyValue
FLASH_ENTRY_POINT (0x08AA or
0x10AA)
?
Return
Yes EntryPoint
Figure 18 shows the transfer flow from the Host side. The operating speed of
the CPU and Host are not critical in this mode as the host will wait for the DSP
and the DSP will in turn wait for the host. In this manner the protocol will work
with both a host running faster and a host running slower then the DSP.
Start transfer
No DSP ready
(GPIOD6=0)
?
Yes
Signal that data
is ready Acknowledge DSP
(GPIOD5=0) (GPIOD5=1)
More Yes
data
?
No
End transfer
Parallel_CopyData
Call
Parallel_GetWordData
to read
BlockHeader.BlockSize
BlockSize= Yes
0x0000 Return
?
No
Call
Parallel_GetLongData
to read
BlockHeader.DestAddr
Transfer
BlockHeader.BlockSize
words of data from
GPIO B port to memory
starting at DestAddr
Figure 20 shows the flow for fetching a single word of data from the parallel
port.
If the DataSize parameter is 8 bits, then the routine will and discard the upper
8 bits of the first read and treat the lower 8 bits as the least significant byte
(LSB) of the word to be fetched. The routine will then perform a 2nd fetch to
read the most significant byte (MSB). It then combines the MSB and LSB into
a single 16-bit value to be passed back to the calling routine.
Parallel_GetWordData A
Data
ready No Data
ready No
(GPIO5=0)
? (GPIO5=0)
?
Yes
Yes
Read word of data from
GPIOB Read word from GPIOB,
throw away the upper 8 bits,
MSB of data=lower 8 bits
Host No
Ack Host
(GPIO5=1) No
Ack
? (GPIO5=1)
?
Yes
Yes
No
Return WordData
The SPI loader expects an 8-bit wide SPI-compatible serial EEPROM device
to be present on the SPI pins as indicated in Figure 21. The SPI bootloader
does not support a 16-bit data stream.
EEPROM
SPISIMOA
DIN
F2810/12 SPISOMIA
DOUT
SPICLKA
CLK
SPIESTEA/GPIOF3
CS
3 LSB = LOSPCP
4 MSB= SPIBRR
5 LSB = reserved
6 MSB = reserved
Blocks of data in the format size/destination address/data as shown in the generic data
stream description
The data transfer is done in “burst” mode from the EEPROM. The transfer is
carried out entirely in byte mode (SPI at 8 bits/character). A step-by step de-
scription of the sequence follows:
2) The GPIOF3 pin is now used as a chip -select for the EEPROM
4) The SPI-A sends the EEPROM an address 0x0000; that is, the host re-
quires that the EEPROM must have the downloadable packet starting at
address 0x0000 in the EEPROM.
5) The next word fetched must match the key value for an 8-bit data stream
(0x08AA).
The most significant byte of this word is the byte read first and the least
significant byte is the next byte fetched. This is true of all word transfers on
the SPI.
If the key value does not match then the load is aborted and the entry point
for the Flash (0x3F 7FF6) is returned to the calling routine.
6) The next 2 bytes fetched can be used to change the value of the low speed
peripheral clock register (LOSPCP) and the SPI Baud rate register
(SPIBRR). The first byte read is the LOSPCP value and the 2nd byte read
is the SPIBRR value.
The next 7 words are reserved for future enhancements. The SPI boot
loader reads these 7 words and discards them.
7) The next 2 words makeup the 32-bit entry point address where execution
will continue after the boot load process is complete. This is typically the
entry point for the program being downloaded through the SPI port.
8) Multiple blocks of code and data are then copied into memory from the ex-
ternal EEPROM through the SPI port. The blocks of code are organized
in the standard data stream structure presented earlier. This is done until
a block size of 0x0000 is encountered. At that point in time the entry point
address is returned to the calling routine that then exits the boot loader and
resumes execution at the address specified.
SPI_Boot
Enable EEPROM
Send read command and Read and discard 7
start at EEPROM address reserved words
0x0000
SPIA_CopyData
Call
SPIA_GetWordData
to read
BlockHeader.BlockSize
BlockSize= Yes
0x0000 Return
?
No
Call
SPIA_GetLongData
to read
BlockHeader.DestAddr
Transfer
BlockHeader.BlockSize
words of data from
SPIA port to memory
starting at DestAddr
Yes
Read LSB
Yes
Read MSB
Return MSB:LSB
Reset
InitBoot
Call
SelectBootMode
Call Yes
BootLoader Call Boot Loader
?
No
Call ExitBoot
Cleanup CPU
registers to default
value after reset*
Dealocate stack
(SP=0x400)
Branch to EntryPoint
Begin execution
at EntryPoint
After the ExitBoot routine completes and the program flow is redirected to the
entry point address, the CPU registers will have the following values:
–boot Convert all sections into bootable form (use instead of a SECTIONS directive)
–sci8 Specify the source of the boot loader table as the SCI-A port, 8-bit mode
–spi8 Specify the source of the boot loader table as the SPI-A port, 8-bit mode
–gpio8 Specify the source of the boot loader table as the GP I/O port, 8-bit mode
–gpio16 Specify the source of the boot loader table as the GP I/O port, 16-bit mode
–bootorg value Specify the source address of the boot loader table
–lospcp value Specify the initial value for the LOSPCP register. This value is used only for the spi8
boot table format and ignored for all other formats. If the value is greater than 0x7F,
the value is truncated to 0x7F.
–spibrr value Specify the initial value for the SPIBRR register. This value is used only for the spi8
boot table format and ignored for all other formats. If the value is greater than 0x7F,
the value is truncated to 0x7F.
–e value Specify the entry point at which to begin execution after boot loading. The value can
be an address or a global symbol.
;;###########################################################################
;;
;; FILE: Init_Boot.asm
;;
;; TITLE: F2810/12 Boot Rom Initialization and Exit routines.
;;
;; Functions:
;;
;; _InitBoot
;; _ExitBoot
;;
;; Notes:
;;
;;###########################################################################
;;
;; Ver | dd mmm yyyy | Who | Description of changes
;; =====|=============|==============|=======================================
;; 1.0 | 12 Mar 2002 | LH | PG Release.
;; | | |
;;###########################################################################
.def _InitBoot
.ref _SelectBootMode
.sect ”.Version”
.word 0x0001 ; F2810/12 Boot ROM Version 1
.word 0x0302 ; Month/Year: 3/02
.sect ”.InitBoot”
;–––––––––––––––––––––––––––––––––––––––––––––––
; _InitBoot
;–––––––––––––––––––––––––––––––––––––––––––––––
;–––––––––––––––––––––––––––––––––––––––––––––––
; This function performs the initial boot routine
; for the F2810/12 boot ROM.
;
; This module performs the following actions:
;
; 1) Initalizes the stack pointer
; 2) Sets the device for C28x operating mode
; 3) Calls the main boot functions
; 4) Calls an exit routine
;–––––––––––––––––––––––––––––––––––––––––––––––
_InitBoot:
; Initalize the stack pointer.
__stack: .usect ”.stack”,0
MOV SP, #__stack ; Initalize the stack pointer
; Initalize the device for running in C28x mode.
C28OBJ ; Select C28x object mode
C28ADDR ; Select C27x/C28x addressing
C28MAP ; Set blocks M0/M1 for C28x mode
CLRC PAGE0 ; Always use stack addressing mode
MOVW DP,#0 ; Initialize DP to point to the low 64 K
CLRC OVM
; Set PM shift of 0
SPM 0
; Read the password locations – this will unlock the
; CSM only if the passwords are erased. Otherwise it
; will not have an effect.
MOVL XAR1,#0x3F7FF8;
MOVL XAR0,*XAR1++
MOVL XAR0,*XAR1++
MOVL XAR0,*XAR1++
MOVL XAR0,*XAR1
; Decide which boot mode to use
LCR _SelectBootMode
; Cleanup and exit. At this point the EntryAddr
; is located in the ACC register
BF _ExitBoot,UNC
;–––––––––––––––––––––––––––––––––––––––––––––––
; _ExitBoot
;–––––––––––––––––––––––––––––––––––––––––––––––
;–––––––––––––––––––––––––––––––––––––––––––––––
;This module cleans up after the boot loader
;
; 1) Make sure the stack is deallocated.
; SP = 0x400 after exiting the boot
; loader
; 2) Push 0 onto the stack so RPC will be
; 0 after using LRETR to jump to the
; entry point
; 2) Load RPC with the entry point
; 3) Clear all XARn registers
; 4) Clear ACC, P and XT registers
; 5) LRETR – this will also clear the RPC
; register since 0 was on the stack
;–––––––––––––––––––––––––––––––––––––––––––––––
_ExitBoot:
;–––––––––––––––––––––––––––––––––––––––––––––––
; Insure that the stack is deallocated
;–––––––––––––––––––––––––––––––––––––––––––––––
MOV SP,#__stack
;–––––––––––––––––––––––––––––––––––––––––––––––
; Clear the bottom of the stack. This will endup
; in RPC when we are finished
;–––––––––––––––––––––––––––––––––––––––––––––––
MOV *SP++,#0
MOV *SP++,#0
;–––––––––––––––––––––––––––––––––––––––––––––––
; Load RPC with the entry point as determined
; by the boot mode. This address will be returned
; in the ACC register.
;–––––––––––––––––––––––––––––––––––––––––––––––
PUSH ACC
POP RPC
;–––––––––––––––––––––––––––––––––––––––––––––––
; Put registers back in their reset state.
;
; Clear all the XARn, ACC, XT, and P and DP
; registers
;
; NOTE: Leave the device in C28x operating mode
; (OBJMODE = 1, AMODE = 0)
;–––––––––––––––––––––––––––––––––––––––––––––––
ZAPA
MOVL XT,ACC
MOVZ AR0,AL
MOVZ AR1,AL
MOVZ AR2,AL
MOVZ AR3,AL
MOVZ AR4,AL
MOVZ AR5,AL
MOVZ AR6,AL
MOVZ AR7,AL
MOVW DP, #0
;––––––––––––––––––––––––––––––––––––––––––––––––
; Restore ST0 and ST1. Note OBJMODE is
; the only bit not restored to its reset state.
; OBJMODE is left set for C28x object operating
; mode.
;
; ST0 = 0x0000 ST1 = 0x0A0B
; 15:10 OVC = 0 15:13 ARP = 0
; 9: 7 PM = 0 12 XF = 0
; 6 V = 0 11 M0M1MAP = 1
; 5 N = 0 10 reserved
; 4 Z = 0 9 OBJMODE = 1
; 3 C = 0 8 AMODE = 0
; 2 TC = 0 7 IDLESTAT = 0
; 1 OVM = 0 6 EALLOW = 0
; 0 SXM = 0 5 LOOP = 0
; 4 SPA = 0
; 3 VMAP = 1
; 2 PAGE0 = 0
; 1 DBGM = 1
; 0 INTM = 1
;–––––––––––––––––––––––––––––––––––––––––––––––
MOV *SP++,#0
MOV *SP++,#0x0A0B
POP ST1
POP ST0
;––––––––––––––––––––––––––––––––––––––––––––––––
; Jump to the EntryAddr as defined by the
; boot mode selected and continue execution
;–––––––––––––––––––––––––––––––––––––––––––––––
LRETR
;eof ––––––––––
//###########################################################################
//
// FILE: SelectMode_Boot.c
//
// TITLE: F2810/12 Boot Mode selection routines
//
// Functions:
//
// ui32 SelectBootMode(void)
// inline void SelectMode_GPOISelect(void)
//
// Notes:
//
//###########################################################################
//
// Ver | dd mmm yyyy | Who | Description of changes
// =====|=============|==============|=======================================
// 1.0 | 12 Mar 2002 | LH | PG Release.
// | | |
//###########################################################################
#include ”F2812_Boot.h”
inline void SelectMode_GPIOSelect(void);
// Define mask for mode selection
// all mode select pins are on GPIOF
// These definitions define which pins
// are used:
//GPIOF4 GPIOF12 GPIOF3 GPIOF2
//(SCITXDA) (MDXA) (SPISTEA) (SPICLKA) Mode Selected
// 1 x x x Jump to Flash address 0x3F 7FF6
// 0 1 x x Call SPI_Boot
// 0 0 1 1 Call SCI_Boot
// 0 0 1 0 Jump to H0 SARAM
// 0 0 0 1 Jump to OTP
// 0 0 0 0 Call Parallel_Boot
#define MODE_PIN1 0x0010 // GPIOF4
#define MODE_PIN2 0x1000 // GPIOF12
#define MODE_PIN3 0x0008 // GPIOF3
#define MODE_PIN4 0x0004 // GPIOF2
// On GP I/O port F use only the following pins to determine the boot mode
#define MODE_MASK (MODE_PIN1 | MODE_PIN2 | MODE_PIN3 | MODE_PIN4)
// Define which pins matter to which modes. Note that some modes
// do not check the state of all 4 pins.
#define FLASH_MASK (MODE_PIN1)
#define SPI_MASK (MODE_PIN1 | MODE_PIN2)
#define SCI_MASK (MODE_PIN1 | MODE_PIN2 | MODE_PIN3 | MODE_PIN4)
#define H0_MASK (MODE_PIN1 | MODE_PIN2 | MODE_PIN3 | MODE_PIN4)
#define OTP_MASK (MODE_PIN1 | MODE_PIN2 | MODE_PIN3 | MODE_PIN4)
#define PARALLEL_MASK (MODE_PIN1 | MODE_PIN2 | MODE_PIN3 | MODE_PIN4)
// Define which pins (out of the ones being examined) must be set
// to boot to a particular mode
#define FLASH_MODE (MODE_PIN1)
#define SPI_MODE (MODE_PIN2)
#define SCI_MODE (MODE_PIN3 | MODE_PIN4)
#define H0_MODE (MODE_PIN3)
SelectMode_GPIOSelect();
BootMode = GPIODataRegs.GPFDAT.all & MODE_MASK;
// ui32 SCI_Boot(void)
// inline void SCIA_GPIOSelect(void)
// inline void SCIA_SysClockEnable(void)
// inline void SCIA_Init(void)
// inline void SCIA_AutobaudLock(void)
// inline ui16 SCIA_CheckKeyVal(void)
// inline void SCIA_ReservedFn(void)
// ui32 SCIA_GetLongData(void)
// ui32 SCIA_GetWordData(void)
// void SCIA_CopyData(void)
//
// Notes:
//
//###########################################################################
//
// Ver | dd mmm yyyy | Who | Description of changes
// =====|=============|==============|=======================================
// 1.0 | 12 Mar 2002 | LH | PG Release.
// | | |
//###########################################################################
#include ”F2812_Boot.h”
// Private functions
inline void SCIA_GPIOSelect(void);
inline void SCIA_Init(void);
inline void SCIA_AutobaudLock(void);
inline ui16 SCIA_CheckKeyVal(void);
inline void SCIA_ReservedFn(void);
inline void SCIA_SysClockEnable(void);
ui32 SCIA_GetLongData(void);
ui16 SCIA_GetWordData(void);
void SCIA_CopyData(void);
// Data section where SCIA control registers
// reside
#pragma DATA_SECTION(SCIARegs,”.SCIARegs”);
volatile struct SCI_REGS SCIARegs;
//#################################################
// ui32 SCI_Boot(void)
//––––––––––––––––––––––––––––––––––––––––––––
// This module is the main SCI boot routine.
// It will load code via the SCI-A port.
//
// It will return a entry point address back
// to the InitBoot routine which in turn calls
// the ExitBoot routine.
//––––––––––––––––––––––––––––––––––––––––––––
ui32 SCI_Boot()
{
ui32 EntryAddr;
ui16 ErrorFlag;
SCIA_SysClockEnable();
SCIA_GPIOSelect();
SCIA_Init();
SCIA_AutobaudLock();
ui16 byteData;
// Must prime baud register with >= 1
SCIARegs.SCILBAUD = 1;
// Prepare for autobaud detection
// Set the CDC bit to enable autobaud detection
// and clear the ABD bit
SCIARegs.SCIFFCT.all = 0x2000;
// Wait until we correctly read an
// ’A’ or ’a’ and lock
while(SCIARegs.SCIFFCT.bit.ABD != 1) {}
// After autobaud lock, clear the CDC bit
SCIARegs.SCIFFCT.bit.CDC = 0;
while(SCIARegs.SCIRXST.bit.RXRDY != 1) { }
byteData = SCIARegs.SCIRXBUF.bit.RXDT;
SCIARegs.SCITXBUF = byteData;
return;
}
//#################################################
// ui16 SCIA_CheckKeyVal(void)
//–––––––––––––––––––––––––––––––––––––––––––––––––
// The header of the datafile should have a proper
// key value of 0x08 0xAA. If it does not, then
// we either have a bad data file or we are not
// booting properly. If this is the case, return
// an error to the main routine.
//–––––––––––––––––––––––––––––––––––––––––––––––––
inline ui16 SCIA_CheckKeyVal()
{
ui16 wordData;
wordData = SCIA_GetWordData();
if(wordData != EIGHT_BIT_HEADER) return ERROR;
// No error found
return NO_ERROR;
}
//#################################################
// void SCIA_ReservedFn(void)
//–––––––––––––––––––––––––––––––––––––––––––––––––
// This function reads 8 reserved words in the header.
// None of these reserved words are used by the
// SCI boot loader at this time, they may be used in
// future devices for enhancments.
//–––––––––––––––––––––––––––––––––––––––––––––––––
inline void SCIA_ReservedFn()
{
ui16 i;
// Read and discard the 8 reserved words.
for(i = 1; i <= 8; i++)
{
SCIA_GetWordData();
}
return;
}
//#################################################
// ui32 SCIA_GetLongData(void)
//–––––––––––––––––––––––––––––––––––––––––––––––
// This routine fetches two words from the SCI-A
// port and puts them together to form a single
// 32-bit value. It is assumed that the host is
// sending the data in the form MSW:LSW.
//–––––––––––––––––––––––––––––––––––––––––––––––
ui32 SCIA_GetLongData()
{
ui32 longData = (ui32)0x00000000;
// Fetch the upper 1/2 of the 32-bit value
longData = ( (ui32)SCIA_GetWordData() << 16);
// Fetch the lower 1/2 of the 32-bit value
longData |= (ui32)SCIA_GetWordData();
return longData;
}
//#################################################
// ui16 SCIA_GetWordData(void)
//–––––––––––––––––––––––––––––––––––––––––––––––
// This routine fetches two bytes from the SCI-A
// port and puts them together to form a single
// 16-bit value. It is assumed that the host is
// sending the data in the order LSB followed by MSB.
//–––––––––––––––––––––––––––––––––––––––––––––––
ui16 SCIA_GetWordData()
{
ui16 wordData;
ui16 byteData;
wordData = 0x0000;
byteData = 0x0000;
//
// Multiple blocks of data are copied until a block
// size of 00 00 is encountered.
//
//–––––––––––––––––––––––––––––––––––––––––––––––––––––
void SCIA_CopyData()
{
struct HEADER {
ui16 BlockSize;
ui32 DestAddr;
} BlockHeader;
ui16 wordData;
ui16 i;
while(BlockHeader.BlockSize != (ui16)0x0000)
{
BlockHeader.DestAddr = SCIA_GetLongData();
for(i = 1; i <= BlockHeader.BlockSize; i++)
{
wordData = SCIA_GetWordData();
*(ui16 *)BlockHeader.DestAddr++ = wordData;
}
//###########################################################################
//
// FILE: Parallel_Boot.c
//
// TITLE: F2810/12 Parallel Port I/O boot routines
//
// Functions:
//
// ui32 Parallel_Boot(void)
// inline void Parallel_GPIOSelect(void)
// inline ui16 Parallel_CheckKeyVal(void)
// invline void Parallel_ReservedFn(void)
// ui32 Parallel_GetLongData(ui16 DataSize)
// ui16 Parallel_GetWordData(ui16 DataSize)
// void Parallel_CopyData(ui16 DataSize)
// void Parallel_WaitHostRdy(void)
// void Parallel_HostHandshake(void)
// Notes:
//
//###########################################################################
//
// Ver | dd mmm yyyy | Who | Description of changes
// =====|=============|==============|=======================================
// 1.0 | 12 Mar 2002 | LH | PG Release.
// | | |
//###########################################################################
#include ”F2812_Boot.h”
// Private function definitions
inline void Parallel_GPIOSelect(void);
inline ui16 Parallel_CheckKeyVal(void);
inline void Parallel_ReservedFn();
ui32 Parallel_GetLongData(ui16 DataSize);
ui16 Parallel_GetWordData(ui16 DataSize);
void Parallel_CopyData(ui16 DataSize);
void Parallel_WaitHostRdy(void);
void Parallel_HostHandshake(void);
#define HOST_DATA_NOT_RDY GPIODataRegs.GPDDAT.bit.GPIOD5!=0
#define WAIT_HOST_ACK GPIODataRegs.GPDDAT.bit.GPIOD5!=1
// Set (DSP_ACK) or Clear (DSP_RDY) GPIOD6
#define DSP_ACK GPIODataRegs.GPDSET.all = 0x0040
#define DSP_RDY GPIODataRegs.GPDCLEAR.all = 0x0040
#define DATA GPIODataRegs.GPBDAT.all
// Data section where GPIO control and data registers
// reside
#pragma DATA_SECTION(GPIODataRegs,”.GPIODataRegs”);
volatile struct GPIO_DATA_REGS GPIODataRegs;
#pragma DATA_SECTION(GPIOMuxRegs,”.GPIOMuxRegs”);
volatile struct GPIO_MUX_REGS GPIOMuxRegs;
#endif
//#################################################
// ui32 Parallel_Boot(void)
//––––––––––––––––––––––––––––––––––––––––––––
// This module is the main Parallel boot routine.
// It will load code via GP I/O port B.
//
// This boot mode accepts 8-bit or 16-bit data.
// 8-bit data is expected to be the order LSB
// followed by MSB.
//
// This function returns a entry point address back
// to the InitBoot routine which in turn calls
// the ExitBoot routine.
//––––––––––––––––––––––––––––––––––––––––––––
ui32 Parallel_Boot()
{
ui32 EntryAddr;
ui16 DataSize;
Parallel_GPIOSelect();
DataSize = Parallel_CheckKeyVal();
if (DataSize == ERROR) return FLASH_ENTRY_POINT;
Parallel_ReservedFn(DataSize);
EntryAddr = Parallel_GetLongData(DataSize);
Parallel_CopyData(DataSize);
return EntryAddr;
}
//#################################################
// void Parallel_GPIOSelect(void)
//––––––––––––––––––––––––––––––––––––––––––
// Enable pins for GP I/O on Port B. Also enable
// the control pins for host ack and DSP ready.
//––––––––––––––––––––––––––––––––––––––––––
inline void Parallel_GPIOSelect()
{
EALLOW;
EDIS;
}
//#################################################
// void Parallel_CheckKeyVal(void)
//–––––––––––––––––––––––––––––––––––––––––
// Determine if the data we are loading is in
// 8-bit or 16-bit format.
// If neither, return an error.
//
// Note that if the host never responds then
// the code will be stuck here. That is there
// is no timeout mechanism.
//––––––––––––––––––––––––––––––––––––––––––
inline ui16 Parallel_CheckKeyVal()
{
ui16 wordData;
wordData = Parallel_GetWordData(SIXTEEN_BIT);
if(wordData == SIXTEEN_BIT_HEADER) return SIXTEEN_BIT;
// If not 16-bit mode, check for 8-bit mode
// Call Parallel_GetWordData with 16-bit mode
// so we only fetch the MSB of the KeyValue and not
// two bytes. We will ignore the upper 8-bits and combine
// the result with the previous byte to form the
// header KeyValue.
ui16 wordData;
ui16 i;
while(BlockHeader.BlockSize != (ui16)0x0000)
{
BlockHeader.DestAddr = Parallel_GetLongData(DataSize);
for(i = 1; i <= BlockHeader.BlockSize; i++)
{
wordData = Parallel_GetWordData(DataSize);
*(ui16 *)BlockHeader.DestAddr++ = wordData;
}
Parallel_WaitHostRdy();
wordData = DATA;
Parallel_HostHandshake();
// If we are in 8-bit mode then the first
// fetch was only the LSB. Fetch the MSB.
if(DataSize == EIGHT_BIT) {
wordData = wordData & 0x00FF;
Parallel_WaitHostRdy();
wordData |= (DATA << 8);
Parallel_HostHandshake();
}
return wordData;
}
//#################################################
// ui32 Parallel_GetLongData(ui16 DataSize)
//–––––––––––––––––––––––––––––––––––––––––––––––
// This routine fetches two words from the GP I/O
// port and puts them together to form a single
// 32-bit value. It is assumed that the host is
// sending the data in the form MSW:LSW.
//–––––––––––––––––––––––––––––––––––––––––––––––
ui32 Parallel_GetLongData(ui16 DataSize)
{
ui32 longData;
longData = ( (ui32)Parallel_GetWordData(DataSize) )<< 16;
longData |= (ui32)Parallel_GetWordData(DataSize);
return longData;
}
//#################################################
// void Parallel_WaitHostRdy(void)
//–––––––––––––––––––––––––––––––––––––––––––––––––––––
// This routine tells the host that the DSP is ready to
// recieve data. The DSP then waits for the host to
// signal that data is ready on the GP I/O port.e
//–––––––––––––––––––––––––––––––––––––––––––––––––––––
void Parallel_WaitHostRdy()
{
DSP_RDY;
while(HOST_DATA_NOT_RDY) { }
}
//#################################################
// void Parallel_HostHandshake(void)
//–––––––––––––––––––––––––––––––––––––––––––––––––––––
// This routine tells the host that the DSP has recieved
// the data. The DSP then waits for the host to acknowledge
// the reciept before continuing.
//–––––––––––––––––––––––––––––––––––––––––––––––––––––
void Parallel_HostHandshake()
{
DSP_ACK;
while(WAIT_HOST_ACK) { }
}
// EOF ––––––––
//###########################################################################
//
// FILE: SPI_Boot.c
//
// TITLE: F2810/12 SPI Boot mode routines
//
// Functions:
//
// ui32 SPI_Boot(void)
// inline void SPIA_GPIOSelect(void)
// inline void SPIA_SysClockEnable(void)
// inline void SPIA_Init(void)
// inline void SPIA_Transmit(u16 cmdData)
// inline ui16 SPIA_CheckKeyVal(void)
// inline void SPIA_ReservedFn(void);
// ui32 SPIA_GetLongData(void)
// ui32 SPIA_GetWordData(void)
// void SPIA_CopyData(void)
//
// Notes:
//
//###########################################################################
//
// Ver | dd mmm yyyy | Who | Description of changes
// =====|=============|==============|=======================================
// 1.0 | 12 Mar 2002 | SS | PG Release.
// | | |
//###########################################################################
#include ”F2812_Boot.h”
#pragma DATA_SECTION(SPIARegs,”.SPIARegs”);
volatile struct SPI_REGS SPIARegs;
// Private functions
inline void SPIA_GPIOSelect(void);
inline void SPIA_Init(void);
inline ui16 SPIA_Transmit(ui16 cmdData);
inline ui16 SPIA_CheckKeyVal(void);
inline void SPIA_ReservedFn(void);
inline void SPIA_SysClockEnable(void);
ui32 SPIA_GetLongData(void);
ui16 SPIA_GetWordData(void);
void SPIA_CopyData(void);
//#################################################
// ui32 SPI_Boot(void)
//––––––––––––––––––––––––––––––––––––––––––––
// This module is the main SPI boot routine.
// It will load code via the SPI-A port.
//
// It will return a entry point address back
// to the ExitBoot routine.
//––––––––––––––––––––––––––––––––––––––––––––
ui32 SPI_Boot()
{
ui32 EntryAddr;
ui16 ErrorFlag;
SPIA_SysClockEnable();
SPIA_GPIOSelect();
SPIA_Init();
// 1. Enable EEPROM chip enable – low – Bit 5 for the IOPORT
// Chip enable – high
GPIODataRegs.GPFCLEAR.bit.GPIOF3 =1;
// 2. Enable EEPROM and send EEPROM Read Command
SPIA_Transmit(0x0300);
// 3. Send Starting for the EEPROM address 16bit
// Sending 0x0000,0000 will work for address and data packets
SPIA_GetWordData();
// 4. Check for 0x08AA data header, else go to flash
ErrorFlag = SPIA_CheckKeyVal();
if (ErrorFlag != 0) return FLASH_ENTRY_POINT;
// 4a.Check for Clock speed change and reserved words
SPIA_ReservedFn();
// 5. Get point of Entry address after load
EntryAddr = SPIA_GetLongData();
// 6. Receive and copy one or more code sections to destination addresses
SPIA_CopyData();
// 7. Disable EEPROM chip enable – high
// Chip enable – high
GPIODataRegs.GPFSET.bit.GPIOF3 =1;
return EntryAddr;
}
//#################################################
// void SPIA_GPIOSelect(void)
//––––––––––––––––––––––––––––––––––––––––––
// Enable pins for the SPI–A module for SPI
// peripheral functionality.
//––––––––––––––––––––––––––––––––––––––––––
inline void SPIA_GPIOSelect()
{
EALLOW
// Enable SPISIMO/SPISOMI/SPICLK pins
GPIOMuxRegs.GPFMUX.all = 0x0007;
EDIS
}
//#################################################
// void SPIA_Init(void)
//––––––––––––––––––––––––––––––––––––––––––––––
// Initialize the SPI–A port for communications
// with the host.
//––––––––––––––––––––––––––––––––––––––––––––––
inline void SPIA_Init()
{
// Enable FIFO reset bit only
SPIARegs.SPIFFTX.all=0x8000;
// 8-bit character
SPIARegs.SPICCR.all = 0x0007;
// Use internal SPICLK master mode and Talk mode
SPIARegs.SPICTL.all = 0x000E;
// Use the slowest baud rate
SPIARegs.SPIBRR = 0x007f;
// Relinquish SPI-A from reset
SPIARegs.SPICCR.all = 0x0087;
return;
}
//#################################################
// void SPIA_Transmit(void)
//––––––––––––––––––––––––––––––––––––––––––––––––
// Send a byte/words through SPI transmit channel
//––––––––––––––––––––––––––––––––––––––––––––––––
inline ui16 SPIA_Transmit(ui16 cmdData)
{
ui16 recvData;
// Send Read command/dummy word to EEPROM to fetch a byte
SPIARegs.SPITXBUF = cmdData;
while( (SPIARegs.SPISTS.bit.INT_FLAG) !=1);
// Clear SPIINT flag and capture received byte
recvData = SPIARegs.SPIRXBUF;
return recvData;
}
//#################################################
// ui16 SPIA_CheckKeyVal(void)
//–––––––––––––––––––––––––––––––––––––––––––––––––
// The header of the datafile should have a proper
// key value of 0x08 0xAA. If it does not, then
// we either have a bad data file or we are not
// booting properly. If this is the case, return
// an error to the main routine.
//–––––––––––––––––––––––––––––––––––––––––––––––––
wordData = SPIA_GetWordData();
if(wordData != 0x08AA) return ERROR;
// No error found
return NO_ERROR;
}
//#################################################
// void SPIA_ReservedFn(void)
//–––––––––––––––––––––––––––––––––––––––––––––––––
// This function reads 8 reserved words in the header.
// The first word has parameters for LOSPCP
// and SPIBRR register 0xMSB:LSB, LSB = is a three
// bit field for LOSPCP change MSB = is a 6bit field
// for SPIBRR register update
//
// If either byte is the default value of the register
// then no speed change occurs. The default values
// are LOSPCP = 0x02 and SPIBRR = 0x7F
// The remaining reserved words are read and discarded
// and then returns to the main routine.
//–––––––––––––––––––––––––––––––––––––––––––––––––
inline void SPIA_ReservedFn()
{
ui16 speedData;
ui16 i;
speedData = (ui16)0x0000;
// update LOSPCP register if 1st reserved byte is not the default
// value of 0x0002
speedData = SPIA_Transmit((ui16)0x0000);
if(speedData != (ui16)0x0002)
{
EALLOW;
SysCtrlRegs.LOSPCP.all = speedData;
EDIS;
// Dummy cycles
asm(” RPT #0x0F ||NOP”);
}
wordData = 0x0000;
ui16 wordData;
ui16 i;
while(BlockHeader.BlockSize != (ui16)0x0000)
{
BlockHeader.DestAddr = SPIA_GetLongData();
for(i = 1; i <= BlockHeader.BlockSize; i++)
{
wordData = SPIA_GetWordData();
*(ui16 *)BlockHeader.DestAddr++ = wordData;
}