snarlingfox wrote on Tuesday, May 17, 2016:
Hi there,
I’ve had CANBUS working successfully on the LPC1788 platform for a good couple of years, using the standard CMSIS / LPCOpen frameworks.
I’m less inclined to believe it’s IRQ related as even when I manually trigger the IRQ using Keils debugger, the program will return gibberish. I know for a fact there should be something in the buffer because I’m firing data at it from an MBED LPC1768 which is received fine using non-RTOS code.
I honestly don’t know if it’s my setup, if I’m incorrectly initialising the CAN subsystem or what. Possibly the memory isn’t assigned properly. Attempting to send fails too with a transmission timeout.
Here’s a slimmed down code block (it may not compile as I’ve removed non-relevant blocks), it’s also hasn’t been touched in months as I took a break;
/*********************************\
* Includes and required variables *
\*********************************/
#include "board.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include <stdlib.h>
#include <string.h>
// #include <stdarg.h>
LPC_CAN_T *CANPort;
bool CANIRQInitialised;
const unsigned char CAN_INTERFACE = 0;
#define CAN_BAUD_RATE 500000UL
#define CAN_FILTER_FRAMES 0
xSemaphoreHandle xCANReceiveSemaphore;
typedef struct {
unsigned char length;
char *data;
} xMessage;
/*********************************\
* Callable functions *
\*********************************/
/* Sets up the CAN controller */
void InitCAN(void) {
if (CANIRQInitialised) {
Chip_CAN_IntDisable(CANPort, CAN_IER_BITMASK);
Chip_CAN_DeInit(CANPort);
}
if (CAN_INTERFACE == 1) CANPort = LPC_CAN2;
else CANPort = LPC_CAN1;
Chip_CAN_Init(CANPort);
Chip_CAN_SetBitRate(CANPort, CAN_BAUD_RATE);
Chip_CAN_SetAFMode(LPC_CANAF, CAN_AF_BYBASS_MODE);
Chip_CAN_IntEnable(CANPort, CAN_IER_BITMASK);
CANIRQInitialised = 1;
}
/* Sets up system hardware */
static void prvSetupHardware (void) {
Board_Init();
InitCAN();
}
/*********************************\
* Tasks *
\*********************************/
/* CAN receive task */
static void vTaskCANReceive (void *pvParameters) {
xMessage message;
portBASE_TYPE xQueueStatus;
CAN_MSG_T canframe;
xSemaphoreTake(xCANReceiveSemaphore, 0);
while (1) {
Chip_CAN_IntEnable(CANPort, CAN_IER_BITMASK);
message.length = 12;
message.data = (char *)calloc(12, 0x0);
while (Chip_CAN_Receive(CANPort, &canframe)) {
canframe.ID &= ~CAN_EXTEND_ID_USAGE;
message.data[0] = ((canframe.ID >> 24) & 0xFF);
message.data[1] = ((canframe.ID >> 16) & 0xFF);
message.data[2] = ((canframe.ID >> 8) & 0xFF);
message.data[3] = ((canframe.ID >> 0) & 0xFF);
memcpy(message.data + 4, canframe.Data, 8);
DEBUGOUT("Received: %s", &message);
}
}
}
/*********************************\
* Interrupt handlers *
\*********************************/
/* CAN IRQ handler */
void CAN_IRQHandler(void) {
portBASE_TYPE xCurrentTaskInterrupted = pdFALSE;
unsigned long IRQStatus = Chip_CAN_GetIntStatus(CANPort);
DEBUGOUT("CAN IRQ received: 0x%04X\r\n", IRQStatus);
if (!(IRQStatus & CAN_ICR_RI)) return;
NVIC_ClearPendingIRQ(CAN_IRQn);
Chip_CAN_IntDisable(CANPort, CAN_IER_BITMASK);
DEBUGOUT("-");
xSemaphoreGiveFromISR(xCANReceiveSemaphore, &xCurrentTaskInterrupted);
portEND_SWITCHING_ISR(xCurrentTaskInterrupted);
}
/*********************************\
* Main function *
\*********************************/
int main (void) {
/* Init */
unsigned long i;
prvSetupHardware();
/* Queues and Semaphore */
vSemaphoreCreateBinary(xCANReceiveSemaphore); if (xCANReceiveSemaphore == NULL) { DEBUGOUT("Unable to create xCANReceiveSemaphore\r\n"); return 1; }
/* IRQs */
Chip_UART_IntConfig(LPC_UART0, UART_INTCFG_RBR, ENABLE);
NVIC_SetPriority(UART0_IRQn, configKERNEL_INTERRUPT_PRIORITY);
NVIC_EnableIRQ(UART0_IRQn);
DEBUGOUT("Waiting for CAN init... ");
InitCAN();
for (i=0; i<50000000; i++) { }
NVIC_SetPriority(CAN_IRQn, configKERNEL_INTERRUPT_PRIORITY - 1);
NVIC_EnableIRQ(CAN_IRQn);
CANIRQInitialised = 1;
AddFrameToAFLUT(0, 0x600UL, 0x700UL);
InitCAN();
DEBUGOUT("Done!\r\n");
/* Tasks */
xTaskCreate(vTaskCANReceive, (signed char *) "CAN Receive", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 1UL), (xTaskHandle *) NULL);
/* Start the scheduler */
vTaskStartScheduler();
/* Should never arrive here */
return 1;
}