From a9296605ae899d82c9e8f682eafe63d999c4a57b Mon Sep 17 00:00:00 2001 From: Jiri Vanek Date: Thu, 16 Feb 2012 12:24:57 +0100 Subject: [PATCH 1/1] Used sysless functions for IRQ handling. Used access functions to the chip register can_read_reg and can_write_reg. --- embedded/app/usbcan/can/lpc17xx_can.h | 1 + embedded/app/usbcan/lpc17xx_can.c | 158 ++++++++++---------------- embedded/app/usbcan/main.c | 17 +-- 3 files changed, 72 insertions(+), 104 deletions(-) diff --git a/embedded/app/usbcan/can/lpc17xx_can.h b/embedded/app/usbcan/can/lpc17xx_can.h index bd2d1e5..0e137a9 100644 --- a/embedded/app/usbcan/can/lpc17xx_can.h +++ b/embedded/app/usbcan/can/lpc17xx_can.h @@ -167,6 +167,7 @@ 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); +int can_lmc1_program_irq(struct candevice_t *candev); // lpc17xx can chip specific functions: int lpc17xx_chip_config(struct canchip_t *chip); diff --git a/embedded/app/usbcan/lpc17xx_can.c b/embedded/app/usbcan/lpc17xx_can.c index 383b6c7..8b3a773 100644 --- a/embedded/app/usbcan/lpc17xx_can.c +++ b/embedded/app/usbcan/lpc17xx_can.c @@ -3,52 +3,6 @@ static void CAN_configPin(); static void CAN_setBusTiming(struct canchip_t *chip); -extern struct canhardware_t *hardware_p; - -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- - - -static inline void can_write_register(struct canchip_t *chip, uint32_t data, uint32_t reg_offs){ - - uint32_t address = chip->chip_base_addr + reg_offs; - (*(volatile uint32_t*)(address)) = data; - -} - -static inline uint32_t can_read_register(struct canchip_t *chip, uint32_t reg_offs){ - - uint32_t address = chip->chip_base_addr + reg_offs; - return (*(volatile uint32_t*)(address)); - -} - -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- - - -// interrupt handler -// 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; - - struct canchip_t *chip; - chip = hardware_p->candevice[0]->chip[0]; - - i = can_read_register(chip, CAN_ICR_o); - - if(i & (CAN_ICR_TI1 | CAN_ICR_RI)) - lpc17xx_irq_handler(0, chip); - - if(i & CAN_ICR_DOI) - can_write_register(chip, CAN_CMR_CDO, CAN_CMR_o); - - -} - //--------------------------------------------------------------------------------- //--------------------------------------------------------------------------------- @@ -64,6 +18,7 @@ int can_lmc1_register(struct hwspecops_t *hwspecops){ hwspecops->init_obj_data = can_lmc1_init_obj_data; hwspecops->write_register = can_lmc1_write_register; hwspecops->read_register = can_lmc1_read_register; + hwspecops->program_irq = can_lmc1_program_irq; return 0; } @@ -74,20 +29,18 @@ int can_lmc1_init_hw_data(struct candevice_t *candev){ candev->nr_82527_chips=0; candev->nr_sja1000_chips=0; candev->nr_all_chips=1; - candev->flags |= 0; + 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; - - //debug + // used CAN1 peripherial -> CAN1 registers base candev->chip[chipnr]->chip_base_addr = CAN1_REGS_BASE; + lpc17xx_fill_chipspecops(candev->chip[chipnr]); + candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct can_lmc1_chip_data)); if (candev->chip[chipnr]->chip_data==NULL) return -ENOMEM; @@ -118,6 +71,10 @@ int can_lmc1_reset(struct candevice_t *candev) return 0; } +int can_lmc1_program_irq(struct candevice_t *candev) +{ + return 0; +} //--------------------------------------------------------------------------------- //--------------------------------------------------------------------------------- @@ -147,7 +104,7 @@ int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj, { // write transmission request - can_write_register(chip, (CAN_CMR_TR | CAN_CMR_STB1), CAN_CMR_o); + can_write_reg(chip, (CAN_CMR_TR | CAN_CMR_STB1), CAN_CMR_o); return 0; } @@ -163,7 +120,7 @@ int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){ can_msgobj_clear_fl(obj,TX_REQUEST); - if (can_read_register(chip, CAN_SR_o) & CAN_SR_TBS1){ + if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){ obj->tx_retry_cnt=0; lpc17xx_irq_write_handler(chip, obj); } @@ -181,34 +138,44 @@ int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) int lpc17xx_irq_handler(int irq, struct canchip_t *chip) { + uint32_t i; struct msgobj_t *obj; obj = chip->msgobj[0]; - if(can_read_register(chip, CAN_SR_o) & CAN_SR_RBS) { - lpc17xx_read(chip,obj); - obj->ret = 0; - } + + i = can_read_reg(chip, CAN_ICR_o); + + if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){ + + if(can_read_reg(chip, CAN_SR_o) & 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))) { + if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) { - can_msgobj_set_fl(obj,TX_REQUEST); + can_msgobj_set_fl(obj,TX_REQUEST); - while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){ + while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){ - obj->ret=0; - can_msgobj_clear_fl(obj,TX_REQUEST); + obj->ret=0; + can_msgobj_clear_fl(obj,TX_REQUEST); - if (can_read_register(chip, CAN_SR_o) & CAN_SR_TBS1){ - obj->tx_retry_cnt=0; - lpc17xx_irq_write_handler(chip, obj); - } + if (can_read_reg(chip, CAN_SR_o) & 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_msgobj_clear_fl(obj,TX_LOCK); + if(!can_msgobj_test_fl(obj,TX_REQUEST)) break; + + } + } - } } + if(i & CAN_ICR_DOI) + can_write_reg(chip, CAN_CMR_CDO, CAN_CMR_o); // clear data overrun return CANCHIP_IRQ_HANDLED; @@ -267,13 +234,14 @@ void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) { canque_filter_msg2edges(obj->qends, &obj->rx_msg); // release Receive buffer - can_write_register(chip, CAN_CMR_RRB, CAN_CMR_o); + can_write_reg(chip, CAN_CMR_RRB, CAN_CMR_o); } int lpc17xx_fill_chipspecops(struct canchip_t *chip){ chip->max_objects=1; + chip->chip_irq = CAN_IRQn; lpc17xx_register(chip->chipspecops); @@ -359,31 +327,31 @@ void CAN_recv(struct canchip_t *chip, canmsg_t* msg){ uint32_t i; // read data lenght - msg->length = (can_read_register(chip, CAN_RFS_o)>>16) & 0xF; + msg->length = (can_read_reg(chip, CAN_RFS_o)>>16) & 0xF; // read identifier - msg->id = can_read_register(chip, CAN_RID_o); + msg->id = can_read_reg(chip, CAN_RID_o); // EXT frame - if(can_read_register(chip, CAN_RFS_o) & CAN_RFS_EXT) + if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_EXT) msg->flags |= MSG_EXT; else msg->flags &= ~MSG_EXT; // RTR frame - if(can_read_register(chip, CAN_RFS_o) & CAN_RFS_RTR) + if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_RTR) msg->flags |= MSG_RTR; else msg->flags &= ~MSG_RTR; // read data - data = can_read_register(chip, CAN_RDA_o); + data = can_read_reg(chip, CAN_RDA_o); for(i=0; i<4; i++) msg->data[i] = (data>>(i*8)) & 0xFF; - data = can_read_register(chip, CAN_RDB_o); + data = can_read_reg(chip, CAN_RDB_o); for(i=4; i<8; i++) msg->data[i] = (data>>((i-4)*8)) & 0xFF; @@ -396,9 +364,9 @@ void CAN_send(struct canchip_t *chip, canmsg_t* msg){ uint32_t i; // check status of TB1 - while (!(can_read_register(chip, CAN_SR_o) & CAN_SR_TBS1)){} + while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){} - can_tfi1 = can_read_register(chip, CAN_TFI1_o); + can_tfi1 = can_read_reg(chip, CAN_TFI1_o); can_tfi1 &= ~0x000F0000; can_tfi1 |= (msg->length)<<16; @@ -415,11 +383,11 @@ void CAN_send(struct canchip_t *chip, canmsg_t* msg){ else can_tfi1 &= ~CAN_TFI1_RTR; - can_write_register(chip, can_tfi1, CAN_TFI1_o); + can_write_reg(chip, can_tfi1, CAN_TFI1_o); // write CAN ID - can_write_register(chip, msg->id, CAN_TID1_o); + can_write_reg(chip, msg->id, CAN_TID1_o); // write first 4 data bytes @@ -427,14 +395,14 @@ void CAN_send(struct canchip_t *chip, canmsg_t* msg){ for(i=0; i<4; i++) data |= (msg->data[i])<<(i*8); - can_write_register(chip, data, CAN_TDA1_o); + can_write_reg(chip, data, CAN_TDA1_o); // write second 4 data bytes data=0; for(i=4; i<8; i++) data |= (msg->data[i])<<((i-4)*8); - can_write_register(chip, data, CAN_TDB1_o); + can_write_reg(chip, data, CAN_TDB1_o); } @@ -450,6 +418,8 @@ void CAN_setBusTiming(struct canchip_t *chip){ uint8_t SAM; uint8_t div; + TSEG1 = TSEG2 = BRP = 0; + // 0 = the bus is sampled once SAM = 0; @@ -503,7 +473,7 @@ void CAN_setBusTiming(struct canchip_t *chip){ } } - can_write_register(chip, ((SAM<<23)|(TSEG2<<20)|(TSEG1<<16)|(SJW<<14)|(BRP<<0)), CAN_BTR_o); + can_write_reg(chip, ((SAM<<23)|(TSEG2<<20)|(TSEG1<<16)|(SJW<<14)|(BRP<<0)), CAN_BTR_o); } @@ -514,7 +484,7 @@ void CAN_init(struct canchip_t *chip){ uint32_t val; uint32_t i; - printf("CAN INIT, baudrate: %d\n", chip->baudrate); + printf("CAN INIT, baudrate: %d\n", (int) chip->baudrate); // configure CAN1 pins CAN_configPin(); @@ -535,25 +505,25 @@ void CAN_init(struct canchip_t *chip){ SC->PCLKSEL0 = pclksel0; // enter reset mode - can_write_register(chip, 1, CAN_MOD_o); + can_write_reg(chip, 1, CAN_MOD_o); // disable all CAN interrupts - can_write_register(chip, 0, CAN_IER_o); + can_write_reg(chip, 0, CAN_IER_o); // reset value of Global Status Register (global controller status and error counters) - can_write_register(chip, 0x3C, CAN_GSR_o); + can_write_reg(chip, 0x3C, CAN_GSR_o); // request command to release Rx, Tx buffer and clear data overrun - can_write_register(chip, (CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO), CAN_CMR_o); + can_write_reg(chip, (CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO), CAN_CMR_o); // read to clear interrupt pending in Interrupt Capture Register - tmp = can_read_register(chip, CAN_ICR_o); + tmp = can_read_reg(chip, CAN_ICR_o); // set bus timing CAN_setBusTiming(chip); // return to normal operating - can_write_register(chip, 0, CAN_MOD_o); + can_write_reg(chip, 0, CAN_MOD_o); //-------------------------- @@ -581,12 +551,8 @@ void CAN_init(struct canchip_t *chip){ // enable interrupt after transmit // enable receive interrupt // enable data overrun interrupt - can_write_register(chip, (CAN_IER_TIE1 | CAN_IER_RIE | CAN_IER_DOIE), CAN_IER_o); + can_write_reg(chip, (CAN_IER_TIE1 | CAN_IER_RIE | CAN_IER_DOIE), CAN_IER_o); - // enable CAN interrupt - NVIC_EnableIRQ(CAN_IRQn); - - } diff --git a/embedded/app/usbcan/main.c b/embedded/app/usbcan/main.c index 41062e3..71fb5e7 100644 --- a/embedded/app/usbcan/main.c +++ b/embedded/app/usbcan/main.c @@ -62,7 +62,7 @@ //#include "./can/ul_usb1.h" -//#include "./can/setup.h" +#include "./can/setup.h" #include "./usb/usb_defs.h" #include "./usb/usb_vend.h" @@ -231,8 +231,8 @@ int main(void) // * CAN device initialization - device side (adapted from LinCAN setup.c) // *********************************************************************** - // DEBUG - //can_init(); // useless with lpc17xx (defined in can_lpcbusemu.c) +// useless with lpc17xx (defined in can_lpcbusemu.c) +// can_init(); DEBUGMSG("Initiating CAN device initialization\n"); @@ -321,11 +321,12 @@ int main(void) chip->flags |= CHIP_ATTACHED; -// Interrupts from chip are served in main cycle -// if(can_chip_setup_irq(chip)<0) { -// CANMSG("Error to setup chip IRQ\n"); -// sys_err(); -// } + // used with lpc17xx: + if(can_chip_setup_irq(chip)<0) { + CANMSG("Error to setup chip IRQ\n"); + sys_err(); + } + } if (candev->flags & CANDEV_PROGRAMMABLE_IRQ) -- 2.39.2