Subversion Repositories NaviCtrl

Rev

Rev 196 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
196 killagreg 1
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
1 ingob 2
* File Name          : usb_core.c
3
* Author             : MCD Application Team
196 killagreg 4
* Version            : V4.0.0
5
* Date               : 09/29/2008
6
* Description        : Standard protocol processing (USB v2.0).
1 ingob 7
********************************************************************************
196 killagreg 8
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
1 ingob 9
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
10
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
11
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
12
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
13
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
14
*******************************************************************************/
15
 
16
/* Includes ------------------------------------------------------------------*/
196 killagreg 17
/* Private typedef -----------------------------------------------------------*/
18
/* Private define ------------------------------------------------------------*/
19
/* Private macro -------------------------------------------------------------*/
20
/* Private variables ---------------------------------------------------------*/
21
/* Private function prototypes -----------------------------------------------*/
22
/* Private functions ---------------------------------------------------------*/
23
 
24
/* Includes ------------------------------------------------------------------*/
1 ingob 25
#include "usb_lib.h"
26
#include "usb_mem.h"
27
#include "usb_conf.h"
196 killagreg 28
 
1 ingob 29
/* Private typedef -----------------------------------------------------------*/
30
/* Private define ------------------------------------------------------------*/
31
#define ValBit(VAR,Place)    (VAR & (1<<Place))
196 killagreg 32
#define SetBit(VAR,Place)    (VAR |= (1<<Place))
33
#define ClrBit(VAR,Place)    (VAR &= ((1<<Place)^255))
1 ingob 34
 
196 killagreg 35
#define Send0LengthData() { \
36
    _SetEPTxCount(ENDP0, 0); \
37
    vSetEPTxStatus(EP_TX_VALID); \
38
  }
1 ingob 39
 
196 killagreg 40
#define vSetEPRxStatus(st)   (SaveRState = st)
41
#define vSetEPTxStatus(st)   (SaveTState = st)
1 ingob 42
 
196 killagreg 43
#define USB_StatusIn()       Send0LengthData()
44
#define USB_StatusOut()      vSetEPRxStatus(EP_RX_VALID)
1 ingob 45
 
196 killagreg 46
#define StatusInfo0          StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */
47
#define StatusInfo1          StatusInfo.bw.bb0
48
 
1 ingob 49
/* Private macro -------------------------------------------------------------*/
50
/* Private variables ---------------------------------------------------------*/
51
u16_u8 StatusInfo;
196 killagreg 52
bool Data_Mul_MaxPacketSize = FALSE;
1 ingob 53
/* Private function prototypes -----------------------------------------------*/
196 killagreg 54
static void DataStageOut(void);
55
static void DataStageIn(void);
56
static void NoData_Setup0(void);
57
static void Data_Setup0(void);
1 ingob 58
/* Private functions ---------------------------------------------------------*/
59
 
60
/*******************************************************************************
196 killagreg 61
* Function Name  : Standard_GetConfiguration.
62
* Description    : Return the current configuration variable address.
1 ingob 63
* Input          : Length - How many bytes are needed.
196 killagreg 64
* Output         : None.
65
* Return         : Return 1 , if the request is invalid when "Length" is 0.
66
*                  Return "Buffer" if the "Length" is not 0.
1 ingob 67
*******************************************************************************/
68
u8 *Standard_GetConfiguration(u16 Length)
69
{
196 killagreg 70
  if (Length == 0)
71
  {
72
    pInformation->Ctrl_Info.Usb_wLength =
73
      sizeof(pInformation->Current_Configuration);
74
 
75
    return 0;
1 ingob 76
  }
196 killagreg 77
  pUser_Standard_Requests->User_GetConfiguration();
78
  return (u8 *)&pInformation->Current_Configuration;
1 ingob 79
}
196 killagreg 80
 
1 ingob 81
/*******************************************************************************
196 killagreg 82
* Function Name  : Standard_SetConfiguration.
1 ingob 83
* Description    : This routine is called to set the configuration value
196 killagreg 84
*                  Then each class should configure device themself.
85
* Input          : None.
86
* Output         : None.
87
* Return         : Return USB_SUCCESS, if the request is performed.
88
*                  Return USB_UNSUPPORT, if the request is invalid.
1 ingob 89
*******************************************************************************/
90
RESULT Standard_SetConfiguration(void)
91
{
196 killagreg 92
  if (pInformation->USBwValue0 <= Device_Table.Total_Configuration
93
      && pInformation->USBwValue1 == 0 && pInformation->USBwIndex == 0)
94
    /*call Back usb spec 2.0*/
95
  {
96
    pInformation->Current_Configuration = pInformation->USBwValue0;
97
    pUser_Standard_Requests->User_SetConfiguration();
98
    return USB_SUCCESS;
99
  }
100
  else
101
  {
102
    return USB_UNSUPPORT;
103
  }
104
}
1 ingob 105
 
106
/*******************************************************************************
196 killagreg 107
* Function Name  : Standard_GetInterface.
108
* Description    : Return the Alternate Setting of the current interface.
109
* Input          : Length - How many bytes are needed.
110
* Output         : None.
111
* Return         : Return 0, if the request is invalid when "Length" is 0.
112
*                  Return "Buffer" if the "Length" is not 0.
1 ingob 113
*******************************************************************************/
114
u8 *Standard_GetInterface(u16 Length)
115
{
196 killagreg 116
  if (Length == 0)
117
  {
118
    pInformation->Ctrl_Info.Usb_wLength =
119
      sizeof(pInformation->Current_AlternateSetting);
1 ingob 120
    return 0;
121
  }
196 killagreg 122
  pUser_Standard_Requests->User_GetInterface();
123
  return (u8 *)&pInformation->Current_AlternateSetting;
1 ingob 124
}
196 killagreg 125
 
1 ingob 126
/*******************************************************************************
196 killagreg 127
* Function Name  : Standard_SetInterface.
128
* Description    : This routine is called to set the interface.
129
*                  Then each class should configure the interface them self.
130
* Input          : None.
131
* Output         : None.
132
* Return         : - Return USB_SUCCESS, if the request is performed.
133
*                  - Return USB_UNSUPPORT, if the request is invalid.
1 ingob 134
*******************************************************************************/
135
RESULT Standard_SetInterface(void)
136
{
196 killagreg 137
  RESULT Re;
138
  /*Test if the specified Interface and Alternate Setting are supported by
139
  the application Firmware*/
140
  Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0,
141
       pInformation->USBwValue0);
1 ingob 142
 
196 killagreg 143
  if (pInformation->Current_Configuration != 0 )
144
  {
145
    if (Re != USB_SUCCESS || pInformation->USBwIndex1 != 0
146
        || pInformation->USBwValue1 != 0)
147
    {
148
      return  USB_UNSUPPORT;
149
    }
150
    else if (Re == USB_SUCCESS)
151
    {
152
      pUser_Standard_Requests->User_SetInterface();
153
      pInformation->Current_Interface = pInformation->USBwIndex0;
154
      pInformation->Current_AlternateSetting = pInformation->USBwValue0;
155
      return USB_SUCCESS;
156
    }
157
  }
158
  return USB_UNSUPPORT;
159
}
1 ingob 160
 
161
/*******************************************************************************
196 killagreg 162
* Function Name  : Standard_GetStatus.
163
* Description    : Copy the device request data to "StatusInfo buffer".
164
* Input          : - Length - How many bytes are needed.
165
* Output         : None.
1 ingob 166
* Return         : Return 0, if the request is at end of data block,
196 killagreg 167
*                  or is invalid when "Length" is 0.
1 ingob 168
*******************************************************************************/
169
u8 *Standard_GetStatus(u16 Length)
170
{
196 killagreg 171
  if (Length == 0)
172
  {
173
    pInformation->Ctrl_Info.Usb_wLength = 2;
174
    return 0;
1 ingob 175
  }
176
 
196 killagreg 177
  StatusInfo.w = 0;
178
  /* Reset Status Information */
1 ingob 179
 
196 killagreg 180
  if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
181
  {
182
    /*Get Device Status */
183
    u8 Feature = pInformation->Current_Feature;
1 ingob 184
 
196 killagreg 185
    /* Remote Wakeup enabled */
186
    if (ValBit(Feature, 5))
187
    {
188
      SetBit(StatusInfo0, 1);
189
    }
1 ingob 190
 
196 killagreg 191
    /* Bus-powered */
192
    if (ValBit(Feature, 6))
193
    {
194
      ClrBit(StatusInfo0, 0);
195
    }
196
    else /* Self-powered */
197
    {
198
      SetBit(StatusInfo0, 0);
199
    }
200
  }
201
  /*Interface Status*/
202
  else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
203
  {
204
    return (u8 *)&StatusInfo;
205
  }
206
  /*Get EndPoint Status*/
207
  else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
208
  {
209
    u8 Related_Endpoint;
210
    u8 wIndex0 = pInformation->USBwIndex0;
1 ingob 211
 
196 killagreg 212
    Related_Endpoint = (wIndex0 & 0x0f);
213
    if (ValBit(wIndex0, 7))
214
    {
215
      /* IN endpoint */
216
      if (_GetTxStallStatus(Related_Endpoint))
217
      {
218
        SetBit(StatusInfo0, 0); /* IN Endpoint stalled */
219
      }
220
    }
221
    else
222
    {
223
      /* OUT endpoint */
224
      if (_GetRxStallStatus(Related_Endpoint))
225
      {
226
        SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */
227
      }
228
    }
229
 
230
  }
231
  else
232
  {
233
    return NULL;
234
  }
235
  pUser_Standard_Requests->User_GetStatus();
236
  return (u8 *)&StatusInfo;
1 ingob 237
}
196 killagreg 238
 
1 ingob 239
/*******************************************************************************
196 killagreg 240
* Function Name  : Standard_ClearFeature.
241
* Description    : Clear or disable a specific feature.
242
* Input          : None.
243
* Output         : None.
244
* Return         : - Return USB_SUCCESS, if the request is performed.
245
*                  - Return USB_UNSUPPORT, if the request is invalid.
1 ingob 246
*******************************************************************************/
247
RESULT Standard_ClearFeature(void)
248
{
249
 
196 killagreg 250
  u32 Type_Rec = Type_Recipient;
251
  u32 Status;
1 ingob 252
 
253
 
196 killagreg 254
  if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT))
255
  {/*Device Clear Feature*/
256
    ClrBit(pInformation->Current_Feature, 5);
257
    pUser_Standard_Requests->User_ClearFeature();
258
    return USB_SUCCESS;
259
  }
260
  else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
261
  {/*EndPoint Clear Feature*/
262
    DEVICE* pDev;
263
    u32 Related_Endpoint;
264
    u32 wIndex0;
265
    u32 rEP;
1 ingob 266
 
196 killagreg 267
    if (pInformation->USBwValue != ENDPOINT_STALL
268
        || pInformation->USBwIndex1 != 0)
269
    {
270
      return USB_UNSUPPORT;
271
    }
1 ingob 272
 
196 killagreg 273
    pDev = &Device_Table;
274
    wIndex0 = pInformation->USBwIndex0;
275
    rEP = wIndex0 & ~0x80;
276
    Related_Endpoint = ENDP0 + rEP;
1 ingob 277
 
196 killagreg 278
    if (ValBit(pInformation->USBwIndex0, 7))
279
    { /*Get Status of endpoint & stall the request if the related_ENdpoint is
280
            Disabled*/
281
      Status = _GetEPTxStatus(Related_Endpoint);
282
    }
283
    else
284
    {
285
      Status = _GetEPRxStatus(Related_Endpoint);
286
    }
1 ingob 287
 
196 killagreg 288
    if (rEP >= pDev->Total_Endpoint || Status == 0
289
        || pInformation->Current_Configuration == 0)
290
    {
291
      return USB_UNSUPPORT;
292
    }
293
 
294
 
295
    if (wIndex0 & 0x80)
296
    {  /* IN endpoint */
297
      if (_GetTxStallStatus(Related_Endpoint ))
298
      {
299
        ClearDTOG_TX(Related_Endpoint);
300
        SetEPTxStatus(Related_Endpoint, EP_TX_VALID);
301
      }
302
    }
303
    else
304
    {       /* OUT endpoint */
305
      if (_GetRxStallStatus(Related_Endpoint))
306
      {
307
        if (Related_Endpoint == ENDP0)
308
        {
309
          /* After clear the STALL, enable the default endpoint receiver */
310
          SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize);
311
          _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
312
        }
313
        else
314
        {
315
          ClearDTOG_RX(Related_Endpoint);
316
          _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
317
        }
318
      }
319
    }
320
    pUser_Standard_Requests->User_ClearFeature();
321
    return USB_SUCCESS;
322
  }
323
 
324
  return USB_UNSUPPORT;
1 ingob 325
}
196 killagreg 326
 
1 ingob 327
/*******************************************************************************
328
* Function Name  : Standard_SetEndPointFeature
329
* Description    : Set or enable a specific feature of EndPoint
196 killagreg 330
* Input          : None.
331
* Output         : None.
332
* Return         : - Return USB_SUCCESS, if the request is performed.
333
*                  - Return USB_UNSUPPORT, if the request is invalid.
1 ingob 334
*******************************************************************************/
335
RESULT Standard_SetEndPointFeature(void)
336
{
196 killagreg 337
  u32    wIndex0;
338
  u32    Related_Endpoint;
339
  u32    rEP;
340
  u32   Status;
1 ingob 341
 
196 killagreg 342
  wIndex0 = pInformation->USBwIndex0;
343
  rEP = wIndex0 & ~0x80;
344
  Related_Endpoint = ENDP0 + rEP;
1 ingob 345
 
196 killagreg 346
  if (ValBit(pInformation->USBwIndex0, 7))
347
  { /* get Status of endpoint & stall the request if the related_ENdpoint is
348
        Disabled*/
349
    Status = _GetEPTxStatus(Related_Endpoint);
350
  }
351
  else
352
  {
353
    Status = _GetEPRxStatus(Related_Endpoint);
354
  }
355
  if (Related_Endpoint >= Device_Table.Total_Endpoint
356
      || pInformation->USBwValue != 0 || Status == 0
357
      || pInformation->Current_Configuration == 0)
358
  {
359
    return USB_UNSUPPORT;
360
  }
361
  else
362
  {
363
    if (wIndex0 & 0x80)
364
    {  /* IN endpoint */
365
      _SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
366
    }
1 ingob 367
 
196 killagreg 368
    else
369
    {    /* OUT endpoint */
370
      _SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
371
    }
372
  }
373
  pUser_Standard_Requests->User_SetEndPointFeature();
374
  return USB_SUCCESS;
375
}
1 ingob 376
 
377
/*******************************************************************************
196 killagreg 378
* Function Name  : Standard_SetDeviceFeature.
379
* Description    : Set or enable a specific feature of Device.
380
* Input          : None.
381
* Output         : None.
382
* Return         : - Return USB_SUCCESS, if the request is performed.
383
*                  - Return USB_UNSUPPORT, if the request is invalid.
1 ingob 384
*******************************************************************************/
385
RESULT Standard_SetDeviceFeature(void)
386
{
196 killagreg 387
  SetBit(pInformation->Current_Feature, 5);
388
  pUser_Standard_Requests->User_SetDeviceFeature();
389
  return USB_SUCCESS;
1 ingob 390
 
391
}
392
 
393
/*******************************************************************************
196 killagreg 394
* Function Name  : Standard_GetDescriptorData.
395
* Description    : Standard_GetDescriptorData is used for descriptors transfer.
396
*                : This routine is used for the descriptors resident in Flash
397
*                  or RAM
398
*                  pDesc can be in either Flash or RAM
399
*                  The purpose of this routine is to have a versatile way to
400
*                  response descriptors request. It allows user to generate
401
*                  certain descriptors with software or read descriptors from
402
*                  external storage part by part.
403
* Input          : - Length - Length of the data in this transfer.
404
*                  - pDesc - A pointer points to descriptor struct.
405
*                  The structure gives the initial address of the descriptor and
406
*                  its original size.
407
* Output         : None.
408
* Return         : Address of a part of the descriptor pointed by the Usb_
409
*                  wOffset The buffer pointed by this address contains at least
410
*                  Length bytes.
1 ingob 411
*******************************************************************************/
412
u8 *Standard_GetDescriptorData(u16 Length, ONE_DESCRIPTOR *pDesc)
413
{
196 killagreg 414
  u32  wOffset;
1 ingob 415
 
196 killagreg 416
  wOffset = pInformation->Ctrl_Info.Usb_wOffset;
417
  if (Length == 0)
418
  {
419
    pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset;
420
    return 0;
421
  }
1 ingob 422
 
196 killagreg 423
  return pDesc->Descriptor + wOffset;
1 ingob 424
}
196 killagreg 425
 
1 ingob 426
/*******************************************************************************
196 killagreg 427
* Function Name  : DataStageOut.
428
* Description    : Data stage of a Control Write Transfer.
429
* Input          : None.
430
* Output         : None.
431
* Return         : None.
1 ingob 432
*******************************************************************************/
433
void DataStageOut(void)
434
{
196 killagreg 435
  ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
436
  u32 save_rLength;
1 ingob 437
 
196 killagreg 438
  save_rLength = pEPinfo->Usb_rLength;
1 ingob 439
 
196 killagreg 440
  if (pEPinfo->CopyData && save_rLength)
441
  {
442
    u8 *Buffer;
443
    u32 Length;
1 ingob 444
 
196 killagreg 445
    Length = pEPinfo->PacketSize;
446
    if (Length > save_rLength)
447
    {
448
      Length = save_rLength;
449
    }
1 ingob 450
 
196 killagreg 451
    Buffer = (*pEPinfo->CopyData)(Length);
452
    pEPinfo->Usb_rLength -= Length;
453
    pEPinfo->Usb_rOffset += Length;
1 ingob 454
 
196 killagreg 455
    PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length);
456
  }
1 ingob 457
 
196 killagreg 458
  if (pEPinfo->Usb_rLength != 0)
459
  {
460
    vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */
461
    SetEPTxCount(ENDP0, 0);
462
    vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */
463
  }
464
  /* Set the next State*/
465
  if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize)
466
  {
467
    pInformation->ControlState = OUT_DATA;
468
  }
469
  else
470
  {
471
    if (pEPinfo->Usb_rLength > 0)
472
    {
473
      pInformation->ControlState = LAST_OUT_DATA;
474
    }
475
    else if (pEPinfo->Usb_rLength == 0)
476
    {
477
      pInformation->ControlState = WAIT_STATUS_IN;
478
      USB_StatusIn();
479
    }
480
  }
481
}
1 ingob 482
 
483
/*******************************************************************************
196 killagreg 484
* Function Name  : DataStageIn.
485
* Description    : Data stage of a Control Read Transfer.
486
* Input          : None.
487
* Output         : None.
488
* Return         : None.
1 ingob 489
*******************************************************************************/
490
void DataStageIn(void)
491
{
196 killagreg 492
  ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
493
  u32 save_wLength = pEPinfo->Usb_wLength;
494
  u32 ControlState = pInformation->ControlState;
1 ingob 495
 
196 killagreg 496
  u8 *DataBuffer;
497
  u32 Length;
1 ingob 498
 
196 killagreg 499
  if ((save_wLength == 0) && (ControlState == LAST_IN_DATA))
500
  {
501
    if(Data_Mul_MaxPacketSize == TRUE)
502
    {
503
      /* No more data to send and empty packet */
504
      Send0LengthData();
505
      ControlState = LAST_IN_DATA;
506
      Data_Mul_MaxPacketSize = FALSE;
507
    }
508
    else
509
    {
510
      /* No more data to send so STALL the TX Status*/
511
      ControlState = WAIT_STATUS_OUT;
512
      vSetEPTxStatus(EP_TX_STALL);
513
    }
514
 
515
    goto Expect_Status_Out;
516
  }
1 ingob 517
 
196 killagreg 518
  Length = pEPinfo->PacketSize;
519
  ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA;
1 ingob 520
 
196 killagreg 521
  if (Length > save_wLength)
522
  {
523
    Length = save_wLength;
524
  }
1 ingob 525
 
196 killagreg 526
  DataBuffer = (*pEPinfo->CopyData)(Length);
1 ingob 527
 
196 killagreg 528
  UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
1 ingob 529
 
196 killagreg 530
  SetEPTxCount(ENDP0, Length);
1 ingob 531
 
196 killagreg 532
  pEPinfo->Usb_wLength -= Length;
533
  pEPinfo->Usb_wOffset += Length;
534
  vSetEPTxStatus(EP_TX_VALID);
1 ingob 535
 
196 killagreg 536
  USB_StatusOut();/* Expect the host to abort the data IN stage */
537
 
1 ingob 538
Expect_Status_Out:
196 killagreg 539
  pInformation->ControlState = ControlState;
1 ingob 540
}
541
/*******************************************************************************
196 killagreg 542
* Function Name  : NoData_Setup0.
543
* Description    : Proceed the processing of setup request without data stage.
544
* Input          : None.
545
* Output         : None.
546
* Return         : None.
1 ingob 547
*******************************************************************************/
548
void NoData_Setup0(void)
549
{
196 killagreg 550
  RESULT Result = USB_UNSUPPORT;
551
  u32 RequestNo = pInformation->USBbRequest;
552
  u32 ControlState;
1 ingob 553
 
196 killagreg 554
  if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
555
  {/* Device Request*/
1 ingob 556
 
196 killagreg 557
    /* SET_CONFIGURATION*/
558
    if (RequestNo == SET_CONFIGURATION)
559
    {
560
      Result = Standard_SetConfiguration();
561
    }
1 ingob 562
 
196 killagreg 563
    /*SET ADDRESS*/
564
    else if (RequestNo == SET_ADDRESS)
565
    {
566
      if (pInformation->USBwValue0 > 127 || pInformation->USBwValue1 != 0
567
          || pInformation->USBwIndex != 0
568
          || pInformation->Current_Configuration != 0)
569
        /* Device Address should be 127 or less -> call Back spec USB 2.0*/
570
      {
571
        ControlState = STALLED;
572
        goto exit_NoData_Setup0;
573
      }
574
      else
575
      {
576
        Result = USB_SUCCESS;
577
      }
578
    }
579
    /*SET FEATURE for Device*/
580
    else if (RequestNo == SET_FEATURE)
581
    {
582
      if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP
583
          && pInformation->USBwIndex == 0
584
          && ValBit(pInformation->Current_Feature, 5))
585
      {
586
        Result = Standard_SetDeviceFeature();
587
      }
588
      else
589
      {
590
        Result = USB_UNSUPPORT;
591
      }
592
    }
593
    /*Clear FEATURE for Device */
594
    else if (RequestNo == CLEAR_FEATURE)
595
    {
596
      if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP
597
          && pInformation->USBwIndex == 0
598
          && ValBit(pInformation->Current_Feature, 5))
599
      {
600
        Result = Standard_ClearFeature();
601
      }
602
      else
603
      {
604
        Result = USB_UNSUPPORT;
605
      }
606
    }
1 ingob 607
 
196 killagreg 608
  }
1 ingob 609
 
196 killagreg 610
  /* Interface Request*/
1 ingob 611
 
196 killagreg 612
  else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
613
  {
1 ingob 614
 
196 killagreg 615
    /*SET INTERFACE*/
616
    if (RequestNo == SET_INTERFACE)
617
    {
618
      Result = Standard_SetInterface();
619
    }
620
  }
1 ingob 621
 
622
 
196 killagreg 623
  /* EndPoint Request*/
1 ingob 624
 
196 killagreg 625
  else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
626
  {
627
    /*CLEAR FEATURE for EndPoint*/
628
    if (RequestNo == CLEAR_FEATURE)
629
    {
630
      Result = Standard_ClearFeature();
631
    }
632
    /* SET FEATURE for EndPoint*/
633
    else if (RequestNo == SET_FEATURE)
634
    {
635
      Result = Standard_SetEndPointFeature();
636
    }
637
  }
638
  else
639
  {
640
    Result = USB_UNSUPPORT;
641
  }
1 ingob 642
 
196 killagreg 643
 
644
  if (Result != USB_SUCCESS)
645
  {
646
    Result = (*pProperty->Class_NoData_Setup)(RequestNo);
647
    if (Result == USB_NOT_READY)
648
    {
649
      ControlState = PAUSE;
650
      goto exit_NoData_Setup0;
651
    }
652
  }
653
 
654
  if (Result != USB_SUCCESS)
655
  {
656
    ControlState = STALLED;
657
    goto exit_NoData_Setup0;
658
  }
659
 
660
  ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */
661
 
662
  USB_StatusIn();
663
 
1 ingob 664
exit_NoData_Setup0:
196 killagreg 665
  pInformation->ControlState = ControlState;
666
  return;
1 ingob 667
}
196 killagreg 668
 
669
 
1 ingob 670
/*******************************************************************************
196 killagreg 671
* Function Name  : Data_Setup0.
672
* Description    : Proceed the processing of setup request with data stage.
673
* Input          : None.
674
* Output         : None.
675
* Return         : None.
1 ingob 676
*******************************************************************************/
677
void Data_Setup0(void)
678
{
196 killagreg 679
  u8 *(*CopyRoutine)(u16);
680
  RESULT Result;
681
  u32 Request_No = pInformation->USBbRequest;
1 ingob 682
 
196 killagreg 683
  u32 Related_Endpoint, Reserved;
684
  u32 wOffset, Status;
1 ingob 685
 
686
 
687
 
196 killagreg 688
  CopyRoutine = NULL;
689
  wOffset = 0;
1 ingob 690
 
196 killagreg 691
  if (Request_No == GET_DESCRIPTOR)
692
  {
693
    if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
694
    {
695
      u8 wValue1 = pInformation->USBwValue1;
696
      if (wValue1 == DEVICE_DESCRIPTOR)
697
      {
698
        CopyRoutine = pProperty->GetDeviceDescriptor;
699
      }
700
      else if (wValue1 == CONFIG_DESCRIPTOR)
701
      {
702
        CopyRoutine = pProperty->GetConfigDescriptor;
703
      }
704
      else if (wValue1 == STRING_DESCRIPTOR)
705
      {
706
        CopyRoutine = pProperty->GetStringDescriptor;
707
      }  /* End of GET_DESCRIPTOR */
708
    }
709
  }
1 ingob 710
 
196 killagreg 711
  /*GET STATUS*/
712
  else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0)
713
           && (pInformation->USBwLength == 0x0002)
714
           && (pInformation->USBwIndex1 == 0))
715
  {
716
    /* GET STATUS for Device*/
717
    if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
718
        && (pInformation->USBwIndex == 0))
719
    {
720
      CopyRoutine = Standard_GetStatus;
721
    }
1 ingob 722
 
196 killagreg 723
    /* GET STATUS for Interface*/
724
    else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
725
    {
726
      if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)
727
          && (pInformation->Current_Configuration != 0))
728
      {
729
        CopyRoutine = Standard_GetStatus;
730
      }
731
    }
1 ingob 732
 
196 killagreg 733
    /* GET STATUS for EndPoint*/
734
    else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
735
    {
736
      Related_Endpoint = (pInformation->USBwIndex0 & 0x0f);
737
      Reserved = pInformation->USBwIndex0 & 0x70;
1 ingob 738
 
196 killagreg 739
      if (ValBit(pInformation->USBwIndex0, 7))
740
      {
741
        /*Get Status of endpoint & stall the request if the related_ENdpoint
742
        is Disabled*/
743
        Status = _GetEPTxStatus(Related_Endpoint);
744
      }
745
      else
746
      {
747
        Status = _GetEPRxStatus(Related_Endpoint);
748
      }
1 ingob 749
 
196 killagreg 750
      if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0)
751
          && (Status != 0))
752
      {
753
        CopyRoutine = Standard_GetStatus;
754
      }
755
    }
1 ingob 756
 
196 killagreg 757
  }
1 ingob 758
 
196 killagreg 759
  /*GET CONFIGURATION*/
760
  else if (Request_No == GET_CONFIGURATION)
761
  {
762
    if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
763
    {
764
      CopyRoutine = Standard_GetConfiguration;
765
    }
766
  }
767
  /*GET INTERFACE*/
768
  else if (Request_No == GET_INTERFACE)
769
  {
770
    if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
771
        && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0)
772
        && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001)
773
        && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS))
774
    {
775
      CopyRoutine = Standard_GetInterface;
776
    }
1 ingob 777
 
196 killagreg 778
  }
779
 
780
  if (CopyRoutine)
781
  {
782
    pInformation->Ctrl_Info.Usb_wOffset = wOffset;
783
    pInformation->Ctrl_Info.CopyData = CopyRoutine;
784
    /* sb in the original the cast to word was directly */
785
    /* now the cast is made step by step */
786
    (*CopyRoutine)(0);
787
    Result = USB_SUCCESS;
788
  }
789
  else
790
  {
791
    Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);
792
    if (Result == USB_NOT_READY)
793
    {
794
      pInformation->ControlState = PAUSE;
795
      return;
796
    }
797
  }
1 ingob 798
 
196 killagreg 799
  if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF)
800
  {
801
    /* Data is not ready, wait it */
802
    pInformation->ControlState = PAUSE;
803
    return;
804
  }
805
  if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0))
806
  {
807
    /* Unsupported request */
808
    pInformation->ControlState = STALLED;
809
    return;
810
  }
1 ingob 811
 
812
 
196 killagreg 813
  if (ValBit(pInformation->USBbmRequestType, 7))
814
  {
815
    /* Device ==> Host */
816
    vu32 wLength = pInformation->USBwLength;
817
 
818
    /* Restrict the data length to be the one host asks */
819
    if (pInformation->Ctrl_Info.Usb_wLength > wLength)
820
    {
821
      pInformation->Ctrl_Info.Usb_wLength = wLength;
822
    }
823
 
824
    else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength)
825
    {
826
      if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize)
827
      {
828
        Data_Mul_MaxPacketSize = FALSE;
829
      }
830
      else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0)
831
      {
832
        Data_Mul_MaxPacketSize = TRUE;
833
      }
834
    }  
1 ingob 835
 
196 killagreg 836
    pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize;
837
    DataStageIn();
838
  }
839
  else
840
  {
841
    pInformation->ControlState = OUT_DATA;
842
    vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */
843
  }
1 ingob 844
 
196 killagreg 845
  return;
846
}
847
 
1 ingob 848
/*******************************************************************************
849
* Function Name  : Setup0_Process
196 killagreg 850
* Description    : Get the device request data and dispatch to individual process.
851
* Input          : None.
852
* Output         : None.
853
* Return         : Post0_Process.
1 ingob 854
*******************************************************************************/
855
u8 Setup0_Process(void)
856
{
857
#ifdef STR7xx /* STR7xx family*/
858
  union {
196 killagreg 859
    u8* b;
860
    u16* w;
861
  } pBuf;
862
  pBuf.b = PMAAddr + (u8 *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */
1 ingob 863
 
196 killagreg 864
  if (pInformation->ControlState != PAUSE)
865
  {
866
    pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
867
    pInformation->USBbRequest  = *pBuf.b++; /* bRequest */
868
    pBuf.w++;  /* word not accessed because of 32 bits addressing */
869
    pInformation->USBwValue  = ByteSwap(*pBuf.w++); /* wValue */
870
    pBuf.w++;  /* word not accessed because of 32 bits addressing */
871
    pInformation->USBwIndex  = ByteSwap(*pBuf.w++); /* wIndex */
872
    pBuf.w++;  /* word not accessed because of 32 bits addressing */
873
    pInformation->USBwLength  = *pBuf.w; /* wLength */
1 ingob 874
  }
875
#endif/* End of STR7xx family*/
196 killagreg 876
 
1 ingob 877
#ifdef STR91x /* STR91x family*/
878
  u16*    pBuf;
879
 
196 killagreg 880
  pBuf = (u16 *)(GetEPRxAddr(ENDP0) + PMAAddr);
1 ingob 881
  if (pInformation->ControlState != PAUSE)
882
  {
196 killagreg 883
    pInformation->USBbmRequestType = (*pBuf) & 0xFF; /* bmRequestType */
884
    pInformation->USBbRequest = ((*pBuf) & 0xFF00) >> 8; /* bRequest */
885
    pInformation->USBwValue = ByteSwap(*(pBuf + 1)); /* wValue */
886
    pInformation->USBwIndex = ByteSwap(*(pBuf + 2)); /* wIndex */
887
    pInformation->USBwLength = *(pBuf + 3);  /* wLength */
1 ingob 888
  }
889
#endif /* End of STR91x family*/
890
  pInformation->ControlState = SETTING_UP;
891
  if (pInformation->USBwLength == 0)
892
  {
893
    /* Setup with no data stage */
894
    NoData_Setup0();
895
  }
896
  else
897
  {
898
    /* Setup with data stage */
899
    Data_Setup0();
900
  }
901
  return Post0_Process();
902
}
196 killagreg 903
 
1 ingob 904
/*******************************************************************************
905
* Function Name  : In0_Process
196 killagreg 906
* Description    : Process the IN token on all default endpoint.
907
* Input          : None.
908
* Output         : None.
909
* Return         : Post0_Process.
1 ingob 910
*******************************************************************************/
911
u8 In0_Process(void)
912
{
196 killagreg 913
  u32 ControlState = pInformation->ControlState;
1 ingob 914
 
196 killagreg 915
  if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
916
  {
917
    DataStageIn();
918
    ControlState = pInformation->ControlState;
919
    /* may be changed outside the function */
920
  }
921
  else if (ControlState == WAIT_STATUS_IN)
922
  {
923
    if (pInformation->USBbRequest == SET_ADDRESS &&
924
        Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT) )
925
    {
926
      SetDeviceAddress(pInformation->USBwValue0);
927
      pUser_Standard_Requests->User_SetDeviceAddress();
928
    }
929
    (*pProperty->Process_Status_IN)();
930
    ControlState = STALLED;
931
  }
932
  else
933
  {
934
    ControlState = STALLED;
935
  }
1 ingob 936
 
196 killagreg 937
  pInformation->ControlState = ControlState;
938
 
939
  return Post0_Process();
1 ingob 940
}
196 killagreg 941
 
1 ingob 942
/*******************************************************************************
943
* Function Name  : Out0_Process
196 killagreg 944
* Description    : Process the OUT token on all default endpoint.
945
* Input          : None.
946
* Output         : None.
947
* Return         : Post0_Process.
1 ingob 948
*******************************************************************************/
949
u8 Out0_Process(void)
950
{
196 killagreg 951
  u32 ControlState = pInformation->ControlState;
1 ingob 952
 
196 killagreg 953
  if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA))
954
  {
955
    DataStageOut();
956
    ControlState = pInformation->ControlState;
957
    /* may be changed outside the function */
958
  }
959
  else if (ControlState == WAIT_STATUS_OUT)
960
  {
961
    (*pProperty->Process_Status_OUT)();
962
    ControlState = STALLED;
963
  }
964
  else if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
965
  {
966
    /* host aborts the transfer before finish */
967
    ControlState = STALLED;
968
  }
969
  /* Unexpect state, STALL the endpoint */
970
  else
971
  {
972
    ControlState = STALLED;
973
  }
1 ingob 974
 
196 killagreg 975
  pInformation->ControlState = ControlState;
1 ingob 976
 
196 killagreg 977
  return Post0_Process();
1 ingob 978
} /* Out0_Process */
979
 
980
/*******************************************************************************
981
* Function Name  : Post0_Process
196 killagreg 982
* Description    : Stall the Endpoint 0 in case of error.
983
* Input          : None.
984
* Output         : None.
985
* Return         : - 0 if the control State is in PAUSE
986
*                  - 1 if not.
1 ingob 987
*******************************************************************************/
988
u8 Post0_Process(void)
989
{
196 killagreg 990
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
1 ingob 991
 
196 killagreg 992
  if (pInformation->ControlState == STALLED)
993
  {
994
    vSetEPRxStatus(EP_RX_STALL);
995
    vSetEPTxStatus(EP_TX_STALL);
996
  }
1 ingob 997
 
196 killagreg 998
  return (pInformation->ControlState == PAUSE);
1 ingob 999
}
196 killagreg 1000
 
1 ingob 1001
/*******************************************************************************
196 killagreg 1002
* Function Name  : SetDeviceAddress.
1003
* Description    : Set the device and all the used Endpoints addresses.
1004
* Input          : - Val: device adress.
1005
* Output         : None.
1006
* Return         : None.
1 ingob 1007
*******************************************************************************/
1008
void SetDeviceAddress(u8 Val)
1009
{
1010
  u32 i;
196 killagreg 1011
  u32 nEP = Device_Table.Total_Endpoint;
1 ingob 1012
 
196 killagreg 1013
  /* set address in every used endpoint */
1014
  for (i = 0; i < nEP; i++)
1015
  {
1016
    _SetEPAddress((u8)i, (u8)i);
1017
  }
1018
  _SetDADDR(Val | DADDR_EF); /* set device address and enable function */
1 ingob 1019
 
1020
}
196 killagreg 1021
 
1 ingob 1022
/*******************************************************************************
1023
* Function Name  : NOP_Process
196 killagreg 1024
* Description    : No operation function.
1025
* Input          : None.
1026
* Output         : None.
1027
* Return         : None.
1 ingob 1028
*******************************************************************************/
1029
void NOP_Process(void)
1030
{
1031
}
196 killagreg 1032
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
1 ingob 1033
 
1034