Added vendor functions to embedded application, data transferred by usb channel seria...
[lincan.git] / embedded / app / usbcan / usb_vend.c
1 #include <stdio.h>
2 #include <system_def.h>
3 #include <hal_intr.h>
4 #include "./can/ul_usb1.h"
5 #include "./can/can.h"
6 #include "./can/can_sysdep.h"
7 #include "./can/main.h"
8 #include "./can/devcommon.h"
9 #include "./usb/usb_vend.h"
10 //#include "./can/ul_usb1.h"
11 #include <endian.h>
12 #if __BYTE_ORDER == __BIG_ENDIAN
13   #include <byteswap.h>
14 #endif
15
16 extern struct canuser_t *canuser;
17
18 int set_ext_mask_complete_fnc(struct usb_ep_t *ep, int status){
19   int dest_chip;
20
21         unsigned long code;
22         unsigned long mask;
23
24         struct ul_usb1_chip_data *chip_data=NULL;
25
26         usb_device_t *udev=ep->udev;
27         unsigned char *data=ep->ptr - ep->actual;
28
29         if (udev->request.bRequest==USBCAN_VENDOR_EXT_MASK_SET){
30                 dest_chip=(udev->request.wIndex);
31                 if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
32                         goto error;
33                 if (!chips_p[dest_chip])
34                         goto error;
35                 if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
36                         goto nodata;
37
38                 mask=*(uint32_t *)(data);
39                 code=*(uint32_t *)(data+4);
40                 #if __BYTE_ORDER == __BIG_ENDIAN
41                 mask  = bswap_32( mask);
42                 code  = bswap_32( code);
43                 #endif
44
45
46                 if (chips_p[dest_chip]->chipspecops->extended_mask(chips_p[dest_chip], code, mask)<0)
47                         goto error;
48                 chip_data->flags |= UL_USB1_CHIP_MASK_SET;
49         }
50         return 0;
51 error:
52         chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
53 nodata:
54         return -1;
55 }
56
57 int set_baud_rate_complete_fnc(struct usb_ep_t *ep, int status){
58   int dest_chip;
59
60         int32_t rate,sjw,sampl_pt,flags;
61
62         struct ul_usb1_chip_data *chip_data=NULL;
63
64         usb_device_t *udev=ep->udev;
65         unsigned char *data=ep->ptr - ep->actual;
66
67         if (udev->request.bRequest==USBCAN_VENDOR_BAUD_RATE_SET){
68                 dest_chip=(udev->request.wIndex);
69                 if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
70                         goto error;
71                 if (!chips_p[dest_chip])
72                         goto error;
73                 if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
74                         goto nodata;
75
76                 rate=*(int32_t *)(data);
77                 sjw=*(int32_t *)(data+4);
78                 sampl_pt=*(int32_t *)(data+8);
79                 flags=*(int32_t *)(data+12);
80                 #if __BYTE_ORDER == __BIG_ENDIAN
81                 rate  = bswap_32( rate);
82                 sjw  = bswap_32( sjw);
83                 sampl_pt  = bswap_32( sampl_pt);
84                 flags  = bswap_32( flags);
85                 #endif
86
87                 if (chips_p[dest_chip]->chipspecops->baud_rate(chips_p[dest_chip], rate, chips_p[dest_chip]->clock, sjw, sampl_pt, flags)<0)
88                         goto error;
89                 chip_data->flags |= UL_USB1_CHIP_BAUD_SET;
90         }
91         return 0;
92 error:
93         chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
94 nodata:
95         return -1;
96 }
97
98 int usbcan_vendor(usb_device_t *udev)
99 {
100   // wIndex, wValue, bRequest, wLength
101   int dest_chip;
102   struct ul_usb1_chip_data *chip_data;
103   uint8_t ret;
104
105   dest_chip=(udev->request.wIndex);
106   if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
107         return 0; // Should look like ok (0) or stall (-1)?
108   if (!chips_p[dest_chip])
109         return 0; // Should look like ok (0) or stall (-1)?
110
111   switch ( udev->request.bRequest) {
112                 case USBCAN_VENDOR_EXT_MASK_SET:
113                         udev->ep0.complete_fnc=set_ext_mask_complete_fnc;
114                         return 1;
115                 case USBCAN_VENDOR_EXT_MASK_STATUS:
116                         ret=-1;
117                         if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
118                                 usb_send_control_data(udev,&ret,1);
119                         else{
120                                 ret=(chip_data->flags & UL_USB1_CHIP_MASK_SET)?1:0;
121                                 usb_send_control_data(udev,&ret,1);
122                         }
123                         chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
124                         return 1;
125
126                 case USBCAN_VENDOR_BAUD_RATE_SET:
127                         udev->ep0.complete_fnc=set_baud_rate_complete_fnc;
128                         return 1;
129                 case USBCAN_VENDOR_BAUD_RATE_STATUS:
130                         ret=-1;
131                         if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
132                                 usb_send_control_data(udev,&ret,1);
133                         else{
134                                 ret=(chip_data->flags & UL_USB1_CHIP_BAUD_SET)?1:0;
135                                 usb_send_control_data(udev,&ret,1);
136                         }
137                         chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
138                         return 1;
139
140                 case USBCAN_VENDOR_SET_BTREGS:
141                         {
142                                 uint16_t value=udev->request.wValue;
143                                 ret=1;
144                                 if (chips_p[dest_chip]->chipspecops->set_btregs(chips_p[dest_chip],value&0xFF,(value>>8)&0xFF)<0)
145                                         ret=0;
146                                 usb_send_control_data(udev,&ret,1);
147                                 return 1;
148                         }
149                         return 1;
150
151                 case USBCAN_VENDOR_CHECK_TX_STAT:
152                         {
153                                 struct canque_edge_t *qedge;
154                                 struct canque_slot_t *slot;
155                                 ret=0;
156                                 if (canque_get_inslot(canuser->qends, &qedge, &slot, 0)>=0){
157                                         canque_abort_inslot(canuser->qends, qedge, slot);
158                                         ret=1;
159                                 }
160                                 usb_send_control_data(udev,&ret,1);
161                                 return 1;
162                         }
163
164                 case USBCAN_VENDOR_START_CHIP:
165                         ret=1;
166                         if (chips_p[dest_chip]->chipspecops->start_chip(chips_p[dest_chip])<0)
167                                 ret=0;
168                         usb_send_control_data(udev,&ret,1);
169                         return 1;
170                 case USBCAN_VENDOR_STOP_CHIP:
171                         ret=1;
172                         if (chips_p[dest_chip]->chipspecops->stop_chip(chips_p[dest_chip])<0)
173                                 ret=0;
174                         usb_send_control_data(udev,&ret,1);
175                         return 1;
176   }
177
178   return 0;
179 }