Used sysless functions for IRQ handling. Used access functions to the chip register...
authorJiri Vanek <vanekjir@fel.cvut.cz>
Thu, 16 Feb 2012 11:24:57 +0000 (12:24 +0100)
committerJiri Vanek <vanekjir@fel.cvut.cz>
Thu, 16 Feb 2012 11:24:57 +0000 (12:24 +0100)
embedded/app/usbcan/can/lpc17xx_can.h
embedded/app/usbcan/lpc17xx_can.c
embedded/app/usbcan/main.c

index bd2d1e5..0e137a9 100644 (file)
@@ -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);
index 383b6c7..8b3a773 100644 (file)
@@ -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);
-
-
        
 }
 
index 41062e3..71fb5e7 100644 (file)
@@ -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)