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