From: Jiri Vanek Date: Thu, 22 Dec 2011 16:02:05 +0000 (+0100) Subject: Transmitting CAN messages with usage of queue system from LinCAN - first version... X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/060d6f042deb8d82aaeb9de8701cd3405bb4c066 Transmitting 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/Makefile.omk b/embedded/app/usbcan/Makefile.omk index 588f007..3077876 100644 --- a/embedded/app/usbcan/Makefile.omk +++ b/embedded/app/usbcan/Makefile.omk @@ -29,6 +29,6 @@ usbcan_MOREOBJS = $(USER_LIB_DIR)/system_stub.o # $(USER_LIB_DIR)/ivt.o nobase_include_HEADERS = usb/usb_defs.h -link_VARIANTS = app boot +#link_VARIANTS = app boot endif #CONFIG_ULBOOT diff --git a/embedded/app/usbcan/can/lpc17xx_can.h b/embedded/app/usbcan/can/lpc17xx_can.h index 1b66997..dd3fdf2 100644 --- a/embedded/app/usbcan/can/lpc17xx_can.h +++ b/embedded/app/usbcan/can/lpc17xx_can.h @@ -5,6 +5,8 @@ #include "hal_machperiph.h" #include "cpu_def.h" #include "system_def.h" + +#include "can/can.h" #include "can/canmsg.h" #ifdef __cplusplus @@ -69,6 +71,28 @@ extern "C" #define CAN1TDB3 (*(uint32_t*)(CAN1_REGS_BASE+CAN_TDB3_o)) +//---------------------------------- + +//CAN Interrupt and Capture Register bits +#define CAN_ICR_TI1 (1<<1) + +//CAN Status Register bits +#define CAN_SR_TBS1 (1<<2) + +//CAN Command Register bits +#define CAN_CMR_TR (1<<0) +#define CAN_CMR_AT (1<<1) +#define CAN_CMR_RRB (1<<2) +#define CAN_CMR_CDO (1<<3) +#define CAN_CMR_STB1 (1<<5) + +//CAN Transmit Frame Information register 1 bits +#define CAN_TFI1_RTR (1<<30) +#define CAN_TFI1_EXT (1<<31) + +//CAN Interrupt Enable Register bits +#define CAN_IER_TIE1 (1<<1) + //---------------------------------- #define PCONP SC->PCONP @@ -93,6 +117,38 @@ extern "C" void CAN_init(uint32_t baudrate); void CAN_send(canmsg_t* msg); +void CAN_IRQHandler(void); + +//---------------------------------- + +struct can_lmc1_chip_data +{ + int flags; +}; + +// board can-lmc1 specific functions: +int can_lmc1_register(struct hwspecops_t *hwspecops); +int can_lmc1_init_hw_data(struct candevice_t *candev); +int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr); +int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr); +void can_lmc1_write_register(unsigned data, unsigned long address); +unsigned can_lmc1_read_register(unsigned long address); +int can_lmc1_request_io(struct candevice_t *candev); +int can_lmc1_reset(struct candevice_t *candev); + +// lpc17xx can chip specific functions: +int lpc17xx_chip_config(struct canchip_t *chip); +int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, + struct canmsg_t *msg); +int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj, + struct canmsg_t *msg); +int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj); +int lpc17xx_irq_handler(int irq, struct canchip_t *chip); +void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj); +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); #ifdef __cplusplus } diff --git a/embedded/app/usbcan/lpc17xx_can.c b/embedded/app/usbcan/lpc17xx_can.c index eee3718..ec82757 100644 --- a/embedded/app/usbcan/lpc17xx_can.c +++ b/embedded/app/usbcan/lpc17xx_can.c @@ -3,7 +3,277 @@ static void CAN_configPin(); static void CAN_setBusTiming(uint32_t baudrate); -//------------------------------------------ +extern struct canhardware_t *hardware_p; + +//--------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------- + +// interrupt handler +// now only for transmitting - irq when one message was transmitted (for check if another message is pending in can msg queue) + +void CAN_IRQHandler(){ + + uint32_t i; + + i = CAN1ICR; + if(!(i & CAN_ICR_TI1)) + return; + + + struct canchip_t *chip; + chip = hardware_p->candevice[0]->chip[0]; + + lpc17xx_irq_handler(0, chip); + +} + + +//--------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------- + + +// board can-lmc1 specific functions: + +int can_lmc1_register(struct hwspecops_t *hwspecops){ + + hwspecops->request_io = can_lmc1_request_io; + hwspecops->reset = can_lmc1_reset; + hwspecops->init_hw_data = can_lmc1_init_hw_data; + hwspecops->init_chip_data = can_lmc1_init_chip_data; + hwspecops->init_obj_data = can_lmc1_init_obj_data; + hwspecops->write_register = can_lmc1_write_register; + hwspecops->read_register = can_lmc1_read_register; + + return 0; +} + +int can_lmc1_init_hw_data(struct candevice_t *candev){ + + candev->res_addr=0; + candev->nr_82527_chips=0; + candev->nr_sja1000_chips=0; + candev->nr_all_chips=1; + candev->flags |= 0; + + return 0; +} + +int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr){ + + lpc17xx_fill_chipspecops(candev->chip[chipnr]); + + candev->chip[chipnr]->flags|= CHIP_IRQ_CUSTOM; + + candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct can_lmc1_chip_data)); + if (candev->chip[chipnr]->chip_data==NULL) + return -ENOMEM; + + return 0; +} + +int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr){ + + //chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10; + + return 0; +} + +void can_lmc1_write_register(unsigned data, unsigned long address){ + + printf("UNSUPPORTED NOW\n"); + +} + +unsigned can_lmc1_read_register(unsigned long address){ + + printf("UNSUPPORTED NOW\n"); + +} + +int can_lmc1_request_io(struct candevice_t *candev) +{ + return 0; +} + +int can_lmc1_reset(struct candevice_t *candev) +{ + return 0; +} + + +//--------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------- + + +// lpc17xx can chip specific functions: + + +int lpc17xx_chip_config(struct canchip_t *chip){ + + CAN_init( (uint32_t) chip->baudrate); + + return 0; +} + +int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, + struct canmsg_t *msg) +{ + + CAN_send(msg); + + return 0; +} + +int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj, + struct canmsg_t *msg) +{ + + // write transmission request + CAN1CMR = (CAN_CMR_TR | CAN_CMR_STB1); + + return 0; +} + +int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) +{ + + can_preempt_disable(); + + can_msgobj_set_fl(obj,TX_PENDING); + can_msgobj_set_fl(obj,TX_REQUEST); + + while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){ + can_msgobj_clear_fl(obj,TX_REQUEST); + + + if (CAN1SR & CAN_SR_TBS1){ + obj->tx_retry_cnt=0; + lpc17xx_irq_write_handler(chip, obj); + } + + can_msgobj_clear_fl(obj,TX_LOCK); + if(!can_msgobj_test_fl(obj,TX_REQUEST)) break; + + } + + can_preempt_enable(); + + return 0; +} + +int lpc17xx_irq_handler(int irq, struct canchip_t *chip) +{ + + struct msgobj_t *obj; + obj = chip->msgobj[0]; + + + if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) { + + can_msgobj_set_fl(obj,TX_REQUEST); + + while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){ + + obj->ret=0; + can_msgobj_clear_fl(obj,TX_REQUEST); + + if (CAN1SR & CAN_SR_TBS1){ + obj->tx_retry_cnt=0; + lpc17xx_irq_write_handler(chip, obj); + } + + can_msgobj_clear_fl(obj,TX_LOCK); + if(!can_msgobj_test_fl(obj,TX_REQUEST)) break; + + } + } + + return CANCHIP_IRQ_HANDLED; + +} + +void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) +{ + int cmd; + + if(obj->tx_slot){ + /* Do local transmitted message distribution if enabled */ + if (processlocal){ + /* fill CAN message timestamp */ + can_filltimestamp(&obj->tx_slot->msg.timestamp); + + obj->tx_slot->msg.flags |= MSG_LOCAL; + canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg); + } + /* Free transmitted slot */ + canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); + obj->tx_slot=NULL; + } + + can_msgobj_clear_fl(obj,TX_PENDING); + cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot); + if(cmd<0) + return; + can_msgobj_set_fl(obj,TX_PENDING); + + if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) { + obj->ret = -1; + canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP); + canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); + obj->tx_slot=NULL; + return; + } + if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) { + obj->ret = -1; + canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND); + canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); + obj->tx_slot=NULL; + return; + } + +} + +int lpc17xx_fill_chipspecops(struct canchip_t *chip){ + + chip->max_objects=1; + chip->baudrate=1000000; + + lpc17xx_register(chip->chipspecops); + return 0; +} + +int lpc17xx_register(struct chipspecops_t *chipspecops){ + + CANMSG("initializing lpc17xx can chip operations\n"); + + chipspecops->attach_to_chip = lpc17xx_attach_to_chip; + chipspecops->pre_read_config = lpc17xx_pre_read_config; + chipspecops->chip_config = lpc17xx_chip_config; + chipspecops->pre_write_config = lpc17xx_pre_write_config; + chipspecops->send_msg = lpc17xx_send_msg; + chipspecops->wakeup_tx = lpc17xx_wakeup_tx; + chipspecops->irq_handler = lpc17xx_irq_handler; + + return 0; + +} + + +int lpc17xx_attach_to_chip(struct canchip_t *chip){ + + return 0; +} + +int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj){ + + return 1; +} + + + +//--------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------- + static void CAN_configPin(){ @@ -51,22 +321,22 @@ void CAN_send(canmsg_t* msg){ uint32_t i; // check status of TB1 - while (!(CAN1SR & (1<<2))){} + while (!(CAN1SR & CAN_SR_TBS1)){} CAN1TFI1 &= ~0x000F0000; CAN1TFI1 |= (msg->length)<<16; // EXT frame if(msg->flags & MSG_EXT) - CAN1TFI1 |= (1<<31); + CAN1TFI1 |= CAN_TFI1_EXT; else - CAN1TFI1 &= ~(1<<31); + CAN1TFI1 &= ~CAN_TFI1_EXT; // RTR frame if(msg->flags & MSG_RTR) - CAN1TFI1 |= (1<<30); + CAN1TFI1 |= CAN_TFI1_RTR; else - CAN1TFI1 &= ~(1<<30); + CAN1TFI1 &= ~CAN_TFI1_RTR; // write CAN ID CAN1TID1 = msg->id; @@ -87,7 +357,7 @@ void CAN_send(canmsg_t* msg){ CAN1TDB1 = data; // write transmission request - CAN1CMR = 0x21; + //CAN1CMR = 0x21; } @@ -166,6 +436,7 @@ void CAN_init(uint32_t baudrate) uint32_t pclksel0; uint32_t val; + printf("CAN INIT, baudrate: %d\n", baudrate); // configure CAN1 pins CAN_configPin(); @@ -195,7 +466,7 @@ void CAN_init(uint32_t baudrate) CAN1GSR = 0x3C; // request command to release Rx, Tx buffer and clear data overrun - CAN1CMR = (1<<1)|(1<<2)|(1<<3); + CAN1CMR = (CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO); // read to clear interrupt pending in Interrupt Capture Register tmp = CAN1ICR; @@ -206,6 +477,11 @@ void CAN_init(uint32_t baudrate) // return to normal operating CAN1MOD = 0; + // enable interrupt after transmit + CAN1IER |= CAN_IER_TIE1; + // enable CAN interrupt + NVIC_EnableIRQ(CAN_IRQn); + } diff --git a/embedded/app/usbcan/main.c b/embedded/app/usbcan/main.c index 4b91631..6053645 100644 --- a/embedded/app/usbcan/main.c +++ b/embedded/app/usbcan/main.c @@ -106,7 +106,6 @@ LT_TIMER_IMP(lt_2sec) typedef void (*FNC)(); //function ptr - /*********************************************************************** * global variables ***********************************************************************/ @@ -230,13 +229,8 @@ int main(void) sys_err(); } -// !!! DEBUG - first version, only transmitting CAN messages withnout usage of queue system from LinCAN - - // CAN - CAN_init(1000000); - // CAN end +// !!! DEBUG - first version, only transmitting CAN messages with usage of queue system from LinCAN -/* //*********************************************************************** // * CAN device initialization - device side (adapted from LinCAN setup.c) @@ -244,8 +238,6 @@ int main(void) // DEBUG //can_init(); // only for successful compiling (defined in can_lpcbusemu.c) - - DEBUGMSG("Initiating CAN device initialization\n"); @@ -274,8 +266,13 @@ int main(void) } memset(candev->hwspecops, 0, sizeof(struct hwspecops_t)); + + // DEBUG //ul_usb1_register(candev->hwspecops); // only for successful compiling (defined in ul_usb1.c) + // register for another board + can_lmc1_register(candev->hwspecops); + bd=baudrate[0]; @@ -283,6 +280,7 @@ int main(void) CANMSG("HW data could not be initialized\n"); sys_err(); } + // Alocate and initialize the chip structures for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) { // if(chipnrnr_all_chips; chipnr++) { struct canchip_t *chip=candev->chip[chipnr]; int objnr; @@ -303,11 +304,17 @@ int main(void) if(m>=0) m++; } } + + if (candev->hwspecops->request_io(candev)) sys_err(); candev->flags|=CANDEV_IO_RESERVED; + + if (candev->hwspecops->reset(candev)) sys_err(); + + for(chipnr=0; chipnrnr_all_chips; chipnr++) { if((chip=candev->chip[chipnr])==NULL) continue; @@ -336,6 +343,7 @@ int main(void) // * CAN device initialization - client side (adapted from LinCAN open.c) // *********************************************************************** + chip=candev->chip[0]; obj=chip->msgobj[0]; atomic_inc(&obj->obj_used); @@ -354,6 +362,7 @@ int main(void) } // End of chip configuration + canuser = (struct canuser_t *)malloc(sizeof(struct canuser_t)); if(canuser == NULL) sys_err(); canuser->flags=0; @@ -381,7 +390,7 @@ int main(void) canque_edge_decref(canuser->rx_edge0); canque_edge_decref(edge); -*/ + /*********************************************************************** * USB Init @@ -430,8 +439,7 @@ int main(void) if (usb_device.ep_events & MASK_EP1RX) { //EP1RX - data waiting to receive - // DEBUG - unused queue system (yet) - //if (canque_get_inslot(qends, &qedge, &slot, 0)>=0){ //Free slot obtained + if (canque_get_inslot(qends, &qedge, &slot, 0)>=0){ //Free slot obtained size=usb_udev_read_endpoint(&eps[0],ep1_rx_buff,16); if (size==16){ @@ -459,24 +467,22 @@ int main(void) /* Automatic selection of extended format if ID>2047 */ if (canmsg.id & ~0x7ffl & MSG_ID_MASK ) canmsg.flags |= MSG_EXT; /* has been dependent on "extended" option */ - - // DEBUG - unused queue system (yet) - //slot->msg=canmsg; - //canque_put_inslot(qends, qedge, slot); - CAN_send(&canmsg); + + slot->msg=canmsg; + canque_put_inslot(qends, qedge, slot); + //CAN_send(&canmsg); } - - // DEBUG - unused queue system (yet) - //else - // canque_abort_inslot(qends,qedge,slot); + else + canque_abort_inslot(qends,qedge,slot); + timer_rx_off=50; //rosviceni diody pri prijmu CLR_OUT_PIN(LED_PORT,LED2_BIT); usb_device.ep_events &= ~MASK_EP1RX; - // DEBUG - //} - + + } + /* if (size==2){ uint8_t val;