이 주제 (DMA & SPI)는 이미 마이크로 칩 포럼의 수많은 스레드에서 이미 다루어졌으며, 사실은 키워드 검색으로 15 페이지를 모두 읽었습니다. dma "를 읽고 dma & spi에 대한 모든 주제를 읽으십시오.PIC32에서 DMA를 통해 SPI 데이터를 수신
그리고 난 아직도 내 문제 붙어 나는 누군가가 나를 도울 수 있기를 바랍니다 :) 여기
가 문제입니다.내 칩은 PIC32MX775F512H입니다. DMA를 통해 SPI를 사용하여 데이터를 수신 (수신 만)하려고합니다. "단지"SPI로 수신 할 수 없으며, SPI 코어가 SPIBUF (SPI1ABUF 용)에 쓰는 경우에만 2 개의 DMA 채널을 사용하여 데이터를 수신하려고 시도 할 때만 SPI 코어를 토글 링하기 시작합니다. 송신 파트의 DMA_CHANNEL1. 수신 파트의 경우 DMA_CHANNEL2입니다.
나는 http://www.microchip.com/forums/tm.aspx?tree=true&high=&m=562453&mpage=1#
의 코드를 붙여 그리고 그것은 운이없이 작동하도록 노력 복사합니다. 그것은 단지 몇 바이트 (5 또는 6)를받습니다.
두 개의 DMA 채널 모두에 이벤트 활성화 플래그를 DMA_EV_BLOCK_DONE으로 설정 했으므로 인터럽트는 발생하지 않습니다.
의견이 있으십니까? 두 인터럽트 핸들러
int Spi_recv_via_DMA(SPI_simple_master_class* SPI_Port, int8u *in_bytes, int16u num_bytes2)
{
DmaChannel dmaTxChn=DMA_CHANNEL1;
DmaChannel dmaRxChn=DMA_CHANNEL2;
SpiChannel spiTxChn=SPI_Port->channel;
int8u dummy_input;
DmaChnOpen(dmaTxChn, DMA_CHN_PRI3, DMA_OPEN_DEFAULT);
DmaChnOpen(dmaRxChn, DMA_CHN_PRI3, DMA_OPEN_DEFAULT);
DmaChnSetEventControl(dmaTxChn, DMA_EV_START_IRQ_EN | DMA_EV_START_IRQ(_SPI1A_RX_IRQ));
DmaChnSetEventControl(dmaRxChn, DMA_EV_START_IRQ_EN | DMA_EV_START_IRQ(_SPI1A_RX_IRQ));
DmaChnClrEvFlags(dmaTxChn, DMA_EV_ALL_EVNTS);
DmaChnClrEvFlags(dmaRxChn, DMA_EV_ALL_EVNTS);
DmaChnSetEvEnableFlags(dmaRxChn, DMA_EV_BLOCK_DONE);
DmaChnSetEvEnableFlags(dmaTxChn, DMA_EV_BLOCK_DONE);
//SpiChnClrTxIntFlag(spiTxChn);
//SpiChnClrRxIntFlag(spiTxChn);
DmaChnSetTxfer(dmaTxChn, tx_dummy_buffer, (void *)&SPI1ABUF, num_bytes2, 1, 1);
DmaChnSetTxfer(dmaRxChn, (void *)&SPI1ABUF, in_bytes, 1, num_bytes2, 1);
while ((SPI1ASTAT & SPIRBE) == 0)
dummy_input = SPI1ABUF;
SPI1ASTAT &= ~SPIROV;
DmaRxIntFlag = 0;
DmaChnEnable(dmaRxChn);
DmaChnStartTxfer(dmaTxChn, DMA_WAIT_NOT, 0);
while(!DmaRxIntFlag);
return 1;
}
:
// handler for the DMA channel 1 interrupt
void __ISR(_DMA1_VECTOR, ipl5) DmaHandler1(void)
{
int evFlags; // event flags when getting the interrupt
//LED_On(LED_CFG);
INTClearFlag(INT_SOURCE_DMA(DMA_CHANNEL1)); // acknowledge the INT controller, we're servicing int
evFlags=DmaChnGetEvFlags(DMA_CHANNEL1); // get the event flags
if(evFlags&DMA_EV_BLOCK_DONE)
{ // just a sanity check. we enabled just the DMA_EV_BLOCK_DONE transfer done interrupt
DmaTxIntFlag = 1;
DmaChnClrEvFlags(DMA_CHANNEL1, DMA_EV_BLOCK_DONE);
}
// LED_Off(LED_CFG);
}
void __ISR(_DMA2_VECTOR, ipl5) DmaHandler2(void)
{
int evFlags; // event flags when getting the interrupt
INTClearFlag(INT_SOURCE_DMA(DMA_CHANNEL2)); // acknowledge the INT controller, we're servicing int
evFlags=DmaChnGetEvFlags(DMA_CHANNEL2); // get the event flags
if(evFlags&DMA_EV_BLOCK_DONE)
{ // just a sanity check. we enabled just the DMA_EV_BLOCK_DONE transfer done interrupt
DmaRxIntFlag = 1;
DmaChnClrEvFlags(DMA_CHANNEL2, DMA_EV_BLOCK_DONE);
}
}
그래서 나는 줄에서 영원히 기다리고 결국 : 여기
내가 사용하고있는 코드입니다 동안 (! DmaRxIntFlag);중단 점을 인터럽트 벡터에 넣었습니다. 절대로 호출되지 않습니다.
이
는 끊임없이 지속되는 대기 중에 여러 레지스터의 상태 :DMASTAT 0x00000001
내가 SPI1A 포트를 사용하고
DMACON 0x0000C800 SPI1ABUF 및 _SPI1A_RX_IRQ
DCH1SPTR의 0x5
DCH1SSIZ 그래서 0x2B
DCH2DPTR 0x6
DCH2DSI Z 0x2B
를 전송하는 데 사용됩니다 0x00000620
DCH2CON 0x00008083
DCH2ECON 0x1B10
DCH2INT 0x00800C4
DCH2SSA 0x1F805820
DCH2DSA은 당신이
SPI 연결의 다른 끝에 어떤 종류의 장치가 있습니까? 데이터를 전송하는 모드에 이미 있다고 가정해야합니다. –