]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/app/usbcan/usb_vend.c
lpc17xx embedded: new function for obtaining chip bittiming constant parameters.
[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_sysdep.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 #include "./can/can_bittiming.h"
18
19 extern struct canuser_t *canuser;
20 extern uint8_t vendor_ret;
21
22 int set_ext_mask_complete_fnc(struct usb_ep_t *ep, int status){
23   int dest_chip;
24
25         unsigned long code;
26         unsigned long mask;
27
28         struct ul_usb1_chip_data *chip_data=NULL;
29
30         usb_device_t *udev=ep->udev;
31         unsigned char *data=ep->ptr - ep->actual;
32
33         if (udev->request.bRequest==USBCAN_VENDOR_EXT_MASK_SET){
34                 dest_chip=(udev->request.wIndex);
35                 if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
36                         goto error;
37                 if (!chips_p[dest_chip])
38                         goto error;
39                 if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
40                         goto nodata;
41
42                 mask=*(uint32_t *)(data);
43                 code=*(uint32_t *)(data+4);
44                 #if __BYTE_ORDER == __BIG_ENDIAN
45                 mask  = bswap_32( mask);
46                 code  = bswap_32( code);
47                 #endif
48
49
50                 if (chips_p[dest_chip]->chipspecops->extended_mask(chips_p[dest_chip], code, mask)<0)
51                         goto error;
52                 chip_data->flags |= UL_USB1_CHIP_MASK_SET;
53         }
54         return 0;
55 error:
56         chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
57 nodata:
58         return -1;
59 }
60
61 int set_baud_rate_complete_fnc(struct usb_ep_t *ep, int status){
62   int dest_chip;
63
64         int32_t rate,sjw,sampl_pt,flags;
65
66         struct ul_usb1_chip_data *chip_data=NULL;
67
68         usb_device_t *udev=ep->udev;
69         unsigned char *data=ep->ptr - ep->actual;
70
71         if (udev->request.bRequest==USBCAN_VENDOR_BAUD_RATE_SET){
72                 dest_chip=(udev->request.wIndex);
73                 if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
74                         goto error;
75                 if (!chips_p[dest_chip])
76                         goto error;
77                 if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
78                         goto nodata;
79
80                 rate=*(int32_t *)(data);
81                 sjw=*(int32_t *)(data+4);
82                 sampl_pt=*(int32_t *)(data+8);
83                 flags=*(int32_t *)(data+12);
84                 #if __BYTE_ORDER == __BIG_ENDIAN
85                 rate  = bswap_32( rate);
86                 sjw  = bswap_32( sjw);
87                 sampl_pt  = bswap_32( sampl_pt);
88                 flags  = bswap_32( flags);
89                 #endif
90
91                 if (chips_p[dest_chip]->chipspecops->baud_rate(chips_p[dest_chip], rate, chips_p[dest_chip]->clock, sjw, sampl_pt, flags)<0)
92                         goto error;
93                 chip_data->flags |= UL_USB1_CHIP_BAUD_SET;
94         }
95         return 0;
96 error:
97         chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
98 nodata:
99         return -1;
100 }
101
102
103
104 int set_bittiming_complete_fnc(struct usb_ep_t *ep, int status){
105   int dest_chip;
106
107         int32_t brp, sjw, tseg1, tseg2;
108
109         usb_device_t *udev=ep->udev;
110         unsigned char *data=ep->ptr - ep->actual;
111
112         if(ep->actual != USBCAN_BITTIMING_SIZE)
113                 goto error;
114
115         if (udev->request.bRequest==USBCAN_VENDOR_SET_BITTIMING){
116                 dest_chip=(udev->request.wIndex);
117                 if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
118                         goto error;
119                 if (!chips_p[dest_chip])
120                         goto error;
121
122                 brp=*(int32_t *)(data);
123                 sjw=*(int32_t *)(data+4);
124                 tseg1=*(int32_t *)(data+8);
125                 tseg2=*(int32_t *)(data+12);
126                 #if __BYTE_ORDER == __BIG_ENDIAN
127                 brp  = bswap_32(brp);
128                 sjw  = bswap_32(sjw);
129                 tseg1  = bswap_32(tseg1);
130                 tseg2  = bswap_32(tseg2);
131                 #endif
132
133
134                 if (chips_p[dest_chip]->chipspecops->set_bittiming(chips_p[dest_chip], brp, sjw, tseg1, tseg2)<0)
135                         goto error;
136         }
137         return 0;
138
139 error:
140         return -1;
141 }
142
143 int usbcan_get_bittiming_const_reply(usb_device_t *udev){
144         int dest_chip;
145         struct canchip_t *chip;
146
147         struct can_bittiming_const btc_buff;
148         struct can_bittiming_const *btc = &btc_buff;
149
150         uint8_t buffer[USBCAN_BITTIMING_CONST_SIZE];
151         uint32_t *ptr;
152
153         if (udev->request.bRequest==USBCAN_VENDOR_GET_BITTIMING_CONST){
154
155                 dest_chip=(udev->request.wIndex);
156                 if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
157                         goto error;
158                 if ((chip = chips_p[dest_chip]) == NULL)
159                         goto error;
160                 if (chip->chipspecops->get_bittiming_const == NULL){
161                         goto error;
162                 }
163
164                 chip->chipspecops->get_bittiming_const(chip, btc);              
165                 ptr = (uint32_t*) buffer;
166
167                 #if __BYTE_ORDER == __BIG_ENDIAN
168                 *(ptr++) = bswap_32(chips_p[dest_chip]->clock);
169                 *(ptr++) = bswap_32(btc->tseg1_min);
170                 *(ptr++) = bswap_32(btc->tseg1_max);
171                 *(ptr++) = bswap_32(btc->tseg2_min);
172                 *(ptr++) = bswap_32(btc->tseg2_max);
173                 *(ptr++) = bswap_32(btc->sjw_max);
174                 *(ptr++) = bswap_32(btc->brp_min);
175                 *(ptr++) = bswap_32(btc->brp_max);
176                 *(ptr) = bswap_32(btc->brp_inc);
177                 #else
178                 *(ptr++) = chips_p[dest_chip]->clock;
179                 *(ptr++) = btc->tseg1_min;
180                 *(ptr++) = btc->tseg1_max;
181                 *(ptr++) = btc->tseg2_min;
182                 *(ptr++) = btc->tseg2_max;
183                 *(ptr++) = btc->sjw_max;
184                 *(ptr++) = btc->brp_min;
185                 *(ptr++) = btc->brp_max;
186                 *(ptr) = btc->brp_inc;
187                 #endif
188
189                 usb_send_control_data(udev, buffer, USBCAN_BITTIMING_CONST_SIZE);
190                                 
191
192         }
193         return 0;
194
195 error:
196         return -1;
197 }
198
199 int usbcan_vendor(usb_device_t *udev)
200 {
201   // wIndex, wValue, bRequest, wLength
202   int dest_chip;
203   struct ul_usb1_chip_data *chip_data;
204
205   dest_chip=(udev->request.wIndex);
206   if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
207         return -1; // Should look like ok (0) or stall (-1)?
208   if (!chips_p[dest_chip])
209         return -1; // Should look like ok (0) or stall (-1)?
210
211   switch ( udev->request.bRequest) {
212                 
213                 //lpc17xx
214                 case USBCAN_VENDOR_SET_BITTIMING:
215                         udev->ep0.complete_fnc=set_bittiming_complete_fnc;
216                         return 1;
217
218                 case USBCAN_VENDOR_GET_BITTIMING_CONST:
219                         usbcan_get_bittiming_const_reply(udev);
220                         return 1;
221                 //lpc17xx - end
222
223                 case USBCAN_VENDOR_EXT_MASK_SET:
224                         udev->ep0.complete_fnc=set_ext_mask_complete_fnc;
225                         return 1;
226                 case USBCAN_VENDOR_EXT_MASK_STATUS:
227                         vendor_ret=-1;
228                         if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
229                                 usb_send_control_data(udev,&vendor_ret,1);
230                         else{
231                                 vendor_ret=(chip_data->flags & UL_USB1_CHIP_MASK_SET)?1:0;
232                                 usb_send_control_data(udev,&vendor_ret,1);
233                         }
234                         chip_data->flags &= ~UL_USB1_CHIP_MASK_SET;
235                         return 1;
236
237                 case USBCAN_VENDOR_BAUD_RATE_SET:
238                         udev->ep0.complete_fnc=set_baud_rate_complete_fnc;
239                         return 1;
240                 case USBCAN_VENDOR_BAUD_RATE_STATUS:
241                         vendor_ret=-1;
242                         if ((chip_data=((struct ul_usb1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
243                                 usb_send_control_data(udev,&vendor_ret,1);
244                         else{
245                                 vendor_ret=(chip_data->flags & UL_USB1_CHIP_BAUD_SET)?1:0;
246                                 usb_send_control_data(udev,&vendor_ret,1);
247                         }
248                         chip_data->flags &= ~UL_USB1_CHIP_BAUD_SET;
249                         return 1;
250
251                 case USBCAN_VENDOR_SET_BTREGS:
252                         {
253                                 uint16_t value=udev->request.wValue;
254                                 vendor_ret=1;
255                                 if (chips_p[dest_chip]->chipspecops->set_btregs(chips_p[dest_chip],value&0xFF,(value>>8)&0xFF)<0)
256                                         vendor_ret=0;
257                                 usb_send_control_data(udev,&vendor_ret,1);
258                         }
259                         return 1;
260
261                 case USBCAN_VENDOR_CHECK_TX_STAT:
262                         {
263                                 struct canque_edge_t *qedge;
264                                 struct canque_slot_t *slot;
265                                 vendor_ret=0;
266                                 if (canque_get_inslot(canuser->qends, &qedge, &slot, 0)>=0){
267                                         canque_abort_inslot(canuser->qends, qedge, slot);
268                                         DEBUGMSG("USBCAN_VENDOR_CHECK_TX_STAT - Free slot found\r\n");
269                                         vendor_ret=1;
270                                 }
271                                 DEBUGMSG("USBCAN_VENDOR_CHECK_TX_STAT - Sending %d\r\n",vendor_ret);
272                                 usb_send_control_data(udev,&vendor_ret,1);
273                                 return 1;
274                         }
275
276                 case USBCAN_VENDOR_START_CHIP:
277                         vendor_ret=1;
278                         if (chips_p[dest_chip]->chipspecops->start_chip(chips_p[dest_chip])<0)
279                                 vendor_ret=0;
280                         usb_send_control_data(udev,&vendor_ret,1);
281                         return 1;
282                 case USBCAN_VENDOR_STOP_CHIP:
283                         vendor_ret=1;
284                         if (chips_p[dest_chip]->chipspecops->stop_chip(chips_p[dest_chip])<0)
285                                 vendor_ret=0;
286                         usb_send_control_data(udev,&vendor_ret,1);
287                         return 1;
288   }
289
290   return 0;
291 }