DMA init に問題があります。ベアメタル プログラミングを使用して DMA を初期化できませんでした。割り込みは呼び出されず、データは渡されません。その間、SPIからの割り込みは機能しています。DMAの設定を確認していただけますか?また、「IP_LPSPI/n/->DER」レジスタに「LPSPI_DER_RDDE」ビットを設定しました。これにより、受信データの DMA が設定されます。
void DMA_Init(volatile uint32_t rxBuffer) {
/*
For remaining S32K3xx devices: DMAMUX_0 channel 0-15 and DMAMUX_1 channel 0-15 are
mapped to eDMA Transfer Control Descriptor(TCD) 0-15 and eDMA Transfer Control Descriptor(TCD)
16-31, respectively
*/
// TCD register init
IP_TCD->TCD0_SADDR = 0U;
IP_TCD->TCD0_SOFF = 0;
IP_TCD->TCD0_ATTR = 0U;
IP_TCD->NBYTES0.TCD0_NBYTES_MLOFFNO = 0U;
IP_TCD->NBYTES0.TCD0_NBYTES_MLOFFYES = 0U;
IP_TCD->TCD0_SLAST_SDA = 0;
IP_TCD->TCD0_DADDR = 0U;
IP_TCD->TCD0_DOFF = 0;
IP_TCD->CITER0.TCD0_CITER_ELINKNO = 0U;
IP_TCD->CITER0.TCD0_CITER_ELINKYES = 0U;
IP_TCD->TCD0_DLAST_SGA = 0;
IP_TCD->TCD0_CSR = 0U;
IP_TCD->BITER0.TCD0_BITER_ELINKNO = 0U;
IP_TCD->BITER0.TCD0_BITER_ELINKYES = 0U;
//===== DMA MUX =====//
// Enable a source without periodic triggering
// 1. Determine the DMA channel with which the source is associated.
// LPSPI1 DMA RX Request -> Source 46
// 2. Write 0 to CHCFGn[ENBL] and CHCFGn[TRIG] of the DMA channel.
IP_DMAMUX_0->CHCFG[0] &= ~DMAMUX_CHCFG_ENBL_MASK;
IP_DMAMUX_0->CHCFG[0] &= ~DMAMUX_CHCFG_TRIG_MASK;
// 3. You can enable the DMA channel at this point.
IP_DMAMUX_0->CHCFG[0] |= DMAMUX_CHCFG_ENBL_MASK;
// 4. Select the source to be routed to the DMA channel.
IP_DMAMUX_0->CHCFG[0] |= DMAMUX_CHCFG_SOURCE(46);
//===== eDMA =====//
// 1. Write to the CSR if a configuration other than the default is wanted.
// 2. Write the channel priority levels to the CHn_PRI registers and group priority levels to the CHn_GRPRI registers if a
// configuration other than the default is wanted.
// 3. Enable error interrupts in the CHn_CSR[EEI] registers if they are wanted.
// 4. Write the 32-byte TCD for each channel that may request service.
// CH0_SBR_MID: Default master id -> 0b10
// Source address -> SPI receive buffer
IP_TCD->TCD0_SADDR = IP_LPSPI_1->RDR;
// Destination address
IP_TCD->TCD0_DADDR = rxBuffer;
// Source Address Offset
IP_TCD->TCD0_SOFF = 4;
// Destination Address Offset
IP_TCD->TCD0_DOFF = 4;
// Source size: 32-bit
IP_TCD->TCD0_ATTR |= DMA_TCD_TCD0_ATTR_SSIZE(0b10);
// Destination size: 32-bit
IP_TCD->TCD0_ATTR |= DMA_TCD_TCD0_ATTR_DSIZE(0b10);
// 4 byte transfer
IP_TCD->NBYTES0.TCD0_NBYTES_MLOFFNO = 4;
// Current Major Loop Count
IP_TCD->CITER0.TCD0_CITER_ELINKNO = 1;
// Beginning Major Loop Count
IP_TCD->BITER0.TCD0_BITER_ELINKNO = 1;
// Interrupt after transfer is complete
IP_TCD->TCD0_CSR |= DMA_TCD_TCD0_CSR_INTMAJOR_MASK;
// Enable interrupt
__NVIC_ClearPendingIRQ(DMATCD0_IRQn);
__NVIC_SetPriority(DMATCD0_IRQn, 0);
__NVIC_EnableIRQ(DMATCD0_IRQn);
// 5. Enable any hardware service requests via the CHn_CSR[ERQ] registers.
IP_TCD->CH0_CSR |= DMA_TCD_CH0_CSR_ERQ_MASK;
}
void DMATCD0_Handler(void) {
// Print rxBuffer
printf("rxBuffer: %ld", rxBuffer);
// Clear interrupt request
IP_TCD->CH0_INT = 1;
}