UP 路径优化
This commit is contained in:
120
lib/spi/inc/spi.h
Normal file
120
lib/spi/inc/spi.h
Normal file
@@ -0,0 +1,120 @@
|
||||
#ifndef SW_LIB_SPI_H
|
||||
#define SW_LIB_SPI_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
#define HIGH 1
|
||||
#define LOW 0
|
||||
#define NOP() 0
|
||||
#define DELAY1US() NOP()
|
||||
|
||||
|
||||
/**
|
||||
* @brief SPI通信模式枚举
|
||||
**/
|
||||
typedef enum {
|
||||
Mode0, // 时钟空闲状态为低电平,数据在时钟的下降沿采样
|
||||
Mode1, // 时钟空闲状态为低电平,数据在时钟的上升沿采样
|
||||
Mode2, // 时钟空闲状态为高电平,数据在时钟的下降沿采样
|
||||
Mode3 // 时钟空闲状态为高电平,数据在时钟的上升沿采样
|
||||
} mode;
|
||||
|
||||
/**
|
||||
* @brief 数据端序枚举
|
||||
**/
|
||||
typedef enum {
|
||||
LTL, // 小端模式,低字节在低地址
|
||||
LTB, // 小端模式,低字节在高地址
|
||||
BTB, // 大端模式,低字节在低地址
|
||||
BTL // 大端模式,低字节在高地址
|
||||
} endian;
|
||||
/**
|
||||
* @brief SPI设备结构体
|
||||
**/
|
||||
typedef struct {
|
||||
uint8_t (*MOSI_SET)(uint8_t); // 设置MOSI引脚状态的函数指针
|
||||
uint8_t (*SCK_SET)(uint8_t); // 设置SCK引脚状态的函数指针
|
||||
uint8_t (*CS_SET)(uint8_t); // 设置CS引脚状态的函数指针
|
||||
uint8_t (*MISO)(); // 读取MISO引脚状态的函数指针
|
||||
mode MODE; // SPI模式
|
||||
uint8_t CS; // CS引脚编号
|
||||
endian ENDIAN; // 数据端序
|
||||
} SW_Dev_Spi;
|
||||
|
||||
/**
|
||||
* @brief 向 SPI 设备写入一个字节并读取返回的数据
|
||||
* @param Dev: [输入] SPI 设备
|
||||
* @param Write_Date: [输入]要写入的数据
|
||||
* @return 读取到的数据
|
||||
**/
|
||||
uint8_t SW_SPI_RW(SW_Dev_Spi Dev, uint8_t Write_Date);
|
||||
|
||||
/**
|
||||
* @brief 向 SPI 设备写入数据流
|
||||
* @param Dev: [输入] SPI 设备
|
||||
* @param Write_Date: [输入]要写入的数据流指针
|
||||
* @param Len: [输入] 数据流长度
|
||||
* @return void
|
||||
**/
|
||||
void SW_SPI_WL(SW_Dev_Spi Dev, uint8_t *Write_Date, uint32_t Len);
|
||||
|
||||
/**
|
||||
* @brief 从 SPI 设备读取数据流
|
||||
* @param Dev: [输入] SPI 设备
|
||||
* @param Read_Date: [输出]存储读取数据的缓冲区指针
|
||||
* @param Len: [输入] 读取数据流长度
|
||||
* @return void
|
||||
**/
|
||||
void SW_SPI_RL(SW_Dev_Spi Dev, uint8_t *Read_Date, uint32_t Len);
|
||||
|
||||
/**
|
||||
* @brief 向 SPI 设备写入数据并读取返回数据流
|
||||
* @param Dev: [输入] SPI 设备
|
||||
* @param Read_Date: [输出]存储读取数据的缓冲区指针
|
||||
* @param Write_Date: [输入]要写入的数据流指针
|
||||
* @param Len: [输入] 数据流长度
|
||||
* @return void
|
||||
**/
|
||||
void SW_SPI_RWL(SW_Dev_Spi Dev, uint8_t *Read_Date, uint8_t *Write_Date, uint32_t Len);
|
||||
|
||||
/**
|
||||
* @brief 向 SPI 设备写入一个字(16位)并读取返回的数据
|
||||
* @param Dev: [输入] SPI 设备
|
||||
* @param Write_Date: [输入]要写入的数据
|
||||
* @return 读取到的数据
|
||||
**/
|
||||
uint16_t SW_SPI_RW16(SW_Dev_Spi Dev, uint16_t Write_Date);
|
||||
|
||||
/**
|
||||
* @brief 从 SPI 设备读取数据流(16位)
|
||||
* @param Dev: [输入] SPI 设备
|
||||
* @param Read_Date: [输出]存储读取数据的缓冲区指针
|
||||
* @param Len: [输入] 读取数据流长度
|
||||
* @return void
|
||||
**/
|
||||
void SW_SPI_RL16(SW_Dev_Spi Dev, uint16_t *Read_Date, uint32_t Len);
|
||||
|
||||
/**
|
||||
* @brief 向 SPI 设备写入数据流(16位)
|
||||
* @param Dev: [输入] SPI 设备
|
||||
* @param Write_Date: [输入]要写入的数据流指针
|
||||
* @param Len: [输入] 数据流长度
|
||||
* @return void
|
||||
**/
|
||||
void SW_SPI_WL16(SW_Dev_Spi Dev, uint16_t *Write_Date, uint32_t Len);
|
||||
|
||||
/**
|
||||
* @brief 向 SPI 设备写入数据并读取返回数据流(16位)
|
||||
* @param Dev: [输入] SPI 设备
|
||||
* @param Read_Date: [输出]存储读取数据的缓冲区指针
|
||||
* @param Write_Date: [输入]要写入的数据流指针
|
||||
* @param Len: [输入] 数据流长度
|
||||
* @return void
|
||||
**/
|
||||
void SW_SPI_RWL16(SW_Dev_Spi Dev, uint16_t *Read_Date, uint16_t *Write_Date, uint32_t Len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //SW_LIB_SPI_H
|
224
lib/spi/spi.cpp
Normal file
224
lib/spi/spi.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "spi.h"
|
||||
#include "tool.h"
|
||||
|
||||
#define CS_ENABLE() Dev.CS ? Dev.CS_SET(HIGH) : Dev.CS_SET(LOW)
|
||||
#define CS_DISABLE() Dev.CS ? Dev.CS_SET(LOW) : Dev.CS_SET(HIGH)
|
||||
|
||||
static inline uint8_t spi_RW(SW_Dev_Spi Dev, uint8_t Write_Date) {
|
||||
uint8_t i, read_date = 0;
|
||||
switch (Dev.MODE) {
|
||||
case Mode0:
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (Write_Date & 0x80)
|
||||
Dev.MOSI_SET(HIGH);
|
||||
else
|
||||
Dev.MOSI_SET(LOW);
|
||||
Write_Date <<= 1;DELAY1US();
|
||||
Dev.SCK_SET(HIGH);
|
||||
read_date <<= 1;
|
||||
if (Dev.MISO())
|
||||
read_date++;DELAY1US();
|
||||
Dev.SCK_SET(LOW);NOP();
|
||||
}
|
||||
break;
|
||||
case Mode1:
|
||||
for (i = 0; i < 8; i++) {
|
||||
Dev.SCK_SET(HIGH);
|
||||
if (Write_Date & 0x80)
|
||||
Dev.MOSI_SET(HIGH);
|
||||
else
|
||||
Dev.MOSI_SET(LOW);
|
||||
Write_Date <<= 1;DELAY1US();
|
||||
Dev.SCK_SET(LOW);
|
||||
read_date <<= 1;
|
||||
if (Dev.MISO())
|
||||
read_date++;DELAY1US();
|
||||
}
|
||||
break;
|
||||
case Mode2:
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (Write_Date & 0x80)
|
||||
Dev.MOSI_SET(HIGH);
|
||||
else
|
||||
Dev.MOSI_SET(LOW);
|
||||
Write_Date <<= 1;DELAY1US();
|
||||
Dev.SCK_SET(LOW);
|
||||
read_date <<= 1;
|
||||
if (Dev.MISO())
|
||||
read_date++;DELAY1US();
|
||||
Dev.SCK_SET(HIGH);
|
||||
}
|
||||
break;
|
||||
case Mode3:
|
||||
for (i = 0; i < 8; i++) {
|
||||
Dev.SCK_SET(LOW);
|
||||
if (Write_Date & 0x80)
|
||||
Dev.MOSI_SET(HIGH);
|
||||
else
|
||||
Dev.MOSI_SET(LOW);
|
||||
Write_Date <<= 1;DELAY1US();
|
||||
Dev.SCK_SET(HIGH);
|
||||
read_date <<= 1;
|
||||
if (Dev.MISO())
|
||||
read_date++;DELAY1US();NOP();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return read_date;
|
||||
}
|
||||
|
||||
uint8_t SW_SPI_RW(SW_Dev_Spi Dev, uint8_t Write_Date) {
|
||||
uint8_t read_date;
|
||||
CS_ENABLE();
|
||||
read_date = spi_RW(Dev, Write_Date);
|
||||
CS_DISABLE();
|
||||
return read_date;
|
||||
}
|
||||
|
||||
void SW_SPI_WL(SW_Dev_Spi Dev, uint8_t *Write_Date, uint32_t Len) {
|
||||
CS_ENABLE();
|
||||
for (uint32_t i = 0; i < Len; i++)
|
||||
spi_RW(Dev, Write_Date[i]);
|
||||
CS_DISABLE();
|
||||
}
|
||||
|
||||
void SW_SPI_RL(SW_Dev_Spi Dev, uint8_t *Read_Date, uint32_t Len) {
|
||||
CS_ENABLE();
|
||||
for (uint32_t i = 0; i < Len; i++)
|
||||
Read_Date[i] = spi_RW(Dev, 0xFF);
|
||||
CS_DISABLE();
|
||||
}
|
||||
|
||||
void SW_SPI_RWL(SW_Dev_Spi Dev, uint8_t *Read_Date, uint8_t *Write_Date, uint32_t Len) {
|
||||
CS_ENABLE();
|
||||
for (uint32_t i = 0; i < Len; i++)
|
||||
Read_Date[i] = spi_RW(Dev, Write_Date[i]);
|
||||
CS_DISABLE();
|
||||
}
|
||||
|
||||
uint16_t SW_SPI_RW16(SW_Dev_Spi Dev, uint16_t Write_Date) {
|
||||
Data16_t wdate16, rdate16;
|
||||
wdate16.u16 = Write_Date;
|
||||
CS_ENABLE();
|
||||
if (Dev.ENDIAN) {
|
||||
rdate16.u8[0] = spi_RW(Dev, wdate16.u8[0]);
|
||||
rdate16.u8[1] = spi_RW(Dev, wdate16.u8[1]);
|
||||
} else {
|
||||
rdate16.u8[0] = spi_RW(Dev, wdate16.u8[1]);
|
||||
rdate16.u8[1] = spi_RW(Dev, wdate16.u8[0]);
|
||||
}
|
||||
CS_DISABLE();
|
||||
return rdate16.u16;
|
||||
}
|
||||
|
||||
void SW_SPI_RL16(SW_Dev_Spi Dev, uint16_t *Read_Date, uint32_t Len) {
|
||||
Data16_t rdate16;
|
||||
CS_ENABLE();
|
||||
switch (Dev.ENDIAN) {
|
||||
case LTL:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
rdate16.u8[0] = spi_RW(Dev, 0xFF);
|
||||
rdate16.u8[1] = spi_RW(Dev, 0xFF);
|
||||
Read_Date[i] = rdate16.u16;
|
||||
}
|
||||
break;
|
||||
case LTB:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
rdate16.u8[0] = spi_RW(Dev, 0xFF);
|
||||
rdate16.u8[1] = spi_RW(Dev, 0xFF);
|
||||
Read_Date[i] = rdate16.u16;
|
||||
}
|
||||
break;
|
||||
case BTB:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
rdate16.u8[1] = spi_RW(Dev, 0xFF);
|
||||
rdate16.u8[0] = spi_RW(Dev, 0xFF);
|
||||
Read_Date[i] = rdate16.u16;
|
||||
}
|
||||
break;
|
||||
case BTL:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
rdate16.u8[1] = spi_RW(Dev, 0xFF);
|
||||
rdate16.u8[0] = spi_RW(Dev, 0xFF);
|
||||
Read_Date[i] = rdate16.u16;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CS_DISABLE();
|
||||
}
|
||||
|
||||
void SW_SPI_WL16(SW_Dev_Spi Dev, uint16_t *Write_Date, uint32_t Len) {
|
||||
Data16_t wdate16;
|
||||
CS_ENABLE();
|
||||
switch (Dev.ENDIAN) {
|
||||
case LTL:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
wdate16.u16 = Write_Date[i];
|
||||
spi_RW(Dev, wdate16.u8[0]);
|
||||
spi_RW(Dev, wdate16.u8[1]);
|
||||
}
|
||||
break;
|
||||
case LTB:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
wdate16.u16 = Write_Date[i];
|
||||
spi_RW(Dev, wdate16.u8[1]);
|
||||
spi_RW(Dev, wdate16.u8[0]);
|
||||
}
|
||||
break;
|
||||
case BTB:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
wdate16.u16 = Write_Date[i];
|
||||
spi_RW(Dev, wdate16.u8[1]);
|
||||
spi_RW(Dev, wdate16.u8[0]);
|
||||
}
|
||||
break;
|
||||
case BTL:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
wdate16.u16 = Write_Date[i];
|
||||
spi_RW(Dev, wdate16.u8[0]);
|
||||
spi_RW(Dev, wdate16.u8[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
CS_DISABLE();
|
||||
}
|
||||
|
||||
void SW_SPI_RWL16(SW_Dev_Spi Dev, uint16_t *Read_Date, uint16_t *Write_Date, uint32_t Len) {
|
||||
Data16_t wdate16, rdate16;
|
||||
CS_ENABLE();
|
||||
switch (Dev.ENDIAN) {
|
||||
case LTL:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
wdate16.u16 = Write_Date[i];
|
||||
rdate16.u8[0] = spi_RW(Dev, wdate16.u8[0]);
|
||||
rdate16.u8[1] = spi_RW(Dev, wdate16.u8[1]);
|
||||
Read_Date[i] = rdate16.u16;
|
||||
}
|
||||
break;
|
||||
case LTB:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
wdate16.u16 = Write_Date[i];
|
||||
rdate16.u8[0] = spi_RW(Dev, wdate16.u8[1]);
|
||||
rdate16.u8[1] = spi_RW(Dev, wdate16.u8[0]);
|
||||
Read_Date[i] = rdate16.u16;
|
||||
}
|
||||
break;
|
||||
case BTB:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
wdate16.u16 = Write_Date[i];
|
||||
rdate16.u8[1] = spi_RW(Dev, wdate16.u8[1]);
|
||||
rdate16.u8[0] = spi_RW(Dev, wdate16.u8[0]);
|
||||
Read_Date[i] = rdate16.u16;
|
||||
}
|
||||
break;
|
||||
case BTL:
|
||||
for (uint32_t i = 0; i < Len; i++) {
|
||||
wdate16.u16 = Write_Date[i];
|
||||
rdate16.u8[1] = spi_RW(Dev, wdate16.u8[0]);
|
||||
rdate16.u8[0] = spi_RW(Dev, wdate16.u8[1]);
|
||||
Read_Date[i] = rdate16.u16;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CS_DISABLE();
|
||||
}
|
Reference in New Issue
Block a user