sync PikaStdDevice for SPI/SOFT_SPI enhance

This commit is contained in:
lyon 2024-02-11 21:43:49 +08:00
parent 6fba67f236
commit fdb9b1baa7
8 changed files with 291 additions and 75 deletions

View File

@ -436,6 +436,9 @@ class SPI(BaseDev):
def setPinMISO(self, pin: str): def setPinMISO(self, pin: str):
"""Set the MISO pin.""" """Set the MISO pin."""
def setPinCS(self, pin: str):
"""Set the CS pin."""
def setName(self, name: str): def setName(self, name: str):
"""Use the device name to select the SPI pin. """Use the device name to select the SPI pin.
exmpale: `"SPI0"`, `"SPI1"` ... exmpale: `"SPI0"`, `"SPI1"` ...
@ -473,25 +476,6 @@ class SPI(BaseDev):
def readBytes(self, length: int) -> bytes: def readBytes(self, length: int) -> bytes:
"""Read bytes from the SPI.""" """Read bytes from the SPI."""
@abstractmethod
def platformEnable(self): ...
@abstractmethod
def platformWrite(self): ...
@abstractmethod
def platformWriteBytes(self): ...
@abstractmethod
def platformRead(self): ...
@abstractmethod
def platformReadBytes(self): ...
@abstractmethod
def platformDisable(self): ...
class CAN(BaseDev): class CAN(BaseDev):
def __init__(self): ... def __init__(self): ...

View File

@ -4,50 +4,140 @@
void PikaStdDevice_SPI___init__(PikaObj* self) { void PikaStdDevice_SPI___init__(PikaObj* self) {
obj_setInt(self, "baudRate", 1000); obj_setInt(self, "baudRate", 1000);
obj_setInt(self, "id", 0); obj_setInt(self, "id", 0);
obj_setStr(self, "name", "none"); obj_setStr(self, "name", "SOFT");
obj_setInt(self, "phase", 0); obj_setInt(self, "phase", 0);
obj_setStr(self, "MISOpin", "none"); obj_setStr(self, "MISOpin", "none");
obj_setStr(self, "MOSIpin", "none"); obj_setStr(self, "MOSIpin", "none");
obj_setStr(self, "SCKpin", "none"); obj_setStr(self, "SCKpin", "none");
obj_setInt(self, "polarity", 0); obj_setInt(self, "polarity", 0);
obj_setPtr(self, "pika_dev", NULL);
}
static pika_dev* _get_dev(PikaObj* self) {
pika_dev* dev = PIKA_HAL_OBJ2DEV(self);
if (NULL != dev) {
return dev;
}
char* name = obj_getStr(self, "name");
if (0 == strcmp(name, "SOFT")) {
dev = pika_hal_open(PIKA_HAL_SOFT_SPI, name);
pika_debug("Open soft spi %s\r\n", name);
} else {
dev = pika_hal_open(PIKA_HAL_SPI, name);
pika_debug("Open spi %s\r\n", name);
}
if (NULL == dev) {
__platform_printf("Error: open IIC '%s' failed.\r\n",
obj_getStr(self, "name"));
return NULL;
}
obj_setPtr(self, "pika_dev", dev);
return dev;
} }
void PikaStdDevice_SPI_disable(PikaObj* self) { void PikaStdDevice_SPI_disable(PikaObj* self) {
obj_runNativeMethod(self, "platformDisable", NULL); pika_dev* dev = _get_dev(self);
if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return;
}
pika_hal_ioctl(dev, PIKA_HAL_IOCTL_DISABLE);
} }
void PikaStdDevice_SPI_enable(PikaObj* self) { void PikaStdDevice_SPI_enable(PikaObj* self) {
obj_runNativeMethod(self, "platformEnable", NULL); pika_dev* dev = _get_dev(self);
if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return;
}
pika_hal_ioctl(dev, PIKA_HAL_IOCTL_ENABLE);
} }
void PikaStdDevice_SPI_write(PikaObj* self, char* data) { void PikaStdDevice_SPI_write(PikaObj* self, char* data) {
obj_setStr(self, "writeData", data); pika_dev* dev = _get_dev(self);
obj_runNativeMethod(self, "platformWrite", NULL); if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return;
}
pika_hal_write(dev, data, strlen(data));
} }
void PikaStdDevice_SPI_writeBytes(PikaObj* self, uint8_t* data, int length) { void PikaStdDevice_SPI_writeBytes(PikaObj* self, uint8_t* data, int length) {
obj_setBytes(self, "writeData", data, length); pika_dev* dev = _get_dev(self);
obj_runNativeMethod(self, "platformWriteBytes", NULL); if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return;
}
pika_hal_write(dev, data, length);
} }
char* PikaStdDevice_SPI_read(PikaObj* self, int length) { char* PikaStdDevice_SPI_read(PikaObj* self, int length) {
obj_setInt(self, "length", length); pika_dev* dev = _get_dev(self);
obj_runNativeMethod(self, "platformRead", NULL); if (NULL == dev) {
return obj_getStr(self, "readData"); pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return NULL;
}
char* data = (char*)pikaMalloc(length + 1);
if (NULL == data) {
pika_platform_printf("Error: SPI read failed, no memory.\r\n");
return NULL;
}
int ret = pika_hal_read(dev, data, length);
if (ret < 0) {
pikaFree(data, length + 1);
return NULL;
}
data[length] = '\0';
char* res = obj_cacheStr(self, data);
pikaFree(data, length + 1);
return res;
} }
Arg* PikaStdDevice_SPI_readBytes(PikaObj* self, int length) { Arg* PikaStdDevice_SPI_readBytes(PikaObj* self, int length) {
obj_setInt(self, "length", length); pika_dev* dev = _get_dev(self);
obj_runNativeMethod(self, "platformReadBytes", NULL); if (NULL == dev) {
return arg_copy(obj_getArg(self, "readData")); pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return NULL;
}
uint8_t* data = (uint8_t*)pikaMalloc(length);
if (NULL == data) {
pika_platform_printf("Error: SPI read failed, no memory.\r\n");
return NULL;
}
int ret = pika_hal_read(dev, data, length);
if (ret < 0) {
pikaFree(data, length);
return NULL;
}
Arg* res = arg_newBytes(data, length);
pikaFree(data, length);
return res;
} }
void PikaStdDevice_SPI_setBaudRate(PikaObj* self, int baudRate) { void PikaStdDevice_SPI_setBaudRate(PikaObj* self, int baudRate) {
obj_setInt(self, "baudRate", baudRate); obj_setInt(self, "baudRate", baudRate);
pika_dev* dev = _get_dev(self);
if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
}
pika_hal_SPI_config cfg = {0};
cfg.speed = baudRate;
pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg);
} }
void PikaStdDevice_SPI_setId(PikaObj* self, int id) { void PikaStdDevice_SPI_setId(PikaObj* self, int id) {
obj_setInt(self, "id", id); obj_setInt(self, "id", id);
Args buffs = {0};
char* name = strsFormat(&buffs, 64, "SPI%d", id);
obj_setName(self, name);
args_deinit(&buffs);
} }
void PikaStdDevice_SPI_setName(PikaObj* self, char* name) { void PikaStdDevice_SPI_setName(PikaObj* self, char* name) {
@ -60,40 +150,72 @@ void PikaStdDevice_SPI_setPhase(PikaObj* self, int phase) {
void PikaStdDevice_SPI_setPinMISO(PikaObj* self, char* pin) { void PikaStdDevice_SPI_setPinMISO(PikaObj* self, char* pin) {
obj_setStr(self, "MISOpin", pin); obj_setStr(self, "MISOpin", pin);
pika_dev* dev = _get_dev(self);
if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return;
}
pika_hal_SPI_config cfg = {0};
cfg.MISO = pika_hal_open(PIKA_HAL_GPIO, pin);
if (NULL == cfg.MISO) {
pika_platform_printf("Error: open MISO '%s' failed.\r\n", pin);
return;
}
pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg);
}
void PikaStdDevice_SPI_setPinCS(PikaObj* self, char* pin) {
obj_setStr(self, "CSpin", pin);
pika_dev* dev = _get_dev(self);
if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return;
}
pika_hal_SPI_config cfg = {0};
cfg.CS = pika_hal_open(PIKA_HAL_GPIO, pin);
if (NULL == cfg.CS) {
pika_platform_printf("Error: open CS '%s' failed.\r\n", pin);
return;
}
pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg);
} }
void PikaStdDevice_SPI_setPinMOSI(PikaObj* self, char* pin) { void PikaStdDevice_SPI_setPinMOSI(PikaObj* self, char* pin) {
obj_setStr(self, "MOSIpin", pin); obj_setStr(self, "MOSIpin", pin);
pika_dev* dev = _get_dev(self);
if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return;
}
pika_hal_SPI_config cfg = {0};
cfg.MOSI = pika_hal_open(PIKA_HAL_GPIO, pin);
if (NULL == cfg.MOSI) {
pika_platform_printf("Error: open MOSI '%s' failed.\r\n", pin);
return;
}
pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg);
} }
void PikaStdDevice_SPI_setPinSCK(PikaObj* self, char* pin) { void PikaStdDevice_SPI_setPinSCK(PikaObj* self, char* pin) {
obj_setStr(self, "SCKpin", pin); obj_setStr(self, "SCKpin", pin);
pika_dev* dev = _get_dev(self);
if (NULL == dev) {
pika_platform_printf("Error: SPI '%s' not found.\r\n",
obj_getStr(self, "name"));
return;
}
pika_hal_SPI_config cfg = {0};
cfg.SCK = pika_hal_open(PIKA_HAL_GPIO, pin);
if (NULL == cfg.SCK) {
pika_platform_printf("Error: open SCK '%s' failed.\r\n", pin);
return;
}
pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg);
} }
void PikaStdDevice_SPI_setPolarity(PikaObj* self, int polarity) { void PikaStdDevice_SPI_setPolarity(PikaObj* self, int polarity) {
obj_setInt(self, "polarity", polarity); obj_setInt(self, "polarity", polarity);
} }
void PikaStdDevice_SPI_platformDisable(PikaObj* self) {
ABSTRACT_METHOD_NEED_OVERRIDE_ERROR();
}
void PikaStdDevice_SPI_platformEnable(PikaObj* self) {
ABSTRACT_METHOD_NEED_OVERRIDE_ERROR();
}
void PikaStdDevice_SPI_platformWrite(PikaObj* self) {
ABSTRACT_METHOD_NEED_OVERRIDE_ERROR();
}
void PikaStdDevice_SPI_platformRead(PikaObj* self) {
ABSTRACT_METHOD_NEED_OVERRIDE_ERROR();
}
void PikaStdDevice_SPI_platformWriteBytes(PikaObj* self) {
ABSTRACT_METHOD_NEED_OVERRIDE_ERROR();
}
void PikaStdDevice_SPI_platformReadBytes(PikaObj* self) {
ABSTRACT_METHOD_NEED_OVERRIDE_ERROR();
}

View File

@ -42,6 +42,8 @@ pika_dev* pika_hal_open(PIKA_HAL_DEV_TYPE dev_type, char* name) {
if (dev == NULL) { if (dev == NULL) {
goto __exit; goto __exit;
} }
pika_debug("pika_hal_open, dev[0x%p], type[%d], name[%s]", dev, dev_type,
name);
memset(dev, 0, sizeof(pika_dev)); memset(dev, 0, sizeof(pika_dev));
dev->type = dev_type; dev->type = dev_type;
dev->ioctl_config = pikaMalloc(_pika_hal_dev_config_size(dev_type)); dev->ioctl_config = pikaMalloc(_pika_hal_dev_config_size(dev_type));
@ -90,10 +92,16 @@ __exit:
int pika_hal_read(pika_dev* dev, void* buf, size_t len) { int pika_hal_read(pika_dev* dev, void* buf, size_t len) {
if (dev == NULL) { if (dev == NULL) {
pika_platform_printf("Error: dev is NULL.\r\n");
return -1;
}
if (!dev->is_enabled) {
pika_platform_printf("Error: dev is not enabled.\r\n");
return -1; return -1;
} }
pika_dev_impl* impl = _pika_dev_get_impl(dev->type); pika_dev_impl* impl = _pika_dev_get_impl(dev->type);
if (impl->read == NULL) { if (impl->read == NULL) {
pika_platform_printf("Error: read not support.\r\n");
return -1; return -1;
} }
return impl->read(dev, buf, len); return impl->read(dev, buf, len);
@ -101,10 +109,16 @@ int pika_hal_read(pika_dev* dev, void* buf, size_t len) {
int pika_hal_write(pika_dev* dev, void* buf, size_t len) { int pika_hal_write(pika_dev* dev, void* buf, size_t len) {
if (dev == NULL) { if (dev == NULL) {
pika_platform_printf("Error: dev is NULL.\r\n");
return -1;
}
if (!dev->is_enabled) {
pika_platform_printf("Error: dev is not enabled.\r\n");
return -1; return -1;
} }
pika_dev_impl* impl = _pika_dev_get_impl(dev->type); pika_dev_impl* impl = _pika_dev_get_impl(dev->type);
if (impl->write == NULL) { if (impl->write == NULL) {
pika_platform_printf("Error: write not support.\r\n");
return -1; return -1;
} }
return impl->write(dev, buf, len); return impl->write(dev, buf, len);
@ -133,14 +147,19 @@ int pika_hal_ioctl(pika_dev* dev, PIKA_HAL_IOCTL_CMD cmd, ...) {
int ret = -1; int ret = -1;
PIKA_HAL_IOCTL_CMD cmd_origin = cmd; PIKA_HAL_IOCTL_CMD cmd_origin = cmd;
if (dev == NULL) { if (dev == NULL) {
pika_platform_printf("Error: dev is NULL.\r\n");
return -1; return -1;
} }
pika_debug("pika_hal_ioctl, dev[0x%p], type[%d], cmd[%d]", dev, dev->type,
cmd);
cmd = _pika_hal_get_arg_cnt(cmd_origin); cmd = _pika_hal_get_arg_cnt(cmd_origin);
if (cmd < 0) { if (cmd < 0) {
pika_platform_printf("Error: cmd invalied.\r\n");
return -1; return -1;
} }
pika_dev_impl* impl = _pika_dev_get_impl(dev->type); pika_dev_impl* impl = _pika_dev_get_impl(dev->type);
if (impl->ioctl == NULL) { if (impl->ioctl == NULL) {
pika_platform_printf("Error: ioctl not support.\r\n");
return -1; return -1;
} }
void* arg_in = NULL; void* arg_in = NULL;
@ -155,6 +174,7 @@ int pika_hal_ioctl(pika_dev* dev, PIKA_HAL_IOCTL_CMD cmd, ...) {
} }
va_end(args); va_end(args);
if (0 != ret) { if (0 != ret) {
pika_platform_printf("Error: ioctl merge config failed.\r\n");
return ret; return ret;
} }
} }
@ -263,6 +283,10 @@ int pika_hal_SPI_ioctl_merge_config(pika_hal_SPI_config* dst,
_IOCTL_CONFIG_USE_DEFAULT(data_width, PIKA_HAL_SPI_DATA_WIDTH_8); _IOCTL_CONFIG_USE_DEFAULT(data_width, PIKA_HAL_SPI_DATA_WIDTH_8);
_IOCTL_CONFIG_USE_DEFAULT(speed, PIKA_HAL_SPI_SPEED_2M); _IOCTL_CONFIG_USE_DEFAULT(speed, PIKA_HAL_SPI_SPEED_2M);
_IOCTL_CONFIG_USE_DEFAULT(timeout, PIKA_HAL_SPI_TIMEOUT_1000MS); _IOCTL_CONFIG_USE_DEFAULT(timeout, PIKA_HAL_SPI_TIMEOUT_1000MS);
_IOCTL_CONFIG_USE_DEFAULT(CS, NULL);
_IOCTL_CONFIG_USE_DEFAULT(SCK, NULL);
_IOCTL_CONFIG_USE_DEFAULT(MOSI, NULL);
_IOCTL_CONFIG_USE_DEFAULT(MISO, NULL);
_IOCTL_CONFIG_USE_DEFAULT(user_data, NULL); _IOCTL_CONFIG_USE_DEFAULT(user_data, NULL);
return 0; return 0;
} }

View File

@ -301,6 +301,8 @@ typedef enum {
PIKA_HAL_SPI_SPEED_100M = 100000000, PIKA_HAL_SPI_SPEED_100M = 100000000,
} PIKA_HAL_SPI_SPEED; } PIKA_HAL_SPI_SPEED;
#define PIKA_HAL_SPI_RX_BUFFER_SIZE 32
typedef struct { typedef struct {
PIKA_HAL_SPI_LSB_OR_MSB lsb_or_msb; PIKA_HAL_SPI_LSB_OR_MSB lsb_or_msb;
PIKA_HAL_SPI_MASTER_OR_SLAVE master_or_slave; PIKA_HAL_SPI_MASTER_OR_SLAVE master_or_slave;
@ -308,6 +310,11 @@ typedef struct {
PIKA_HAL_SPI_DATA_WIDTH data_width; PIKA_HAL_SPI_DATA_WIDTH data_width;
PIKA_HAL_SPI_SPEED speed; PIKA_HAL_SPI_SPEED speed;
PIKA_HAL_SPI_TIMEOUT timeout; PIKA_HAL_SPI_TIMEOUT timeout;
pika_dev* CS; // Just for MCU with pin mux like ESP32
pika_dev* SCK; // Just for MCU with pin mux like ESP32
pika_dev* MOSI; // Just for MCU with pin mux like ESP32
pika_dev* MISO; // Just for MCU with pin mux like ESP32
uint8_t tranfer_rx_buffer[PIKA_HAL_SPI_RX_BUFFER_SIZE];
void* user_data; void* user_data;
} pika_hal_SPI_config; } pika_hal_SPI_config;
@ -318,12 +325,13 @@ typedef struct {
PIKA_HAL_SPI_DATA_WIDTH data_width; PIKA_HAL_SPI_DATA_WIDTH data_width;
PIKA_HAL_SPI_SPEED speed; PIKA_HAL_SPI_SPEED speed;
PIKA_HAL_SPI_TIMEOUT timeout; PIKA_HAL_SPI_TIMEOUT timeout;
void* user_data;
// Uper must be the same with SPI_config
pika_dev* CS; pika_dev* CS;
pika_dev* SCK; pika_dev* SCK;
pika_dev* MOSI; pika_dev* MOSI;
pika_dev* MISO; pika_dev* MISO;
uint8_t tranfer_rx_buffer[PIKA_HAL_SPI_RX_BUFFER_SIZE];
void* user_data;
// Uper must be the same with SPI_config
} pika_hal_SOFT_SPI_config; } pika_hal_SOFT_SPI_config;
typedef enum { typedef enum {

View File

@ -34,16 +34,11 @@ int pika_hal_platform_SOFT_SPI_close(pika_dev* dev) {
int pika_hal_platform_SOFT_SPI_ioctl_config(pika_dev* dev, int pika_hal_platform_SOFT_SPI_ioctl_config(pika_dev* dev,
pika_hal_SOFT_SPI_config* cfg) { pika_hal_SOFT_SPI_config* cfg) {
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;
}
return 0; return 0;
} }
int pika_hal_platform_SOFT_SPI_ioctl_enable(pika_dev* dev) { 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* cfg =
(pika_hal_SOFT_SPI_config*)dev->ioctl_config; (pika_hal_SOFT_SPI_config*)dev->ioctl_config;
if (cfg->SCK == NULL || cfg->MOSI == NULL) { if (cfg->SCK == NULL || cfg->MOSI == NULL) {
@ -62,20 +57,28 @@ int pika_hal_platform_SOFT_SPI_ioctl_enable(pika_dev* dev) {
cfg_MISO.dir = PIKA_HAL_GPIO_DIR_IN; cfg_MISO.dir = PIKA_HAL_GPIO_DIR_IN;
if (NULL != cfg->CS) { if (NULL != cfg->CS) {
pika_debug("CS[0x%p] config", cfg->CS);
pika_hal_ioctl(cfg->CS, PIKA_HAL_IOCTL_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_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); pika_hal_ioctl(cfg->MOSI, PIKA_HAL_IOCTL_CONFIG, &cfg_MOSI);
if (NULL != cfg->MISO) { if (NULL != cfg->MISO) {
pika_debug("MISO[0x%p] config", cfg->MISO);
pika_hal_ioctl(cfg->MISO, PIKA_HAL_IOCTL_CONFIG, &cfg_MISO); pika_hal_ioctl(cfg->MISO, PIKA_HAL_IOCTL_CONFIG, &cfg_MISO);
} }
if (NULL != cfg->CS) { if (NULL != cfg->CS) {
pika_debug("CS[0x%p] enable", cfg->CS);
pika_hal_ioctl(cfg->CS, PIKA_HAL_IOCTL_ENABLE); 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_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); pika_hal_ioctl(cfg->MOSI, PIKA_HAL_IOCTL_ENABLE);
if (NULL != cfg->MISO) { if (NULL != cfg->MISO) {
pika_debug("MISO[0x%p] enable", cfg->MISO);
pika_hal_ioctl(cfg->MISO, PIKA_HAL_IOCTL_ENABLE); pika_hal_ioctl(cfg->MISO, PIKA_HAL_IOCTL_ENABLE);
} }
@ -109,41 +112,63 @@ static inline void _SPI_delay(void) {
sleep_us(1); sleep_us(1);
} }
static inline int SPIv_WriteData(pika_hal_SOFT_SPI_config* cfg, static inline int SPIv_TransferByte(pika_hal_SOFT_SPI_config* cfg,
uint8_t Data, uint8_t tx,
uint8_t* rx,
int is_msb) { int is_msb) {
unsigned char i = 0; unsigned char i = 0;
uint8_t received_data = 0; // Used to store the received data
if (is_msb) { if (is_msb) {
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (Data & 0x80) { if (tx & 0x80) {
_GPIO_write(cfg->MOSI, 1); _GPIO_write(cfg->MOSI, 1);
} else { } else {
_GPIO_write(cfg->MOSI, 0); _GPIO_write(cfg->MOSI, 0);
} }
_GPIO_write(cfg->SCK, 0); _GPIO_write(cfg->SCK, 0);
_SPI_delay(); _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); _GPIO_write(cfg->SCK, 1);
_SPI_delay(); _SPI_delay();
Data <<= 1; tx <<= 1;
} }
} else { } else {
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (Data & 0x01) { if (tx & 0x01) {
_GPIO_write(cfg->MOSI, 1); _GPIO_write(cfg->MOSI, 1);
} else { } else {
_GPIO_write(cfg->MOSI, 0); _GPIO_write(cfg->MOSI, 0);
} }
_GPIO_write(cfg->SCK, 0); _GPIO_write(cfg->SCK, 0);
_SPI_delay(); _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); _GPIO_write(cfg->SCK, 1);
_SPI_delay(); _SPI_delay();
Data >>= 1; tx >>= 1;
} }
} }
*rx = received_data; // Store the received data into the variable pointed
// to by rx
return 0; return 0;
} }
static inline int SPIv_ReadData(pika_hal_SOFT_SPI_config* cfg, int is_msb) { static inline int SPIv_ReadByte(pika_hal_SOFT_SPI_config* cfg, int is_msb) {
unsigned char i = 0; unsigned char i = 0;
unsigned char Data = 0; unsigned char Data = 0;
if (is_msb) { if (is_msb) {
@ -182,7 +207,9 @@ int pika_hal_platform_SOFT_SPI_write(pika_dev* dev, void* buf, size_t count) {
} }
int is_msb = cfg->lsb_or_msb == PIKA_HAL_SPI_MSB ? 1 : 0; int is_msb = cfg->lsb_or_msb == PIKA_HAL_SPI_MSB ? 1 : 0;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
SPIv_WriteData(cfg, data[i], is_msb); SPIv_TransferByte(
cfg, data[i],
&cfg->tranfer_rx_buffer[i % PIKA_HAL_SPI_RX_BUFFER_SIZE], is_msb);
} }
if (NULL != cfg->CS) { if (NULL != cfg->CS) {
_GPIO_write(cfg->CS, 1); _GPIO_write(cfg->CS, 1);
@ -205,7 +232,7 @@ int pika_hal_platform_SOFT_SPI_read(pika_dev* dev, void* buf, size_t count) {
} }
int is_msb = cfg->lsb_or_msb == PIKA_HAL_SPI_MSB ? 1 : 0; int is_msb = cfg->lsb_or_msb == PIKA_HAL_SPI_MSB ? 1 : 0;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
data[i] = SPIv_ReadData(cfg, is_msb); data[i] = SPIv_ReadByte(cfg, is_msb);
} }
if (NULL != cfg->CS) { if (NULL != cfg->CS) {
_GPIO_write(cfg->CS, 1); _GPIO_write(cfg->CS, 1);

View File

@ -159,6 +159,53 @@ int pika_hal_utils_SPI_config(pika_dev* dev, pika_hal_SPI_config* cfg) {
return ret; return ret;
} }
int pika_hal_utils_SPI_transfer(pika_dev* dev,
uint8_t* txbuff,
uint8_t* rxbuff,
uint32_t size) {
// Modify parameter check logic: allow unidirectional transfer
if (dev == NULL || (txbuff == NULL && rxbuff == NULL)) {
return -1; // Parameter check failed
}
pika_hal_SPI_config* cfg = (pika_hal_SPI_config*)dev->ioctl_config;
uint32_t transferred = 0; // Amount of data transferred
uint32_t remaining = size; // Amount of data remaining
uint32_t chunkSize; // Amount of data for the current batch transfer
while (remaining > 0) {
chunkSize = remaining > PIKA_HAL_SPI_RX_BUFFER_SIZE
? PIKA_HAL_SPI_RX_BUFFER_SIZE
: remaining;
// Call SPI_write to transfer data only if txbuff is not NULL
if (txbuff != NULL) {
pika_hal_write(dev, &txbuff[transferred], chunkSize);
}
// Call hal_read instead of directly retrieving data from
// transfer_rx_buffer only if rxbuff is not NULL
if (rxbuff != NULL) {
if (txbuff == NULL) {
// Perform data reception only
pika_hal_read(dev, &rxbuff[transferred], chunkSize);
} else {
// Handle both data sending and receiving, assuming hal_write
// already includes reading logic
for (uint32_t i = 0; i < chunkSize; i++) {
rxbuff[transferred + i] =
cfg->tranfer_rx_buffer[i % PIKA_HAL_SPI_RX_BUFFER_SIZE];
}
}
}
transferred += chunkSize; // Update the amount of data transferred
remaining -= chunkSize; // Update the amount of data remaining
}
return 0; // Successfully completed the transfer
}
/* ADC utils */ /* ADC utils */
int pika_hal_utils_ADC_config(pika_dev* dev, pika_hal_ADC_config* cfg) { int pika_hal_utils_ADC_config(pika_dev* dev, pika_hal_ADC_config* cfg) {
int ret = pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, cfg); int ret = pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, cfg);

View File

@ -42,6 +42,10 @@ int pika_hal_utils_IIC_set_slave_addr(pika_dev* dev, uint32_t slave_addr);
/* SPI utils */ /* SPI utils */
int pika_hal_utils_SPI_config(pika_dev* dev, pika_hal_SPI_config* cfg); int pika_hal_utils_SPI_config(pika_dev* dev, pika_hal_SPI_config* cfg);
int pika_hal_utils_SPI_transfer(pika_dev* dev,
uint8_t* txbuff,
uint8_t* rxbuff,
uint32_t size);
/* ADC utils */ /* ADC utils */
int pika_hal_utils_ADC_config(pika_dev* dev, pika_hal_ADC_config* cfg); int pika_hal_utils_ADC_config(pika_dev* dev, pika_hal_ADC_config* cfg);

View File

@ -2,4 +2,4 @@
#define PIKA_VERSION_MINOR 13 #define PIKA_VERSION_MINOR 13
#define PIKA_VERSION_MICRO 2 #define PIKA_VERSION_MICRO 2
#define PIKA_EDIT_TIME "2024/02/10 00:40:58" #define PIKA_EDIT_TIME "2024/02/11 21:43:11"