]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - embedded/app/usbcan/main.c
Merge branch 'master' into can-usb1
[lincan.git] / embedded / app / usbcan / main.c
index 97d9785907fd158223ccb49d4c4fe452367385ee..fd12f59bf9e5c603b604769a7ec2e629184f2933 100644 (file)
 #include <lpciap.h>
 #include <lpciap_kvpb.h>
 
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+  #include <byteswap.h>
+#endif
+
 #include "./can/can.h"
 #include "./can/sja1000p.h"
 #include "./can/main.h"
 
-#include "./can/can_sysdep.h"
+// #include "./can/can_sysdep.h"
 #include "./can/modparms.h"
 #include "./can/devcommon.h"
 
 #include "./can/ul_usb1.h"
 //#include "./can/setup.h"
 
+#include "./usb/usb_vend.h"
+
 #define MASK_EP1RX  0x01
 #define MASK_EP1TX  0x02
 
-#ifdef USB_MAX_PACKET
-       #undef USB_MAX_PACKET
-       #define USB_MAX_PACKET 16
-#endif
-
 #define CAN_OP_MASK 0x80
 #define CAN_OP_READ 0x80
 #define CAN_OP_WRITE 0x00
 
+#ifdef USB_MAX_PACKET
+       #undef USB_MAX_PACKET
+       #define USB_MAX_PACKET 16
+#endif
 /***********************************************************************
  * Note:
  * Comparing to LinCAN, there is no need to sleep for processes
@@ -75,6 +81,8 @@ unsigned char ep1_tx_buff[USB_MAX_PACKET];
 uint8_t timer_str,timer_rx_off,timer_tx_off,timer_configured;
 volatile uint8_t bootloader_run;
 
+uint8_t vendor_ret;
+
 int processlocal;
 
 int baudrate[MAX_TOT_CHIPS];
@@ -83,9 +91,14 @@ struct canhardware_t *hardware_p=&canhardware;
 struct canchip_t *chips_p[MAX_TOT_CHIPS];
 struct msgobj_t *objects_p[MAX_TOT_MSGOBJS];
 
+struct canuser_t *canuser;
+
+extern int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate);
+extern int register_chip_struct(struct canchip_t *chip, int minorbase);
+extern int register_obj_struct(struct msgobj_t *obj, int minorbase);
 
 /***********************************************************************
- * SOMETHING BAD HAPPENED
+ * IF SOMETHING BAD HAPPENED
  ***********************************************************************/
 
 int sys_err(){
@@ -134,7 +147,6 @@ int main(void)
        struct candevice_t *candev;
        struct canchip_t *chip=NULL;
        struct msgobj_t *obj;
-       struct canuser_t *canuser;
        struct canque_ends_t *qends;
        struct canque_edge_t *edge,*qedge;
        struct canque_slot_t *slot;
@@ -142,7 +154,9 @@ int main(void)
        can_spin_irqflags_t iflags;
 
        int chipnr,bd;
-       int i,size;
+       int i,size,m=0;
+
+       CANMSG("Starting USBCAN module firmware...\n");
 
 //     volatile int i=0;
        bootloader_run=0;
@@ -154,11 +168,18 @@ int main(void)
        SET_OUT_PIN(LED_PORT,LED_ERR);
        CLR_OUT_PIN(LED_PORT,LED_GP);
 
+       if (USB_MAX_PACKET<16){
+               CANMSG("Maximum packet size less than 16B (is %dB)\n",USB_MAX_PACKET);
+               sys_err();
+       }
+
        /***********************************************************************
         * CAN device initialization - device side (adapted from LinCAN setup.c)
         ***********************************************************************/
 
+       can_init();
 
+       DEBUGMSG("Initiating CAN device initialization\n");
        baudrate[0]=1000;
 
        canqueue_kern_initialize();
@@ -166,8 +187,11 @@ int main(void)
        hardware_p->nr_boards=1;
 
        candev=(struct candevice_t *)malloc(sizeof(struct candevice_t));
-               if (candev==NULL) sys_err();
-               memset(candev, 0, sizeof(struct candevice_t));
+       if (!candev){
+               CANMSG("No space left in memory\n");
+               sys_err();
+       }
+       memset(candev, 0, sizeof(struct candevice_t));
 
        hardware_p->candevice[0]=candev;
        candev->candev_idx=0;
@@ -175,18 +199,38 @@ int main(void)
        candev->dev_base_addr=0;
 
        candev->hwspecops=(struct hwspecops_t *)malloc(sizeof(struct hwspecops_t));
-               if (candev->hwspecops==NULL) sys_err();
-               memset(candev->hwspecops, 0, sizeof(struct hwspecops_t));
+       if (!candev->hwspecops){
+               CANMSG("No space left in memory\n");
+               sys_err();
+       }
+       memset(candev->hwspecops, 0, sizeof(struct hwspecops_t));
 
        ul_usb1_register(candev->hwspecops);
 
        bd=baudrate[0];
-       if (candev->hwspecops->init_hw_data(candev)) sys_err();
+       if (candev->hwspecops->init_hw_data(candev)){
+               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(chipnr<irqnum)
                        irqsig=irq[*irq_param_idx_p+chipnr];*/
-               if (init_chip_struct(candev, chipnr, 0, bd*1000)) sys_err();
+               if (init_chip_struct(candev, chipnr, 0, bd*1000)){
+                       CANMSG("Chip structure could not be initialized\n");
+                       sys_err();
+               }
+       }
+       for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) {
+               struct canchip_t *chip=candev->chip[chipnr];
+               int objnr;
+
+               register_chip_struct(chip, m);
+
+               for (objnr=0; objnr<chip->max_objects; objnr++) {
+                       register_obj_struct(chip->msgobj[objnr], m);
+                       if(m>=0) m++;
+               }
        }
        if (candev->hwspecops->request_io(candev))
                sys_err();
@@ -287,12 +331,11 @@ int main(void)
        eps[0].udev = &usb_device;
        eps[1].udev = &usb_device;
 
-//  usb_device.vendor_fnc=usb_loader;
+  usb_device.vendor_fnc=usbcan_vendor;
 
        usb_init(&usb_device);
        usb_connect(&usb_device);
-
-       can_init();
+       usb_device.ep_events |= MASK_EP1TX;
 
        /***********************************************************************
         * Start
@@ -304,20 +347,34 @@ int main(void)
                usb_check_events(&usb_device);
                usb_control_response(&usb_device);
 
-               if (!(IO0PIN&P0_SJA1000_INT_PIN))
+               if (!(IO0PIN&P0_SJA1000_INT_PIN)) //INT PIN is inverted
                        chip->chipspecops->irq_handler(0,chip);
 
                if (usb_device.ep_events & MASK_EP1RX) {  //EP1RX - data waiting to receive
                        uint8_t val;
                        if (canque_get_inslot(qends, &qedge, &slot, 0)>=0){ //Free slot obtained
-                               size=usb_udev_read_endpoint(&eps[0],ep1_rx_buff,USB_MAX_PACKET);
+                               size=usb_udev_read_endpoint(&eps[0],ep1_rx_buff,16);
                                if (size==16){
+                                       uint16_t msgflags;
+                                       uint32_t msgid;
                                        canmsg.cob=0;
-                                       canmsg.id=*((uint32_t*)ep1_rx_buff);
-                                       canmsg.flags=(*((uint32_t*)(ep1_rx_buff+4)))>>8;
-                                       canmsg.length=(*((uint16_t*)(ep1_rx_buff+6)))&0x00FF;
-                                       for (i=0;i<CAN_MSG_LENGTH;i++){
-                                               canmsg.data[i]=*((unsigned char*)(ep1_rx_buff+8+i));
+                                       canmsg.length=*(uint8_t *)(ep1_rx_buff+1);
+                                       if (canmsg.length > CAN_MSG_LENGTH)
+                                               canmsg.length=CAN_MSG_LENGTH;
+                                       msgflags=*(uint16_t *)(ep1_rx_buff+2);
+                                       msgid=*(uint32_t *)(ep1_rx_buff+4);
+                                       #if __BYTE_ORDER == __BIG_ENDIAN
+                                               msgflags  = bswap_16( msgflags);
+                                               msgid  = bswap_32( msgid);
+                                       #endif
+                                       canmsg.flags=msgflags;
+                                       canmsg.id=msgid;
+
+                                       for (i=0;i<canmsg.length;i++){
+                                               canmsg.data[i]=*(unsigned char*)(ep1_rx_buff+8+i);
+                                       }
+                                       for (;i<CAN_MSG_LENGTH;i++){
+                                               canmsg.data[i]=0;
                                        }
                                        /* Automatic selection of extended format if ID>2047 */
                                        if (canmsg.id & ~0x7ffl & MSG_ID_MASK ) canmsg.flags |= MSG_EXT;
@@ -352,12 +409,29 @@ int main(void)
 
                if(usb_device.ep_events & MASK_EP1TX){ //EP1TX - data transmitted
                        if(canque_test_outslot(qends, &qedge, &slot)>=0){
-                               (*((uint32_t*)ep1_tx_buff))=slot->msg.id;
-                               (*((uint32_t*)(ep1_tx_buff+4)))=slot->msg.flags<<8 | (slot->msg.length&0xFF);
-                               for (i=0;i<CAN_MSG_LENGTH;i++){
-                                       (*((uint32_t*)(ep1_tx_buff+8+i)))=slot->msg.data[i];
+                               DEBUGMSG("CAN message ready to send over usb\n");
+                               uint16_t msgflags;
+                               uint32_t msgid;
+
+                               *(uint8_t *)(ep1_tx_buff)=0;
+                               *(uint8_t *)(ep1_tx_buff+1)=slot->msg.length;
+
+                               msgflags=slot->msg.flags;
+                               msgid=slot->msg.id;
+                               #if __BYTE_ORDER == __BIG_ENDIAN
+                                       msgflags  = bswap_16( msgflags);
+                                       msgid  = bswap_32( msgid);
+                               #endif
+
+                               *(uint16_t *)(ep1_tx_buff+2)=msgflags;
+                               *(uint32_t *)(ep1_tx_buff+4)=msgid;
+                               for (i=0;i<slot->msg.length;i++){
+                                       *(uint8_t *)(ep1_tx_buff+8+i)=slot->msg.data[i];
+                               }
+                               for (;i<CAN_MSG_LENGTH;i++){
+                                       *(uint8_t *)(ep1_tx_buff+8+i)=0;
                                }
-                               usb_udev_write_endpoint(&eps[1],ep1_tx_buff,USB_MAX_PACKET);
+                               usb_udev_write_endpoint(&eps[1],ep1_tx_buff,16);
 
                                canque_free_outslot(qends, qedge, slot);
                                timer_tx_off=50;                //rozsviceni diod pri vysilani