73 ChipSelectMethod cs_assert, ChipSelectMethod cs_deassert,
74 OSMutex *bus_lock,
size_t dma_threshold,
75 uint32_t dma_channel_index_tx,
76 uint32_t dma_channel_index_rx)
77 :
SPI(name, cs_assert, cs_deassert, bus_lock)
80 , interrupt_(interrupt)
81 , dmaThreshold_(dma_threshold)
82 , dmaChannelIndexTx_(dma_channel_index_tx)
83 , dmaChannelIndexRx_(dma_channel_index_rx)
90 MAP_PRCMPeripheralClkEnable(PRCM_GSPI, PRCM_RUN_MODE_CLK);
91 MAP_PRCMPeripheralReset(PRCM_GSPI);
92 clock_ = MAP_PRCMPeripheralClockGet(PRCM_GSPI);
107 unsigned long new_mode;
108 unsigned long bits_per_word;
109 unsigned long fifo_level;
115 new_mode = SPI_SUB_MODE_0;
118 new_mode = SPI_SUB_MODE_1;
121 new_mode = SPI_SUB_MODE_2;
124 new_mode = SPI_SUB_MODE_3;
134 bits_per_word = SPI_WL_8;
135 fifo_level =
sizeof(uint8_t);
138 bits_per_word = SPI_WL_16;
139 fifo_level =
sizeof(uint16_t);
142 bits_per_word = SPI_WL_32;
143 fifo_level =
sizeof(uint32_t);
160 MAP_SPIDisable(
base_);
163 (SPI_3PIN_MODE | SPI_TURBO_ON | bits_per_word));
164 MAP_SPIFIFOEnable(
base_, SPI_RX_FIFO | SPI_TX_FIFO);
165 MAP_SPIFIFOLevelSet(
base_, fifo_level, fifo_level);
166 MAP_IntPrioritySet(
interrupt_, configKERNEL_INTERRUPT_PRIORITY);
168 MAP_SPIEnable(
base_);
185 static uint32_t scratch_buffer __attribute__((aligned(4))) = 0;
189 uint32_t channel_control_options;
190 unsigned config_index;
206 items = msg->len /
sizeof(uint8_t);
210 items = msg->len /
sizeof(uint16_t);
214 items = msg->len /
sizeof(uint32_t);
219 HASSERT(items <= MAX_DMA_TRANSFER_AMOUNT);
223 channel_control_options = dmaTxConfig_[config_index];
224 buf = (
void*)msg->tx_buf;
228 channel_control_options = dmaNullConfig_[config_index];
229 buf = &scratch_buffer;
233 uDMAChannelControlSet(dmaChannelIndexTx_ | UDMA_PRI_SELECT,
234 channel_control_options);
238 uDMAChannelAttributeDisable(dmaChannelIndexTx_, UDMA_ATTR_ALTSELECT);
240 HWREG(UDMA_BASE + UDMA_O_ALTCLR) = 1 << (dmaChannelIndexTx_ & 0x1f);
242 uDMAChannelTransferSet(dmaChannelIndexTx_ | UDMA_PRI_SELECT,
243 UDMA_MODE_BASIC, buf, (
void*)(base_ + MCSPI_O_TX0),
248 channel_control_options = dmaRxConfig_[config_index];
249 buf = (
void*)msg->rx_buf;
253 channel_control_options = dmaNullConfig_[config_index];
254 buf = &scratch_buffer;
258 uDMAChannelControlSet(dmaChannelIndexRx_ | UDMA_PRI_SELECT,
259 channel_control_options);
263 uDMAChannelAttributeDisable(dmaChannelIndexRx_, UDMA_ATTR_ALTSELECT);
265 HWREG(UDMA_BASE + UDMA_O_ALTCLR) = 1 << (dmaChannelIndexRx_ & 0x1f);
267 uDMAChannelTransferSet(dmaChannelIndexRx_ | UDMA_PRI_SELECT,
268 UDMA_MODE_BASIC, (
void*)(base_ + MCSPI_O_RX0), buf,
274 uDMAChannelAssign(dmaChannelIndexRx_);
275 uDMAChannelAssign(dmaChannelIndexTx_);
277 SPIDmaEnable(base_, SPI_RX_DMA | SPI_TX_DMA);
278 SPIIntClear(base_, SPI_INT_DMARX);
279 SPIIntEnable(base_, SPI_INT_DMARX);
282 uDMAChannelEnable(dmaChannelIndexTx_);
283 uDMAChannelEnable(dmaChannelIndexRx_);
300 if (SPIIntStatus(base_,
true) & SPI_INT_DMATX)
302 SPIIntDisable(base_, SPI_INT_DMATX);
303 SPIIntClear(base_, SPI_INT_DMATX);
305 if (uDMAChannelIsEnabled(dmaChannelIndexRx_))
311 SPIDmaDisable(base_, SPI_RX_DMA | SPI_TX_DMA);
312 SPIIntDisable(base_, SPI_INT_DMARX);
315 sem_->post_from_isr(&woken);
316 os_isr_exit_yield_test(woken);