mirror of https://github.com/commaai/panda.git
H7: remove busy wait on TXC (#1381)
* works * cleanup * less irq * less diff --------- Co-authored-by: Comma Device <device@comma.ai>
This commit is contained in:
parent
f9485c8d5d
commit
8e1ca608b0
|
@ -27,6 +27,7 @@ enum {
|
|||
SPI_STATE_DATA_TX
|
||||
};
|
||||
|
||||
bool spi_tx_dma_done = false;
|
||||
uint8_t spi_state = SPI_STATE_HEADER;
|
||||
uint8_t spi_endpoint;
|
||||
uint16_t spi_data_len_mosi;
|
||||
|
|
|
@ -46,6 +46,7 @@ void TIM8_CC_IRQHandler(void) {handle_interrupt(TIM8_CC_IRQn);}
|
|||
void DMA1_Stream7_IRQHandler(void) {handle_interrupt(DMA1_Stream7_IRQn);}
|
||||
void TIM5_IRQHandler(void) {handle_interrupt(TIM5_IRQn);}
|
||||
void SPI3_IRQHandler(void) {handle_interrupt(SPI3_IRQn);}
|
||||
void SPI4_IRQHandler(void) {handle_interrupt(SPI4_IRQn);}
|
||||
void UART4_IRQHandler(void) {handle_interrupt(UART4_IRQn);}
|
||||
void UART5_IRQHandler(void) {handle_interrupt(UART5_IRQn);}
|
||||
void TIM6_DAC_IRQHandler(void) {handle_interrupt(TIM6_DAC_IRQn);}
|
||||
|
|
|
@ -34,6 +34,9 @@ void llspi_miso_dma(uint8_t *addr, int len) {
|
|||
// clear under-run while we were reading
|
||||
SPI4->IFCR |= SPI_IFCR_UDRC;
|
||||
|
||||
// setup interrupt on TXC
|
||||
register_set(&(SPI4->IER), (1U << SPI_IER_EOTIE_Pos), 0x3FFU);
|
||||
|
||||
// enable DMA
|
||||
register_set_bits(&(SPI4->CFG1), SPI_CFG1_TXDMAEN);
|
||||
DMA2_Stream3->CR |= DMA_SxCR_EN;
|
||||
|
@ -52,28 +55,38 @@ void DMA2_Stream2_IRQ_Handler(void) {
|
|||
|
||||
// panda -> master DMA finished
|
||||
void DMA2_Stream3_IRQ_Handler(void) {
|
||||
// Clear interrupt flag
|
||||
ENTER_CRITICAL();
|
||||
|
||||
DMA2->LIFCR = DMA_LIFCR_CTCIF3;
|
||||
spi_tx_dma_done = true;
|
||||
|
||||
// Wait until the transaction is actually finished and clear the DR.
|
||||
// Timeout to prevent hang when the master clock stops.
|
||||
bool timed_out = false;
|
||||
uint32_t start_time = microsecond_timer_get();
|
||||
while (!(SPI4->SR & SPI_SR_TXC)) {
|
||||
if (get_ts_elapsed(microsecond_timer_get(), start_time) > SPI_TIMEOUT_US) {
|
||||
timed_out = true;
|
||||
break;
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
// panda TX finished
|
||||
void SPI4_IRQ_Handler(void) {
|
||||
ENTER_CRITICAL();
|
||||
|
||||
// clear flag
|
||||
SPI4->IFCR |= SPI_IFCR_EOTC;
|
||||
|
||||
if (spi_tx_dma_done && ((SPI4->SR & SPI_SR_TXC) != 0)) {
|
||||
spi_tx_dma_done = false;
|
||||
|
||||
register_set(&(SPI4->IER), 0, 0x3FFU);
|
||||
|
||||
volatile uint8_t dat = SPI4->TXDR;
|
||||
(void)dat;
|
||||
spi_handle_tx(false);
|
||||
}
|
||||
volatile uint8_t dat = SPI4->TXDR;
|
||||
(void)dat;
|
||||
|
||||
spi_handle_tx(timed_out);
|
||||
EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
|
||||
void llspi_init(void) {
|
||||
// We expect less than 50 transactions (including control messages and CAN buffers) at the 100Hz boardd interval. Can be raised if needed.
|
||||
REGISTER_INTERRUPT(SPI4_IRQn, SPI4_IRQ_Handler, 5000U, FAULT_INTERRUPT_RATE_SPI_DMA)
|
||||
REGISTER_INTERRUPT(DMA2_Stream2_IRQn, DMA2_Stream2_IRQ_Handler, 5000U, FAULT_INTERRUPT_RATE_SPI_DMA)
|
||||
REGISTER_INTERRUPT(DMA2_Stream3_IRQn, DMA2_Stream3_IRQ_Handler, 5000U, FAULT_INTERRUPT_RATE_SPI_DMA)
|
||||
|
||||
|
@ -88,6 +101,7 @@ void llspi_init(void) {
|
|||
register_set(&(DMA2_Stream3->PAR), (uint32_t)&(SPI4->TXDR), 0xFFFFFFFFU);
|
||||
|
||||
// Enable SPI
|
||||
register_set(&(SPI4->IER), 0, 0x3FFU);
|
||||
register_set(&(SPI4->CFG1), (7U << SPI_CFG1_DSIZE_Pos), SPI_CFG1_DSIZE_Msk);
|
||||
register_set(&(SPI4->UDRDR), 0xcd, 0xFFFFU); // set under-run value for debugging
|
||||
register_set(&(SPI4->CR1), SPI_CR1_SPE, 0xFFFFU);
|
||||
|
@ -95,4 +109,5 @@ void llspi_init(void) {
|
|||
|
||||
NVIC_EnableIRQ(DMA2_Stream2_IRQn);
|
||||
NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
||||
NVIC_EnableIRQ(SPI4_IRQn);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue