Last Updated on : 2025-05-12 03:09:46download
Serial peripheral interface (SPI) is a high-speed, full-duplex, synchronous communication bus. SPI follows a controller–peripheral architecture, where a controller orchestrates communication with one or more peripheral devices.
The signal lines of an SPI controller are described as follows:
The following figure shows a typical SPI wiring.
The four operating modes supported by the SPI bus depend on the combination of clock polarity (CPOL) and clock phase (CPHA).
The timing of the four operating modes is described as follows:
Mode 0: CPOL = 0, CPHA = 0. The SCK line remains idle at low level. Data is sampled on the rising edge of SCK, and changes occur on the falling edge.
Mode 1: CPOL = 0, CPHA = 1. The SCK line remains idle at low level. Data is sampled on the falling edge of SCK, and changes occur on the rising edge.
Mode 2: CPOL = 1, CPHA = 0. The SCK line remains idle at high level. Data is sampled on the falling edge of SCK, and changes occur on the rising edge.
Mode 3: CPOL = 1, CPHA = 1. The SCK line remains idle at high level. Data is sampled on the rising edge of SCK, and changes occur on the falling edge.
OPERATE_RET tkl_spi_init(TUYA_SPI_NUM_E port, CONST TUYA_SPI_BASE_CFG_T *cfg);
Features:
Parameters:
port
: The port number.cfg
: Basic SPI configuration.typedef struct {
TUYA_SPI_ROLE_E role;
TUYA_SPI_MODE_E mode;
TUYA_SPI_TYPE_E type;
TUYA_SPI_DATABITS_E databits;
TUYA_SPI_BIT_ORDER_E bitorder;
UINT_T freq_hz;
UINT_T spi_dma_flags; /*!< SPI dma format , 1 use dma */
} TUYA_SPI_BASE_CFG_T;
Name | Definition |
---|---|
TUYA_SPI_ROLE_INACTIVE | The SPI is idle. |
TUYA_SPI_ROLE_MASTER | The SPI is in full-duplex controller mode. |
TUYA_SPI_ROLE_SLAVE | The SPI is in full-duplex peripheral mode. |
TUYA_SPI_ROLE_MASTER_SIMPLEX | The SPI is in half-duplex controller mode. |
TUYA_SPI_ROLE_SLAVE_SIMPLEX | The SPI is in half-duplex peripheral mode. |
Name | Definition |
---|---|
TUYA_SPI_MODE0 | CPOL = 0, CPHA = 0 |
TUYA_SPI_MODE1 | CPOL = 0, CPHA = 1 |
TUYA_SPI_MODE2 | CPOL = 1, CPHA = 0 |
TUYA_SPI_MODE3 | CPOL = 1, CPHA = 1 |
Name | Definition | Remarks |
---|---|---|
TUYA_SPI_AUTO_TYPE | SS pin mode, automatically configured by hardware | Slave select (SS): corresponds to the chip select pin |
TUYA_SPI_SOFT_TYPE | SS pin mode, manually configured by software | - |
TUYA_SPI_SOFT_ONE_WIRE_TYPE | Three-wire mode, with SS pin invalid | - |
Name | Definition |
---|---|
TUYA_SPI_DATA_BIT8 | 8-bit pattern |
TUYA_SPI_DATA_BIT16 | 16-bit pattern |
Name | Definition |
---|---|
TUYA_SPI_ORDER_MSB2LSB | The most significant bit (MSB) first, and the least significant bit (LSB) last |
TUYA_SPI_ORDER_LSB2MSB | The LSB first, and the MSB last |
Return value:
OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.OPERATE_RET tkl_spi_deinit(TUYA_SPI_NUM_E port);
port
: The port number.OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.OPERATE_RET tkl_spi_send(TUYA_SPI_NUM_E port, VOID_T *data, UINT16_T size);
port
: The port number.data
: The buffer address of the data to be sent.size
: The size of the data to be sent.OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.OPERATE_RET tkl_spi_recv(TUYA_SPI_NUM_E port, VOID_T *data, UINT16_T size);
port
: The port number.data
: The buffer address of the data to be received.size
: The size of the data to be received.OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.OPERATE_RET tkl_spi_transfer(TUYA_SPI_NUM_E port, VOID_T* send_buf, VOID_T* receive_buf, UINT32_T length);
port
: The port number.send_buf
: The buffer address of the data to be sent.receive_buf
: The buffer address of the data to be received.length
: The length.OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.OPERATE_RET tkl_spi_abort_transfer(TUYA_SPI_NUM_E port);
port
: The port number.OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.OPERATE_RET tkl_spi_get_status(TUYA_SPI_NUM_E port, TUYA_SPI_STATUS_T *status);
port
: The port number.TUYA_SPI_STATUS_T
.Name | Definition | Remarks |
---|---|---|
busy : 1 |
Busy status bit of data transfer, receiving, and sending | 1: valid |
data_lost : 1 |
Data loss | 1: valid |
mode_fault : 1 |
Mode error | 1: valid |
OPERATE_RET tkl_spi_irq_init(TUYA_SPI_NUM_E port, TUYA_SPI_IRQ_CB cb);
port
: The port number.cb
: The interrupt callback.OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.OPERATE_RET tkl_spi_irq_enable(TUYA_SPI_NUM_E port);
port
: The port number.OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.OPERATE_RET tkl_spi_irq_disable(TUYA_SPI_NUM_E port);
port
: The port number.OPRT_OK
: success. For more information, see the definitions in tuya_error_code.h
> OS_ADAPTER_SPI
.INT32_T tkl_spi_get_data_count(TUYA_SPI_NUM_E port);
port
: The port number.< 0
: An error occurred.≥ 0
: The length in bytes of the last transfer.tkl_spi_send
, tkl_spi_recv
, and tkl_spi_transfer
.void tuya_spi_test1(void)
{
OPERATE_RET ret;
TUYA_SPI_BASE_CFG_T cfg;
TUYA_SPI_STATUS_T status;
// Receive buffer
char rcv_buf[8];
// Data to send
char send_buf[8] = {0,1,2,3,4,5,6,7};
tkl_io_pinmux_config(TUYA_IO_PIN_0, TUYA_SPI0_MISO);
tkl_io_pinmux_config(TUYA_IO_PIN_1, TUYA_SPI0_MOSI);
tkl_io_pinmux_config(TUYA_IO_PIN_2, TUYA_SPI0_CS);
tkl_io_pinmux_config(TUYA_IO_PIN_3, TUYA_SPI0_CLK);
cfg.role = TUYA_SPI_ROLE_MASTER;
cfg.mode = TUYA_SPI_MODE0;
cfg.type = TUYA_SPI_AUTO_TYPE;
cfg.databits = TUYA_SPI_DATA_BIT8;
cfg.bitorder = TUYA_SPI_ORDER_MSB2LSB;
cfg.freq_hz = 1000000;
ret = tkl_spi_init(TUYA_SPI_NUM_0, &cfg);
if (ret != OPRT_OK) {
// Failed
return;
}
ret = tkl_spi_send(TUYA_SPI_NUM_0, send_buf, 8);
if (ret < 0) {
// Failed
}
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
while (status.busy) {
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
tkl_system_sleep(2);
}
ret = tkl_spi_recv(TUYA_SPI_NUM_0, rcv_buf, 8);
if (ret < 0) {
// Failed
}
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
while (status.busy) {
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
tkl_system_sleep(2);
}
ret = tkl_spi_transfer(TUYA_SPI_NUM_0, send_buf,rcv_buf, 6);
if (ret < 0) {
// Failed
}
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
while (status.busy) {
tkl_spi_get_status(TUYA_SPI_NUM_0, &status);
tkl_system_sleep(2);
}
// Uninitialize iic
ret = tkl_spi_deinit(TUYA_SPI_NUM_0);
if (ret != 0) {
// Failed
}
}
int event_flag = -1;
static void spi_event_cb(TUYA_SPI_NUM_E port, TUYA_SPI_IRQ_EVT_E event)
{
//printf("\nspi_event_cb_fun:%d\n",event);
event_flag = event;
}
void tuya_spi_test2(void)
{
OPERATE_RET ret;
TUYA_SPI_BASE_CFG_T cfg;
TUYA_SPI_STATUS_T status;
// Receive buffer
char rcv_buf[6];
// Data to send
char send_buf[6] = {0x90,0x0,0x0,0x0,0x0,0x0};
tkl_io_pinmux_config(TUYA_IO_PIN_0, TUYA_SPI0_MISO);
tkl_io_pinmux_config(TUYA_IO_PIN_1, TUYA_SPI0_MOSI);
tkl_io_pinmux_config(TUYA_IO_PIN_2, TUYA_SPI0_CS);
tkl_io_pinmux_config(TUYA_IO_PIN_3, TUYA_SPI0_CLK);
cfg.role = TUYA_SPI_ROLE_MASTER;
cfg.mode = TUYA_SPI_MODE0;
cfg.type = TUYA_SPI_AUTO_TYPE;
cfg.databits = TUYA_SPI_DATA_BIT8;
cfg.bitorder = TUYA_SPI_ORDER_MSB2LSB;
cfg.freq_hz = 1000000;
ret = tkl_spi_init(TUYA_SPI_NUM_0, &cfg);
if (ret != OPRT_OK) {
// Failed
return;
}
tkl_spi_irq_init(TUYA_SPI_NUM_0 , spi_event_cb);
tkl_spi_irq_enable(TUYA_SPI_NUM_0);
event_flag = -1;
ret = tkl_spi_transfer(TUYA_SPI_NUM_0, send_buf,rcv_buf, 6);
if (ret < 0) {
// Failed
}
while (TUYA_SPI_EVENT_TRANSFER_COMPLETE != event_flag) {
tkl_system_sleep(2);
}
// Transfer completed
event_flag = -1;
ret = tkl_spi_send(TUYA_SPI_NUM_0, send_buf, 6);
if (ret < 0) {
// Failed
}
while (TUYA_SPI_EVENT_TX_COMPLETE != event_flag) {
tkl_system_sleep(2);
}
// Sending completed
event_flag = -1;
ret = tkl_spi_recv(TUYA_SPI_NUM_0, rcv_buf, 6);
if (ret < 0) {
// Failed
}
while (TUYA_SPI_EVENT_RX_COMPLETE != event_flag) {
tkl_system_sleep(2);
}
// Receiving completed
tkl_spi_irq_disable(TUYA_SPI_NUM_0);
// Uninitialize iic
ret = tkl_spi_deinit(TUYA_SPI_NUM_0);
if (ret != 0) {
// Failed
}
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback