Quantcast
Channel: MSP low-power microcontrollers
Viewing all articles
Browse latest Browse all 62309

Forum Post: RE: SPI DMA Freezes when using DMA_INT0 with MSP432 Rev. C Silicon

$
0
0
Hi Chris, Thank you for your reply and help. I tried a few things based on your reply. I too was thinking that the second time the DMA IRQ handler executed was probably because of the DMA RX completing...However, when I read the DMA_INT0_SRCFLG register just after entering the DMA_INT0_IRQHandler (the 2nd time), I noticed all bits were zero. Perhaps this happened because I had already cleared the DMA RX interrupt flag in the DMA_INT0_IRQHandler so when the handler ran because of the TX DMA completion, my code cleared both the TX and RX interrupt flags. Regarding your comment about disabling the interrupt before the receive DMA is finished: this seems unlikely because when I read the DMA_INT0_SRCFLG register right after the DMA_INT0_IRQHandler was entered, I read a value of 0x3 : which means that both the DMA RX and TX channels are signaling that they are done (am I correct in this assumption?) So now to my 2 modifications based on your suggestions. (see code below) First, I added a while loop in the Port IRQ to wait for the TXIFG flag. I saw this line of code in a previous post in the forums, but I think it slightly defeats the purpose of DMA : I do not think one should have to poll the eUSCI to check if the TXIFG bit is ready, shouldn't the DMA just handle that on its own: I should just enable the DMA channels and exit the ISR and be able to enter a LPM instead of polling the eUSCI to check if the TX Buffer was ready. In any case I added the while loop, just in case I was not waiting long enough for the eUSCI module to be ready. Secondly, I modified the DMA_INT0_IRQHandler code to just clear the individual TX , RX DMA interrupt flags and also disable the channels based on which DMA channel (RX , TX) caused the DMA_INT0_IRQHandler to execute. The problem still exists and the symptom is exactly the same as I had shown in my previous post. Since you are going to re-create the test on your setup I am also adding some additional defines to help you. I am also including the code I used to setup the SPI peripheral Again , thanks a lot for your help. ----------------------------------------------------------------------------------------- // number of bytes in the register file #define INERTIAL_REG_FILE_SIZE_BYTES (46U) #define INERTIAL_NUM_BYTES_TO_READ_PER_SAMPLE (18U) /* * The receive buffer will store the reply from the sensor IC * 1 additional byte is required to store the reply on the MISO * line for the address byte transmitted on the MOSI line. * This additional byte stored at mRXData[0] is discarded */ #define INERTIAL_NUM_BYTES_RX_BUFFER (INERTIAL_NUM_BYTES_TO_READ_PER_SAMPLE + 1U) // define and clear receive and transmit buffers uint8_t InertialSensor::mRXData[INERTIAL_NUM_BYTES_RX_BUFFER] = {0x00}; uint8_t InertialSensor::mTXData[INERTIAL_REG_FILE_SIZE_BYTES] = {0x00}; ----------------------------------------------------------------------------------------------------------------------------- void InertialSensor::PORT2_IRQHandler(void) { /* * disable the interrupt on the I2C DRDY port * DMA operation on SPI and I2C should be atomic. * Disable the other interrupts so that the current operation * completes atomically before starting the other peripheral */ MAP_Interrupt_disableInterrupt(INT_PORT3); uint32_t status; status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P2); MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, 0xFF); /* * LSM6DS3 is signaling data is ready. * Trigger the SPI read operation using DMA */ // reset the DMA transfer complete flag mDMAXferComplete = false; /* first assert the Chip Select (CS) to signal the start of the SPI transmission */ MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN4); // Enabling DMA interrupts MAP_DMA_enableInterrupt(INT_DMA_INT0); MAP_Interrupt_enableInterrupt(INT_DMA_INT0); MAP_DMA_enableChannel(DMA_CHANNEL_1); MAP_DMA_enableChannel(DMA_CHANNEL_0); /* Polling to see if the TX buffer is ready */ while (!(MAP_SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT))); / * at this point DMA will take over and complete reception of rest of the data from the * inertial sensor */ } --------------------------------------------------------------------------------------------------------------------------------- void InertialSensor::DMA_INT0_IRQHandler(void) { uint32_t int0_srcflg_dma = DMA_Channel->INT0_SRCFLG; if (int0_srcflg_dma & DMA_INT0_SRCFLG_CH0) // Transmit DMA completed { MAP_DMA_clearInterruptFlag(DMA_CH0_EUSCIB0TX0); // clear the TX DMA interrupt flag MAP_DMA_disableChannel(DMA_CHANNEL_0); // disable the TX channel } else if (int0_srcflg_dma & DMA_INT0_SRCFLG_CH1) // Recieve DMA completed { MAP_DMA_clearInterruptFlag(DMA_CH1_EUSCIB0RX0); // clear the RX DMA interrupt flag MAP_DMA_disableChannel(DMA_CHANNEL_1); // disable the RX channel } else { __nop(); return; } //deassert the chip select line to indicate end of SPI transmission MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN4); // set the DMA transfer complete flag mDMAXferComplete = true; } ----------------------------------------------------------------------------- void InertialSensor::ConfigureSPI() { /* Configure P1.4 is CS */ MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN4); MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN4); /* Selecting P1.5 (SCLK) P1.6 (MOSI) in SPI mode */ MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN5 | GPIO_PIN6 , GPIO_PRIMARY_MODULE_FUNCTION); /* Selecting P1.7 (MISO) in SPI mode */ MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION); /* Configuring SPI in 3wire master mode */ MAP_SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig); /* Enable SPI module */ MAP_SPI_enableModule(EUSCI_B0_BASE); /* * if the mode for SPI is set to read samples : * DMA is used and therefore SPI TX and RX interrupts are not used so disable them */ MAP_SPI_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_SPI_RECEIVE_INTERRUPT); MAP_SPI_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT); MAP_Interrupt_disableInterrupt(INT_EUSCIB0); }

Viewing all articles
Browse latest Browse all 62309

Trending Articles