415 lines
7.9 KiB
C
415 lines
7.9 KiB
C
#include "ls1x_spi.h"
|
||
#include "ls1x.h"
|
||
#include "Config.h"
|
||
|
||
/*** SPI READ OPTIONS ***/
|
||
#define NORMAL 0x0
|
||
#define FAST 0x1
|
||
#define DUAL_IO 0x2
|
||
|
||
/**
|
||
* @Description: SPI 分频系数配置 分别配置到控制寄存器、外部寄存器、参数控制寄存器
|
||
* @Input: 分频系数
|
||
* @Output: 无
|
||
* @return {*}无
|
||
* @param {uint8_t} spr 分频系数
|
||
*/
|
||
void Spi_FreqDiv(uint8_t spr)
|
||
{
|
||
|
||
SPI->SPCR &=0xFC;
|
||
SPI->SPER &=0xFC;
|
||
|
||
SPI->SPCR |=(spr & 0x03);
|
||
SPI->SPER |=((spr>>2) & 0x03);
|
||
|
||
SPI->PARAM &= 0x02;
|
||
SPI->PARAM |=((spr<<4) & 0xF0);
|
||
printf("\r\n0 SPI->PARAM:%x H \r\n",SPI->PARAM);
|
||
}
|
||
/**
|
||
* @Description: spi init
|
||
* @Input: spi 分频系数
|
||
* SPI_DIV_2 SPI_DIV_4 SPI_DIV_16 SPI_DIV_32 SPI_DIV_8 SPI_DIV_64 SPI_DIV_128
|
||
* SPI_DIV_256 SPI_DIV_512 SPI_DIV_1024 SPI_DIV_2048 SPI_DIV_4096
|
||
* @Output: 无
|
||
* @return {*}
|
||
* @param {uint8_t} spr 分频系数 固定为以上的宏定义
|
||
*/
|
||
void Spi_Init(uint8_t spr)
|
||
{
|
||
SPI->SPCR = 0x50; // {int_en, spi, rsvd, mstr, cpol, cpha, spr[1:0]}
|
||
SPI->SPER = 0;
|
||
while(!SPI_TXEMPTY) ; // wait till tx empty
|
||
while(!SPI_RXEMPTY) SPI->DATA; // read till rx empty
|
||
}
|
||
|
||
/**
|
||
* @Description: spi 读、写 1~4字节
|
||
* @Input: 数据缓冲,读、写数量
|
||
* @Output: 无
|
||
* @return {*}
|
||
* @param {uint8_t*} buf 数据缓冲
|
||
* @param {int} n 读写数据字节数
|
||
*/
|
||
void Spi_Write_Read_1to4(uint8_t* buf, int n)
|
||
{
|
||
|
||
uint32_t i;
|
||
for (i=0; i<n; i++) SPI->DATA = buf[i];
|
||
while(!SPI_TXEMPTY) ;
|
||
for (i=0; i<n-1; i++) buf[i] = SPI->DATA;
|
||
while(SPI_RXEMPTY) ;
|
||
buf[n-1] = SPI->DATA;
|
||
}
|
||
|
||
/**
|
||
* @Description: spi 读 写 N字节
|
||
* @Input: 数据缓冲,读写字节数
|
||
* @Output: 无
|
||
* @return {*}
|
||
* @param {uint8_t*} buf 数据缓冲
|
||
* @param {int} n 读写字节数
|
||
*/
|
||
void Spi_Write_Read_N(uint8_t* buf, int n)
|
||
{
|
||
uint32_t i, j;
|
||
for (i=0; i<4; i++) SPI->DATA = buf[i];
|
||
for (j=0; i<n; i++, j++)
|
||
{
|
||
while(SPI_RXEMPTY) ;
|
||
buf[j] = SPI->DATA;
|
||
SPI->DATA = buf[i];
|
||
}
|
||
for (; j<n; j++)
|
||
{
|
||
while(SPI_RXEMPTY) ;
|
||
buf[j] = SPI->DATA;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @Description: SPI 片选信号0 使能并拉低
|
||
* @Input: 无
|
||
* @Output: 无
|
||
* @return {*}
|
||
*/
|
||
void Spi_Cs_Down(void)
|
||
{
|
||
// SPI->SOFTCS = 0xef;
|
||
|
||
SPI_ENABLE_CS(0);
|
||
SPI_LOW_CS(0);
|
||
}
|
||
/**
|
||
* @Description: SPI 片选信号0 使能并拉高
|
||
* @Input: 无
|
||
* @Output: 无
|
||
* @return {*}
|
||
*/
|
||
void Spi_Cs_Up(void)
|
||
{
|
||
// SPI->SOFTCS = 0xff;
|
||
|
||
SPI_ENABLE_CS(0);
|
||
SPI_HIGH_CS(0);
|
||
}
|
||
|
||
/**
|
||
* @Description: SPI 发送数据
|
||
* @Input: 数据缓冲;数据数量
|
||
* @Output: 无
|
||
* @return {*}
|
||
* @param {uint8_t*} buf 数据缓冲
|
||
* @param {int} n 数据量
|
||
*/
|
||
void Spi_Send(uint8_t* buf, int n)
|
||
{
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, n);
|
||
Spi_Cs_Up();
|
||
}
|
||
|
||
/**
|
||
* @Description:
|
||
* @Input:
|
||
* @Output:
|
||
* @return {*}
|
||
*/
|
||
uint8_t Spiflash_Rdsr(void)
|
||
{
|
||
uint8_t buf[4] = {0x05};
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 2);
|
||
Spi_Cs_Up();
|
||
return buf[1];
|
||
}
|
||
|
||
/**
|
||
* @Description: 等待置0
|
||
* @Input: 无
|
||
* @Output:无
|
||
* @return {*}
|
||
*/
|
||
void Spiflash_Wait_Wip_Zero(void)
|
||
{
|
||
while (Spiflash_Rdsr() & 0x01) {}
|
||
}
|
||
|
||
/**
|
||
* @Description: spi flash 写
|
||
* @Input:
|
||
* @Output:
|
||
* @return {*}
|
||
*/
|
||
void Spiflash_Wren(void)
|
||
{
|
||
uint8_t buf[4] = {0x06};
|
||
|
||
Spiflash_Wait_Wip_Zero();
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 1);
|
||
Spi_Cs_Up();
|
||
}
|
||
|
||
/**
|
||
* @Description: spi flash 写寄存器
|
||
* @Input: 状态
|
||
* @Output: 无
|
||
* @return {*}
|
||
* @param {uint8_t} st 状态
|
||
*/
|
||
void Spiflash_Wrsr(uint8_t st)
|
||
{
|
||
uint8_t buf[4] = {0x01};
|
||
|
||
Spiflash_Wren();
|
||
buf[1] = st;
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 2);
|
||
Spi_Cs_Up();
|
||
}
|
||
|
||
/**
|
||
* @Description: spi flash 读寄存器2
|
||
* @Input: 无
|
||
* @Output: 返回寄存器读取数据
|
||
* @return {*}
|
||
*/
|
||
uint8_t Spiflash_Rdsr2(void)
|
||
{
|
||
uint8_t buf[4] = {0x35};
|
||
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 2);
|
||
Spi_Cs_Up();
|
||
|
||
return buf[1];
|
||
}
|
||
|
||
/**
|
||
* @Description: spi flash 读寄存器3
|
||
* @Input: 无
|
||
* @Output: 返回读取的值
|
||
* @return {*}
|
||
*/
|
||
uint8_t Spiflash_Rdsr3(void)
|
||
{
|
||
uint8_t buf[4] = {0x15};
|
||
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 2);
|
||
Spi_Cs_Up();
|
||
|
||
return buf[1];
|
||
}
|
||
|
||
/**
|
||
* @Description: SPI flash 读 ID
|
||
* @Input: 无
|
||
* @Output: 返回id
|
||
* @return {*}
|
||
*/
|
||
uint16_t Spiflash_Rdid(void)
|
||
{
|
||
uint8_t buf[4] = {0x90, 0, 0, 0};
|
||
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 4);//trans
|
||
Spi_Write_Read_1to4(buf, 2);//recv
|
||
Spi_Cs_Up();
|
||
|
||
return *((uint16_t*)buf);
|
||
}
|
||
|
||
/**
|
||
* @Description: SPI flash 扇区擦除
|
||
* @Input:
|
||
* @Output:
|
||
* @return {*}
|
||
* @param {uint32_t} addr
|
||
*/
|
||
void Spiflash_Sector_Erase(uint32_t addr)
|
||
{
|
||
uint8_t buf[4] = {0x20};
|
||
|
||
buf[3] = addr & 0xff; addr >>= 8;
|
||
buf[2] = addr & 0xff; addr >>= 8;
|
||
buf[1] = addr & 0xff;
|
||
|
||
Spiflash_Wren();
|
||
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 4);
|
||
Spi_Cs_Up();
|
||
Spiflash_Wait_Wip_Zero();
|
||
}
|
||
|
||
|
||
/**
|
||
* @Description: SPI flash 64k 块擦除
|
||
* @Input: 地址
|
||
* @Output: 无
|
||
* @return {*}
|
||
* @param {uint32_t} addr
|
||
*/
|
||
void Spiflash_Block64k_Erase(uint32_t addr)
|
||
{
|
||
uint8_t buf[4] = {0xd8};
|
||
|
||
buf[3] = addr & 0xff; addr >>= 8;
|
||
buf[2] = addr & 0xff; addr >>= 8;
|
||
buf[1] = addr & 0xff;
|
||
|
||
Spiflash_Wren();
|
||
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 4);
|
||
Spi_Cs_Up();
|
||
Spiflash_Wait_Wip_Zero();
|
||
}
|
||
|
||
/**
|
||
* @Description: SPI flash 页编程
|
||
* @Input: 页地址;数据;
|
||
* @Output: 无
|
||
* @return {*}
|
||
* @param {uint32_t} addr 页地址
|
||
* @param {uint8_t*} data_256 数据缓冲指针
|
||
*/
|
||
void Spiflash_Page_Program(uint32_t addr, uint8_t* data_256,int n)
|
||
{
|
||
uint8_t buf[4] = {0x02};
|
||
|
||
buf[3] = addr & 0xff; addr >>= 8;
|
||
buf[2] = addr & 0xff; addr >>= 8;
|
||
buf[1] = addr & 0xff;
|
||
|
||
Spiflash_Wren();
|
||
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 4);
|
||
Spi_Write_Read_N(data_256, n);
|
||
Spi_Cs_Up();
|
||
Spiflash_Wait_Wip_Zero();
|
||
}
|
||
|
||
/**
|
||
* @Description: spi flash 读数据
|
||
* @Input: 地址;数据缓冲;数据量;
|
||
* @Output: 无
|
||
* @return {*}
|
||
* @param {uint32_t} addr
|
||
* @param {uint8_t*} data
|
||
* @param {int} n
|
||
*/
|
||
void Spiflash_Read_Bytes(uint32_t addr, uint8_t* data, int n)
|
||
{
|
||
uint8_t buf[4] = {0x03};
|
||
|
||
buf[3] = addr & 0xff; addr >>= 8;
|
||
buf[2] = addr & 0xff; addr >>= 8;
|
||
buf[1] = addr & 0xff;
|
||
|
||
Spi_Cs_Down();
|
||
Spi_Write_Read_1to4(buf, 4);
|
||
Spi_Write_Read_N(data, n);
|
||
Spi_Cs_Up();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/******************************************************************************
|
||
* 函数名: SpiTransByte
|
||
* 功能: 通过SPI接口传输一个字节
|
||
* 输入参数:
|
||
* byte:写入字节
|
||
* 返回值:
|
||
* none
|
||
* 备注:无
|
||
******************************************************************************/
|
||
uint8_t SPI_TransByte(uint8_t byte)
|
||
{
|
||
uint8_t ucResult=0;
|
||
uint8_t retry=0;
|
||
/*清除中断和溢出标志位*/
|
||
SPI->SPSR = 0xc0;
|
||
|
||
//判断写寄存器是否为空
|
||
while(!(SPI->SPSR & 0x04))
|
||
{
|
||
retry++;
|
||
if(retry > 200){
|
||
printf("spi no data send\r\n");
|
||
return 0;
|
||
}
|
||
}
|
||
retry = 0;
|
||
SPI->DATA = byte;
|
||
while(SPI->SPSR & 0x01)
|
||
{
|
||
retry++;
|
||
if(retry > 200){
|
||
printf("spi no data receive\r\n");
|
||
return 0;
|
||
}
|
||
}
|
||
ucResult = SPI->DATA;
|
||
|
||
|
||
return ucResult;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* 函数名: SpiFlashCsn0Enable
|
||
* 功能: spi flash csn0 使能
|
||
* 输入参数:
|
||
* none
|
||
* 返回值:
|
||
* none
|
||
* 备注:无
|
||
******************************************************************************/
|
||
void SpiFlashCsn0Enable()
|
||
{
|
||
/*使能片选信号CSN0*/
|
||
SPI->SOFTCS = 0xE1;//E1
|
||
}
|
||
|
||
/******************************************************************************
|
||
* 函数名: SpiFlashCsn0Disable
|
||
* 功能: spi flash csn0 不使能
|
||
* 输入参数:
|
||
* none
|
||
* 返回值:
|
||
* none
|
||
* 备注:无
|
||
******************************************************************************/
|
||
void SpiFlashCsn0Disable()
|
||
{
|
||
/*使能片选信号CSN0*/
|
||
SPI->SOFTCS = 0xF1;
|
||
}
|