This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP432P401R: Question about DMA and low power modes

Part Number: MSP432P401R

I have read the manual and I have seen that DMA doesn't work in LP3/4 but still, I need to ask a few questions.

I have my MSP432 connected over EUSCIB0 to the chip CC1200 which has a FIFO for receiving bytes. 
You can read from the FIFO by lowering chip select and then sending a command which instructs the CC1200 to burst read from the FIFO. After the transfer has finished, I pull the chip select up.

Now, I need to do all these activities as reactions to certain interrupts. When I need to read from the CC1200 I get a GPIO interrupt which prepares and starts the DMA, which then reads from the CC1200 and at the end I get an interrupt when the transfer has finished.

Everything was good till I entered low power mode 3 or 4. In active mode and low power mode 0 everything works fine, but in low power mode 3 and 4 a strange thing happens.

For example, I send this packet "12345". When I use LP0 I receive everything ok, but in LP3 and LP4 I receive "22345". 
No matter how big the packet is or what data I send, the second byte sent is always replicated on the first and second place. It's always the same problem. 

Now after so much explanation I need to ask, why does my DMA even work in LP3 and LP4 when it states in the manual that peripherals don't work in these modes?
Why does my DMA interrupt wake the MCU up when it states in the manual that it shouldn't be possible?
Do I not understand the manual or is the functioning of the DMA not defined in these modes and that is why it states that it doesn't work in these modes?

  • Hello,
    Could you provide a little more detail around the GPIO interrupt and how the system transitions from the GPIO interrupt to the DMA action? The GPIO interrupt will wake up the device from LPM3. Now depending upon if you have enabled the sleep on interrupt or the rude mode a number of things may be happening where the DMA was initiated in the GPIO ISR but when the ISR was exited the device tried to return to low power mode 3. I would recommend within the GPIO isr to clear the deep sleep bit, so that upon exit of the isr it returns to LPM0 instead of LPM3. You could then return to LPM3 after the DMA was complete.

    /*
    * Disable deepSleep, lpm3->lpm0
    */
    SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
    /*

    Regards,
    Chris
  • Hi Chris,

    I'll give the code that I use in the interrupt. In that code, I do not do anything with the sleep state and I just exit the interrupt which means that the MCU goes back to LP3 or LP4.

    Could you please give me an answer to the questions which I asked, because the solution to the problem is just to exit deep sleep and I was aware of that but why does the DMA even work in LP3 and LP4 when it shouldn't and why does the DMA interrupt wake the MCU up in LP3 and LP4 when the documentation says that it can't do that?

    void PORT1_IRQHandler(void)
    {
        uint32_t status;
    
        status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
    
        if (status & GPIO_PIN2)
        {
            CC1200_InterruptFIFO();
        }
    }
    
    void CC1200_InterruptFIFO()
    {
        MAP_GPIO_disableInterrupt(GPIO_PORT_P1, GPIO_PIN2);
    
        CC1200_StartDMA(cc1200_state);
    }
    
    void CC1200_StartDMA(state_e state)
    {
        CC1200_SelectModule(); /* Pulls chip select down and sets some variables */
    
        /* Enable DMA interrupt */
        MAP_Interrupt_enableInterrupt(CC1200_DMA_INTERRUPT);
        MAP_DMA_enableInterrupt(CC1200_DMA_INTERRUPT);
    
    
            /* Setup the TX transfer characteristics & buffers */
            MAP_DMA_setChannelControl(CC1200_DMA_TX | UDMA_PRI_SELECT,
            UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1);
            MAP_DMA_setChannelTransfer(CC1200_DMA_TX | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC,
                                       &CC1200_dummyByte,
                                       (void *) SPI_getTransmitBufferAddressForDMA(CC1200_SPI),
                                       length);
    
            /* Setup the RX transfer characteristics & buffers */
            MAP_DMA_setChannelControl(CC1200_DMA_RX | UDMA_PRI_SELECT,
            UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
            MAP_DMA_setChannelTransfer(CC1200_DMA_RX | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC,
                                       (void *) SPI_getReceiveBufferAddressForDMA(CC1200_SPI),
                                       buffer,
                                       length);
    
            /* Assign and disable DMA interrupt */
            MAP_DMA_assignInterrupt(CC1200_DMA_INTERRUPT, CC1200_DMA_RX & 0x0F);
            MAP_DMA_disableInterrupt(CC1200_DMA_INTERRUPT);
            MAP_DMA_clearInterruptFlag(CC1200_DMA_RX & 0x0F);
    
        CC1200_TransmitByte(CC1200_ADDRESS_FIFO | CC1200_READ_BURST);
        CC1200_ReceiveByte();
    
        MAP_DMA_enableChannel(CC1200_DMA_RX & 0x0F);
        MAP_DMA_enableChannel(CC1200_DMA_TX & 0x0F);
    }
    
    

     

  • Hello,

        Thank you for sharing your code.  By default the SLEEPONEXIT is set to '0' and returns to thread mode and not sleep.

    Also, please note that if the DMA is active and requesting a clock that the device will not enter LPM3/4 when requested unless you force the LPM entry.

    "why does the DMA even work in LP3 and LP4 when it shouldn't and why does the DMA interrupt wake the MCU up in LP3 and LP4 when the documentation says that it can't do that"


    Your device is not in LPM3 but in LPM0.  Because of the clock request from the DMA the device is not allowed to enter LPM3.  You should be able to confirm this by measuring the current and/or checking the LPM_INVALID_CLK_IFG.

    Regards,
    Chris

     

**Attention** This is a public forum