Je sais que ce sujet (DMA & SPI) a déjà été abordé sur de nombreux threads dans le forum de la micropuce, en fait j'ai lu toutes les 15 pages en résultat de la recherche avec le mot clé " dma "et lire tous les sujets sur dma & spi.Recevoir des données SPI via DMA sur PIC32
Et je suis toujours coincé avec mon problème, j'espère que quelqu'un peut me aider :)
est ici le problème.
Ma puce est un PIC32MX775F512H. J'essaie de recevoir (seulement recevoir) des données en utilisant SPI via DMA. Comme vous ne pouvez pas "juste" recevoir en SPI, et que le noyau SPI commence à basculer l'horloge SPI seulement si vous écrivez dans le SPIBUF (SPI1ABUF pour moi) j'essaye de recevoir mes données en utilisant 2 canaux DMA. DMA_CHANNEL1 pour la partie de transmission. DMA_CHANNEL2 pour la partie réceptrice.
-je copier collé le code de http://www.microchip.com/forums/tm.aspx?tree=true&high=&m=562453&mpage=1#
et a essayé de le faire fonctionner sans chance. Il ne reçoit que plusieurs octets (5 ou 6).
J'ai défini les indicateurs d'activation d'événement sur DMA_EV_BLOCK_DONE pour les deux canaux dma, aucune interruption ne se produit.
Avez-vous une idée?
Voici le code que je utilise:
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;
}
avec ces deux gestionnaires d'interruption:
// 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);
}
}
Je finissent par attendre pour toujours à la ligne: while (! DmaRxIntFlag);
J'ai mis des points d'arrêt dans les vecteurs d'interruption, ils ne sont jamais appelés.
C'est l'état de plusieurs registres au cours de la toujours durable attente:
DMACON 0x0000C800
DMASTAT 0x00000001
J'utilise le port SPI1A, si SPI1ABUF et _SPI1A_RX_IRQ
DCH1SPTR 0x5
DCH1SSIZ 0x2B
DCH2DPTR 0x6
DCH2DSI Z 0x2B
DCH2CON 0x00008083
DCH2ECON 0x1B10
DCH2INT 0x00800C4
DCH2SSA 0x1F805820
DCH2DSA 0x00000620
canal 1 est utilisé pour transmettre
Channel 2 est utilisé pour recevoir
Quel type de périphérique se trouve à l'autre extrémité de la connexion SPI? Je dois supposer qu'il est déjà dans un mode où il envoie des données? –