dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_spislave.c
Go to the documentation of this file.
1 #include <pios_spislave.h>
2 
3 #ifdef PIOS_INCLUDE_SPISLAVE
4 
5 struct pios_spislave_dev {
6  const struct pios_spislave_cfg *cfg;
7  bool last_ssel;
8 };
9 
10 static void setup_spi_dma(spislave_t slave_dev, uint32_t tx_len)
11 {
12  DMA_Cmd(slave_dev->cfg->rx_dma.channel, DISABLE);
13  DMA_Cmd(slave_dev->cfg->tx_dma.channel, DISABLE);
14 
15  SPI_Cmd(slave_dev->cfg->regs, DISABLE);
16 
17  SPI_I2S_DMACmd(slave_dev->cfg->regs, SPI_I2S_DMAReq_Tx, DISABLE);
18  SPI_I2S_DMACmd(slave_dev->cfg->regs, SPI_I2S_DMAReq_Rx, DISABLE);
19 
20  DMA_SetCurrDataCounter(slave_dev->cfg->tx_dma.channel, tx_len);
21  DMA_SetCurrDataCounter(slave_dev->cfg->rx_dma.channel,
22  slave_dev->cfg->max_rx_len);
23 
24  SPI_I2S_DMACmd(slave_dev->cfg->regs, SPI_I2S_DMAReq_Rx, ENABLE);
25  DMA_Cmd(slave_dev->cfg->rx_dma.channel, ENABLE);
26  DMA_Cmd(slave_dev->cfg->tx_dma.channel, ENABLE);
27  SPI_I2S_DMACmd(slave_dev->cfg->regs, SPI_I2S_DMAReq_Tx, ENABLE);
28 
29  SPI_Cmd(slave_dev->cfg->regs, ENABLE);
30 }
31 
32 int32_t PIOS_SPISLAVE_PollSS(spislave_t slave_dev)
33 {
34  if (DMA_GetCurrDataCounter(slave_dev->cfg->rx_dma.channel) ==
35  slave_dev->cfg->max_rx_len) {
36  // Nothing clocked. So even if the CS blipped, we don't
37  // care-- ignore it.
38 
39  return 0;
40  }
41 
42  bool pin_status = GPIO_ReadInputDataBit(slave_dev->cfg->ssel.gpio,
43  slave_dev->cfg->ssel.init.GPIO_Pin) == Bit_SET;
44 
45  if (slave_dev->last_ssel != pin_status) {
46  slave_dev->last_ssel = pin_status;
47 
48  /* This was a rising edge that we spotted. */
49  if (pin_status) {
50  int resp_len;
51 
52  /* XXX figure out count, wait as appropriate, meh */
53  slave_dev->cfg->process_message(
54  slave_dev->cfg->ctx, 0, &resp_len);
55 
56  setup_spi_dma(slave_dev, resp_len);
57  }
58  }
59 
60  return 0;
61 }
62 
63 int32_t PIOS_SPISLAVE_Init(spislave_t *spislave_id,
64  const struct pios_spislave_cfg *cfg,
65  int initial_tx_size)
66 {
67  PIOS_Assert(spislave_id);
68  PIOS_Assert(cfg);
69 
70  spislave_t slave_dev = PIOS_malloc(sizeof(*slave_dev));
71  if (!slave_dev) goto out_fail;
72 
73  slave_dev->cfg = cfg;
74  slave_dev->last_ssel = true;
75 
76 #ifndef STM32F10X_MD
77  /* Initialize the GPIO pins */
78  /* note __builtin_ctz() due to the difference between GPIO_PinX and GPIO_PinSourceX */
79  if (slave_dev->cfg->remap) {
80  GPIO_PinAFConfig(slave_dev->cfg->sclk.gpio,
81  __builtin_ctz(slave_dev->cfg->sclk.init.GPIO_Pin),
82  slave_dev->cfg->remap);
83  GPIO_PinAFConfig(slave_dev->cfg->mosi.gpio,
84  __builtin_ctz(slave_dev->cfg->mosi.init.GPIO_Pin),
85  slave_dev->cfg->remap);
86  GPIO_PinAFConfig(slave_dev->cfg->miso.gpio,
87  __builtin_ctz(slave_dev->cfg->miso.init.GPIO_Pin),
88  slave_dev->cfg->remap);
89  GPIO_PinAFConfig(slave_dev->cfg->ssel.gpio,
90  __builtin_ctz(slave_dev->cfg->ssel.init.GPIO_Pin),
91  slave_dev->cfg->remap);
92  }
93 #endif
94 
95  GPIO_Init(slave_dev->cfg->sclk.gpio,
96  (GPIO_InitTypeDef *) & (slave_dev->cfg->sclk.init));
97  GPIO_Init(slave_dev->cfg->mosi.gpio,
98  (GPIO_InitTypeDef *) & (slave_dev->cfg->mosi.init));
99  GPIO_Init(slave_dev->cfg->miso.gpio,
100  (GPIO_InitTypeDef *) & (slave_dev->cfg->miso.init));
101  GPIO_Init(slave_dev->cfg->ssel.gpio,
102  (GPIO_InitTypeDef *) & (slave_dev->cfg->miso.init));
103 
104  SPI_I2S_DeInit(slave_dev->cfg->regs);
105  SPI_Init(slave_dev->cfg->regs,
106  (SPI_InitTypeDef *) & (slave_dev->cfg->init));
107  SPI_CalculateCRC(slave_dev->cfg->regs, DISABLE);
108  SPI_RxFIFOThresholdConfig(slave_dev->cfg->regs,
109  SPI_RxFIFOThreshold_QF);
110 
111  DMA_DeInit(slave_dev->cfg->rx_dma.channel);
112  DMA_DeInit(slave_dev->cfg->tx_dma.channel);
113 
114  DMA_Init(slave_dev->cfg->rx_dma.channel,
115  (DMA_InitTypeDef *) &slave_dev->cfg->rx_dma.init);
116  DMA_Init(slave_dev->cfg->tx_dma.channel,
117  (DMA_InitTypeDef *) &slave_dev->cfg->tx_dma.init);
118 
119  setup_spi_dma(slave_dev, initial_tx_size);
120 
121  *spislave_id = slave_dev;
122 
123  return 0;
124 
125 out_fail:
126  return -1;
127 }
128 
129 #endif
int32_t PIOS_SPISLAVE_Init(spislave_t *spislave_id, const struct pios_spislave_cfg *cfg, int initial_tx_size)
int32_t PIOS_SPISLAVE_PollSS(spislave_t spislave_dev)
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
SPI private definitions.
static struct flyingpicmd_cfg_fa cfg
Definition: main.c:49
struct pios_spislave_dev * spislave_t
Definition: pios_spislave.h:39
#define PIOS_Assert(test)
Definition: pios_debug.h:52