Receiving CAN messages with usage of queue system from LinCAN - first version. Attemp...
authorJiri Vanek <vanekjir@fel.cvut.cz>
Thu, 29 Dec 2011 09:11:12 +0000 (10:11 +0100)
committerJiri Vanek <vanekjir@fel.cvut.cz>
Thu, 29 Dec 2011 09:11:12 +0000 (10:11 +0100)
embedded/app/usbcan/can/lpc17xx_can.h
embedded/app/usbcan/lpc17xx_can.c
embedded/app/usbcan/main.c

index dd3fdf2..d4683e5 100644 (file)
@@ -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
 }
index ec82757..9defc72 100644 (file)
@@ -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);
 
+
        
 }
 
index 6053645..ad7fe36 100644 (file)
@@ -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 && )