No dispara un DMA de interrupción al leer SPI. La transacción del último byte no llega

1

Uso DMA para leer con SPI flash usando USART. MCU - maestro, flash - esclavo. Leí 1029 bytes por transacción. Algoritmo de intercambio:

  1. Activo el flash (CS = 0)
  2. Configuré el canal DMA para recibir 1029 bytes. Permitir la interrupción de lectura de IRQ_RX
  3. Configuré otro canal DMA para transmitir 1029 bytes. Permitir la interrupción de IRQ_TX, habilitar el canal, en este momento enviar / recibir
  4. En el controlador IRQ_TX, borre el indicador de habilitación de interrupción
  5. En el controlador IRQ_RX, borro el indicador de activación de interrupción + desactivo el flash (CS = 1)

Funciona. Pero muy raramente hay un error cuando envío 1029 bytes, pero solo se recibe 1028. En el depurador, veo que el contador de DMA enviado bytes es 0 (enviado 1029), y el contador leído es 1 (hasta 1028). Como DMA no recibió el último byte, la interrupción de RX no se produce y no puedo ingresar al controlador de interrupciones de RX. Se llama al manejador de interrupciones TX, es decir, 1029 bytes se envían con precisión. Las banderas de error son cero. Este error ocurre raramente. ¿Por qué no recibo el último byte, qué podría estar mal?

MCU - Serie F2MC-16FX MB96600. IDE Softune Workbench

void USART_start_DMA_read(void)
{   
    /* correct size_pic and address */

    //INIT DMA FOR READ
    if(UART2_SSR2_RDRF==0)
    UART2_ESIR2_RDRF=0; //clear RDRF -  Reception data register full 

    DSR_DTE2 = 0x0; //Clear possible DMA 2 request
    DER_EN2 = 0x0; //DMA 2 channel disable
    DISEL2 = _IRQ_LINR2; //< LIN USART 2 RX
    DCT2 = 1029; //how much to read
    IOA2 = (unsigned long)&UART2_RDR2;
    DMACS2 = 0x10; //no IOA update, BAP update, byte transfer, IOA -> BAP
    BAPH2 = (unsigned long) &graph_buf[beg_byte] >> 16;
    BAPM2 = (unsigned long) &graph_buf[beg_byte] >> 8;
    BAPL2 = (unsigned long) &graph_buf[beg_byte] & 0xFF;
    DER_EN2 = 1; // DMA 2 channel enable

    UART2_SSR2_RIE = 1; //enable irq RX - at this point the channel is ready to receive bytes

    FLASH_CS = FLASH_ON; //enable flash

    //INIT DMA FOR SEND
    if(UART2_SSR2_TDRE==0)
        UART2_ESIR2_TDRE=0; //clear TDRF -  Transmit data register full     

    DSR_DTE3 = 0x0; //Clear possible DMA 3 request
    DER_EN3 = 0x0; //DMA 3 channel disable
    DISEL3 = _IRQ_LINT2; //< LIN USART 2 TX
    DCT3 = DCT2; //how much to send
    IOA3 = (unsigned long)&UART2_TDR2;
    DMACS3 = 0x12; //no IOA update, BAP update, byte transfer, BAP -> IOA
    BAPH3 = (unsigned long) &read_flash_cmd[0] >> 16;
    BAPM3 = (unsigned long) &read_flash_cmd[0] >> 8;
    BAPL3 = ((unsigned long) &read_flash_cmd[0] & 0xFF);
    DER_EN3 = 1; // DMA 3 channel enable

    UART2_SSR2_TIE = 1; //enable irq TX - at this point the transmission / reading starts
}

void IRQ_USART2_TX()
{
    //after transferring 1029 bytes
    UART2_SSR2_TIE=0; //disable irq TX
    DSR_DTE3 = 0x0; //clear DMA channel request
    __wait_nop();
    __wait_nop();
    __wait_nop();
    __wait_nop();
    __wait_nop();
}

void IRQ_USART2_RX(void)
{
    //after reading 1029 bytes
    FLASH_CS = FLASH_OFF; //disable flash
    UART2_SSR2_RIE = 0; //disable irq RX
    DSR_DTE2 = 0x0; //clear DMA channel request

    //if not the entire object is read - read the following data block
    if(size_pic)
    {
        USART_start_DMA_read();
    }
}

Actualizado. Se produce un error si ejecuto el firmware a través del depurador. Si corro sin depurador, todo funciona sin fallos. ¿Qué piensas, puede el depurador afectar el trabajo?

    
pregunta avg33

1 respuesta

0

Soy nuevo en este microcontrolador, y esto es lo que veo:

  • su manual de hardware enlace (denominado "MB96600 Series: F2MC-16FX Hardware Manual") solo contiene una mención de SPI a través de USART;
  • No puedo encontrar una nota de aplicación fácilmente disponible que explique cómo interactuar con SPI a través de USART, y espero que lo que intente lograr sea realmente alcanzable con el nivel de confiabilidad requerido ;
  • no indica qué es su dispositivo flash y no proporciona un diagrama del circuito, por lo que no hay forma de verificar cómo pueden funcionar juntos los dispositivos;
  • ve cómo los problemas de hardware y su arquitectura (hardware y software) pueden causar un bloqueo del sistema. Lo más probable es que tenga que rediseñar el software (firmware) de la MCU para manejar tales situaciones, o elegir otra arquitectura de hardware;
  • usted dice que el dispositivo flash que utiliza es SPI. Como sé, el protocolo SPI proporciona un algoritmo muy débil de retroalimentación desde el dispositivo esclavo (a través de MISO), por lo que en SPI nativo hay una manera muy limitada de conocer el estado del dispositivo remoto y por qué no cumple las expectativas;
  • y, finalmente, debes hacer dos cosas:
    • explíquenos, y a usted mismo, cómo debería funcionar la comunicación desde su perspectiva y desde su comprensión de las hojas de datos. Puede suceder en esta etapa que tenga algunas expectativas erróneas o que pierda un poco de información sobre los dispositivos;
    • mire cómo funciona en realidad usando un rastreador de hardware, y compare con cómo considera que debería funcionar. Puede encontrar fallos en el reloj, o discrepancias en el siguiente algoritmo serial (estoy especulando aquí, ya que no tengo más idea sobre el diseño de su hardware).

Pondría estos pensamientos como comentarios a la pregunta, pero tiene más letras de las que pueden contener los comentarios.

    
respondido por el Anonymous

Lea otras preguntas en las etiquetas