TMS320x2833x, 2823x Boot ROM,,SPI Boot固化源码
机制分析,通过配置GPIO87,GPIO86, GPIO85, GPIO84这几个引脚,DSP上电后决定进入哪个Boot模式(spi,sci,iic,can等)。
进入spi模式后,读取eeprom里面的数据(FLASH烧写驱动,CAN驱动),然后写进dsp的RAM里面,然后从RAM运行程序。
然后就可以与外界的端口(如CAN上位机)进行通信,更新程序
=============================================
2.20 SPI_BootFunction
The SPI loaderexpects an SPI-compatible 16-bit or 24-bit addressable serial EEPROM or serialflash
device to bepresent on the SPI-A pins as indicated in Figure 2-28. The SPI bootloadersupports an 8-bit
data stream. Itdoes not support a 16-bit data stream.
The SPI-A loaderuses following pins:
• SPISIMOA on GPIO16
• SPISOMIA on GPIO17
• SPICLKA on GPIO18
• SPISTEA on GPIO19
The SPI boot ROMloader initializes the SPI module to interface to a serial SPI EEPROM or flash.Devices
of this typeinclude, but are not limited to, the Xicor X25320 (4Kx8) and Xicor X25256(32Kx8) SPI serial
SPI EEPROMs andthe Atmel AT25F1024A serial flash.
The SPI boot ROMloader initializes the SPI with the following settings: FIFO enabled, 8-bitcharacter,
internal SPICLKmaster mode and talk mode, clock phase = 1, polarity = 0, using the slowestbaud rate.
If the download isto be performed from an SPI port on another device, then that device must besetup to
operate in theslave mode and mimic a serial SPI EEPROM. Immediately after entering theSPI_Boot
function, the pinfunctions for the SPI pins are set to primary and the SPI is initialized. Theinitialization is
done at theslowest speed possible. Once the SPI is initialized and the key value read, youcould specify a
change in baudrate or low speed peripheral clock
============================================================================================
// TI File $Revision: /main/4 $
// Checkin $Date: July 2, 2007 16:41:42 $
//###########################################################################
//FILE: Shared_Boot.c
//TITLE: 2833x Boot loader shared functions
//Functions:
// void CopyData(void)
// Uint32 GetLongData(void)
// void ReadReservedFn(void)
//
//###########################################################################
// $TI Release: 2833x/2823x Boot ROM V2 $
// $Release Date: March 4, 2008 $
//###########################################################################
#include "DSP2833x_Device.h"
#include "TMS320x2833x_Boot.h"
// GetWordData is a pointer to the function that interfaces to the peripheral.
// Each loader assigns this pointer to it's particular GetWordData function.
uint16fptr GetWordData;
Uint16 BootMode;
// Function prototypes
Uint32 GetLongData();
void CopyData(void);
void ReadReservedFn(void);
//#################################################
// void CopyData(void)
//-----------------------------------------------------
// This routine copies multiple blocks of data from the host
// to the specified RAM locations. There is no error
// checking on any of the destination addresses.
// That is it is assumed all addresses and block size
// values are correct.
//Multiple blocks of data are copied until a block
// size of 00 00 is encountered.
//
//-----------------------------------------------------
void CopyData()
{
struct HEADER {
Uint16 BlockSize;
Uint32 DestAddr;
} BlockHeader;
Uint16 wordData;
Uint16 i;
// Get the size in words of the first block
BlockHeader.BlockSize = (*GetWordData)();
// While the block size is > 0 copy the data
// to the DestAddr. There is no error checking
// as it is assumed the DestAddr is a valid
// memory location
while(BlockHeader.BlockSize != (Uint16)0x0000)
{
BlockHeader.DestAddr = GetLongData();
for(i = 1; i <= BlockHeader.BlockSize; i++)
{
wordData = (*GetWordData)();
*(Uint16 *)BlockHeader.DestAddr++ = wordData;
}
// Get the size of the next block
BlockHeader.BlockSize = (*GetWordData)();
}
return;
}
//#################################################
// Uint32 GetLongData(void)
//-----------------------------------------------------// This routine fetches a 32-bit value from the peripheral
// input stream.
//-----------------------------------------------------
Uint32 GetLongData()
{
Uint32 longData;
// Fetch the upper 1/2 of the 32-bit value
longData = ( (Uint32)(*GetWordData)() << 16);
// Fetch the lower 1/2 of the 32-bit value
longData |= (Uint32)(*GetWordData)();
return longData;
}
//#################################################
// void Read_ReservedFn(void)
//-------------------------------------------------// This function reads 8 reserved words in the header.
// None of these reserved words are used by the
// this boot loader at this time, they may be used in
// future devices for enhancements. Loaders that use
// these words use their own read function.
//-------------------------------------------------
void ReadReservedFn()
{
Uint16 i;
// Read and discard the 8 reserved words.
for(i = 1; i <= 8; i++)
{
GetWordData();
}
return;
}
// TI File $Revision: /main/5 $
// Checkin $Date: May 8, 2007 12:28:35 $
//###########################################################################
//FILE: SPI_Boot.c
//TITLE: 2833x SPI Boot mode routines
//Functions:
//Uint32 SPI_Boot(void)
// inline void SPIA_Init(void)
// Uint16 SPIA_SetAddress_KeyChk(void)
// inline void SPIA_Transmit(u16 cmdData)
// inline void SPIA_ReservedFn(void);
// Uint32 SPIA_GetWordData(void)
//Notes:
//
//###########################################################################
// $TI Release: 2833x/2823x Boot ROM V2 $
// $Release Date: March 4, 2008 $
//###########################################################################
#include "DSP2833x_Device.h"
//SPRU963A – September 2007 – Revised August 2008 Bootloader Code Overview 79
//Submit Documentation Feedback
//Bootloader Code Listing (V2.0) www.ti.com
#include "TMS320x2833x_Boot.h"
// Private functions
inline void SPIA_Init(void);
inline Uint16 SPIA_Transmit(Uint16 cmdData);
inline void SPIA_ReservedFn(void);
Uint16 SPIA_GetWordData(void);
Uint16 SPIA_SetAddress_KeyChk(void);
// External functions
extern void CopyData(void);
Uint32 GetLongData(void);
//#################################################
// Uint32 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.
//--------------------------------------------
Uint32 SPI_Boot()
{
Uint32 EntryAddr;
// Assign GetWordData to the SPI-A version of the
// function. GetWordData is a pointer to a function.
GetWordData = SPIA_GetWordData;
// 1. Init SPI-A and set
// EEPROM chip enable - low
SPIA_Init();
// 2. Enable EEPROM and send EEPROM Read Command
SPIA_Transmit(0x0300);
// 3. Send Starting Address for Serial EEPROM (16-bit - 0x0000,0000)
// or Serial Flash (24-bit - 0x0000,0000,0000)
// Then check for 0x08AA data header, else go to flash
if(SPIA_SetAddress_KeyChk() != 0x08AA)
return FLASH_ENTRY_POINT;
// 4.Check for Clock speed change and reserved words
SPIA_ReservedFn();
// 5. Get point of entry address after load
EntryAddr = GetLongData();
// 6. Receive and copy one or more code sections to destination addresses
CopyData();
// 7. Disable EEPROM chip enable - high
// Chip enable - high
GpioDataRegs.GPASET.bit.GPIO19 = 1;
return EntryAddr;
}
//#################################################
// Uint16 SPIA_SetAddress_KeyChk(void)
//-----------------------------------------------// This routine sends either a 16-bit address to
// Serial EEPROM or a 24-bit address to Serial
// FLASH. It then fetches the 2 bytes that make
// up the key value from the SPI-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 form MSB:LSB.
//-----------------------------------------------
Uint16 SPIA_SetAddress_KeyChk()
{
Uint16 keyValue;
// Transmit first byte of Serial Memory address
SPIA_Transmit(0x0000);
// Transmit second byte of Serial Memory address
SPIA_Transmit(0x0000);
// Transmit third byte of Serial Memory address (0x00) if using Serial Flash
// or receive first byte of key value if using Serial EEPROM.
keyValue = SPIA_Transmit(0x0000);
// If previously received LSB of key value (Serial EEPROM), then fetch MSB of key value
if (keyValue == 0x00AA)
{
keyValue |= (SPIA_Transmit(0x0000)<<8);
}
else
{
// Serial Flash is being used - keyValue will be received after 24-bit address in the next 2 bytes
// Fetch Key Value LSB (after 24-bit addressing)
keyValue = SPIA_Transmit(0x0000);
// Fetch Key Value MSB (after 24-bit addressing)
keyValue |= (SPIA_Transmit(0x0000)<<8);
}
return keyValue;
}
//#################################################
// void SPIA_Init(void)
//----------------------------------------------// Initialize the SPI-A port for communications
// with the host.
//----------------------------------------------
inline void SPIA_Init()
{
// Enable SPI-A clocks
EALLOW;
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;
SysCtrlRegs.LOSPCP.all = 0x0002;
// 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;
// Enable SPISIMO/SPISOMI/SPICLK pins
// Enable pull-ups on SPISIMO/SPISOMI/SPICLK/SPISTE pins
// GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;
// GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;
// GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;
// GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;
GpioCtrlRegs.GPAPUD.all &= 0xFFF0FFFF;
// GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1;
// GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1;
// GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1;
GpioCtrlRegs.GPAMUX2.all |= 0x00000015;
// SPI-A pins are asynch
// GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3;
// GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3;
// GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3;
GpioCtrlRegs.GPAQSEL2.all |= 0x0000003F;
// IOPORT as output pin instead of SPISTE
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO19 = 1;
// Chip enable - low
GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;
EDIS;
return;
}
//#################################################
// Uint16 SPIA_Transmit(Uint16 cmdData)
//------------------------------------------------
// Send a byte/words through SPI transmit channel
//------------------------------------------------
inline Uint16 SPIA_Transmit(Uint16 cmdData)
{
Uint16 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;
}
//#################################################
// 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()
{
Uint16 speedData;
Uint16 I;
// update LOSPCP register
speedData = SPIA_Transmit((Uint16)0x0000);
EALLOW;
SysCtrlRegs.LOSPCP.all = speedData;
EDIS;
asm(" RPT #0x0F ||NOP");
// update SPIBRR register
speedData = SPIA_Transmit((Uint16)0x0000);
SpiaRegs.SPIBRR = speedData;
asm(" RPT #0x0F ||NOP");
// Read and discard the next 7 reserved words.
for(I = 1; I <= 7; I++)
{
SPIA_GetWordData();
}
return;
}
//#################################################
// Uint16 SPIA_GetWordData(void)
//-----------------------------------------------
// This routine fetches two bytes from the SPI-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 form MSB:LSB.
//-----------------------------------------------
Uint16 SPIA_GetWordData()
{
Uint16 wordData;
// Fetch the LSB
wordData = SPIA_Transmit(0x0000);
// Fetch the MSB
wordData |= (SPIA_Transmit(0x0000) << 8);
return wordData;
}
// T