Ian,
I don't know if the following helps in any way, but this is the code I use in all of my LPC1549 projects. Please note that I use Keil's RTOS, so some of the code does not apply to your case, but perhaps there is something that fills some gaps you can use ?
#include "chip.h"
#include "system.h"
#include "rom_can_15xx.h"
#include "CAN.h"
#define BITRATE100K12MHZ 0x0000050e
#define BITRATE125K12MHZ 0x00001c05
#define BITRATE250K12MHZ 0x00001c02
#define BITRATE500K12MHZ 0x00000502
#define BITRATE1000K12MHZ 0x00000900
static MUTEX mut;
static CAN_HANDLE_T pCanHandle;
#define CAN_MSGOBJ_EXT 0x20000000UL
#define MAX_CAN_PARAM_SIZE 512
static uint32_t gCANapiMem[MAX_CAN_PARAM_SIZE];
static CAN_CFG gCANConfig;
void CAN_rx(uint8_t msg_obj_num);
void CAN_tx(uint8_t msg_obj_num);
void CAN_error(uint32_t error_info);
CAN_CALLBACKS callbacks = {
CAN_rx,
CAN_tx,
CAN_error
};
CAN_API_INIT_PARAM_T myCANConfig = {
(uint32_t)&gCANapiMem[0],
LPC_C_CAN0_BASE,
&gCANConfig,
(CAN_CALLBACKS *)&callbacks,
(CAN_CANOPENCFG *)NULL,
(CANOPEN_CALLBACKS *)NULL,
};
#define MAX_QUEUE 8
static _declare_box(CANMSGList, sizeof(CAN_MSG_OBJ), MAX_QUEUE);
static os_mbx_declare(mbCANMSG, MAX_QUEUE);
static U64 stkthPacket[100];
static int init=FALSE;
static int idle=TRUE;
static int overRun=0, numFrames=0;
static CAN_MSG_OBJ msg_obj;
void CAN_rx(uint8_t msg_obj_num){
void *box=NULL;
CAN_MSG_OBJ msg_obj;
msg_obj.msgobj = msg_obj_num;
LPC_CAND_API->hwCAN_MsgReceive(pCanHandle, &msg_obj);
if (msg_obj_num == 1) {
msg_obj.mode_id &= ~CAN_MSGOBJ_EXT;
box = _alloc_box (CANMSGList);
if (box==NULL) {
overRun++;
return;
}
numFrames++;
memcpy(box, &msg_obj, sizeof(msg_obj));
isr_mbx_send (mbCANMSG, box);
}
return;
}
void CAN_tx(uint8_t msg_obj_num){
idle=TRUE;
return;
}
void CAN_error(uint32_t error_info){
return;
}
void C_CAN0_IRQHandler (void){
LPC_CAND_API->hwCAN_Isr(pCanHandle);
}
void sendDataCAN(unsigned int id, unsigned char data[8]) {
CAN_MSG_OBJ msg_obj;
int i=0;
if (init==FALSE)
return;
MUTEX_ACQUIRE(mut);
while (idle==FALSE && i++ < 10) OS_WAIT(10);
idle=FALSE;
msg_obj.msgobj = 0;
msg_obj.mode_id = CAN_MSGOBJ_EXT | id;
msg_obj.mask = 0x0;
msg_obj.dlc = 8;
for (i=0; i<8; i++)
msg_obj.data[i]=data[i];
LPC_CAND_API->hwCAN_MsgTransmit(pCanHandle, &msg_obj);
MUTEX_RELEASE(mut);
}
int getOverrunCAN(void) {
return overRun;
}
int getNumFramesCAN(void) {
return numFrames;
}
__attribute__ ((weak)) void rxCAN(unsigned int id, unsigned char * buffer, unsigned char length) {
}
static __task void thPacket(void) {
void *msg;
while(1) {
if (os_mbx_wait (mbCANMSG, &msg, 0xFFFF)) {
rxCAN(((CAN_MSG_OBJ*)msg)->mode_id, ((CAN_MSG_OBJ*)msg)->data, ((CAN_MSG_OBJ*)msg)->dlc);
if (_free_box(CANMSGList, msg)) {
}
}
}
}
void initCAN(void) {
MUTEX_INIT(mut);
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CAN);
Chip_SYSCTL_PeriphReset(RESET_CAN);
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 27, (IOCON_MODE_INACT | IOCON_DIGMODE_EN));
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 28, (IOCON_MODE_INACT | IOCON_DIGMODE_EN));
Chip_SWM_MovablePortPinAssign(SWM_CAN_TD1_O , 0, 27);
Chip_SWM_MovablePortPinAssign(SWM_CAN_RD1_I, 0, 28);
_init_box(CANMSGList, sizeof (CANMSGList), sizeof(CAN_MSG_OBJ));
os_mbx_init(mbCANMSG, sizeof(mbCANMSG));
gCANConfig.clkdiv = 5;
gCANConfig.btr = BITRATE1000K12MHZ;
gCANConfig.isr_ena = TRUE;
LPC_CAND_API->hwCAN_Init(&pCanHandle, (CAN_API_INIT_PARAM_T *)&myCANConfig);
NVIC_EnableIRQ(CAN_IRQn);
msg_obj.msgobj = 1;
msg_obj.mode_id = CAN_MSGOBJ_EXT | 0x0;
msg_obj.mask = 0x0;
LPC_CAND_API->hwCAN_ConfigRxmsgobj(pCanHandle, &msg_obj);
START_THREAD_USR(thPacket, 2, (void*)stkthPacket, sizeof(stkthPacket));
init=TRUE;
}