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

415 lines
7.9 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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