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.

AM2434: UART Multi-drop Parity Address Match Mode is not working

Part Number: AM2434

Hi,

I am currently trying to put the UART multi-drop parity address match mode into operation on the M4F core of the AM243x.


I have written the following code for this:

// Included Files
#include "serial_communication.h"   // Contains all necessary headers

#define SERIAL_TASK_PRI   (3u)
#define SERIAL_TASK_SIZE (1024u)

#define APP_UART_BUFSIZE              (200U)
#define APP_UART_RECEIVE_BUFSIZE      (8U)

StackType_t serialTaskStack[SERIAL_TASK_SIZE] __attribute__((aligned(32)));
StaticTask_t gSerialTaskObj;
TaskHandle_t serialTask;

uint8_t gUartBuffer[APP_UART_BUFSIZE] = {0x01, 0x02, 0x03};
uint8_t gUartReceiveBuffer[APP_UART_RECEIVE_BUFSIZE];

UART_Transaction trans;

void serial_main(void *args)
{
    TickType_t xLastWakeTime;
    xLastWakeTime = xTaskGetTickCount();

    for(;;)
    {
        int32_t transferOK;
        UART_Transaction_init(&trans);

        /* Send data */
//        HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_ECR), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_ECR) | 0x01));  // Next byte is written as an address byte
        trans.buf   = &gUartBuffer[0U];
        trans.count = 3;
        transferOK = UART_write(gUartHandle[COMM_UART1], &trans);
        DebugP_log("Message sent!\r\n");

//TODO: xTaskDelayUntil()
        vTaskDelay(1000 / portTICK_PERIOD_MS);     // Set the overall task period to 1ms
    }
}



void empty_main(void *args)
{
    /* Open drivers to open the UART driver for console */
    Drivers_open();
    Board_driversOpen();

//    // Enable Multi-drop Parity Address Match Mode
//    HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_ECR), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_ECR) & 0xFFFFFFF7));      // Disable Receive Mode
//    HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_EFR2), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_EFR2) | 0x00000004));    // Enable Multi-drop address match mode
//    HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_MAR), (uint32_t)0x10);                                                                // Set matching device address
//    HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_MMR), (uint32_t)0xFF);                                                                // Set address match masking
//    HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_MBR), (uint32_t)0xFF);                                                                // Set broadcast address match
//    HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_EFR2), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_EFR2) | 0x00000080));    // Enable broadcast address matching (if needed)
//    HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_ECR), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_ECR) | 0x08));            // Enable RX

    /* create the tasks, order of task creation does not matter for this example */
    serialTask = xTaskCreateStatic( serial_main,        /* Pointer to the function that implements the task. */
                                  "Serial_polling",     /* Text name for the task.  This is to facilitate debugging only. */
                                  SERIAL_TASK_SIZE,     /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                  NULL,                 /* We are not using the task parameter. */
                                  SERIAL_TASK_PRI,      /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                  serialTaskStack,      /* pointer to stack base */
                                  &gSerialTaskObj );    /* pointer to statically allocated task object memory */
    configASSERT(serialTask != NULL);
    DebugP_log("The task is created!\r\n");

    Board_driversClose();

    /* Don't close drivers to keep the UART driver open for console */
    /* Drivers_close(); */
}

(In the main.c just a one-time task is created, which calls the empty_main() function, and the scheduler is started)


With the commented multi-drop enable routine, the programme works and sends the appropriate bytes via the UART interface. However, when I activate the multi-drop mode (uncomment the code), the microcontroller gets stuck there and does not process anything else. What could be the reason for this? And is the multi-drop match mode supported from the M4F Core at all?

Thanks for your help!

  • Quick update:

    The registers must be set before uart_open() so the register values now get written correctly. But I am only able to send 8-bit messages with no address parity bit. Is it possible that the AM2434 is not supporting the Multi-drop mode?

  • Hi Joshua,

    Thanks for reaching out on the TI E2E Support Forum.

    I would be happy to help you on this issue.

    I would like to know few things beforehand:

    1. Are you on the latest MCU PLUS SDK Version?

    2. Instead of simply the main.c file can you send the entire project file for me to browse through and run it at my setup?

    3. Is this application running on AM243-LP or AM243-EVM?

    4. Also looking at your code, its a FREERTOS application, correct?

    Looking forward to your response.

    Regards,

    Vaibhav

  • Hi Vaibhav Kumar,

    thank you for your response!

    To your questions:

    1. I am on the latest MCU Plus SDK Version.

    2. I attach my whole code below

    3. I am using the AM243-EVM.

    4. Yes, I want to use the FreeRTOS application.

    main.h:

    #ifndef MAIN_H_
    #define MAIN_H_
    
    // Included Files
    #include <stdlib.h>
    #include <string.h>
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_config.h"
    #include "ti_board_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include "FreeRTOS.h"
    #include "task.h"
    #include <drivers/hw_include/hw_types.h>
    
    #endif /* MAIN_H_ */

    main.c:

    // Included files
    #include "main.h"
    
    #define MAIN_TASK_PRI  (configMAX_PRIORITIES-1)
    #define MAIN_TASK_SIZE (16384U/sizeof(configSTACK_DEPTH_TYPE))
    
    StackType_t gMainTaskStack[MAIN_TASK_SIZE] __attribute__((aligned(32)));
    
    StaticTask_t gMainTaskObj;
    TaskHandle_t gMainTask;
    
    void empty_main(void *args);
    
    void freertos_main(void *args)
    {
        empty_main(NULL);
    
        vTaskDelete(NULL);
    }
    
    int main()
    {
        /* init SOC specific modules */
        System_init();
        Board_init();
    
        /* This task is created at highest priority, it should create more tasks and then delete itself */
        gMainTask = xTaskCreateStatic( freertos_main,   /* Pointer to the function that implements the task. */
                                      "freertos_main", /* Text name for the task.  This is to facilitate debugging only. */
                                      MAIN_TASK_SIZE,  /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                      NULL,            /* We are not using the task parameter. */
                                      MAIN_TASK_PRI,   /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                      gMainTaskStack,  /* pointer to stack base */
                                      &gMainTaskObj ); /* pointer to statically allocated task object memory */
        configASSERT(gMainTask != NULL);
    
    //    empty_main(NULL);
    
        /* Start the scheduler to start the tasks executing. */
        vTaskStartScheduler();
    
        /* vTaskStartScheduler() only returns if there was not enough FreeRTOS heap memory available */
        DebugP_log("Heap memory overflow! Should never be reached!\r\n");
        DebugP_assertNoLog(0);
    
        return 0;
    }

    serial_communication.h:

    #ifndef SERIAL_COMMUNICATION_H_
    #define SERIAL_COMMUNICATION_H_
    
    // Included Files
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/HwiP.h>
    #include <inttypes.h>
    #include "ti_drivers_config.h"
    #include "ti_board_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include "FreeRTOS.h"
    #include "task.h"
    #include <drivers/hw_include/hw_types.h>
    #include <semphr.h>
    
    void toggleLED(uint32_t addr, uint32_t pinNum);
    
    #endif /* SERIAL_COMMUNICATION_H_ */

    serial_communication.c:

    // Included Files
    #include "serial_communication.h"
    
    #define SERIAL_TASK_PRI   (3u)
    #define SERIAL_TASK_SIZE (1024u)
    
    #define APP_UART_BUFSIZE              (200U)
    #define APP_UART_RECEIVE_BUFSIZE      (8U)
    
    StackType_t serialTaskStack[SERIAL_TASK_SIZE] __attribute__((aligned(32)));
    StaticTask_t gSerialTaskObj;
    TaskHandle_t serialTask;
    
    uint8_t gUartBuffer[APP_UART_BUFSIZE] = {0x01, 0x02, 0x03};
    uint8_t gUartReceiveBuffer[APP_UART_RECEIVE_BUFSIZE];
    
    UART_Transaction trans;
    
    void serial_main(void *args)
    {
        TickType_t xLastWakeTime;
        xLastWakeTime = xTaskGetTickCount();
    
        for(;;)
        {
            int32_t transferOK;
            UART_Transaction_init(&trans);
    
            /* Send data */
            HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_ECR), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_ECR) | 0x01));        // Next byte is an address byte
            trans.buf   = &gUartBuffer[0U];
            trans.count = 1;
            transferOK = UART_write(gUartHandle[COMM_UART1], &trans);
            HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_ECR), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_ECR) & 0xFFFFFFFE));  // Next byte is an address byte
    
            trans.buf   = &gUartBuffer[1U];
            trans.count = 2;
            transferOK = UART_write(gUartHandle[COMM_UART1], &trans);
            DebugP_log("Message sent!\r\n");
    
    //TODO: xTaskDelayUntil()
            vTaskDelay(1000 / portTICK_PERIOD_MS);     // Set the overall task period to 1ms
        }
    }
    
    
    
    void empty_main(void *args)
    {
    
        // Enable Multi-drop Parity Address Match Mode
        HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_ECR), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_ECR) & 0xFFFFFFF7));      // Disable Receive Mode
        HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_EFR2), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_EFR2) | 0x00000004));    // Enable Multi-drop address match mode
        HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_MAR), (uint32_t)0x10);                                                                // Set matching device address
        HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_MMR), (uint32_t)0xFF);                                                                // Set address match masking
        HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_MBR), (uint32_t)0xFF);                                                                // Set broadcast address match
        HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_EFR2), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_EFR2) | 0x00000080));    // Enable broadcast address matching (if needed)
        HW_WR_REG32(((uint32_t)gUartHandle[COMM_UART1] + UART_ECR), (HW_RD_REG32((uint32_t)gUartHandle[COMM_UART1] + UART_ECR) | 0x08));            // Enable RX
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        /* then create the tasks, order of task creation does not matter for this example */
        serialTask = xTaskCreateStatic( serial_main,        /* Pointer to the function that implements the task. */
                                      "Serial_polling",     /* Text name for the task.  This is to facilitate debugging only. */
                                      SERIAL_TASK_SIZE,     /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                      NULL,                 /* We are not using the task parameter. */
                                      SERIAL_TASK_PRI,      /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                      serialTaskStack,      /* pointer to stack base */
                                      &gSerialTaskObj );    /* pointer to statically allocated task object memory */
        configASSERT(serialTask != NULL);
        DebugP_log("The task is created!\r\n");
    
        Board_driversClose();
    
        /* Don't close drivers to keep the UART driver open for console */
        /* Drivers_close(); */
    }

    For your information, I am building on the empty_am243x-evm_m4fss0-0_freertos_ti-arm-clang example.

    Regards,

    Joshua

  • Hi Joshua,

    Thanks for the detailed response to my questions.

    Allow me sometime to go through the same.

    Regards,

    Vaibhav

  • Hi Joshua,

    Apologies for delayed responses.

    As I was going through the TRM, I got to know that the MULTI Drop is not supported as of today as a part of TI's SDK offering.

    NOTE: Apart from UART if the Receiver supports I2C and SPI you can opt for it as I see your requirement is to send data from one point to multiple receivers.

    Regards,

    Vaibhav

  • Hi Vaibhav Kumar,
    thanks for your reply. I have seen that too and was just unsure because the multidrop function is described in the TRM detailed. But I have now solved it with  another way. Thanks anyway.

    Best regards,

    Joshua