153 lines
2.9 KiB
C
153 lines
2.9 KiB
C
#include <string.h>
|
|
|
|
#include "FreeRTOS.h"
|
|
#include "chip.h"
|
|
#include "errno.h"
|
|
|
|
#define MAX_SPI_DEVICE_NUM 2
|
|
|
|
static struct spi_slave *spi_devs[MAX_SPI_DEVICE_NUM] = {NULL};
|
|
static int spi_devices_count = 0;
|
|
|
|
int spi_add_slave(struct spi_slave *slave)
|
|
{
|
|
if (spi_devices_count >= MAX_SPI_DEVICE_NUM)
|
|
return -1;
|
|
|
|
spi_devs[spi_devices_count++] = slave;
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct spi_slave *spi_open(const char *spidev)
|
|
{
|
|
struct spi_slave *slave;
|
|
int i;
|
|
|
|
for (i = 0; i < spi_devices_count; i++) {
|
|
slave = spi_devs[i];
|
|
if (!strcmp(slave->name, spidev)) {
|
|
slave->open_count++;
|
|
if (slave->open_count == 1)
|
|
slave->xMutex = xSemaphoreCreateMutex();
|
|
return slave;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void spi_close(struct spi_slave *slave)
|
|
{
|
|
if (slave && --slave->open_count == 0)
|
|
vSemaphoreDelete(slave->xMutex);
|
|
}
|
|
|
|
int spi_send_then_recv(struct spi_slave *slave, const void *send_buf,
|
|
size_t send_length, void *recv_buf,
|
|
size_t recv_length)
|
|
{
|
|
int result;
|
|
struct spi_message message = {0};
|
|
|
|
/* send data */
|
|
message.send_buf = send_buf;
|
|
message.recv_buf = NULL;
|
|
message.length = send_length;
|
|
message.cs_take = 1;
|
|
message.cs_release = 0;
|
|
message.next = NULL;
|
|
|
|
result = slave->xfer(slave, &message);
|
|
if (result < 0)
|
|
{
|
|
result = -EIO;
|
|
goto __exit;
|
|
}
|
|
|
|
/* recv data */
|
|
message.send_buf = NULL;
|
|
message.recv_buf = recv_buf;
|
|
message.length = recv_length;
|
|
message.cs_take = 0;
|
|
message.cs_release = 1;
|
|
message.next = NULL;
|
|
|
|
result = slave->xfer(slave, &message);
|
|
if (result < 0)
|
|
{
|
|
result = -EIO;
|
|
goto __exit;
|
|
}
|
|
|
|
result = ENOERR;
|
|
|
|
__exit:
|
|
return result;
|
|
}
|
|
|
|
int spi_transfer(struct spi_slave *slave, const void *send_buf,
|
|
void *recv_buf, size_t length)
|
|
{
|
|
int result;
|
|
struct spi_message message = {0};
|
|
|
|
configASSERT(slave != NULL);
|
|
|
|
xSemaphoreTake(slave->xMutex, portMAX_DELAY);
|
|
|
|
/* initial message */
|
|
message.send_buf = send_buf;
|
|
message.recv_buf = recv_buf;
|
|
message.length = length;
|
|
message.cs_take = 1;
|
|
message.cs_release = 1;
|
|
message.next = NULL;
|
|
|
|
/* transfer message */
|
|
result = slave->xfer(slave, &message);
|
|
if (result < 0)
|
|
{
|
|
result = -EIO;
|
|
goto __exit;
|
|
}
|
|
|
|
__exit:
|
|
xSemaphoreGive(slave->xMutex);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
int spi_configure(struct spi_slave *slave, struct spi_configuration *cfg)
|
|
{
|
|
int ret;
|
|
|
|
configASSERT(slave && cfg);
|
|
|
|
xSemaphoreTake(slave->xMutex, portMAX_DELAY);
|
|
|
|
ret = slave->configure(slave, cfg);
|
|
|
|
xSemaphoreGive(slave->xMutex);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
int spi_recv(struct spi_slave *slave, void *recv_buf, size_t length)
|
|
{
|
|
return spi_transfer(slave, NULL, recv_buf, length);
|
|
}
|
|
|
|
int spi_send(struct spi_slave *slave, const void *send_buf, size_t length)
|
|
{
|
|
return spi_transfer(slave, send_buf, NULL, length);
|
|
}
|
|
|
|
void spi_init(void)
|
|
{
|
|
ecspi_init();
|
|
dwspi_init();
|
|
}
|