]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - embedded/app/usbcan/lpc17xx_can.c
Receiving CAN messages with usage of queue system from LinCAN - first version. Attemp...
[lincan.git] / embedded / app / usbcan / lpc17xx_can.c
index ec827575c503c3cd22c112d66822fe1424ddd71b..9defc721a2d5af0242ad9fce963375a035e1018c 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);
 
+
        
 }