mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +08:00
243 lines
7.3 KiB
C
243 lines
7.3 KiB
C
#include "pika_hal.h"
|
|
|
|
static int _GPIO_write(pika_dev* dev, uint32_t val) {
|
|
return pika_hal_write(dev, &val, sizeof(val));
|
|
}
|
|
|
|
static uint32_t _GPIO_read(pika_dev* dev) {
|
|
uint32_t val = 0;
|
|
pika_hal_read(dev, &val, sizeof(val));
|
|
return val;
|
|
}
|
|
|
|
int pika_hal_platform_SOFT_SPI_open(pika_dev* dev, char* name) {
|
|
return 0;
|
|
}
|
|
|
|
int pika_hal_platform_SOFT_SPI_close(pika_dev* dev) {
|
|
pika_hal_SOFT_SPI_config* cfg =
|
|
(pika_hal_SOFT_SPI_config*)dev->ioctl_config;
|
|
if (cfg->CS != NULL) {
|
|
pika_hal_close(cfg->CS);
|
|
}
|
|
if (cfg->SCK != NULL) {
|
|
pika_hal_close(cfg->SCK);
|
|
}
|
|
if (cfg->MOSI != NULL) {
|
|
pika_hal_close(cfg->MOSI);
|
|
}
|
|
if (cfg->MISO != NULL) {
|
|
pika_hal_close(cfg->MISO);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int pika_hal_platform_SOFT_SPI_ioctl_config(pika_dev* dev,
|
|
pika_hal_SOFT_SPI_config* cfg) {
|
|
return 0;
|
|
}
|
|
|
|
int pika_hal_platform_SOFT_SPI_ioctl_enable(pika_dev* dev) {
|
|
pika_debug("SOFT_SPI_ioctl_enable, dev[0x%p]", dev);
|
|
pika_hal_SOFT_SPI_config* cfg =
|
|
(pika_hal_SOFT_SPI_config*)dev->ioctl_config;
|
|
if (cfg->SCK == NULL || cfg->MOSI == NULL) {
|
|
__platform_printf(
|
|
"Error: SOFT SPI config error, CS, SCK, MOSI, MISO must be "
|
|
"set\r\n");
|
|
return -1;
|
|
}
|
|
pika_hal_GPIO_config cfg_CS = {0};
|
|
pika_hal_GPIO_config cfg_SCK = {0};
|
|
pika_hal_GPIO_config cfg_MOSI = {0};
|
|
pika_hal_GPIO_config cfg_MISO = {0};
|
|
cfg_CS.dir = PIKA_HAL_GPIO_DIR_OUT;
|
|
cfg_SCK.dir = PIKA_HAL_GPIO_DIR_OUT;
|
|
cfg_MOSI.dir = PIKA_HAL_GPIO_DIR_OUT;
|
|
cfg_MISO.dir = PIKA_HAL_GPIO_DIR_IN;
|
|
|
|
if (NULL != cfg->CS) {
|
|
pika_debug("CS[0x%p] config", cfg->CS);
|
|
pika_hal_ioctl(cfg->CS, PIKA_HAL_IOCTL_CONFIG, &cfg_CS);
|
|
}
|
|
pika_debug("SCK[0x%p] config", cfg->SCK);
|
|
pika_hal_ioctl(cfg->SCK, PIKA_HAL_IOCTL_CONFIG, &cfg_SCK);
|
|
pika_debug("MOSI[0x%p] config", cfg->MOSI);
|
|
pika_hal_ioctl(cfg->MOSI, PIKA_HAL_IOCTL_CONFIG, &cfg_MOSI);
|
|
if (NULL != cfg->MISO) {
|
|
pika_debug("MISO[0x%p] config", cfg->MISO);
|
|
pika_hal_ioctl(cfg->MISO, PIKA_HAL_IOCTL_CONFIG, &cfg_MISO);
|
|
}
|
|
|
|
if (NULL != cfg->CS) {
|
|
pika_debug("CS[0x%p] enable", cfg->CS);
|
|
pika_hal_ioctl(cfg->CS, PIKA_HAL_IOCTL_ENABLE);
|
|
}
|
|
pika_debug("SCK[0x%p] enable", cfg->SCK);
|
|
pika_hal_ioctl(cfg->SCK, PIKA_HAL_IOCTL_ENABLE);
|
|
pika_debug("MOSI[0x%p] enable", cfg->MOSI);
|
|
pika_hal_ioctl(cfg->MOSI, PIKA_HAL_IOCTL_ENABLE);
|
|
if (NULL != cfg->MISO) {
|
|
pika_debug("MISO[0x%p] enable", cfg->MISO);
|
|
pika_hal_ioctl(cfg->MISO, PIKA_HAL_IOCTL_ENABLE);
|
|
}
|
|
|
|
if (NULL != cfg->CS) {
|
|
_GPIO_write(cfg->CS, 1);
|
|
}
|
|
_GPIO_write(cfg->SCK, 1);
|
|
_GPIO_write(cfg->MOSI, 1);
|
|
return 0;
|
|
}
|
|
|
|
int pika_hal_platform_SOFT_SPI_ioctl_disable(pika_dev* dev) {
|
|
pika_hal_SOFT_SPI_config* cfg =
|
|
(pika_hal_SOFT_SPI_config*)dev->ioctl_config;
|
|
if (NULL != cfg->CS) {
|
|
pika_hal_ioctl(cfg->CS, PIKA_HAL_IOCTL_DISABLE);
|
|
}
|
|
pika_hal_ioctl(cfg->SCK, PIKA_HAL_IOCTL_DISABLE);
|
|
pika_hal_ioctl(cfg->MOSI, PIKA_HAL_IOCTL_DISABLE);
|
|
if (NULL != cfg->MISO) {
|
|
pika_hal_ioctl(cfg->MISO, PIKA_HAL_IOCTL_DISABLE);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static inline void sleep_us(uint32_t us) {
|
|
pika_platform_sleep_us(us);
|
|
}
|
|
|
|
static inline void _SPI_delay(void) {
|
|
sleep_us(1);
|
|
}
|
|
|
|
static inline int SPIv_TransferByte(pika_hal_SOFT_SPI_config* cfg,
|
|
uint8_t tx,
|
|
uint8_t* rx,
|
|
int is_msb) {
|
|
unsigned char i = 0;
|
|
uint8_t received_data = 0; // Used to store the received data
|
|
|
|
if (is_msb) {
|
|
for (i = 0; i < 8; i++) {
|
|
if (tx & 0x80) {
|
|
_GPIO_write(cfg->MOSI, 1);
|
|
} else {
|
|
_GPIO_write(cfg->MOSI, 0);
|
|
}
|
|
_GPIO_write(cfg->SCK, 0);
|
|
_SPI_delay();
|
|
received_data <<=
|
|
1; // Shift received data left, preparing for the new bit
|
|
if (NULL != cfg->MISO) {
|
|
if (_GPIO_read(cfg->MISO)) { // Read data from the MISO line
|
|
received_data |= 0x01; // If MISO is high, set the lowest
|
|
// bit of the received data to 1
|
|
}
|
|
}
|
|
_GPIO_write(cfg->SCK, 1);
|
|
_SPI_delay();
|
|
tx <<= 1;
|
|
}
|
|
} else {
|
|
for (i = 0; i < 8; i++) {
|
|
if (tx & 0x01) {
|
|
_GPIO_write(cfg->MOSI, 1);
|
|
} else {
|
|
_GPIO_write(cfg->MOSI, 0);
|
|
}
|
|
_GPIO_write(cfg->SCK, 0);
|
|
_SPI_delay();
|
|
received_data >>=
|
|
1; // Shift received data right, preparing for the new bit
|
|
if (NULL != cfg->MISO) {
|
|
if (_GPIO_read(cfg->MISO)) { // Read data from the MISO line
|
|
received_data |= 0x80; // If MISO is high, set the highest
|
|
// bit of the received data to 1
|
|
}
|
|
}
|
|
_GPIO_write(cfg->SCK, 1);
|
|
_SPI_delay();
|
|
tx >>= 1;
|
|
}
|
|
}
|
|
|
|
*rx = received_data; // Store the received data into the variable pointed
|
|
// to by rx
|
|
return 0;
|
|
}
|
|
|
|
static inline int SPIv_ReadByte(pika_hal_SOFT_SPI_config* cfg, int is_msb) {
|
|
unsigned char i = 0;
|
|
unsigned char Data = 0;
|
|
if (is_msb) {
|
|
for (i = 0; i < 8; i++) {
|
|
Data <<= 1;
|
|
_GPIO_write(cfg->SCK, 0);
|
|
_SPI_delay();
|
|
if (_GPIO_read(cfg->MISO)) {
|
|
Data++;
|
|
}
|
|
_GPIO_write(cfg->SCK, 1);
|
|
_SPI_delay();
|
|
}
|
|
} else {
|
|
for (i = 0; i < 8; i++) {
|
|
Data >>= 1;
|
|
_GPIO_write(cfg->SCK, 0);
|
|
_SPI_delay();
|
|
if (_GPIO_read(cfg->MISO)) {
|
|
Data |= 0x80;
|
|
}
|
|
_GPIO_write(cfg->SCK, 1);
|
|
_SPI_delay();
|
|
}
|
|
}
|
|
return Data;
|
|
}
|
|
|
|
int pika_hal_platform_SOFT_SPI_write(pika_dev* dev, void* buf, size_t count) {
|
|
pika_hal_SOFT_SPI_config* cfg =
|
|
(pika_hal_SOFT_SPI_config*)dev->ioctl_config;
|
|
uint8_t* data = (uint8_t*)buf;
|
|
if (NULL != cfg->CS) {
|
|
_GPIO_write(cfg->CS, 0);
|
|
_SPI_delay();
|
|
}
|
|
int is_msb = cfg->lsb_or_msb == PIKA_HAL_SPI_MSB ? 1 : 0;
|
|
for (int i = 0; i < count; i++) {
|
|
SPIv_TransferByte(
|
|
cfg, data[i],
|
|
&cfg->tranfer_rx_buffer[i % PIKA_HAL_SPI_RX_BUFFER_SIZE], is_msb);
|
|
}
|
|
if (NULL != cfg->CS) {
|
|
_GPIO_write(cfg->CS, 1);
|
|
_SPI_delay();
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int pika_hal_platform_SOFT_SPI_read(pika_dev* dev, void* buf, size_t count) {
|
|
pika_hal_SOFT_SPI_config* cfg =
|
|
(pika_hal_SOFT_SPI_config*)dev->ioctl_config;
|
|
if (NULL == cfg->MISO) {
|
|
__platform_printf("Error: SOFT SPI config error, MISO must be set\r\n");
|
|
return -1;
|
|
}
|
|
uint8_t* data = (uint8_t*)buf;
|
|
if (NULL != cfg->CS) {
|
|
_GPIO_write(cfg->CS, 0);
|
|
_SPI_delay();
|
|
}
|
|
int is_msb = cfg->lsb_or_msb == PIKA_HAL_SPI_MSB ? 1 : 0;
|
|
for (int i = 0; i < count; i++) {
|
|
data[i] = SPIv_ReadByte(cfg, is_msb);
|
|
}
|
|
if (NULL != cfg->CS) {
|
|
_GPIO_write(cfg->CS, 1);
|
|
_SPI_delay();
|
|
}
|
|
return count;
|
|
}
|