/** Get a received value out of the SPI receive buffer in slave mode * * Blocks until a value is available * @param[in] obj The SPI peripheral to read * @return The value received */ int spi_slave_read(spi_t *obj) { int count = 0; struct spi_s *spiobj = SPI_S(obj); /* wait the SPI receive buffer is not empty */ while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE)) && (count++ < 1000)); if (count >= 1000) { return -1; } else { return spi_i2s_data_receive(spiobj->spi); } }
/** Write a byte out in master mode and receive a value * * @param[in] obj The SPI peripheral to use for sending * @param[in] value The value to send * @return Returns the value received during send */ int spi_master_write(spi_t *obj, int value) { int count = 0; struct spi_s *spiobj = SPI_S(obj); /* wait the SPI transmit buffer is empty */ while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TBE)) && (count++ < 1000)); if (count >= 1000) { return -1; } else { spi_i2s_data_transmit(spiobj->spi, value); } count = 0; /* wait the SPI receive buffer is not empty */ while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE)) && (count++ < 1000)); if (count >= 1000) { return -1; } else { return spi_i2s_data_receive(spiobj->spi); } }
static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message) { struct rt_spi_bus * gd32_spi_bus = (struct rt_spi_bus *)device->bus; struct gd32f4_spi *f4_spi = (struct gd32f4_spi *)gd32_spi_bus->parent.user_data; struct rt_spi_configuration * config = &device->config; struct gd32_spi_cs * gd32_spi_cs = device->parent.user_data; uint32_t spi_periph = f4_spi->spi_periph; RT_ASSERT(device != NULL); RT_ASSERT(message != NULL); /* take CS */ if(message->cs_take) { gpio_bit_reset(gd32_spi_cs->GPIOx, gd32_spi_cs->GPIO_Pin); DEBUG_PRINTF("spi take cs\n"); } { if(config->data_width <= 8) { const rt_uint8_t * send_ptr = message->send_buf; rt_uint8_t * recv_ptr = message->recv_buf; rt_uint32_t size = message->length; DEBUG_PRINTF("spi poll transfer start: %d\n", size); while(size--) { rt_uint8_t data = 0xFF; if(send_ptr != RT_NULL) { data = *send_ptr++; } // Todo: replace register read/write by gd32f4 lib //Wait until the transmit buffer is empty while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); // Send the byte spi_i2s_data_transmit(spi_periph, data); //Wait until a data is received while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); // Get the received data data = spi_i2s_data_receive(spi_periph); if(recv_ptr != RT_NULL) { *recv_ptr++ = data; } } DEBUG_PRINTF("spi poll transfer finsh\n"); } else if(config->data_width <= 16) { const rt_uint16_t * send_ptr = message->send_buf; rt_uint16_t * recv_ptr = message->recv_buf; rt_uint32_t size = message->length; while(size--) { rt_uint16_t data = 0xFF; if(send_ptr != RT_NULL) { data = *send_ptr++; } //Wait until the transmit buffer is empty while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); // Send the byte spi_i2s_data_transmit(spi_periph, data); //Wait until a data is received while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); // Get the received data data = spi_i2s_data_receive(spi_periph); if(recv_ptr != RT_NULL) { *recv_ptr++ = data; } } } } /* release CS */ if(message->cs_release) { gpio_bit_set(gd32_spi_cs->GPIOx, gd32_spi_cs->GPIO_Pin); DEBUG_PRINTF("spi release cs\n"); } return message->length; };