AnsweredAssumed Answered

Program only works when stepping through - LPCXpresso18S37

Question asked by can.pouliquen@etu.umontpellier.fr on Jun 26, 2020
Latest reply on Jun 29, 2020 by Con Verse

Hello, I am not very experienced in embedded systems and I need to develop a program on an LPCXpresso18S37 that is able to communicate with a Python script to send and receive data using UART and the DMA. I am using MCUXpresso IDE and LPCOpen library.

 

The communication is basically a series of byte exchanges, where the Python script sends commands, to which the MCU responds by performing specific actions.

For example : if the Python scripts sends command "1", the MCU will send it back as an ack, and then wait to receive 16-bytes of plaintext, which will be sent by the Python script, etc...

 

Here is my problem : when in debug mode and stepping through instructions, the program behaves as expected : bytes are received and sent properly, stored in designated memory.

However, whenever I run the program "full speed", without any breakpoints or without stepping instructions, things get weird and the programs starts behaving in a way I really can not understand : most of the data being sent or received seems to be lost.

I have spent a lot of time trying to debug or at least figure out what's going on, but, I admit, without great success...

I am using the DMA without interruptions, as a different buffer is fulled everytime.

 

I would gladly welcome any help or ideas. Thank you in advance.

 

Here is the code in question :

 

#if defined (__USE_LPCOPEN)
#if defined(NO_BOARD_LIB)
#include "chip.h"
#else
#include "board.h"
#endif
#endif

#include <cr_section_macros.h>

 

uint8_t dmaChannelNumTx, dmaChannelNumRx;

FunctionalState  isDMATx = ENABLE;

 

static void App_DMA_Init(void)
{
    /* Initialize GPDMA controller */
    Chip_GPDMA_Init(LPC_GPDMA);
}

 

static void App_DMA_DeInit(void)
{
    Chip_GPDMA_Stop(LPC_GPDMA, dmaChannelNumTx);
    Chip_GPDMA_Stop(LPC_GPDMA, dmaChannelNumRx);
}

 

//Send data via USART0 and DMA
void Send_DMA(uint8_t *data_array, uint32_t data_size, uint8_t dmaChannelNumTx)
{
    isDMATx = ENABLE;
    while(Chip_GPDMA_Transfer(LPC_GPDMA,
                        dmaChannelNumTx,
                        (uint32_t) data_array,
                        GPDMA_CONN_UART0_Tx,
                        GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, //Memory to peripheral
                        data_size) != SUCCESS) {}
}

 

void Receive_DMA(uint8_t *data_array, uint32_t data_size, uint8_t dmaChannelNumRx)
{
    isDMATx = DISABLE;
    while(Chip_GPDMA_Transfer(LPC_GPDMA,
                        dmaChannelNumRx,
                        GPDMA_CONN_UART0_Rx,
                        (uint32_t) data_array,
                        GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA, //peripheral to memory
                        data_size) != SUCCESS) {}
}

 

int main(void) {

 

    #if defined (__USE_LPCOPEN)
    // Read clock settings and update SystemCoreClock variable
    SystemCoreClockUpdate();

 

    #if !defined(NO_BOARD_LIB)

 

    // Set up and initialize all required blocks and
    // functions related to the board hardware
    Board_Init();
    Board_UART_Init(LPC_USART0);

 

    //Initialise USART with 115200 baudrate, 8-bits length, no parity and 1-bit stop
    Chip_UART_Init(LPC_USART0);
    Chip_UART_SetBaud(LPC_USART0, 115200);
    Chip_UART_ConfigData(LPC_USART0, (UART_LCR_WLEN8 | UART_LCR_SBS_1BIT | UART_LCR_PARITY_DIS));
    Chip_UART_TXEnable(LPC_USART0);

    #endif

 

    #endif

 

    //Setting up communication using DMA
    Chip_UART_SetupFIFOS(LPC_USART0, (UART_FCR_FIFO_EN | UART_FCR_RX_RS |
                                UART_FCR_TX_RS | UART_FCR_DMAMODE_SEL | UART_FCR_TRG_LEV0));

 

    //=======================================================================//
    /* Init command, receiver and trasmitter buffers ------------------------*/
    //=======================================================================//
        uint8_t command[1];
        uint8_t RX_plaintext[16];
        uint8_t RX_key[16];
        uint8_t TX_ciphertext[16];
        command[0] = 0;
    //=======================================================================//


    while(1)
    {
        App_DMA_Init();
        dmaChannelNumTx = Chip_GPDMA_GetFreeChannel(LPC_GPDMA, GPDMA_CONN_UART0_Tx);
        dmaChannelNumRx = Chip_GPDMA_GetFreeChannel(LPC_GPDMA, GPDMA_CONN_UART0_Rx);

 

        //Receive and send back command
        Receive_DMA((uint8_t*) command, 1, dmaChannelNumRx);
        Send_DMA((uint8_t*) command, 1, dmaChannelNumTx);

 

           //Obey the command
        switch(command[0])
            {
                //Command to receive plaintext and send back first byte for ack
                case 1:
                    Receive_DMA((uint8_t*) RX_plaintext, 16, dmaChannelNumRx);
                    Send_DMA((uint8_t*) &RX_plaintext[0], 1, dmaChannelNumTx);
                    command[0] = 0;
                break;

 

                //Command to receive key and send back first byte for ack
                case 2:
                    Receive_DMA((uint8_t*) RX_key, 16, dmaChannelNumRx);
                    Send_DMA((uint8_t*) &RX_key[0], 1, dmaChannelNumTx);
                    command[0] = 0;
                break;

 

                //Command to XOR key and plaintext
                case 3:
                    for(int i = 0; i<16; i++)
                        TX_ciphertext[i] = RX_plaintext[i] ^ RX_key[i];
                    command[0] = 0;
                break;

 

                //Command to send ciphertext
                case 4:
                    Send_DMA((uint8_t*) TX_ciphertext, 16, dmaChannelNumTx);
                    command[0] = 0;
                break;
                default:
                    break;

 


            }

 

    }

 

    App_DMA_DeInit();
    Chip_UART_DeInit(LPC_USART0);

 

    return 0 ;
}

Outcomes