mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/soft_spi:fix soft spi transfer bug
This commit is contained in:
parent
8ca676aa6e
commit
0c39c2321f
@ -30,6 +30,7 @@
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define READ_PADDING_BYTE (0x00)
|
||||
/**
|
||||
* @brief Allocate one lock per SPI device
|
||||
*/
|
||||
@ -79,7 +80,7 @@ void soft_spi_init_pins(soft_spi_t bus)
|
||||
gpio_clear(soft_spi_config[bus].mosi_pin);
|
||||
}
|
||||
if (gpio_is_valid(soft_spi_config[bus].miso_pin)) {
|
||||
gpio_init(soft_spi_config[bus].mosi_pin, GPIO_IN);
|
||||
gpio_init(soft_spi_config[bus].miso_pin, GPIO_IN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,29 +138,35 @@ void soft_spi_release(soft_spi_t bus)
|
||||
|
||||
static inline uint8_t _transfer_one_byte(soft_spi_t bus, uint8_t out)
|
||||
{
|
||||
int8_t bit = 0, i = 0;
|
||||
uint8_t i = 8;
|
||||
if (SOFT_SPI_MODE_1 == soft_spi_config[bus].soft_spi_mode ||
|
||||
SOFT_SPI_MODE_3 == soft_spi_config[bus].soft_spi_mode) {
|
||||
/* CPHA = 1*/
|
||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
||||
}
|
||||
|
||||
bit = (out & (1 << 7)) >> 7;
|
||||
gpio_write(soft_spi_config[bus].mosi_pin, bit);
|
||||
for (i = 6; i >= 0; i--) {
|
||||
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
||||
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
||||
bit = (out & (1 << i)) >> i;
|
||||
do {
|
||||
uint8_t bit = out >> 7;
|
||||
gpio_write(soft_spi_config[bus].mosi_pin, bit);
|
||||
}
|
||||
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
||||
|
||||
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
||||
|
||||
out <<= 1; /*shift transfer register*/
|
||||
|
||||
bit = gpio_read(soft_spi_config[bus].miso_pin);
|
||||
out = bit ? (out | 0x01) : (out & 0xfe); /*set or delete bit 0*/
|
||||
|
||||
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
||||
--i;
|
||||
if (i > 0) {
|
||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
||||
}
|
||||
} while (i > 0);
|
||||
|
||||
if (SOFT_SPI_MODE_0 == soft_spi_config[bus].soft_spi_mode ||
|
||||
SOFT_SPI_MODE_2 == soft_spi_config[bus].soft_spi_mode) {
|
||||
/* CPHASE = 1 */
|
||||
/* CPHA = 0 */
|
||||
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
||||
}
|
||||
@ -191,22 +198,40 @@ uint8_t soft_spi_transfer_byte(soft_spi_t bus, soft_spi_cs_t cs, bool cont, uint
|
||||
}
|
||||
|
||||
void soft_spi_transfer_bytes(soft_spi_t bus, soft_spi_cs_t cs, bool cont,
|
||||
const void *out, void *in, size_t len)
|
||||
const void *out, void *in, size_t len)
|
||||
{
|
||||
DEBUG("Soft SPI soft_spi_transfer_bytes\n");
|
||||
|
||||
assert(soft_spi_bus_is_valid(bus));
|
||||
/* make sure at least one input or one output buffer is given */
|
||||
assert(out || in);
|
||||
|
||||
uint8_t tmp = 0;
|
||||
const uint8_t *outbuf = out;
|
||||
uint8_t *inbuf = in;
|
||||
|
||||
for (size_t i = 0; i < len-1; i++) {
|
||||
tmp = (NULL != out) ? ((uint8_t *)out)[i] : 0;
|
||||
uint8_t retval = soft_spi_transfer_byte(bus, cs, true, tmp);
|
||||
if (NULL != in) {
|
||||
((uint8_t *)in)[0] = retval;
|
||||
/* activate the given chip select line */
|
||||
if ((cs != GPIO_UNDEF) && (cs != SOFT_SPI_CS_UNDEF)) {
|
||||
gpio_clear((gpio_t)cs);
|
||||
}
|
||||
|
||||
if (!inbuf) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
_transfer_one_byte(bus, outbuf[i]);
|
||||
}
|
||||
}
|
||||
else if (!outbuf) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
inbuf[i] = _transfer_one_byte(bus, READ_PADDING_BYTE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
inbuf[i] = _transfer_one_byte(bus, outbuf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
tmp = (NULL != out) ? ((uint8_t *)out)[len-1] : 0;
|
||||
soft_spi_transfer_byte(bus, cs, cont, tmp);
|
||||
if (!cont) {
|
||||
if ((cs != GPIO_UNDEF) && (cs != SOFT_SPI_CS_UNDEF)) {
|
||||
gpio_set((gpio_t)cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user