📄 serialize.c
字号:
/****** implementation File for support of STFL-I based Serial Flash Memory Driver *****
Filename: Serialize.c
Description: Support to c2076.c. This files is aimed at giving a basic
example of the SPI serial interface used to communicate with STMicroelectronics
serial Flash devices. The functions below are used in an environment where the
master has an embedded SPI port (STMicroelectronics 礟SD).
Version: 1.0
Date: 08-11-2004
Authors: Tan Zhi, STMicroelectronics, Shanghai (China)
Copyright (c) 2004 STMicroelectronics.
THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH
CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A
RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH
SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN
IN CONNECTION WITH THEIR PRODUCTS.
********************************************************************************
Version History.
Ver. Date Comments
1.0 08/11/2004 Initial release
*******************************************************************************/
#include "Serialize.h"
#include "includes.h"
#if 0
#define IO_PER_LOC_SPI1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x08)|0x08; } while (0)
//*****************************************************************************
// Macro for setting up an SPI connection. The macro configures the appropriate
// pins for peripheral operation, sets the baudrate if the chip is configured
// to be SPI master, and sets the desired clock polarity and phase. Whether to
// transfer MSB or LSB first is also determined. _spi_ indicates whether
// to use spi 0 or 1. _baudRate_ must be one of 2400, 4800, 9600, 14400, 19200,
// 28800, 38400, 57600, 76800, 115200, 153600, 230400 or 307200.
// Possible options are defined below.
#define SPI_SETUP(spi, baudRate, options) \
do { \
U##spi##UCR = 0x80; \
U##spi##CSR = 0x00; \
\
if(spi == 0){ \
if(PERCFG & 0x01){ \
P1SEL |= 0x3C; \
} else { \
P0SEL |= 0x3C; \
} \
} \
else { \
if(PERCFG & 0x02){ \
P1SEL |= 0xF0; \
} else { \
P0SEL |= 0x3C; \
} \
} \
\
if(options & SPI_SLAVE){ \
U##spi##CSR = 0x20; \
} \
else { \
U##spi##GCR = BAUD_E(baudRate, CLKSPD); \
U##spi##BAUD = BAUD_M(baudRate); \
} \
U##spi##GCR |= (options & 0xE0); \
} while(0)
// Options for the SPI_SETUP macro.
#define SPI_SLAVE 0x01
#define SPI_MASTER 0x00
#define SPI_CLOCK_POL_LO 0x00
#define SPI_CLOCK_POL_HI 0x80
#define SPI_CLOCK_PHA_0 0x00
#define SPI_CLOCK_PHA_1 0x40
#define SPI_TRANSFER_MSB_FIRST 0x20
#define SPI_TRANSFER_MSB_LAST 0x00
/*******************************************************************************
Function: InitSPIMaster(void)
Arguments:
Return Values:There is no return value for this function.
Description: This function is a one-time configuration for the CPU to set some
ports to work in SPI mode (when they have multiple functions. For
example, in some CPUs, the ports can be GPIO pins or SPI pins if
properly configured).
please refer to the specific CPU datasheet for proper
configurations.
*******************************************************************************/
void InitSPIMaster(void)
{
// Master Mode
IO_PER_LOC_SPI1_AT_PORT1_PIN4567();
PERCFG |= 0x02; // PERCFG.U1CFG = 1
P1SEL |= 0xE0; // P1_7, P1_6, and P1_5 are peripherals
P1SEL &= ~0x10; // P1_4 is GPIO (SSN)
P1DIR |= 0x10; // SSN is set as output
// Set baud rate to max (system clock frequency / 8)
// Assuming a 26 MHz crystal (CC1110Fx/CC2510Fx)
// max baud rate = 26 MHz / 8 = 3.25 MHz.
U1BAUD = 0x00; // BAUD_M = 0
U1GCR |= 0x11; // BAUD_E = 17
// SPI Master Mode
U1CSR &= ~0xA0;
// Configure phase, polarity, and bit order
U1GCR &= ~0xC0; // CPOL = CPHA = 0
U1GCR |= 0x20; // ORDER = 1
/**
P4SFS0 |= 0x70;
P4SFS1 |= 0x70; // Setup P4[4..6] Port as SPI
// P4.7 works in GPIO mode as the Slave Select signal
SPICON1=0x00; //bit3:TEIE=0. SPI transmission end interrupt disable
//bit2:RORIE=0. SPI receive overrun interrupt disable
//bit1:TIE=0. SPI transmission interrupt disable
//bit0:RIE=0 SPI reception interrupt disable
SPICLKD=0x2C; //select frequency divider=0x2C
SPICON0=0x72; //bit6:TE=1. SPI Transmitter enable
//bit5:RE=1. SPI Receiver enable
//bit4:SPIEN=1. SPI enable
//bit3:SSEL=0. SPI Slave select output is disabled,use P4.7 as the Select Slave signal
//bit2:FLSB=0. SPI Transfer the MSB first
//bit1:SPO=1. SPI Sample data on the rising edge of the clock
*/
}
/*******************************************************************************
Function: ConfigureSpiMaster(SpiMasterConfigOptions opt)
Arguments: opt configuration options, all acceptable values are enumerated in
SpiMasterConfigOptions, which is a typedefed enum.
Return Values:There is no return value for this function.
Description: This function can be used to properly configure the SPI master
before and after the transfer/receive operation
Pseudo Code:
Step 1 : perform or skip select/deselect slave
Step 2 : perform or skip enable/disable transfer
Step 3 : perform or skip enable/disable receive
*******************************************************************************/
#define CSS P1_3
#define SelectSlave() (CSS = 0)
#define DeSelectSlave() (CSS = 1)
void ConfigureSpiMaster(SpiMasterConfigOptions opt)
{
if(enumNull == opt) return;
if(opt & MaskBit_SelectSlave_Relevant) (opt & MaskBit_SlaveSelect)?SelectSlave():DeSelectSlave();
/* if(opt & MaskBit_Trans_Relevant) (opt & MaskBit_Trans) ? EnableTrans():DisableTrans();
if(opt & MaskBit_Recv_Relevant) (opt & MaskBit_Recv) ? EnableRcv():DisableRcv();
*/
}
/*******************************************************************************
Function: Serialize(const CharStream* char_stream_send,
CharStream* char_stream_recv,
SpiMasterConfigOptions optBefore,
SpiMasterConfigOptions optAfter
)
Arguments: char_stream_send, the char stream to be sent from the SPI master to
the Flash memory, usually contains instruction, address, and data to be
programmed.
char_stream_recv, the char stream to be received from the Flash memory
to the SPI master, usually contains data to be read from the memory.
optBefore, configurations of the SPI master before any transfer/receive
optAfter, configurations of the SPI after any transfer/receive
Return Values:TRUE
Description: This function can be used to encapsulate a complete transfer/receive
operation
Pseudo Code:
Step 1 : perform pre-transfer configuration
Step 2 : perform transfer/ receive
Step 2-1: transfer ...
(a typical process, it may vary with the specific CPU)
Step 2-1-1: check until the SPI master is available
Step 2-1-2: send the byte stream cycle after cycle. it usually involves:
a) checking until the transfer-data-register is ready
b) filling the register with a new byte
Step 2-2: receive ...
(a typical process, it may vary with the specific CPU)
Step 2-2-1: Execute ONE pre-read cycle to clear the receive-data-register.
Step 2-2-2: receive the byte stream cycle after cycle. it usually involves:
a) triggering a dummy cycle
b) checking until the transfer-data-register is ready(full)
c) reading the transfer-data-register
Step 3 : perform post-transfer configuration
*******************************************************************************/
/******************************************************************************
******************* Common USART functions/macros *******************
******************************************************************************/
// The macros in this section are available for both SPI and UART operation.
//*****************************************************************************
// Example usage:
// USART0_FLUSH();
#define USART_FLUSH(num) (U##num##UCR |= 0x80)
#define USART0_FLUSH() USART_FLUSH(0)
#define USART1_FLUSH() USART_FLUSH(1)
// Example usage:
// if (USART0_BUSY())
// ...
#define USART_BUSY(num) (U##num##CSR & 0x01 == 0x01)
#define USART0_BUSY() USART_BUSY(0)
#define USART1_BUSY() USART_BUSY(1)
// Example usage:
// while(!USART1_BYTE_RECEIVED())
// ...
#define USART_BYTE_RECEIVED(num) ((U##num##CSR & 0x04) == 0x04)
#define USART0_BYTE_RECEIVED() USART_BYTE_RECEIVED(0)
#define USART1_BYTE_RECEIVED() USART_BYTE_RECEIVED(1)
// Example usage:
// if(USART1_BYTE_TRANSMITTED())
// ...
#define USART_BYTE_TRANSMITTED(num) ((U##num##CSR & 0x02) == 0x02)
#define USART0_BYTE_TRANSMITTED() USART_BYTE_TRANSMITTED(0)
#define USART1_BYTE_TRANSMITTED() USART_BYTE_TRANSMITTED(1)
#define SSN P1_4
Bool Serialize(const CharStream* char_stream_send,
CharStream* char_stream_recv,
SpiMasterConfigOptions optBefore,
SpiMasterConfigOptions optAfter
)
{
ST_uint32 i;
ST_uint32 length;
unsigned char dummyByte = 0;
unsigned char* pChar;
// Step 1 : perform pre-transfer configuration
ConfigureSpiMaster(optBefore);
CSS = 0;
// Step 2 : perform transfer / receive
// Step 2-1: transfer ...
length = char_stream_send->length;
pChar = char_stream_send->pChar;
// 2-1-1 Wait until SPI is available
while(USART1_BUSY()); //while (SPISTAT & SPI_FLAG_BUSY);
// 2-1-2 send the byte stream cycle after cycle
SSN = LOW;
for (i =0; i <=length; i++)
{
U1DBUF = *(pChar++);;
while (U1ACTIVE);
}
SSN = HIGH;
// Step 2-2: receive ...
// Step 2-2-1: execute ONE pre-read cycle to clear the receive-data-register.
i=U1DBUF; // i = SPIRDR;
// Step 2-2-2: send the byte stream cycle after cycle.
if(ptrNull != (int)char_stream_recv) // skip if no reception needed
{
length = char_stream_recv->length;
pChar = char_stream_recv->pChar;
SSN = LOW;
for (i = 0; i <= length; i++)
{
U1DBUF = dummyByte; // U1ACTIVE is asserted
while (!U1TX_BYTE); // Wait for U1ACTIVE to be de-asserted (U1DBUF can be read)
*(pChar++) = U1DBUF;
}
SSN = HIGH;
}
// Step 3 : perform post-transfer configuration
ConfigureSpiMaster(optAfter);
CSS = 1;
return TRUE;
}
#endif
#define USE_M25P20 //如果型号改变请修改此值
/* Possible Values: USE_M25P40 USE_M25P80 USE_M25P16 USE_M25P32 */
#define COUNT_FOR_WRITE_DELAY (0x5FFFFL) //根据不同的硬件来调整
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -