Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

CAN Transmit and Receive Testing on AC7840x Microcontroller

Tech 3

Hardware Configuration

CAN Transceiver Circuit

Standard CAN transceiver circuitry implemented.

Interface Pins

CAN signals routed through:

  • PE4: Receiver input
  • PE5: Transmitter output

Port Mapping

PE4 and PE5 configured for CAN0 controller operation.

Software Implementation

CAN Driver Module

#include "ac7840x.h"
#include "gpio_drv.h"
#include "can_drv.h"
#include "clock_config.h"

#define CLK_SRC_FREQ      (60000000UL)
#define PROCESS_FRAMES    (1)
#define ENABLE_TIMESTAMP  (0)

typedef struct {
    uint32_t rx_count;
    uint32_t tx_count;
} can_stats_t;

#if (CLK_SRC_FREQ == 80000000UL)
static const can_time_segment_t baud_config[] = {
    {0x1C, 0x09, 0x09, 0x01},  // 1M
    {0x26, 0x09, 0x09, 0x01},  // 800K
    {0x1C, 0x09, 0x09, 0x03},  // 500K
    {0x1C, 0x09, 0x09, 0x07},  // 250K
    {0x1C, 0x09, 0x09, 0x0F},  // 125K
    {0x1C, 0x09, 0x09, 0x13},  // 100K
    {0x1C, 0x09, 0x09, 0x27}   // 50K
};
elif (CLK_SRC_FREQ == 60000000UL)
static const can_time_segment_t baud_config[] = {
    {0x0D, 0x04, 0x04, 0x02},  // 1M
    {0x12, 0x04, 0x04, 0x02},  // 800K
    {0x1C, 0x09, 0x09, 0x02},  // 500K
    {0x1C, 0x09, 0x09, 0x05},  // 250K
    {0x1C, 0x09, 0x09, 0x0B},  // 125K
    {0x1C, 0x09, 0x09, 0x0E},  // 100K
    {0x1C, 0x09, 0x09, 0x1D}   // 50K
};
#endif

static can_stats_t can_status[4] = {0};

void configure_can_pins(uint8_t channel) {
    if(channel == 0) {
        GPIO_DRV_SetMuxModeSel(PORTE, 4, PORT_MUX_ALT5);
        GPIO_DRV_SetMuxModeSel(PORTE, 5, PORT_MUX_ALT5);
    }
}

static can_time_segment_t get_baud_config(uint8_t index) {
    return (index < sizeof(baud_config)/sizeof(baud_config[0])) ? 
           baud_config[index] : (can_time_segment_t){0};
}

static void process_received_frame(uint8_t ch, const can_msg_info_t* frame) {
    can_status[ch].rx_count++;
    #if PROCESS_FRAMES
    if(frame->IDE) {
        // Extended ID processing
    } else {
        // Standard ID processing
    }
    #endif
}

void can_event_handler(uint8_t ch, uint32_t event, uint32_t error) {
    can_msg_info_t rx_frame = {0};
    uint8_t data_buf[8] = {0};
    
    if(event & CAN_EVENT_RECEIVE_DONE) {
        while(CAN_DRV_GetRbufStatus(ch)) {
            rx_frame.DATA = data_buf;
            if(CAN_DRV_Receive(ch, &rx_frame)) {
                process_received_frame(ch, &rx_frame);
            }
        }
    }
}

void initialize_can_controller(void) {
    can_user_config_t cfg = {
        .filterNum = 0,
        .canMode = CAN_NORMAL_MODE,
        .interruptEn = true,
        .tsMode = CAN_TSMODE_FIFO,
        .bitrate = get_baud_config(2),  // 500Kbps
        .callback = can_event_handler
    };
    
    configure_can_pins(0);
    CAN_DRV_Init(0, &cfg);
}

void transmit_can_frame(uint8_t* payload) {
    static can_msg_info_t tx_frame = {
        .ID = 0x220,
        .IDE = 0,
        .RTR = 0,
        .DLC = 8
    };
    uint8_t data_buffer[8];
    memcpy(data_buffer, payload, 8);
    tx_frame.DATA = data_buffer;
    
    if(CAN_DRV_Send(0, &tx_frame, CAN_TRANSMIT_SECONDARY) == STATUS_SUCCESS) {
        can_status[0].tx_count++;
    }
}

Main Application

#include "ac7840x.h"
#include "clock_config.h"
#include "can.h"

uint8_t transmission_buffer[8];

int main(void) {
    SystemClock_Config();
    initialize_can_controller();
    
    uint8_t counter = 0;
    while(1) {
        transmission_buffer[0] = counter++;
        transmit_can_frame(transmission_buffer);
        OSIF_TimeDelay(100);
    }
}

Test Verification

Transmission Test

Connected CAN analyzer confirms recepsion of periodic frames with incrementign first byte.

Reception Test

Serial temrinal displays decoded CAN frames matching transmitted data patterns.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.