From: Jiri Vanek Date: Thu, 29 Dec 2011 09:11:12 +0000 (+0100) Subject: Receiving CAN messages with usage of queue system from LinCAN - first version. Attemp... X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/8c25832fed15843b3ca7cdda9c99e755f063196b Receiving CAN messages with usage of queue system from LinCAN - first version. Attempt to keep the functionality of the previous project (can-usb1) in the main.c file for possible future choice of which hardware to use. --- diff --git a/embedded/app/usbcan/can/lpc17xx_can.h b/embedded/app/usbcan/can/lpc17xx_can.h index dd3fdf2..d4683e5 100644 --- a/embedded/app/usbcan/can/lpc17xx_can.h +++ b/embedded/app/usbcan/can/lpc17xx_can.h @@ -17,6 +17,7 @@ extern "C" #define CAN1_REGS_BASE 0x40044000UL #define CAN2_REGS_BASE 0x40048000UL +#define CANAF_REGS_BASE 0x4003C000UL #define CAN_MOD_o 0x0000 #define CAN_CMR_o 0x0004 @@ -43,6 +44,16 @@ extern "C" #define CAN_TDA3_o 0x0058 #define CAN_TDB3_o 0x005C + +#define CANAF_AFMR_o 0x0000 +#define CANAF_SFF_sa_o 0x0004 +#define CANAF_SFF_GRP_sa_o 0x0008 +#define CANAF_EFF_sa_o 0x000C +#define CANAF_EFF_GRP_sa_o 0x0010 +#define CANAF_ENDofTable_o 0x0014 +#define CANAF_LUTerrAd_o 0x0018 +#define CANAF_LUTerr_o 0x001C + //---------------------------------- #define CAN1MOD (*(uint32_t*)(CAN1_REGS_BASE+CAN_MOD_o)) @@ -71,12 +82,30 @@ extern "C" #define CAN1TDB3 (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDB3_o)) + +#define CANAF_AFMR (*(uint32_t*)(CANAF_REGS_BASE+CANAF_AFMR_o)) +#define CANAF_SFF_sa (*(uint32_t*)(CANAF_REGS_BASE+CANAF_SFF_sa_o)) +#define CANAF_SFF_GRP_sa (*(uint32_t*)(CANAF_REGS_BASE+CANAF_SFF_GRP_sa_o)) +#define CANAF_EFF_sa (*(uint32_t*)(CANAF_REGS_BASE+CANAF_EFF_sa_o)) +#define CANAF_EFF_GRP_sa (*(uint32_t*)(CANAF_REGS_BASE+CANAF_EFF_GRP_sa_o)) +#define CANAF_ENDofTable (*(uint32_t*)(CANAF_REGS_BASE+CANAF_ENDofTable_o)) +#define CANAF_LUTerrAd (*(uint32_t*)(CANAF_REGS_BASE+CANAF_LUTerrAd_o)) +#define CANAF_LUTerr (*(uint32_t*)(CANAF_REGS_BASE+CANAF_LUTerr_o)) + //---------------------------------- +//CAN Global Status Register +#define CAN_GSR_BS (1<<7) + //CAN Interrupt and Capture Register bits +#define CAN_ICR_RI (1<<0) #define CAN_ICR_TI1 (1<<1) +#define CAN_ICR_DOI (1<<3) +#define CAN_ICR_IDI (1<<8) //CAN Status Register bits +#define CAN_SR_RBS (1<<0) +#define CAN_SR_DOS (1<<1) #define CAN_SR_TBS1 (1<<2) //CAN Command Register bits @@ -90,8 +119,16 @@ extern "C" #define CAN_TFI1_RTR (1<<30) #define CAN_TFI1_EXT (1<<31) +//CAN Receive Frame Status register +#define CAN_RFS_RTR (1<<30) +#define CAN_RFS_EXT (1<<31) + //CAN Interrupt Enable Register bits +#define CAN_IER_RIE (1<<0) #define CAN_IER_TIE1 (1<<1) +#define CAN_IER_DOIE (1<<3) +#define CAN_IER_IDIE (1<<8) + //---------------------------------- @@ -117,6 +154,7 @@ extern "C" void CAN_init(uint32_t baudrate); void CAN_send(canmsg_t* msg); +void CAN_recv(canmsg_t* msg); void CAN_IRQHandler(void); //---------------------------------- @@ -149,6 +187,7 @@ int lpc17xx_fill_chipspecops(struct canchip_t *chip); int lpc17xx_register(struct chipspecops_t *chipspecops); int lpc17xx_attach_to_chip(struct canchip_t *chip); int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj); +void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj); #ifdef __cplusplus } diff --git a/embedded/app/usbcan/lpc17xx_can.c b/embedded/app/usbcan/lpc17xx_can.c index ec82757..9defc72 100644 --- a/embedded/app/usbcan/lpc17xx_can.c +++ b/embedded/app/usbcan/lpc17xx_can.c @@ -5,29 +5,38 @@ static void CAN_setBusTiming(uint32_t baudrate); extern struct canhardware_t *hardware_p; +extern volatile uint32_t cnt; //--------------------------------------------------------------------------------- //--------------------------------------------------------------------------------- // interrupt handler -// now only for transmitting - irq when one message was transmitted (for check if another message is pending in can msg queue) +// for transmitting - irq when one message was transmitted (for check if another message is pending in can msg queue) +// for receiving - irq when message was received and is available in Receive buffer void CAN_IRQHandler(){ uint32_t i; - + i = CAN1ICR; - if(!(i & CAN_ICR_TI1)) - return; + + if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){ + + struct canchip_t *chip; + chip = hardware_p->candevice[0]->chip[0]; - struct canchip_t *chip; - chip = hardware_p->candevice[0]->chip[0]; - - lpc17xx_irq_handler(0, chip); + lpc17xx_irq_handler(0, chip); + } + if(i & CAN_ICR_DOI){ + printf("Data overrun\n"); + CAN1CMR = CAN_CMR_CDO; + } + + + } - //--------------------------------------------------------------------------------- //--------------------------------------------------------------------------------- @@ -167,7 +176,13 @@ int lpc17xx_irq_handler(int irq, struct canchip_t *chip) struct msgobj_t *obj; obj = chip->msgobj[0]; - + + if(CAN1SR & CAN_SR_RBS) { + lpc17xx_read(chip,obj); + obj->ret = 0; + } + + if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) { can_msgobj_set_fl(obj,TX_REQUEST); @@ -188,6 +203,7 @@ int lpc17xx_irq_handler(int irq, struct canchip_t *chip) } } + return CANCHIP_IRQ_HANDLED; } @@ -233,6 +249,21 @@ void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) } +void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) { + + + CAN_recv(&obj->rx_msg); + + // fill CAN message timestamp + can_filltimestamp(&obj->rx_msg.timestamp); + + canque_filter_msg2edges(obj->qends, &obj->rx_msg); + + // release Receive buffer + CAN1CMR = CAN_CMR_RRB; + +} + int lpc17xx_fill_chipspecops(struct canchip_t *chip){ chip->max_objects=1; @@ -315,6 +346,53 @@ static void CAN_configPin(){ } +void CAN_recv(canmsg_t* msg){ + +/* + msg->id = ++cnt; + msg->data[0] = 0xAA; + msg->data[1] = 0xBB; + msg->length = 2; +*/ + + + uint32_t data; + uint32_t i; + + // only for debug + cnt++; + + // read data lenght + msg->length = ((CAN1RFS)>>16) & 0xF; + + // read identifier + msg->id = CAN1RID; + + // EXT frame + if(CAN1RFS & CAN_RFS_EXT) + msg->flags |= MSG_EXT; + else + msg->flags &= ~MSG_EXT; + + + // RTR frame + if(CAN1RFS & CAN_RFS_RTR) + msg->flags |= MSG_RTR; + else + msg->flags &= ~MSG_RTR; + + + // read data + data = CAN1RDA; + for(i=0; i<4; i++) + msg->data[i] = (data>>(i*8)) & 0xFF; + + data = CAN1RDB; + for(i=4; i<8; i++) + msg->data[i] = (data>>((i-4)*8)) & 0xFF; + +} + void CAN_send(canmsg_t* msg){ uint32_t data; @@ -435,6 +513,7 @@ void CAN_init(uint32_t baudrate) uint32_t tmp; uint32_t pclksel0; uint32_t val; + uint32_t i; printf("CAN INIT, baudrate: %d\n", baudrate); @@ -477,11 +556,39 @@ void CAN_init(uint32_t baudrate) // return to normal operating CAN1MOD = 0; + //-------------------------- + + // Acceptance Filter Off Mode + CANAF_AFMR = 0x01; + + // clear RAM masks + for (i = 0; i < 512; i++) { + CANAF_RAM->mask[i] = 0x00; + } + + CANAF_SFF_sa = 0x00; + CANAF_SFF_GRP_sa = 0x00; + CANAF_EFF_sa = 0x00; + CANAF_EFF_GRP_sa = 0x00; + CANAF_ENDofTable = 0x00; + + + // Acceptance Filter Bypass Mode - all messages accepted + CANAF_AFMR = 0x02; + + //-------------------------- + // enable interrupt after transmit CAN1IER |= CAN_IER_TIE1; + // enable receive interrupt + CAN1IER |= CAN_IER_RIE; + // enable data overrun interrupt + CAN1IER |= CAN_IER_DOIE; + // enable CAN interrupt NVIC_EnableIRQ(CAN_IRQn); + } diff --git a/embedded/app/usbcan/main.c b/embedded/app/usbcan/main.c index 6053645..ad7fe36 100644 --- a/embedded/app/usbcan/main.c +++ b/embedded/app/usbcan/main.c @@ -109,7 +109,7 @@ typedef void (*FNC)(); //function ptr /*********************************************************************** * global variables ***********************************************************************/ - +volatile uint32_t cnt; usb_device_t usb_device; @@ -209,8 +209,9 @@ int main(void) int chipnr,bd; int i,size,m=0; + cnt=0; + CANMSG("Starting USBCAN module firmware...\n"); - // volatile int i=0; bootloader_run=0; @@ -229,7 +230,7 @@ int main(void) sys_err(); } -// !!! DEBUG - first version, only transmitting CAN messages with usage of queue system from LinCAN +// !!! DEBUG - transmitting and receiving CAN messages with usage of queue system from LinCAN - first version! //*********************************************************************** @@ -437,6 +438,10 @@ int main(void) // if (!(IO0PIN&P0_SJA1000_INT_PIN)) //INT PIN is inverted // chip->chipspecops->irq_handler(0,chip); +// if (CAN1SR & CAN_SR_RBS) +// chip->chipspecops->irq_handler(0,chip); + + if (usb_device.ep_events & MASK_EP1RX) { //EP1RX - data waiting to receive if (canque_get_inslot(qends, &qedge, &slot, 0)>=0){ //Free slot obtained @@ -502,8 +507,7 @@ int main(void) }*/ } - // DEBUG - only transmitting CAN messages, no reading (yet) - /* + if(usb_device.ep_events & MASK_EP1TX){ //EP1TX - data transmitted if(canque_test_outslot(qends, &qedge, &slot)>=0){ DEBUGMSG("CAN message ready to send over usb\n"); @@ -530,13 +534,17 @@ int main(void) } usb_udev_write_endpoint(&eps[1],ep1_tx_buff,16); + //printf("ID: %d\n", msgid); + canque_free_outslot(qends, qedge, slot); timer_tx_off=50; //rozsviceni diod pri vysilani CLR_OUT_PIN(LED_PORT,LED1_BIT); usb_device.ep_events &= ~MASK_EP1TX; + } + } - */ + //if (usb_can_send && )