2017-07-21 14:14:27 +08:00
|
|
|
// IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4
|
|
|
|
|
2019-06-25 01:25:30 +08:00
|
|
|
void spi_init(void);
|
2019-05-22 01:32:16 +08:00
|
|
|
int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out);
|
|
|
|
|
|
|
|
// end API
|
|
|
|
|
2017-07-21 14:14:27 +08:00
|
|
|
#define SPI_BUF_SIZE 256
|
|
|
|
uint8_t spi_buf[SPI_BUF_SIZE];
|
|
|
|
int spi_buf_count = 0;
|
|
|
|
int spi_total_count = 0;
|
|
|
|
|
2019-06-25 01:25:30 +08:00
|
|
|
void spi_init(void) {
|
2017-07-13 02:25:10 +08:00
|
|
|
//puts("SPI init\n");
|
|
|
|
SPI1->CR1 = SPI_CR1_SPE;
|
2017-04-18 09:17:34 +08:00
|
|
|
|
2017-07-13 02:25:10 +08:00
|
|
|
// enable SPI interrupts
|
|
|
|
//SPI1->CR2 = SPI_CR2_RXNEIE | SPI_CR2_ERRIE | SPI_CR2_TXEIE;
|
|
|
|
SPI1->CR2 = SPI_CR2_RXNEIE;
|
2017-07-21 14:14:27 +08:00
|
|
|
|
|
|
|
NVIC_EnableIRQ(DMA2_Stream2_IRQn);
|
|
|
|
NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
|
|
|
//NVIC_EnableIRQ(SPI1_IRQn);
|
|
|
|
|
2017-07-25 03:31:47 +08:00
|
|
|
// reset handshake back to pull up
|
2017-08-30 01:46:08 +08:00
|
|
|
set_gpio_mode(GPIOB, 0, MODE_INPUT);
|
|
|
|
set_gpio_pullup(GPIOB, 0, PULL_UP);
|
2017-07-25 03:31:47 +08:00
|
|
|
|
2017-07-21 14:14:27 +08:00
|
|
|
// setup interrupt on falling edge of SPI enable (on PA4)
|
|
|
|
SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA;
|
2019-07-03 14:43:06 +08:00
|
|
|
EXTI->IMR |= (1U << 4);
|
|
|
|
EXTI->FTSR |= (1U << 4);
|
2017-07-21 14:14:27 +08:00
|
|
|
NVIC_EnableIRQ(EXTI4_IRQn);
|
2017-07-13 02:25:10 +08:00
|
|
|
}
|
2017-04-07 09:11:36 +08:00
|
|
|
|
2017-07-13 02:25:10 +08:00
|
|
|
void spi_tx_dma(void *addr, int len) {
|
|
|
|
// disable DMA
|
|
|
|
SPI1->CR2 &= ~SPI_CR2_TXDMAEN;
|
|
|
|
DMA2_Stream3->CR &= ~DMA_SxCR_EN;
|
|
|
|
|
|
|
|
// DMA2, stream 3, channel 3
|
|
|
|
DMA2_Stream3->M0AR = (uint32_t)addr;
|
|
|
|
DMA2_Stream3->NDTR = len;
|
|
|
|
DMA2_Stream3->PAR = (uint32_t)&(SPI1->DR);
|
|
|
|
|
|
|
|
// channel3, increment memory, memory -> periph, enable
|
|
|
|
DMA2_Stream3->CR = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_EN;
|
2018-04-12 07:15:32 +08:00
|
|
|
delay(0);
|
2017-07-13 02:25:10 +08:00
|
|
|
DMA2_Stream3->CR |= DMA_SxCR_TCIE;
|
|
|
|
|
|
|
|
SPI1->CR2 |= SPI_CR2_TXDMAEN;
|
2017-07-25 03:31:47 +08:00
|
|
|
|
|
|
|
// signal data is ready by driving low
|
|
|
|
// esp must be configured as input by this point
|
2017-08-30 01:46:08 +08:00
|
|
|
set_gpio_output(GPIOB, 0, 0);
|
2017-07-13 02:25:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void spi_rx_dma(void *addr, int len) {
|
|
|
|
// disable DMA
|
|
|
|
SPI1->CR2 &= ~SPI_CR2_RXDMAEN;
|
|
|
|
DMA2_Stream2->CR &= ~DMA_SxCR_EN;
|
|
|
|
|
|
|
|
// drain the bus
|
2017-07-30 10:19:33 +08:00
|
|
|
volatile uint8_t dat = SPI1->DR;
|
2017-07-13 02:25:10 +08:00
|
|
|
(void)dat;
|
|
|
|
|
|
|
|
// DMA2, stream 2, channel 3
|
|
|
|
DMA2_Stream2->M0AR = (uint32_t)addr;
|
|
|
|
DMA2_Stream2->NDTR = len;
|
|
|
|
DMA2_Stream2->PAR = (uint32_t)&(SPI1->DR);
|
|
|
|
|
|
|
|
// channel3, increment memory, periph -> memory, enable
|
|
|
|
DMA2_Stream2->CR = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0 | DMA_SxCR_MINC | DMA_SxCR_EN;
|
2018-04-12 07:15:32 +08:00
|
|
|
delay(0);
|
2017-07-13 02:25:10 +08:00
|
|
|
DMA2_Stream2->CR |= DMA_SxCR_TCIE;
|
|
|
|
|
|
|
|
SPI1->CR2 |= SPI_CR2_RXDMAEN;
|
|
|
|
}
|
2017-04-18 16:12:04 +08:00
|
|
|
|
2017-07-21 14:14:27 +08:00
|
|
|
// ***************************** SPI IRQs *****************************
|
|
|
|
|
2017-07-25 03:31:47 +08:00
|
|
|
// can't go on the stack cause it's DMAed
|
|
|
|
uint8_t spi_tx_buf[0x44];
|
|
|
|
|
2017-07-21 14:14:27 +08:00
|
|
|
// SPI RX
|
|
|
|
void DMA2_Stream2_IRQHandler(void) {
|
2017-07-25 03:31:47 +08:00
|
|
|
int *resp_len = (int*)spi_tx_buf;
|
2019-07-04 07:01:01 +08:00
|
|
|
(void)memset(spi_tx_buf, 0xaa, 0x44);
|
2017-08-13 19:31:03 +08:00
|
|
|
*resp_len = spi_cb_rx(spi_buf, 0x14, spi_tx_buf+4);
|
2017-07-25 03:31:47 +08:00
|
|
|
#ifdef DEBUG_SPI
|
|
|
|
puts("SPI write: ");
|
|
|
|
puth(*resp_len);
|
|
|
|
puts("\n");
|
|
|
|
#endif
|
|
|
|
spi_tx_dma(spi_tx_buf, *resp_len + 4);
|
2017-08-22 07:40:38 +08:00
|
|
|
|
|
|
|
// ack
|
|
|
|
DMA2->LIFCR = DMA_LIFCR_CTCIF2;
|
2017-07-21 14:14:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// SPI TX
|
|
|
|
void DMA2_Stream3_IRQHandler(void) {
|
2017-07-25 03:31:47 +08:00
|
|
|
#ifdef DEBUG_SPI
|
|
|
|
puts("SPI handshake\n");
|
2018-04-12 07:15:32 +08:00
|
|
|
#endif
|
2017-07-25 03:31:47 +08:00
|
|
|
|
2017-07-21 14:14:27 +08:00
|
|
|
// reset handshake back to pull up
|
2017-08-30 01:46:08 +08:00
|
|
|
set_gpio_mode(GPIOB, 0, MODE_INPUT);
|
|
|
|
set_gpio_pullup(GPIOB, 0, PULL_UP);
|
2017-08-22 07:40:38 +08:00
|
|
|
|
|
|
|
// ack
|
|
|
|
DMA2->LIFCR = DMA_LIFCR_CTCIF3;
|
2017-07-21 14:14:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void EXTI4_IRQHandler(void) {
|
2019-07-04 16:04:58 +08:00
|
|
|
volatile unsigned int pr = EXTI->PR & (1U << 4);
|
2017-07-30 10:19:33 +08:00
|
|
|
#ifdef DEBUG_SPI
|
|
|
|
puts("exti4\n");
|
|
|
|
#endif
|
2017-08-22 07:40:38 +08:00
|
|
|
// SPI CS falling
|
2019-07-04 16:04:58 +08:00
|
|
|
if ((pr & (1U << 4)) != 0U) {
|
2017-07-21 14:14:27 +08:00
|
|
|
spi_total_count = 0;
|
|
|
|
spi_rx_dma(spi_buf, 0x14);
|
|
|
|
}
|
|
|
|
EXTI->PR = pr;
|
|
|
|
}
|
|
|
|
|