APM:Libraries
spi.h
Go to the documentation of this file.
1 #ifndef _SPI_H_
2 #define _SPI_H_
3 
4 
5 #include "gpio_hal.h"
6 #include <stm32f4xx.h>
7 #include "dma.h"
8 #include "nvic.h"
9 
10 
11 /*
12  * Devices
13  */
14 
15 typedef struct SPI_DMA {
16  uint32_t channel;
19 } Spi_DMA;
20 
21 typedef struct SPI_state {
23  uint8_t * dst;
24  uint16_t len;
25  volatile bool busy;
26 } spi_state;
27 
29 typedef struct spi_dev {
30  SPI_TypeDef* SPIx;
31  uint8_t afio;
32  IRQn_Type irq;
33  uint16_t clock;
36 } spi_dev;
37 
38 extern const spi_dev * const _SPI1;
39 extern const spi_dev * const _SPI2;
40 extern const spi_dev * const _SPI3;
41 
42 typedef enum spi_firstbit {
45 } spi_firstbit;
46 
54 typedef enum spi_mode {
63 } spi_mode;
64 
70 typedef enum spi_baud_rate {
71  SPI_BAUD_PCLK_DIV_2 = ((uint16_t)0x0000),
72  SPI_BAUD_PCLK_DIV_4 = ((uint16_t)0x0008),
73  SPI_BAUD_PCLK_DIV_8 = ((uint16_t)0x0010),
74  SPI_BAUD_PCLK_DIV_16 = ((uint16_t)0x0018),
75  SPI_BAUD_PCLK_DIV_32 = ((uint16_t)0x0020),
76  SPI_BAUD_PCLK_DIV_64 = ((uint16_t)0x0028),
77  SPI_BAUD_PCLK_DIV_128 = ((uint16_t)0x0030),
78  SPI_BAUD_PCLK_DIV_256 = ((uint16_t)0x0038),
80 
81 
82 #define SPI_BIT_RXNE ((uint16_t)0x0001)
83 #define SPI_BIT_TXE ((uint16_t)0x0002)
84 #define SPI_BIT_CRCERR ((uint16_t)0x0010)
85 #define SPI_BIT_MODF ((uint16_t)0x0020)
86 #define SPI_BIT_OVR ((uint16_t)0x0040)
87 #define SPI_BIT_BSY ((uint16_t)0x0080)
88 #define SPI_BIT_TIFRFE ((uint16_t)0x0100)
89 
90 #define SPI_size_16b ((uint16_t)0x0800)
91 #define SPI_size_8b ((uint16_t)0x0000)
92 
93 #define SPI_DMAreq_Tx ((uint16_t)0x0002)
94 #define SPI_DMAreq_Rx ((uint16_t)0x0001)
95 
97 typedef enum spi_interrupt {
107 } spi_interrupt;
108 
113 #define SPI_INTERRUPTS_ALL (SPI_TXE_INTERRUPT | \
114  SPI_RXNE_INTERRUPT | \
115  SPI_ERR_INTERRUPT)
116 
117 
118 #ifdef __cplusplus
119  extern "C" {
120 #endif
121 
128 static inline void spi_peripheral_enable(const spi_dev *dev) {
129  // SPI_Cmd(dev->SPIx, ENABLE);
130  dev->SPIx->CR1 |= SPI_CR1_SPE;
131 }
132 
138 static inline void spi_peripheral_disable(const spi_dev *dev) {
139  //SPI_Cmd(dev->SPIx, DISABLE);
140  dev->SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
141 }
142 
143 void spi_reconfigure(const spi_dev *dev, uint8_t ismaster, uint16_t baudPrescaler, uint16_t bitorder, uint8_t mode);
144 
149 void spi_init(const spi_dev *dev);
150 
163 static inline void spi_master_enable(const spi_dev *dev,
164  spi_baud_rate baudPrescaler,
165  spi_mode mode,
166  uint16_t bitorder)
167 {
168  spi_reconfigure(dev, 1, baudPrescaler, bitorder, mode);
169 }
170 
171 void spi_gpio_slave_cfg(const spi_dev *dev,
172  const gpio_dev *comm_dev, uint8_t sck_bit,
173  uint8_t miso_bit,
174  uint8_t mosi_bit);
175 
188 void spi_gpio_master_cfg(const spi_dev *dev,
189  const gpio_dev *comm_dev,
190  uint8_t sck_bit,
191  uint8_t miso_bit,
192  uint8_t mosi_bit);
193 
194 
195 
196 
207 void spi_slave_enable(const spi_dev *dev,
208  spi_mode mode,
209  uint16_t bitorder);
210 
211 
212 void spi_set_speed(const spi_dev *dev, uint16_t baudPrescaler);
213 
214 
215 void spi_foreach(void (*fn)(const spi_dev*));
216 
217 uint32_t spi_tx(const spi_dev *dev, const void *buf, uint16_t len);
218 
219 int spimaster_transfer(const spi_dev *dev,
220  const uint8_t *txbuf,
221  uint16_t txcount,
222  uint8_t *rxbuf,
223  uint16_t rxcount);
224 
225 
226 
227 static inline uint8_t spi_is_enabled(const spi_dev *dev) {
228  return dev->SPIx->CR1 & SPI_CR1_SPE;
229 }
230 
231 static inline void spi_peripheral_disable_all(void) {
233 }
234 
235 
236 //[ new ones - for enum spi_interrupt
237 static inline void spi_enable_irq(const spi_dev *dev, spi_interrupt interrupt_flags) {
238  dev->SPIx->CR2 |= interrupt_flags;
239 }
240 
241 static inline void spi_disable_irq(const spi_dev *dev, spi_interrupt interrupt_flags) {
242  dev->SPIx->CR2 &= ~interrupt_flags;
243 }
244 
245 
246 static inline bool spi_is_irq_enabled(const spi_dev *dev, uint32_t interrupt_flags) {
247  return dev->SPIx->CR2 & interrupt_flags;
248 }
249 //]
250 
251 static inline uint16_t spi_dff(const spi_dev *dev) {
252  return ((dev->SPIx->CR1 & SPI_size_16b) == SPI_size_8b ? SPI_size_8b : SPI_size_16b);
253 }
254 
255 static inline uint8_t spi_is_rx_nonempty(const spi_dev *dev) {
256  return (dev->SPIx->SR & SPI_BIT_RXNE);
257 }
258 
259 static inline uint8_t spi_rx_reg(const spi_dev *dev) {
260  return (uint8_t)dev->SPIx->DR;
261 }
262 
263 static inline uint8_t spi_is_tx_empty(const spi_dev *dev) {
264  return (dev->SPIx->SR & SPI_BIT_TXE);
265 }
266 
267 static inline void spi_tx_reg(const spi_dev *dev, uint8_t val) {
268  dev->SPIx->DR = val;
269 }
270 
271 static inline uint8_t spi_is_busy(const spi_dev *dev) {
272  return (dev->SPIx->SR & SPI_BIT_BSY);
273 }
274 
275 static inline void spi_wait_busy(const spi_dev *dev) {
276 // Wait until the transfer is complete - to not disable CS too early
277  uint32_t dly=3000;
278  while (dev->SPIx->SR & SPI_BIT_BSY){ // but datasheet prohibits this usage
279  dly--;
280  if(dly==0) break;
281  }
282 }
283 
284 static inline void spi_enable_dma_req(const spi_dev *dev, uint16_t SPI_DMAReq) {
285  /* Enable the selected SPI DMA requests */
286  dev->SPIx->CR2 |= SPI_DMAReq;
287 }
288 
289 static inline void spi_disable_dma_req(const spi_dev *dev, uint16_t SPI_DMAReq) {
290  /* Disable the selected SPI DMA requests */
291  dev->SPIx->CR2 &= (uint16_t)~SPI_DMAReq;
292 }
293 
294 
295 static inline void spi_attach_interrupt(const spi_dev *dev, Handler handler){
296  dev->state->handler = handler;
297 
298  IRQn_Type irq=dev->irq;
299 
300 // NVIC_ClearPendingIRQ(irq);
301 // NVIC_EnableIRQ(irq);
302 // NVIC_SetPriority(irq, SPI_INT_PRIORITY);
304 }
305 
306 static inline void spi_detach_interrupt(const spi_dev *dev){
307  dev->state->handler = 0;
308 }
309 
310 #ifdef __cplusplus
311  }
312 #endif
313 
314 #endif
#define SPI_BIT_RXNE
Definition: spi.h:82
IRQn_Type irq
Definition: spi.h:32
Definition: spi.h:55
Definition: spi.h:59
static void spi_disable_dma_req(const spi_dev *dev, uint16_t SPI_DMAReq)
Definition: spi.h:289
struct SPI_DMA Spi_DMA
const spi_dev *const _SPI2
Definition: spi.c:43
const spi_dev *const _SPI3
Definition: spi.c:54
uint32_t spi_tx(const spi_dev *dev, const void *buf, uint16_t len)
static void spi_peripheral_disable(const spi_dev *dev)
Disable a SPI peripheral.
Definition: spi.h:138
static void spi_attach_interrupt(const spi_dev *dev, Handler handler)
Definition: spi.h:295
static void spi_wait_busy(const spi_dev *dev)
Definition: spi.h:275
void spi_foreach(void(*fn)(const spi_dev *))
Call a function on each SPI port.
Definition: spi.c:84
#define SPI_INTERRUPTS_ALL
Mask for all spi_interrupt values.
Definition: spi.h:113
void spi_reconfigure(const spi_dev *dev, uint8_t ismaster, uint16_t baudPrescaler, uint16_t bitorder, uint8_t mode)
Definition: spi.c:132
void spi_gpio_master_cfg(const spi_dev *dev, const gpio_dev *comm_dev, uint8_t sck_bit, uint8_t miso_bit, uint8_t mosi_bit)
Configure and enable a SPI device as bus master.
Definition: spi.c:92
static void spi_enable_dma_req(const spi_dev *dev, uint16_t SPI_DMAReq)
Definition: spi.h:284
Definition: spi.h:15
Handler handler
Definition: spi.h:22
#define SPI_size_8b
Definition: spi.h:91
#define SPI_BIT_TXE
Definition: spi.h:83
uint8_t afio
Definition: spi.h:31
uint16_t len
Definition: spi.h:24
uint16_t clock
Definition: spi.h:33
static uint8_t spi_rx_reg(const spi_dev *dev)
Definition: spi.h:259
static void spi_peripheral_disable_all(void)
Definition: spi.h:231
static void spi_detach_interrupt(const spi_dev *dev)
Definition: spi.h:306
Spi_DMA dma
Definition: spi.h:34
Definition: spi.h:57
spi_mode
SPI mode configuration.
Definition: spi.h:54
dma_stream stream_rx
Definition: spi.h:17
dma_stream stream_tx
Definition: spi.h:18
static AP_HAL::OwnPtr< AP_HAL::Device > dev
Definition: ICM20789.cpp:16
spi_firstbit
Definition: spi.h:42
const spi_dev *const _SPI1
Definition: spi.c:32
static void spi_disable_irq(const spi_dev *dev, spi_interrupt interrupt_flags)
Definition: spi.h:241
struct spi_dev spi_dev
static uint8_t spi_is_busy(const spi_dev *dev)
Definition: spi.h:271
Definition: spi.h:43
uint8_t * dst
Definition: spi.h:23
static uint8_t spi_is_enabled(const spi_dev *dev)
Definition: spi.h:227
void enable_nvic_irq(uint8_t irq, uint8_t prio)
Definition: nvic.c:8
volatile bool busy
Definition: spi.h:25
Definition: spi.h:61
void spi_set_speed(const spi_dev *dev, uint16_t baudPrescaler)
Definition: spi.c:205
static void spi_master_enable(const spi_dev *dev, spi_baud_rate baudPrescaler, spi_mode mode, uint16_t bitorder)
Configure GPIO bit modes for use as a SPI port&#39;s pins.
Definition: spi.h:163
static bool spi_is_irq_enabled(const spi_dev *dev, uint32_t interrupt_flags)
Definition: spi.h:246
static uint8_t spi_is_tx_empty(const spi_dev *dev)
Definition: spi.h:263
enum Dma_stream dma_stream
static void spi_tx_reg(const spi_dev *dev, uint8_t val)
Definition: spi.h:267
spi_interrupt
Definition: spi.h:97
struct SPI_state spi_state
SPI_TypeDef * SPIx
Definition: spi.h:30
uint32_t channel
Definition: spi.h:16
spi_baud_rate
SPI baud rate configuration, as a divisor of f_PCLK, the PCLK clock frequency.
Definition: spi.h:70
Definition: spi.h:44
Definition: spi.h:21
static void spi_peripheral_enable(const spi_dev *dev)
Enable a SPI peripheral.
Definition: spi.h:128
int spimaster_transfer(const spi_dev *dev, const uint8_t *txbuf, uint16_t txcount, uint8_t *rxbuf, uint16_t rxcount)
Definition: spi.c:219
void spi_gpio_slave_cfg(const spi_dev *dev, const gpio_dev *comm_dev, uint8_t sck_bit, uint8_t miso_bit, uint8_t mosi_bit)
Definition: spi.c:115
void spi_slave_enable(const spi_dev *dev, spi_mode mode, uint16_t bitorder)
Configure and enable a SPI device as a bus slave.
spi_state * state
Definition: spi.h:35
uint64_t Handler
Definition: hal_types.h:19
static uint16_t spi_dff(const spi_dev *dev)
Definition: spi.h:251
static uint8_t spi_is_rx_nonempty(const spi_dev *dev)
Definition: spi.h:255
Definition: spi.h:29
#define SPI_BIT_BSY
Definition: spi.h:87
#define SPI_INT_PRIORITY
Definition: Config.h:57
void spi_init(const spi_dev *dev)
Initialize and reset a SPI device.
Definition: spi.c:57
static void spi_enable_irq(const spi_dev *dev, spi_interrupt interrupt_flags)
Definition: spi.h:237
#define SPI_size_16b
Definition: spi.h:90