Hi expert,
I try to set up a CAN communication on my digital loop regulation. I use a peak probe to transmit and see frames on my PC (with PCAN-View). I want to generate CAN interrupts when frames was detected on RX but it doesn't work very well. When I load program I observe frames for a few cycles and after nothing at all why ?
Can you explain me where is my mistakes please ? You can see my code.
It's difficult to debug because when I compile with optimizations level 2 on RAM it compile but on debug mode I never pass on interrupt, why ? (some calls are not possible ?) And when I try to compile with no optimization it doesn't compile I have this message :
error #10099-D: program will not fit into available memory, or the section contains a call site that requires a trampoline that can't be generated for this section. placement with alignment/blocking fails for section ".text" size 0x214cpage 0. Available memory ranges:
RAMLS4567 size: 0x2000 unused: 0x2000 max hole: 0x2000
RAMGS0 size: 0x7f8 unused: 0x7f8 max hole: 0x7f8
I need your help please !
Thanks
Damien
void main(void) { // Initialize device clock and peripherals Device_init(); // Disable pin locks and enable internal pullups. Device_initGPIO(); // Initialize PIE and clear PIE registers. Disables CPU interrupts. Interrupt_initModule(); // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR). Interrupt_initVectorTable(); can_init(); // Initialization timer timer_cpu_init(); // Interrupt all of (us) 10ms timer_cpu_config(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000); // Disable sync and clock to PWM SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); Interrupt_register(INT_TIMER0, &isr_timer); Interrupt_register(INT_CANA0, &isr_can); CPUTimer_enableInterrupt(CPUTIMER0_BASE); Interrupt_enable(INT_TIMER0); CAN_enableInterrupt(CANA_BASE, CAN_INT_STATUS | CAN_INT_IE0 | CAN_INT_ERROR); Interrupt_enable(INT_CANA0); CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0); // Enable sync and clock to PWM SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // Start CAN module operations CAN_startModule(CANA_BASE); // Start timer for interrupt CAN (to send frames) CPUTimer_startTimer(CPUTIMER0_BASE); // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) EINT; ERTM; while(1) { } }
#include "device.h" #include "can_module.h" #include "epwm_module.h" uint16_t rx_tx_parameters[SIZE]; void can_init(void) { EALLOW; GPIO_setPinConfig(GPIO_33_CANA_RX); GPIO_setPinConfig(GPIO_32_CANA_TX); // To visualize timings GPIO_setPinConfig(GPIO_40_GPIO40); GPIO_setDirectionMode(40, GPIO_DIR_MODE_OUT); GPIO_setPadConfig(40, GPIO_PIN_TYPE_STD); EDIS; CAN_initModule(CANA_BASE); CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 250000, 20); CAN_setupMessageObject(CANA_BASE, 1, 0x100, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, 0,8); CAN_setupMessageObject(CANA_BASE, 2, 0x010, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,8); } void timer_cpu_init() { // Initialize timer period to maximum CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF); // Initialize pre-scale counter to divide by 1 (SYSCLKOUT) CPUTimer_setPreScaler(CPUTIMER0_BASE, 0); // Make sure timer is stopped CPUTimer_stopTimer(CPUTIMER0_BASE); // Reload all counter register with period value CPUTimer_reloadTimerCounter(CPUTIMER0_BASE); } void timer_cpu_config(uint32_t cpuTimer, float freq, float period) { uint32_t temp; // Initialize timer period: temp = (uint32_t)(freq / 1000000 * period); CPUTimer_setPeriod(cpuTimer, temp); // Set pre-scale counter to divide by 1 (SYSCLKOUT): CPUTimer_setPreScaler(cpuTimer, 0); // Initializes timer control register. The timer is stopped, reloaded, free run disabled, and interrupt enabled. Additionally, the free and soft bits are set CPUTimer_stopTimer(cpuTimer); CPUTimer_reloadTimerCounter(cpuTimer); CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT); CPUTimer_enableInterrupt(cpuTimer); } __interrupt void isr_timer(void) // generate all of 10ms { GPIO_writePin(40, 1); // for debug can_send_frames(); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); GPIO_writePin(40, 0); } void can_send_frames(void) { rx_tx_parameters[0] = epwm_dutycyle; // Send CAN message data from message object 1 CAN_sendMessage(CANA_BASE, 1, 8, (uint16_t*) rx_tx_parameters); } __interrupt void isr_can(void) { GPIO_writePin(27, 1); // for debug CAN_readMessage(CANA_BASE, 2, (uint16_t*) rx_tx_parameters); epwm_dutycyle = rx_tx_parameters[0]; epwm_get_cmpa_from_dutycyle(EPWM1_BASE, epwm_dutycyle); epwm_get_cmpa_from_dutycyle(EPWM2_BASE, epwm_dutycyle); epwm_get_cmpa_from_dutycyle(EPWM3_BASE, epwm_dutycyle); CAN_clearInterruptStatus(CANA_BASE, 2); CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9); GPIO_writePin(27, 0); }