]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - embedded/app/usbcan/usb_vend.c
Added vendor functions to embedded application, data transferred by usb channel seria...
[lincan.git] / embedded / app / usbcan / usb_vend.c
diff --git a/embedded/app/usbcan/usb_vend.c b/embedded/app/usbcan/usb_vend.c
new file mode 100644 (file)
index 0000000..8ee992c
--- /dev/null
@@ -0,0 +1,179 @@
+#include <stdio.h>
+#include <system_def.h>
+#include <hal_intr.h>
+#include "./can/ul_usb1.h"
+#include "./can/can.h"
+#include "./can/can_sysdep.h"
+#include "./can/main.h"
+#include "./can/devcommon.h"
+#include "./usb/usb_vend.h"
+//#include "./can/ul_usb1.h"
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+  #include <byteswap.h>
+#endif
+
+extern struct canuser_t *canuser;
+
+int set_ext_mask_complete_fnc(struct usb_ep_t *ep, int status){
+  int dest_chip;
+
+       unsigned long code;
+       unsigned long mask;
+
+       struct ul_usb1_chip_data *chip_data=NULL;
+
+       usb_device_t *udev=ep->udev;
+       unsigned char *data=ep->ptr - ep->actual;
+
+       if (udev->request.bRequest==USBCAN_VENDOR_EXT_MASK_SET){
+               dest_chip=(udev->request.wIndex);
+               if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+                       goto error;
+               if (!chips_p[dest_chip])
+                       goto error;
+               if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+                       goto nodata;
+
+               mask=*(uint32_t *)(data);
+               code=*(uint32_t *)(data+4);
+               #if __BYTE_ORDER == __BIG_ENDIAN
+               mask  = bswap_32( mask);
+               code  = bswap_32( code);
+               #endif
+
+
+               if (chips_p[dest_chip]->chipspecops->extended_mask(chips_p[dest_chip], code, mask)<0)
+                       goto error;
+               chip_data->flags |= UL_USB1_CHIP_MASK_SET;
+       }
+       return 0;
+error:
+       chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
+nodata:
+       return -1;
+}
+
+int set_baud_rate_complete_fnc(struct usb_ep_t *ep, int status){
+  int dest_chip;
+
+       int32_t rate,sjw,sampl_pt,flags;
+
+       struct ul_usb1_chip_data *chip_data=NULL;
+
+       usb_device_t *udev=ep->udev;
+       unsigned char *data=ep->ptr - ep->actual;
+
+       if (udev->request.bRequest==USBCAN_VENDOR_BAUD_RATE_SET){
+               dest_chip=(udev->request.wIndex);
+               if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+                       goto error;
+               if (!chips_p[dest_chip])
+                       goto error;
+               if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+                       goto nodata;
+
+               rate=*(int32_t *)(data);
+               sjw=*(int32_t *)(data+4);
+               sampl_pt=*(int32_t *)(data+8);
+               flags=*(int32_t *)(data+12);
+               #if __BYTE_ORDER == __BIG_ENDIAN
+               rate  = bswap_32( rate);
+               sjw  = bswap_32( sjw);
+               sampl_pt  = bswap_32( sampl_pt);
+               flags  = bswap_32( flags);
+               #endif
+
+               if (chips_p[dest_chip]->chipspecops->baud_rate(chips_p[dest_chip], rate, chips_p[dest_chip]->clock, sjw, sampl_pt, flags)<0)
+                       goto error;
+               chip_data->flags |= UL_USB1_CHIP_BAUD_SET;
+       }
+       return 0;
+error:
+       chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
+nodata:
+       return -1;
+}
+
+int usbcan_vendor(usb_device_t *udev)
+{
+  // wIndex, wValue, bRequest, wLength
+  int dest_chip;
+  struct ul_usb1_chip_data *chip_data;
+  uint8_t ret;
+
+  dest_chip=(udev->request.wIndex);
+  if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+       return 0; // Should look like ok (0) or stall (-1)?
+  if (!chips_p[dest_chip])
+       return 0; // Should look like ok (0) or stall (-1)?
+
+  switch ( udev->request.bRequest) {
+               case USBCAN_VENDOR_EXT_MASK_SET:
+                       udev->ep0.complete_fnc=set_ext_mask_complete_fnc;
+                       return 1;
+               case USBCAN_VENDOR_EXT_MASK_STATUS:
+                       ret=-1;
+                       if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+                               usb_send_control_data(udev,&ret,1);
+                       else{
+                               ret=(chip_data->flags & UL_USB1_CHIP_MASK_SET)?1:0;
+                               usb_send_control_data(udev,&ret,1);
+                       }
+                       chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
+                       return 1;
+
+               case USBCAN_VENDOR_BAUD_RATE_SET:
+                       udev->ep0.complete_fnc=set_baud_rate_complete_fnc;
+                       return 1;
+               case USBCAN_VENDOR_BAUD_RATE_STATUS:
+                       ret=-1;
+                       if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
+                               usb_send_control_data(udev,&ret,1);
+                       else{
+                               ret=(chip_data->flags & UL_USB1_CHIP_BAUD_SET)?1:0;
+                               usb_send_control_data(udev,&ret,1);
+                       }
+                       chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
+                       return 1;
+
+               case USBCAN_VENDOR_SET_BTREGS:
+                       {
+                               uint16_t value=udev->request.wValue;
+                               ret=1;
+                               if (chips_p[dest_chip]->chipspecops->set_btregs(chips_p[dest_chip],value&0xFF,(value>>8)&0xFF)<0)
+                                       ret=0;
+                               usb_send_control_data(udev,&ret,1);
+                               return 1;
+                       }
+                       return 1;
+
+               case USBCAN_VENDOR_CHECK_TX_STAT:
+                       {
+                               struct canque_edge_t *qedge;
+                               struct canque_slot_t *slot;
+                               ret=0;
+                               if (canque_get_inslot(canuser->qends, &qedge, &slot, 0)>=0){
+                                       canque_abort_inslot(canuser->qends, qedge, slot);
+                                       ret=1;
+                               }
+                               usb_send_control_data(udev,&ret,1);
+                               return 1;
+                       }
+
+               case USBCAN_VENDOR_START_CHIP:
+                       ret=1;
+                       if (chips_p[dest_chip]->chipspecops->start_chip(chips_p[dest_chip])<0)
+                               ret=0;
+                       usb_send_control_data(udev,&ret,1);
+                       return 1;
+               case USBCAN_VENDOR_STOP_CHIP:
+                       ret=1;
+                       if (chips_p[dest_chip]->chipspecops->stop_chip(chips_p[dest_chip])<0)
+                               ret=0;
+                       usb_send_control_data(udev,&ret,1);
+                       return 1;
+  }
+
+  return 0;
+}