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
|
#define ENABLE_DEBUG 0
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
#define READ_PADDING_BYTE (0x00)
|
||||||
/**
|
/**
|
||||||
* @brief Allocate one lock per SPI device
|
* @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);
|
gpio_clear(soft_spi_config[bus].mosi_pin);
|
||||||
}
|
}
|
||||||
if (gpio_is_valid(soft_spi_config[bus].miso_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)
|
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 ||
|
if (SOFT_SPI_MODE_1 == soft_spi_config[bus].soft_spi_mode ||
|
||||||
SOFT_SPI_MODE_3 == soft_spi_config[bus].soft_spi_mode) {
|
SOFT_SPI_MODE_3 == soft_spi_config[bus].soft_spi_mode) {
|
||||||
/* CPHA = 1*/
|
/* CPHA = 1*/
|
||||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
gpio_toggle(soft_spi_config[bus].clk_pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bit = (out & (1 << 7)) >> 7;
|
do {
|
||||||
gpio_write(soft_spi_config[bus].mosi_pin, bit);
|
uint8_t bit = out >> 7;
|
||||||
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;
|
|
||||||
gpio_write(soft_spi_config[bus].mosi_pin, bit);
|
gpio_write(soft_spi_config[bus].mosi_pin, bit);
|
||||||
}
|
|
||||||
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
||||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
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 ||
|
if (SOFT_SPI_MODE_0 == soft_spi_config[bus].soft_spi_mode ||
|
||||||
SOFT_SPI_MODE_2 == 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);
|
xtimer_nanosleep(soft_spi_config[bus].soft_spi_clk);
|
||||||
gpio_toggle(soft_spi_config[bus].clk_pin);
|
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,
|
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");
|
DEBUG("Soft SPI soft_spi_transfer_bytes\n");
|
||||||
|
|
||||||
assert(soft_spi_bus_is_valid(bus));
|
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++) {
|
/* activate the given chip select line */
|
||||||
tmp = (NULL != out) ? ((uint8_t *)out)[i] : 0;
|
if ((cs != GPIO_UNDEF) && (cs != SOFT_SPI_CS_UNDEF)) {
|
||||||
uint8_t retval = soft_spi_transfer_byte(bus, cs, true, tmp);
|
gpio_clear((gpio_t)cs);
|
||||||
if (NULL != in) {
|
}
|
||||||
((uint8_t *)in)[0] = retval;
|
|
||||||
|
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;
|
if (!cont) {
|
||||||
soft_spi_transfer_byte(bus, cs, cont, tmp);
|
if ((cs != GPIO_UNDEF) && (cs != SOFT_SPI_CS_UNDEF)) {
|
||||||
|
gpio_set((gpio_t)cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user