2011-03-02 3 views
3

이 주제 (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

채널 1 채널 2
를 전송하는 데 사용됩니다 0x00000620

DCH2CON 0x00008083
DCH2ECON 0x1B10
DCH2INT 0x00800C4
DCH2SSA 0x1F805820
DCH2DSA은 당신이

+0

SPI 연결의 다른 끝에 어떤 종류의 장치가 있습니까? 데이터를 전송하는 모드에 이미 있다고 가정해야합니다. –

답변

0
  1. 을 수신하는 데 사용됩니다

    슬레이브 모드에서 SPI를 사용합니까? 또는 마스터 모드에서 명령에 대한 응답을 읽으려고합니까?

  2. 이 칩의 실리콘 에라타를 확인하셨습니까? dspic 33fj 제품군에는 SPI 종속 모드가 작동하지 않는 문제가있었습니다.

그 외에도 DmaRxIntFlag 변경을 기다리는 것이 좋습니다. DMA 전송을 구성하고 메인 루프를 계속 진행해야합니다. DMA가 인터럽트 처리기를 트리거합니다.

희망이 도움이됩니다.

1

당신은이 누락 :

INTEnable(INT_SOURCE_DMA(dmaTxChn), INT_ENABLED); // Tx 
INTEnable(INT_SOURCE_DMA(dmaRxChn), INT_ENABLED); // Rx 

rigth 행운

DmaRxIntFlag = 0; 
DmaChnEnable(dmaRxChn); 
DmaChnStartTxfer(dmaTxChn, DMA_WAIT_NOT, 0); 

전에!

관련 문제