From b20f21f2c5b5e84b06e16a50ac98e22a3d381ab8 Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:38:01 +0100 Subject: [PATCH 01/12] sam3x8e: Basic implementation of spi_acquire(), spi_release() Signed-off-by: Joakim Gebart --- cpu/sam3x8e/periph/spi.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/cpu/sam3x8e/periph/spi.c b/cpu/sam3x8e/periph/spi.c index 62d2d32cdf..96971c9fcb 100644 --- a/cpu/sam3x8e/periph/spi.c +++ b/cpu/sam3x8e/periph/spi.c @@ -15,11 +15,14 @@ * * @author Maxime Blanloeil * @author Peter Kietzmann + * @author Hauke Petersen + * @author Joakim Gebart * * @} */ #include "cpu.h" +#include "mutex.h" #include "sched.h" #include "thread.h" #include "periph/gpio.h" @@ -30,6 +33,21 @@ /* guard this file in case no SPI device is defined */ #if SPI_NUMOF +/** + * @brief Array holding one pre-initialized mutex for each SPI device + */ +static mutex_t locks[] = { +#if SPI_0_EN + [SPI_0] = MUTEX_INIT, +#endif +#if SPI_1_EN + [SPI_1] = MUTEX_INIT, +#endif +#if SPI_2_EN + [SPI_2] = MUTEX_INIT +#endif +}; + typedef struct { char(*cb)(char data); } spi_state_t; @@ -274,6 +292,24 @@ int spi_conf_pins(spi_t dev) return 0; } +int spi_acquire(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_lock(&locks[dev]); + return 0; +} + +int spi_release(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_unlock(&locks[dev]); + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { Spi *spi_port; From bec43f11d8c3155b58666d7dfeb17c13710d8ba0 Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:38:01 +0100 Subject: [PATCH 02/12] samd21: Basic implementation of spi_acquire(), spi_release() Signed-off-by: Joakim Gebart --- cpu/samd21/periph/spi.c | 42 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/cpu/samd21/periph/spi.c b/cpu/samd21/periph/spi.c index d921e42204..f3ce948a1a 100644 --- a/cpu/samd21/periph/spi.c +++ b/cpu/samd21/periph/spi.c @@ -14,12 +14,15 @@ * @brief Low-level SPI driver implementation * * @author Thomas Eichinger - * Troels Hoffmeyer + * @author Troels Hoffmeyer + * @author Hauke Petersen + * @author Joakim Gebart * * @} */ #include "cpu.h" +#include "mutex.h" #include "periph/gpio.h" #include "periph/spi.h" #include "periph_conf.h" @@ -28,6 +31,21 @@ #include "debug.h" #if SPI_0_EN || SPI_1_EN +/** + * @brief Array holding one pre-initialized mutex for each SPI device + */ +static mutex_t locks[] = { +#if SPI_0_EN + [SPI_0] = MUTEX_INIT, +#endif +#if SPI_1_EN + [SPI_1] = MUTEX_INIT, +#endif +#if SPI_2_EN + [SPI_2] = MUTEX_INIT +#endif +}; + int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { SercomSpi* spi_dev = 0; @@ -80,7 +98,7 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) /* Enable sercom4 in power manager */ PM->APBCMASK.reg |= PM_APBCMASK_SERCOM4; GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN - | GCLK_CLKCTRL_GEN_GCLK0 + | GCLK_CLKCTRL_GEN_GCLK0 | (SERCOM4_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos))); /* Setup clock */ @@ -174,7 +192,25 @@ int spi_init_slave(spi_t dev, spi_conf_t conf, char (*cb)(char)) } void spi_transmission_begin(spi_t dev, char reset_val) { - /* TODO*/ + /* TODO*/ +} + +int spi_acquire(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_lock(&locks[dev]); + return 0; +} + +int spi_release(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_unlock(&locks[dev]); + return 0; } int spi_transfer_byte(spi_t dev, char out, char *in) From 98c88b0549624f8a4ed64f0e34fb5222e075b320 Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:38:01 +0100 Subject: [PATCH 03/12] stm32f0: Basic implementation of spi_acquire(), spi_release() Signed-off-by: Joakim Gebart --- cpu/stm32f0/periph/spi.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/cpu/stm32f0/periph/spi.c b/cpu/stm32f0/periph/spi.c index 6b9bc1c3f8..8d5929139e 100644 --- a/cpu/stm32f0/periph/spi.c +++ b/cpu/stm32f0/periph/spi.c @@ -16,12 +16,14 @@ * @author Peter Kietzmann * @author Hauke Petersen * @author Fabian Nack + * @author Joakim Gebart * * @} */ #include "cpu.h" #include "board.h" +#include "mutex.h" #include "periph/spi.h" #include "periph_conf.h" #include "thread.h" @@ -30,6 +32,21 @@ /* guard file in case no SPI device is defined */ #if SPI_NUMOF +/** + * @brief Array holding one pre-initialized mutex for each SPI device + */ +static mutex_t locks[] = { +#if SPI_0_EN + [SPI_0] = MUTEX_INIT, +#endif +#if SPI_1_EN + [SPI_1] = MUTEX_INIT, +#endif +#if SPI_2_EN + [SPI_2] = MUTEX_INIT +#endif +}; + int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { SPI_TypeDef *spi; @@ -142,6 +159,24 @@ int spi_conf_pins(spi_t dev) return 0; } +int spi_acquire(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_lock(&locks[dev]); + return 0; +} + +int spi_release(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_unlock(&locks[dev]); + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { char tmp; From f64c54bf6666fcedc21a0484cb1cb2c2bb2e17b0 Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:38:02 +0100 Subject: [PATCH 04/12] stm32f1: Basic implementation of spi_acquire(), spi_release() Signed-off-by: Joakim Gebart --- cpu/stm32f1/periph/spi.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/cpu/stm32f1/periph/spi.c b/cpu/stm32f1/periph/spi.c index 0944099a8f..8956191689 100644 --- a/cpu/stm32f1/periph/spi.c +++ b/cpu/stm32f1/periph/spi.c @@ -15,11 +15,14 @@ * * @author Thomas Eichinger * @author Fabian Nack + * @author Hauke Petersen + * @author Joakim Gebart * * @} */ #include "stm32f10x.h" +#include "mutex.h" #include "periph/gpio.h" #include "periph/spi.h" #include "periph_conf.h" @@ -31,6 +34,21 @@ /* guard file in case no SPI device is defined */ #if SPI_0_EN +/** + * @brief Array holding one pre-initialized mutex for each SPI device + */ +static mutex_t locks[] = { +#if SPI_0_EN + [SPI_0] = MUTEX_INIT, +#endif +#if SPI_1_EN + [SPI_1] = MUTEX_INIT, +#endif +#if SPI_2_EN + [SPI_2] = MUTEX_INIT +#endif +}; + int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { SPI_TypeDef *spi; @@ -125,6 +143,24 @@ int spi_conf_pins(spi_t dev) return 0; } +int spi_acquire(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_lock(&locks[dev]); + return 0; +} + +int spi_release(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_unlock(&locks[dev]); + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { SPI_TypeDef *spi; From 32929875160f0ec4c0b14a5fbb9f290e70cf38ce Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:38:02 +0100 Subject: [PATCH 05/12] stm32f3: Basic implementation of spi_acquire(), spi_release() Signed-off-by: Joakim Gebart --- cpu/stm32f3/periph/spi.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/cpu/stm32f3/periph/spi.c b/cpu/stm32f3/periph/spi.c index 6203ec6dee..2b401e6468 100644 --- a/cpu/stm32f3/periph/spi.c +++ b/cpu/stm32f3/periph/spi.c @@ -17,6 +17,7 @@ * @author Peter Kietzmann * @author Fabian Nack * @author Hauke Petersen + * @author Joakim Gebart * * @} */ @@ -24,6 +25,7 @@ #include "board.h" #include "cpu.h" +#include "mutex.h" #include "periph/spi.h" #include "periph_conf.h" #include "thread.h" @@ -57,6 +59,21 @@ static inline void irq_handler_transfer(SPI_TypeDef *spi, spi_t dev); static spi_state_t spi_config[SPI_NUMOF]; +/** + * @brief Array holding one pre-initialized mutex for each SPI device + */ +static mutex_t locks[] = { +#if SPI_0_EN + [SPI_0] = MUTEX_INIT, +#endif +#if SPI_1_EN + [SPI_1] = MUTEX_INIT, +#endif +#if SPI_2_EN + [SPI_2] = MUTEX_INIT +#endif +}; + int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { uint8_t speed_divider; @@ -262,6 +279,24 @@ int spi_conf_pins(spi_t dev) return 0; } +int spi_acquire(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_lock(&locks[dev]); + return 0; +} + +int spi_release(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_unlock(&locks[dev]); + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { if (dev >= SPI_NUMOF) { From d68b4ef6c2aa148f0189040c56aeebab7b6a5bfe Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:38:02 +0100 Subject: [PATCH 06/12] stm32l1: Basic implementation of spi_acquire(), spi_release() Signed-off-by: Joakim Gebart --- cpu/stm32l1/periph/spi.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/cpu/stm32l1/periph/spi.c b/cpu/stm32l1/periph/spi.c index 5d983ab5b9..f2544ec4be 100644 --- a/cpu/stm32l1/periph/spi.c +++ b/cpu/stm32l1/periph/spi.c @@ -17,11 +17,13 @@ * @author Hauke Petersen * @author Fabian Nack * @author Thomas Eichinger + * @author Joakim Gebart * * @} */ #include "cpu.h" +#include "mutex.h" #include "periph/spi.h" #include "periph_conf.h" #include "thread.h" @@ -30,6 +32,21 @@ /* guard file in case no SPI device is defined */ #if SPI_NUMOF +/** + * @brief Array holding one pre-initialized mutex for each SPI device + */ +static mutex_t locks[] = { +#if SPI_0_EN + [SPI_0] = MUTEX_INIT, +#endif +#if SPI_1_EN + [SPI_1] = MUTEX_INIT, +#endif +#if SPI_2_EN + [SPI_2] = MUTEX_INIT +#endif +}; + int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { SPI_TypeDef *spi; @@ -138,6 +155,24 @@ int spi_conf_pins(spi_t dev) return 0; } +int spi_acquire(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_lock(&locks[dev]); + return 0; +} + +int spi_release(spi_t dev) +{ + if (dev >= SPI_NUMOF) { + return -1; + } + mutex_unlock(&locks[dev]); + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { char tmp; From 1f577b4fee6e3bfe6c5369f30fd9c3a2fea7e5db Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:46:58 +0100 Subject: [PATCH 07/12] at86rf231: Acquire exclusive access to SPI bus. Signed-off-by: Joakim Gebart --- drivers/at86rf231/at86rf231.c | 2 ++ drivers/at86rf231/at86rf231_spi.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/at86rf231/at86rf231.c b/drivers/at86rf231/at86rf231.c index 55e3013729..b26aea18b0 100644 --- a/drivers/at86rf231/at86rf231.c +++ b/drivers/at86rf231/at86rf231.c @@ -411,7 +411,9 @@ int at86rf231_get_monitor(void) void at86rf231_gpio_spi_interrupts_init(void) { /* SPI init */ + spi_acquire(AT86RF231_SPI); spi_init_master(AT86RF231_SPI, SPI_CONF_FIRST_RISING, SPI_SPEED); + spi_release(AT86RF231_SPI); /* IRQ0 */ gpio_init_int(AT86RF231_INT, GPIO_NOPULL, GPIO_RISING, (gpio_cb_t)at86rf231_rx_irq, NULL); /* CS */ diff --git a/drivers/at86rf231/at86rf231_spi.c b/drivers/at86rf231/at86rf231_spi.c index 72fb0ff987..8dc7b9d413 100644 --- a/drivers/at86rf231/at86rf231_spi.c +++ b/drivers/at86rf231/at86rf231_spi.c @@ -15,6 +15,7 @@ * * @author Alaeddine Weslati * @author Thomas Eichinger + * @author Joakim Gebart * * @} */ @@ -27,29 +28,39 @@ void at86rf231_reg_write(uint8_t addr, uint8_t value) { + /* Acquire exclusive access to the bus. */ + spi_acquire(AT86RF231_SPI); /* Start the SPI transfer */ gpio_clear(AT86RF231_CS); /* write to register */ spi_transfer_reg(AT86RF231_SPI, AT86RF231_ACCESS_REG | AT86RF231_ACCESS_WRITE | addr, value, 0); /* End the SPI transfer */ gpio_set(AT86RF231_CS); + /* Release the bus for other threads. */ + spi_release(AT86RF231_SPI); } uint8_t at86rf231_reg_read(uint8_t addr) { char value; + /* Acquire exclusive access to the bus. */ + spi_acquire(AT86RF231_SPI); /* Start the SPI transfer */ gpio_clear(AT86RF231_CS); /* read from register */ spi_transfer_reg(AT86RF231_SPI, AT86RF231_ACCESS_REG | AT86RF231_ACCESS_READ | addr, 0, &value); /* End the SPI transfer */ gpio_set(AT86RF231_CS); + /* Release the bus for other threads. */ + spi_release(AT86RF231_SPI); return (uint8_t)value; } void at86rf231_read_fifo(uint8_t *data, radio_packet_length_t length) { + /* Acquire exclusive access to the bus. */ + spi_acquire(AT86RF231_SPI); /* Start the SPI transfer */ gpio_clear(AT86RF231_CS); /* Read a number of bytes from the devices frame buffer */ @@ -57,10 +68,14 @@ void at86rf231_read_fifo(uint8_t *data, radio_packet_length_t length) 0, (char*)data, length); /* End the SPI transfer */ gpio_set(AT86RF231_CS); + /* Release the bus for other threads. */ + spi_release(AT86RF231_SPI); } void at86rf231_write_fifo(const uint8_t *data, radio_packet_length_t length) { + /* Acquire exclusive access to the bus. */ + spi_acquire(AT86RF231_SPI); /* Start the SPI transfer */ gpio_clear(AT86RF231_CS); /* Send Frame Buffer Write access */ @@ -68,6 +83,8 @@ void at86rf231_write_fifo(const uint8_t *data, radio_packet_length_t length) (char*)data, 0, length); /* End the SPI transfer */ gpio_set(AT86RF231_CS); + /* Release the bus for other threads. */ + spi_release(AT86RF231_SPI); } uint8_t at86rf231_get_status(void) From af1ddef1fb3744e8cdd5fafbf7ce30963574661b Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:47:21 +0100 Subject: [PATCH 08/12] cc110x: Acquire exclusive access to SPI bus. Signed-off-by: Joakim Gebart --- drivers/cc110x/cc110x-spi.c | 31 +++++++++++++++++++++++++------ drivers/cc110x/cc110x.c | 2 ++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/cc110x/cc110x-spi.c b/drivers/cc110x/cc110x-spi.c index cddb33161b..178b7bcb60 100644 --- a/drivers/cc110x/cc110x-spi.c +++ b/drivers/cc110x/cc110x-spi.c @@ -16,6 +16,7 @@ * @author Thomas Hillebrandt * @author Heiko Will * @author Fabian Nack + * @author Joakim Gebart * @} */ @@ -65,17 +66,22 @@ void cc110x_cs(void) void cc110x_writeburst_reg(uint8_t addr, char *src, uint8_t count) { - unsigned int cpsr = disableIRQ(); + unsigned int cpsr; + spi_acquire(CC110X_SPI); + cpsr = disableIRQ(); cc110x_cs(); spi_transfer_regs(CC110X_SPI, addr | CC1100_WRITE_BURST, src, 0, count); gpio_set(CC110X_CS); restoreIRQ(cpsr); + spi_release(CC110X_SPI); } void cc110x_readburst_reg(uint8_t addr, char *buffer, uint8_t count) { int i = 0; - unsigned int cpsr = disableIRQ(); + unsigned int cpsr; + spi_acquire(CC110X_SPI); + cpsr = disableIRQ(); cc110x_cs(); spi_transfer_byte(CC110X_SPI, addr | CC1100_READ_BURST, 0); while (i < count) { @@ -84,46 +90,59 @@ void cc110x_readburst_reg(uint8_t addr, char *buffer, uint8_t count) } gpio_set(CC110X_CS); restoreIRQ(cpsr); + spi_release(CC110X_SPI); } void cc110x_write_reg(uint8_t addr, uint8_t value) { - unsigned int cpsr = disableIRQ(); + unsigned int cpsr; + spi_acquire(CC110X_SPI); + cpsr = disableIRQ(); cc110x_cs(); spi_transfer_reg(CC110X_SPI, addr, value, 0); gpio_set(CC110X_CS); restoreIRQ(cpsr); + spi_release(CC110X_SPI); } uint8_t cc110x_read_reg(uint8_t addr) { char result; - unsigned int cpsr = disableIRQ(); + unsigned int cpsr; + spi_acquire(CC110X_SPI); + cpsr = disableIRQ(); cc110x_cs(); spi_transfer_reg(CC110X_SPI, addr | CC1100_READ_SINGLE, CC1100_NOBYTE, &result); gpio_set(CC110X_CS); restoreIRQ(cpsr); + spi_release(CC110X_SPI); return (uint8_t) result; } uint8_t cc110x_read_status(uint8_t addr) { char result; - unsigned int cpsr = disableIRQ(); + unsigned int cpsr; + spi_acquire(CC110X_SPI); + cpsr = disableIRQ(); cc110x_cs(); spi_transfer_reg(CC110X_SPI, addr | CC1100_READ_BURST, CC1100_NOBYTE, &result); gpio_set(CC110X_CS); restoreIRQ(cpsr); + spi_release(CC110X_SPI); return (uint8_t) result; } uint8_t cc110x_strobe(uint8_t c) { char result; - unsigned int cpsr = disableIRQ(); + unsigned int cpsr; + spi_acquire(CC110X_SPI); + cpsr = disableIRQ(); cc110x_cs(); spi_transfer_byte(CC110X_SPI, c, &result); gpio_set(CC110X_CS); restoreIRQ(cpsr); + spi_release(CC110X_SPI); return (uint8_t) result; } diff --git a/drivers/cc110x/cc110x.c b/drivers/cc110x/cc110x.c index 671da45f87..4e1f6c1cfa 100644 --- a/drivers/cc110x/cc110x.c +++ b/drivers/cc110x/cc110x.c @@ -76,7 +76,9 @@ int cc110x_initialize(netdev_t *dev) /* Configure SPI */ spi_poweron(CC110X_SPI); + spi_acquire(CC110X_SPI); spi_init_master(CC110X_SPI, SPI_CONF_FIRST_RISING, SPI_SPEED_5MHZ); + spi_release(CC110X_SPI); /* Load driver & reset */ power_up_reset(); From a991d7c58e7c95f97f3cbad85f14ee1ac8288e62 Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:22:46 +0100 Subject: [PATCH 09/12] nrf24l01p: Remove redundant gpio_clear/gpio_set. This change removes extra gpio_clear(dev->cs) before calling nrf24l01p_read_reg(), nrf24l01p_write_reg(). The GPIO handling is not necessary since nrf24l01p_{read,write}_reg() handle the CS pin internally. Signed-off-by: Joakim Gebart --- drivers/nrf24l01p/nrf24l01p.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/nrf24l01p/nrf24l01p.c b/drivers/nrf24l01p/nrf24l01p.c index 7ffe844309..df48c40257 100644 --- a/drivers/nrf24l01p/nrf24l01p.c +++ b/drivers/nrf24l01p/nrf24l01p.c @@ -189,12 +189,10 @@ int nrf24l01p_on(nrf24l01p_t *dev) char read; int status; - gpio_clear(dev->cs); nrf24l01p_read_reg(dev, REG_CONFIG, &read); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = nrf24l01p_write_reg(dev, REG_CONFIG, (read | PWR_UP)); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); - gpio_set(dev->cs); hwtimer_wait(DELAY_CHANGE_PWR_MODE_US); @@ -206,12 +204,10 @@ int nrf24l01p_off(nrf24l01p_t *dev) char read; int status; - gpio_clear(dev->cs); nrf24l01p_read_reg(dev, REG_CONFIG, &read); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = nrf24l01p_write_reg(dev, REG_CONFIG, (read & ~PWR_UP)); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); - gpio_set(dev->cs); hwtimer_wait(DELAY_CHANGE_PWR_MODE_US); From b6d94d95258ecc6eb3fd66060174a304253de5b5 Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Mon, 19 Jan 2015 16:34:52 +0100 Subject: [PATCH 10/12] nrf24l01p: Remove superfluous delays in nrf24l01p_on, nrf24l01p_off. The delays were introduced in an attempt to fix "inexplicable timing errors", although the errors were in the SPI bus driver rather than the nrf24l01p driver. See also: - https://github.com/RIOT-OS/RIOT/pull/1704 - https://github.com/RIOT-OS/RIOT/pull/2315 Signed-off-by: Joakim Gebart --- drivers/nrf24l01p/nrf24l01p.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/nrf24l01p/nrf24l01p.c b/drivers/nrf24l01p/nrf24l01p.c index df48c40257..be327dee8e 100644 --- a/drivers/nrf24l01p/nrf24l01p.c +++ b/drivers/nrf24l01p/nrf24l01p.c @@ -190,9 +190,7 @@ int nrf24l01p_on(nrf24l01p_t *dev) int status; nrf24l01p_read_reg(dev, REG_CONFIG, &read); - hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = nrf24l01p_write_reg(dev, REG_CONFIG, (read | PWR_UP)); - hwtimer_spin(DELAY_CS_TOGGLE_TICKS); hwtimer_wait(DELAY_CHANGE_PWR_MODE_US); @@ -205,9 +203,7 @@ int nrf24l01p_off(nrf24l01p_t *dev) int status; nrf24l01p_read_reg(dev, REG_CONFIG, &read); - hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = nrf24l01p_write_reg(dev, REG_CONFIG, (read & ~PWR_UP)); - hwtimer_spin(DELAY_CS_TOGGLE_TICKS); hwtimer_wait(DELAY_CHANGE_PWR_MODE_US); From c457cd954df35593c157cd6e343332a52f843cc5 Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 13:47:38 +0100 Subject: [PATCH 11/12] nrf24l01p: Acquire exclusive access to SPI bus. Signed-off-by: Joakim Gebart --- drivers/nrf24l01p/nrf24l01p.c | 53 ++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/nrf24l01p/nrf24l01p.c b/drivers/nrf24l01p/nrf24l01p.c index be327dee8e..f319f2b9b4 100644 --- a/drivers/nrf24l01p/nrf24l01p.c +++ b/drivers/nrf24l01p/nrf24l01p.c @@ -10,10 +10,12 @@ * @ingroup drivers_nrf24l01p * @{ * @author Peter Kietzmann + * @author Joakim Gebart * @} */ #include "nrf24l01p.h" #include "nrf24l01p_settings.h" +#include "mutex.h" #include "periph/gpio.h" #include "periph/spi.h" #include "hwtimer.h" @@ -29,11 +31,15 @@ int nrf24l01p_read_reg(nrf24l01p_t *dev, char reg, char *answer) { int status; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_reg(dev->spi, (CMD_R_REGISTER | (REGISTER_MASK & reg)), CMD_NOP, answer); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -45,11 +51,15 @@ int nrf24l01p_write_reg(nrf24l01p_t *dev, char reg, char write) int status; char reg_content; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_reg(dev->spi, (CMD_W_REGISTER | (REGISTER_MASK & reg)), write, ®_content); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -82,7 +92,9 @@ int nrf24l01p_init(nrf24l01p_t *dev, spi_t spi, gpio_t ce, gpio_t cs, gpio_t irq /* Init SPI */ spi_poweron(dev->spi); + spi_acquire(dev->spi); status = spi_init_master(dev->spi, SPI_CONF_FIRST_RISING, SPI_SPEED_400KHZ); + spi_release(dev->spi); if (status < 0) { return status; @@ -223,12 +235,16 @@ int nrf24l01p_read_payload(nrf24l01p_t *dev, char *answer, unsigned int size) { int status; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_regs(dev->spi, CMD_R_RX_PAYLOAD, 0, answer, size); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); + /* Release the bus for other threads. */ + spi_release(dev->spi); return status; } @@ -272,11 +288,15 @@ int nrf24l01p_preload(nrf24l01p_t *dev, char *data, unsigned int size) size = (size <= 32) ? size : 32; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_regs(dev->spi, CMD_W_TX_PAYLOAD, data, NULL, size); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -373,11 +393,15 @@ int nrf24l01p_set_tx_address(nrf24l01p_t *dev, char *saddr, unsigned int length) { int status; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_regs(dev->spi, (CMD_W_REGISTER | (REGISTER_MASK & REG_TX_ADDR)), saddr, NULL, length); /* address width is 5 byte */ hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -400,11 +424,15 @@ int nrf24l01p_set_tx_address_long(nrf24l01p_t *dev, uint64_t saddr, unsigned int return -1; } + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_regs(dev->spi, (CMD_W_REGISTER | (REGISTER_MASK & REG_TX_ADDR)), buf, NULL, length); /* address width is 5 byte */ hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -417,11 +445,15 @@ uint64_t nrf24l01p_get_tx_address_long(nrf24l01p_t *dev) uint64_t saddr_64 = 0; char addr_array[INITIAL_ADDRESS_WIDTH]; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_regs(dev->spi, (CMD_R_REGISTER | (REGISTER_MASK & REG_TX_ADDR)), 0, addr_array, INITIAL_ADDRESS_WIDTH); /* address width is 5 byte */ hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -473,11 +505,15 @@ int nrf24l01p_set_rx_address(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe, char *s return -1; } + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_regs(dev->spi, (CMD_W_REGISTER | (REGISTER_MASK & pipe_addr)), saddr, NULL, length); /* address width is 5 byte */ hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -541,11 +577,15 @@ uint64_t nrf24l01p_get_rx_address_long(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pip return -1; } + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_regs(dev->spi, (CMD_R_REGISTER | (REGISTER_MASK & pipe_addr)), 0, addr_array, INITIAL_ADDRESS_WIDTH); /* address width is 5 byte */ hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); if (status < 0) { return -1; @@ -592,11 +632,15 @@ int nrf24l01p_set_datarate(nrf24l01p_t *dev, nrf24l01p_dr_t dr) int nrf24l01p_get_status(nrf24l01p_t *dev) { char status; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); spi_transfer_byte(dev->spi, CMD_NOP, &status); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -831,11 +875,15 @@ int nrf24l01p_flush_tx_fifo(nrf24l01p_t *dev) int status; char reg_content; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_byte(dev->spi, CMD_FLUSH_TX, ®_content); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); @@ -847,12 +895,15 @@ int nrf24l01p_flush_rx_fifo(nrf24l01p_t *dev) int status; char reg_content; + /* Acquire exclusive access to the bus. */ + spi_acquire(dev->spi); gpio_clear(dev->cs); - hwtimer_spin(DELAY_CS_TOGGLE_TICKS); status = spi_transfer_byte(dev->spi, CMD_FLUSH_RX, ®_content); hwtimer_spin(DELAY_CS_TOGGLE_TICKS); gpio_set(dev->cs); + /* Release the bus for other threads. */ + spi_release(dev->spi); hwtimer_spin(DELAY_AFTER_FUNC_TICKS); From dfb0d58cfb1e1e9fd4081fcfa38f2e8eafdc9491 Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Fri, 16 Jan 2015 16:05:04 +0100 Subject: [PATCH 12/12] tests/periph_spi: Lock bus for exclusive access when communicating. --- tests/periph_spi/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/periph_spi/main.c b/tests/periph_spi/main.c index 10f2c00544..2a65838f38 100644 --- a/tests/periph_spi/main.c +++ b/tests/periph_spi/main.c @@ -178,7 +178,9 @@ void cmd_init_master(int argc, char **argv) if (parse_spi_dev(argc, argv) < 0) { return; } + spi_acquire(spi_dev); res = spi_init_master(spi_dev, spi_mode, spi_speed); + spi_release(spi_dev); if (res < 0) { printf("spi_init_master: error initializing SPI_%i device (code %i)\n", spi_dev, res); return; @@ -202,7 +204,9 @@ void cmd_init_slave(int argc, char **argv) if (parse_spi_dev(argc, argv) < 0) { return; } + spi_acquire(spi_dev); res = spi_init_slave(spi_dev, spi_mode, slave_on_data); + spi_release(spi_dev); if (res < 0) { printf("spi_init_slave: error initializing SPI_%i device (code: %i)\n", spi_dev, res); return; @@ -236,9 +240,11 @@ void cmd_transfer(int argc, char **argv) } /* do the actual data transfer */ + spi_acquire(spi_dev); gpio_clear(spi_cs); res = spi_transfer_bytes(spi_dev, hello, buffer, strlen(hello)); gpio_set(spi_cs); + spi_release(spi_dev); /* look at the results */ if (res < 0) {