Files
ls1x-master-v0.4/public/ls1x_spi.c
2024-11-27 15:39:05 +08:00

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;
}