SPI with DMA: INTDMA0 triggered but no TX

Hallo everyone,

I'm trying to implement SPI TX with DMA using RH850/F1KM-S4 and try to implement following flow

chip select pin Low --> write first data to CSIG2TX0H --> INTDMA0 triggerd, set flag A --> IF A & !(CSIG2STR0&(1<<7) --> chip select pin high.

On the oscilloscope i can confirm that chip select pin was toggled high -> low -> high. But only the first data was transmitted (i.e. DMA transfer is not happening).

How can INTDMA0 is still triggered?

  • I tried to post code snippets here. but it seems it didn't work.

  • static uint16_t g_data_cisg_dma[4] ={0x5a, 0xa5, 0x7b, 0xb7};

    DMAC Init:

    void test_csig_dma_init(void){
        /* Disable DMAC00 operation */
        DMAC0DCEN0 = _DMAC_CHANNEL_OPERATION_DISABLED;

         /* Disable DMAC00 complete interrupt (INTDMA0) operation and clear request */
        INTC2MKDMA0 = _INT_PROCESSING_DISABLED;
        INTC2RFDMA0 = _INT_REQUEST_NOT_OCCUR;

         /* Set DMAC00 complete interrupt (INTDMA0) setting */
        INTC2TBDMA0 = _INT_TABLE_VECTOR;
        INTC2ICDMA0 &= _INT_PRIORITY_LEVEL8;

        /* Set DMAC00 global setting */
        DMAC0DM00CM = _DMAC_PE1_SETTING | _DMAC_SPID0_SETTING | _DMAC_SUPERVISON_MODE;
        DMAC0DSA0 = (uint32_t)&g_data_cisg_dma;
        DMAC0DDA0 = (uint32_t)&CSIG2TX0H;
        DMAC0DTC0 = (uint16_t)0x03U;
        DMAC0DTCT0 = _DMAC_CYCLES_EXECUTED | _DMAC_TRANSFER_HARDWARE | _DMAC_SELECT_CHAIN_1 |
                                    _DMAC_CHAIN_DISABLE | _DMAC_TRANSFER_COMPLETION_INTERRUPT_ENABLE |
                                    _DMAC_CONTINUOUS_TRANSFER_ENABLE |
                                    _DMAC_RELOAD2_DISABLE | _DMAC_RELOAD1_DISABLE | _DMAC_DESTINATION_FIXED |
                                    _DMAC_SOURCE_INCREMENT | _DMAC_TRANSFER_DATA_16BITS |
                                    _DMAC_BOLCK_TRANSFER_1;
         DMAC0DTFR0 = _DMAC_TRIGGER_SOURCE_78 | _DMAC_HARDWARE_TRIGGER_ENABLE;

        /* Clear DMA Transfer Request (PDMAnDTFRRQCm) and DMAC Trasnfer Status (PDMAnDCSTCm) */
        DMAC0DCSTC0 &= _DMAC_CLEAR_ERC & _DMAC_CLEAR_TCC & _DMAC_CLEAR_SRC; // Clear ERC, TCC & SRC respectively
        DMAC0DTFRRQC0 &= _DMAC_CLEAR_DTFR;

        /* Clear DMAC00 complete interrupt (INTDMA0) request and enable operation */
        INTC2RFDMA0 = _INT_REQUEST_NOT_OCCUR;
        INTC2MKDMA0 = _INT_PROCESSING_ENABLED;

        /* Enable DMAC00 operation */
        DMAC0DCEN0 = _DMAC_CHANNEL_OPERATION_ENABLED;
    }

    CSIG2 Init:

    void R_CSIG2_Init(void){
        /* Stop CSIG2 operation */
        CSIG2CTL0 = _CSIG_OPERATION_CLOCK_STOP;

         /* Disable CSIG2 interrupt operation */
        INTC2MKCSIG2IC = _INT_PROCESSING_DISABLED;
        INTC2MKCSIG2IR = _INT_PROCESSING_DISABLED;
        INTC2MKCSIG2IRE = _INT_PROCESSING_DISABLED;

         /* Clear CSIG2 interrupt operation */
        INTC2RFCSIG2IC = _INT_REQUEST_NOT_OCCUR;
        INTC2RFCSIG2IR = _INT_REQUEST_NOT_OCCUR;
        INTC2RFCSIG2IRE = _INT_REQUEST_NOT_OCCUR;

         /* Set CSIG2 interrupt setting */
        INTC2TBCSIG2IC = _INT_TABLE_VECTOR;
        INTC2ICCSIG2IC &= _INT_PRIORITY_LEVEL8;

         /* Set CSIG2 control setting */
        CSIG2CTL1 = _CSIG_CLOCK_INVERTING_LOW |//SPI MODE 0
                                _CSIG_INTERRUPT_TIMING_NORMAL | _CSIG_EXTENDED_DATALENGTH_DISABLED |
                                _CSIG_DATA_CONSISTENCY_CHECK_DISABLE | _CSIG_HANDSHAKE_DISABLE |
                                _CSIG_SLAVE_SELECT_DISABLE;
        CSIG2CTL2 = _CSIG_8MHz_BAUD_RATE;

         /* Set CSIG2 configuration setting */
        CSIG2CFG0 = _CSIG_PARITY_NO | _CSIG_DATA_LENGTH_8 | _CSIG_DATA_DIRECTION_MSB |
                                _CSIG_PHASE_SELECTION_TYPE4; //SPI MODE 0

         /* Enable CSIG2 operation */
         CSIG2CTL0 = _CSIG_OPERATION_CLOCK_PROVIDE | _CSIG_TRANSMISSION_PERMIT |
         _CSIG_RECEPTION_PROHIBIT | _CSIG_DIRECTACCESS;

         /* Clear CSIG2 interrupt operation */
         INTC2RFCSIG2IC = _INT_REQUEST_NOT_OCCUR;
         INTC2RFCSIG2IR = _INT_REQUEST_NOT_OCCUR;
         INTC2RFCSIG2IRE = _INT_REQUEST_NOT_OCCUR;

    }

  • I think i solved the problem.

    I changed DMAC0DM00CM = _DMAC_PE1_SETTING | _DMAC_SPID0_SETTING | _DMAC_SUPERVISON_MODE;

    which is translated to 0x0010 to DMAC0DM00CM = 0x0000 and use _DMAC_SINGLE_TRANSFER since ICCSIG2IC was triggered after TX is completed.

    So my question will be, how one determine the value of SPID[1:0] und PEID[2:0]?

  • Hello Arno,

    you should be able to determine the value of SPID[1:0] und PEID[2:0] from the PDMAnDMyiCM register:

    Best regards,

    Erik

  • Hi Erik,

    thanks for the reply. I'm a little bit confused. The value after reset for PDMAnDMyiCM is 0x0010, when I try to used DMAC00 I need to change PDMA0DM00CM to 0x0000 so it can work.

    My question is, if I want to use DMAC17 do I need to set PDMA1DM17CM to 0x0071 ?

  • Hi Arno,

    we are currently investigating your question. Which IDE do you use? Are you generating your code with the Smart Configurator?

    Best regards,

    Erik

  • Hi Erik,

    Yes i used smart configurator for setting-up DMAC. I use GHS for compiling and VScode for editing.

    Thanks in advance.

    Cheers

    Arno

  • Hi Arno,

    is it possible for you to share the project or at least the values of the Smart Configurator, so we can take a look at it?  

    Best regards,

    Erik

  • I dont think i can share the project. what value from Smart configuration do you need. maybe i can provide here. If i can write a source code on the forum (i tried so many times, it always failed/didn't get post)

    test code
    .