summaryrefslogtreecommitdiff
path: root/src/stm
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-07-05 00:04:06 -0700
committerKeith Packard <keithp@keithp.com>2014-07-05 00:38:10 -0700
commit292cb8380b478542555b5f370e8252eafa2f74ac (patch)
treec596a045bf49faefe845e42539691db7adbca8cc /src/stm
parente0ee2ac6bc68b73e13bf34fac3ffd4a3b79dce98 (diff)
altos: Rework packet receive for cc1120
Instead of blocking on PQT, just set up the receiver to start going and when the first bit interrupt comes in, grab the SPI bus if possible and configure it for reception. This improves sensitivity in the radio by a significant amount while making the code conceptually a bit nicer. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/stm')
-rw-r--r--src/stm/ao_arch_funcs.h25
-rw-r--r--src/stm/ao_spi_stm.c51
2 files changed, 66 insertions, 10 deletions
diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h
index b461cd3f..7ad3b4b8 100644
--- a/src/stm/ao_arch_funcs.h
+++ b/src/stm/ao_arch_funcs.h
@@ -64,6 +64,9 @@
#define AO_SPI_INDEX(id) ((id) & AO_SPI_INDEX_MASK)
#define AO_SPI_CONFIG(id) ((id) & AO_SPI_CONFIG_MASK)
+uint8_t
+ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id);
+
void
ao_spi_get(uint8_t spi_index, uint32_t speed);
@@ -77,6 +80,9 @@ void
ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index);
void
+ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index);
+
+void
ao_spi_recv(void *block, uint16_t len, uint8_t spi_index);
void
@@ -95,6 +101,15 @@ ao_spi_init(void);
ao_spi_set_cs(reg,mask); \
} while (0)
+static inline uint8_t
+ao_spi_try_get_mask(struct stm_gpio *reg, uint16_t mask, uint8_t bus, uint32_t speed, uint8_t task_id)
+{
+ if (!ao_spi_try_get(bus, speed, task_id))
+ return 0;
+ ao_spi_set_cs(reg, mask);
+ return 1;
+}
+
#define ao_spi_put_mask(reg,mask,bus) do { \
ao_spi_clr_cs(reg,mask); \
ao_spi_put(bus); \
@@ -252,6 +267,8 @@ extern struct ao_stm_usart ao_stm_usart3;
#define ARM_PUSH32(stack, val) (*(--(stack)) = (val))
+typedef uint32_t ao_arch_irq_t;
+
static inline uint32_t
ao_arch_irqsave(void) {
uint32_t primask;
@@ -369,10 +386,10 @@ static inline void ao_arch_start_scheduler(void) {
ao_arch_block_interrupts(); \
} while (0)
-#define ao_arch_critical(b) do { \
- ao_arch_block_interrupts(); \
- do { b } while (0); \
- ao_arch_release_interrupts(); \
+#define ao_arch_critical(b) do { \
+ uint32_t __mask = ao_arch_irqsave(); \
+ do { b } while (0); \
+ ao_arch_irqrestore(__mask); \
} while (0)
#endif /* _AO_ARCH_FUNCS_H_ */
diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c
index 56329c24..885af544 100644
--- a/src/stm/ao_spi_stm.c
+++ b/src/stm/ao_spi_stm.c
@@ -154,6 +154,28 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index)
}
void
+ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index)
+{
+ uint8_t *b = block;
+ struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi;
+
+ stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) |
+ (0 << STM_SPI_CR2_RXNEIE) |
+ (0 << STM_SPI_CR2_ERRIE) |
+ (0 << STM_SPI_CR2_SSOE) |
+ (0 << STM_SPI_CR2_TXDMAEN) |
+ (0 << STM_SPI_CR2_RXDMAEN));
+
+ /* Clear RXNE */
+ (void) stm_spi->dr;
+
+ while (len--) {
+ while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE)));
+ stm_spi->dr = *b++;
+ }
+}
+
+void
ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)
{
struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi;
@@ -356,13 +378,11 @@ ao_spi_enable_index(uint8_t spi_index)
}
}
-void
-ao_spi_get(uint8_t spi_index, uint32_t speed)
+static void
+ao_spi_config(uint8_t spi_index, uint32_t speed)
{
uint8_t id = AO_SPI_INDEX(spi_index);
struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi;
-
- ao_mutex_get(&ao_spi_mutex[id]);
stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) | /* Three wire mode */
(0 << STM_SPI_CR1_BIDIOE) |
(0 << STM_SPI_CR1_CRCEN) | /* CRC disabled */
@@ -378,7 +398,7 @@ ao_spi_get(uint8_t spi_index, uint32_t speed)
(0 << STM_SPI_CR1_CPOL) | /* Format 0 */
(0 << STM_SPI_CR1_CPHA));
if (spi_index != ao_spi_index[id]) {
-
+
/* Disable old config
*/
ao_spi_disable_index(ao_spi_index[id]);
@@ -386,13 +406,32 @@ ao_spi_get(uint8_t spi_index, uint32_t speed)
/* Enable new config
*/
ao_spi_enable_index(spi_index);
-
+
/* Remember current config
*/
ao_spi_index[id] = spi_index;
}
}
+uint8_t
+ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id)
+{
+ uint8_t id = AO_SPI_INDEX(spi_index);
+
+ if (!ao_mutex_try(&ao_spi_mutex[id], task_id))
+ return 0;
+ ao_spi_config(spi_index, speed);
+ return 1;
+}
+
+void
+ao_spi_get(uint8_t spi_index, uint32_t speed)
+{
+ uint8_t id = AO_SPI_INDEX(spi_index);
+ ao_mutex_get(&ao_spi_mutex[id]);
+ ao_spi_config(spi_index, speed);
+}
+
void
ao_spi_put(uint8_t spi_index)
{