"); //-->
广州创龙电子基于TMS320C6748开发的SPI_FLAH程序,此程序的作用是实现SPI FLASH设备的数据读写功能,此设备挂载在SPI1总线,按照工程导入步骤加载SPI_FLASH.out文件,将开发板的UART2和PC机连接,打开ZOC串口调试软件,设置好波特率为115200,数据位8位,停止位1位,检验位无,流控制无,然后点击程序运行按钮。
演示现象
(1) ZOC串口调试终端会打印出信息:
此程序先提示是否擦除SPI FLASH,输入y擦除SPI FLASH上的数据,然后对比写入和读出的数据,根据结果判断SPI FLASH设备读写是否成功。
代码解析:
/*******************************************/
/* */
/* 核心板及底板SPI FLASH读写 测试 */
/* */
/* 2014年5月19日 */
/* */
/*******************************************/
#include "main.h"
#include <string.h>
#include "soc_C6748.h"
#include "hw_psc_C6748.h"
#include "evmC6748.h"
#include "uart.h"
#include "spi.h"
#include "psc.h"
#include "interrupt.h"
#include "uartStdio.h"
/**************************************
** 宏定义
**************************************/
/* value to configure SMIO,SOMI,CLK and CS pin as functional pin */
#define SIMO_SOMI_CLK_CS 0x00000E01
#define CHAR_LENGTH 0x8
/* flash address where data will be written and read */
#define SPI_FLASH_ADDR_MSB1 0x0A
#define SPI_FLASH_ADDR_MSB0 0x00
#define SPI_FLASH_ADDR_LSB 0x00
/* sector erase command */
#define SPI_FLASH_SECTOR_ERASE 0xD8
/* page program command */
#define SPI_FLASH_PAGE_WRITE 0x02
/* status register read command */
#define SPI_FLASH_STATUS_RX 0x05
/* write enable command */
#define SPI_FLASH_WRITE_EN 0x06
/* flash data read command */
#define SPI_FLASH_READ 0x03
/* flash data read */
#define WRITE_IN_PROGRESS 0x01
/********************************************
** 函数原型声明
********************************************/
static void SPIConfigDataFmtReg(unsigned int dataFormat);
static void ReadFromFlash(void);
static void IsFlashBusy(void);
static void WritetoFlash(void);
static void WriteEnable(void);
static void SpiTransfer(void);
static void SectorErase(void);
static int VerifyData(void);
static void StatusGet(void);
static void SetUpInt(void);
static void SetUpSPI(void);
void SPIIsr(void);
/**********************************************
** 变量定义
**********************************************/
volatile unsigned int flag = 1;
unsigned int tx_len;
unsigned int rx_len;
unsigned char vrf_data[260];
unsigned char tx_data[260];
unsigned char rx_data[260];
unsigned char *p_tx;
unsigned char *p_rx;
/*****************************************
** 函数定义
*****************************************/
int main(void)
{
int result = 0;
char choice ;
/* Waking up the SPI1 instance. */
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_SPI1, PSC_POWERDOMAIN_ALWAYS_ON,
PSC_MDCTL_NEXT_ENABLE);
/* Initializing the UART instance for serial communication. */
UARTStdioInit();
/* Setting the UART Receiver Trigger Level*/
UARTFIFOLevelSet(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1);
UARTPuts("\r\n ============Test Start===========.\r\n", -1);
UARTPuts("Welcome to StarterWare SPI FLASH application.\r\n\r\n", -1);
UARTPuts("Here the SPI controller on the SoC communicates with", -1);
UARTPuts(" the SPI Flash present on the SoM.\r\n\r\n", -1);
/* Performing the Pin Multiplexing for SPI1. */
SPIPinMuxSetup(1);
/*
** Using the Chip Select(CS) 0 pin of SPI1 to communicate with SPI Flash.
** AM1808 EVM mandates us to do so.
*/
SPI1CSPinMuxSetup(0);
/* Enable use of SPI1 interrupts. */
SetUpInt();
/* Configuring and enabling the SPI1 instance. */
SetUpSPI();
/* Preparing the Flash for a Write. */
WriteEnable();
UARTPuts("Do you want to erase a sector of the flash before writing to it ?.", -1);
UARTPuts("\r\nInput y(Y)/n(N) to proceed.\r\n", -1);
choice = UARTGetc();
UARTPutc(choice);
if(('y' == choice) || ('Y' == choice))
{
/* Erasing a Sector of the Flash. */
SectorErase();
}
WriteEnable();
/* Programming the necessary data to Flash. */
WritetoFlash();
/* Reading from the required location from Flash. */
ReadFromFlash();
/* Comparing the written and read data. */
result = VerifyData();
UARTPuts("\r\n ============Test End===========.\r\n", -1);
while(1);
}
/*
** Reads the status register of m25p80 flash
**
*/
static void StatusGet(void)
{
tx_data[0] = SPI_FLASH_STATUS_RX;
tx_len = rx_len = 2;
SPIDat1Config(SOC_SPI_1_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), 0x1);
SpiTransfer();
}
/*
** Enables write to m25p80 flash
**
*/
static void WriteEnable(void)
{
tx_data[0] = SPI_FLASH_WRITE_EN;
tx_len = rx_len = 1;
SPIDat1Config(SOC_SPI_1_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), 0x1);
SpiTransfer();
}
/*
** It polls for write in progress bit(wip)in status register of m25p80 flash
**
*/
static void IsFlashBusy(void)
{
do{
StatusGet();
}while(rx_data[1] & WRITE_IN_PROGRESS);
}
/*
** Set the all bits to 1 in chosen sector
**
*/
static void SectorErase(void)
{
tx_data[0] = SPI_FLASH_SECTOR_ERASE;
tx_data[1] = SPI_FLASH_ADDR_MSB1;
tx_data[2] = SPI_FLASH_ADDR_MSB0;
tx_data[3] = SPI_FLASH_ADDR_LSB;
tx_len = rx_len = 4;
SPIDat1Config(SOC_SPI_1_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), 0x1);
SpiTransfer();
IsFlashBusy();
}
/*
** Writes 256 bytes of data to desired memory address
**
*/
static void WritetoFlash(void)
{
unsigned int index;
tx_data[0] = SPI_FLASH_PAGE_WRITE;
tx_data[1] = SPI_FLASH_ADDR_MSB1;
tx_data[2] = SPI_FLASH_ADDR_MSB0;
tx_data[3] = SPI_FLASH_ADDR_LSB;
/* Populate the data to be written to the flash */
for (index = 4; index < 260; index++)
{
tx_data[index] = index;
}
for(index = 4; index < 260; index++)
{
vrf_data[index] = index;
}
tx_len = rx_len = index;
SPIDat1Config(SOC_SPI_1_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), 0x1);
SpiTransfer();
IsFlashBusy();
}
/*
** Reads the data from addressed memory of flash
**
*/
static void ReadFromFlash(void)
{
unsigned int index;
tx_data[0] = SPI_FLASH_READ;
tx_data[1] = SPI_FLASH_ADDR_MSB1;
tx_data[2] = SPI_FLASH_ADDR_MSB0;
tx_data[3] = SPI_FLASH_ADDR_LSB;
/* Reset the data in the tx buffer */
for (index = 4; index < 260; index++)
{
tx_data[index] = 0;
}
tx_len = rx_len = index;
SPIDat1Config(SOC_SPI_1_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), 0x1);
SpiTransfer();
}
/*
** Verfies the data written to flash and read from the flash of same address
**
*/
/*******************************************/
/* */
/* 校验写入到SPI FLASH中的数据与相同地址读出的是否一致 */
/* */
/* 返回值 = 1: 一致 */
/* = 0: 不一致 */
/* */
/*******************************************/
static int VerifyData(void)
{
unsigned int index;
for(index = 4; index < 260; index++)
{
if(vrf_data[index] != rx_data[index])
{
UARTPuts("\r\n", -1);
UARTPuts("VerifyData: Comparing the data written to and read", -1);
UARTPuts(" from Flash.\r\nThe two data blocks are unequal.", -1);
UARTPuts(" Mismatch found at index ", -1);
UARTPutNum((int)index - 3);
UARTPuts("\r\n", -1);
UARTPuts("Verify Failed.\r\n", -1);
return 0;
}
}
if (index == 260)
{
UARTPuts("\r\nThe data in the Flash and the one written ", -1);
UARTPuts("to it are equal.\r\n", -1);
UARTPuts("Verify successfully.\r\n", -1);
return 1;
}
}
/*******************************************/
/* */
/* 配置DSP中断控制器 产生SPI中断 */
/* */
/*******************************************/
static void SetUpInt(void)
{
// Initialize the DSP interrupt controller
IntDSPINTCInit();
// Register the ISR in the vector table
IntRegister(C674X_MASK_INT4, SPIIsr);
// Map system interrupt to the DSP maskable interrupt
IntEventMap(C674X_MASK_INT4, SYS_INT_SPI1_INT);
// Enable the DSP maskable interrupt
IntEnable(C674X_MASK_INT4);
// Enable DSP interrupts globally
IntGlobalEnable();
}
/*******************************************/
/* */
/* 配置SPI控制器 */
/* */
/*******************************************/
static void SetUpSPI(void)
{
unsigned char cs = 0x01;
unsigned char dcs = 0x01;
unsigned int val = SIMO_SOMI_CLK_CS;
SPIReset(SOC_SPI_1_REGS);
SPIOutOfReset(SOC_SPI_1_REGS);
SPIModeConfigure(SOC_SPI_1_REGS, SPI_MASTER_MODE);
SPIClkConfigure(SOC_SPI_1_REGS, 150000000, 20000000, SPI_DATA_FORMAT0);
SPIPinControl(SOC_SPI_1_REGS, 0, 0, &val);
SPIDefaultCSSet(SOC_SPI_1_REGS, dcs);
/* Configures SPI Data Format Register */
SPIConfigDataFmtReg(SPI_DATA_FORMAT0);
/* Selects the SPI Data format register to used and Sets CSHOLD
* to assert CS pin(line)
*/
SPIDat1Config(SOC_SPI_1_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), cs);
/* map interrupts to interrupt line INT1 */
SPIIntLevelSet(SOC_SPI_1_REGS, SPI_RECV_INTLVL | SPI_TRANSMIT_INTLVL);
/* Enable SPI communication */
SPIEnable(SOC_SPI_1_REGS);
}
/*******************************************/
/* */
/* 配置SPI数据格式寄存器 */
/* */
/*******************************************/
static void SPIConfigDataFmtReg(unsigned int dataFormat)
{
/* Configures the polarity and phase of SPI clock */
SPIConfigClkFormat(SOC_SPI_1_REGS,
(SPI_CLK_POL_HIGH | SPI_CLK_INPHASE),
dataFormat);
/* Configures SPI to transmit MSB bit First during data transfer */
SPIShiftMsbFirst(SOC_SPI_1_REGS, dataFormat);
/* Sets the Charcter length */
SPICharLengthSet(SOC_SPI_1_REGS, CHAR_LENGTH, dataFormat);
}
/****************************************/
/* */
/* 使能 SPI发送和接收中断 */
/* */
/****************************************/
static void SpiTransfer(void)
{
p_tx = &tx_data[0];
p_rx = &rx_data[0];
SPIIntEnable(SOC_SPI_1_REGS, (SPI_RECV_INT | SPI_TRANSMIT_INT));
while(flag);
flag = 1;
/* Deasserts the CS pin(line) */
SPIDat1Config(SOC_SPI_1_REGS, SPI_DATA_FORMAT0, 0x1);
}
/*******************************************/
/* */
/* SPI中断处理函数 */
/* */
/*******************************************/
void SPIIsr(void)
{
unsigned int intCode = 0;
IntEventClear(SYS_INT_SPI1_INT);
intCode = SPIInterruptVectorGet(SOC_SPI_1_REGS);
while (intCode)
{
if(intCode == SPI_TX_BUF_EMPTY)
{
tx_len--;
SPITransmitData1(SOC_SPI_1_REGS, *p_tx);
p_tx++;
if (!tx_len)
{
SPIIntDisable(SOC_SPI_1_REGS, SPI_TRANSMIT_INT);
}
}
if(intCode == SPI_RECV_FULL)
{
rx_len--;
*p_rx = (char)SPIDataReceive(SOC_SPI_1_REGS);
p_rx++;
if (!rx_len)
{
flag = 0;
SPIIntDisable(SOC_SPI_1_REGS, SPI_RECV_INT);
}
}
intCode = SPIInterruptVectorGet(SOC_SPI_1_REGS);
}
}
/******* End of file **************/
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。