📄 parser.c
字号:
/*----------------------------------------------------------------------------
* Copyright (c) 200 by National Semiconductor Corporation
* National Semiconductor Corporation
*
* All rights reserved
*
*<<<-------------------------------------------------------------------------
* File Contents:
* parser.c
*
* Project: USB Demo firmware
* Author : Yan Nosovitsky
* Date : Oct 2001
*----------------------------------------------------------------------->>>*/
#define parser_c
#include "..\include\all.h"
#include "..\usb\usb.h"
#include <string.h>
#include <stdlib.h>
#include "command_api.h"
#include "parser.h"
#ifdef TMON
byte buffer[1024];
#else
byte buffer[2*1024];
#endif
byte *readPtr = buffer;
byte *writePtr = buffer;
State bulkState ;
State isoState ;
InterruptState interruptState;
byte feedback[8];
volatile unsigned int local_event_table = 0;
extern Device_buffers_t device_buffers;
extern const int usbn9604_rx_endpoint_addr[];
extern const int usbn9604_tx_endpoint_addr[];
extern endpoint_status_t *endpoint_stat[];
__inline__ void BulkTransmitEvent();
__inline__ void BulkReceiveEvent();
__inline__ void IsoTransmitEvent();
__inline__ void IsoReceiveEvent();
__inline__ void TimerEvent();
__inline__ void USB_write_data (int data_size, byte data, endpoint_t ep_num);
__inline__ int USB_read_compare(byte data_size, byte data, endpoint_t ep_num);
__inline__ void USB_fast_read(byte data_size, byte* data_ptr, endpoint_t ep_num);
void pingPong();
#define clear_local_event(X) { \
_di_(); \
local_event_table &= ~X; \
_ei_(); \
}
#define EVT_PING_PONG 0x20
void event_wait(void)
{
_di();
while (event_table == 0)
__asm__("eiwait");
_ei();
}
/*----------------------------------------------------------------------------------------------
* Prototype
* int main()
*
* Parameters
* None
*
* Returns
* Success
*
* Description
* Polls on the event table (event_table) and perform appropriate request.
----------------------------------------------------------------------------------------------*/
int main()
{
/* UART init */
UART_init();
UART_config(DATA_BITS_8, ODD_PARITY, FALSE, STOP_BITS_1, UART_19200);
ICU_unmask_int(16);
while(TRUE)
{
event_wait();
local_event_table |= event_table;
/* -------------------------------------------------------------
* Check whether new isochronous packet received from the host
* --------------------------------------------------------------*/
if (local_event_table & EVT_USB_ISO_RX)
{
IsoReceiveEvent();
if (local_event_table == 0)
continue;
}
/* -------------------------------------------------------------
* Check whether the host is ready to get next isochronous packet
* --------------------------------------------------------------*/
if (local_event_table & EVT_USB_ISO_TX)
{
IsoTransmitEvent();
if (local_event_table == 0)
continue;
}
/* -------------------------------------------------------------
* Check whether new bulk packet received from the host
* --------------------------------------------------------------*/
if (local_event_table & EVT_USB_BULK_RX)
{
BulkReceiveEvent();
if (local_event_table == 0)
continue;
}
/* -------------------------------------------------------------
* Check whether the host is ready to get next bulk packet
* --------------------------------------------------------------*/
if (local_event_table & EVT_USB_BULK_TX)
{
BulkTransmitEvent();
if (local_event_table == 0)
continue;
}
/*---------------------------------
* Should interrupt packet be sent?
*---------------------------------*/
if (local_event_table&EVT_TIMER_INT)
TimerEvent();
if (local_event_table & EVT_PING_PONG)
pingPong();
}
return 1;
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void Bulk_Parser(USB_request_t *req)
*
* Parameters
* req - pointer to structure representing host request
*
* Returns
* none
*
* Description
* Parses an imcoming bulk command
----------------------------------------------------------------------------------------------*/
void Bulk_Parser(USB_request_t *req)
{
byte command;
/*-----------------------------------------------------------------------------------
* Read the command, parse it and update relevant fields in the bulk state structure.
*----------------------------------------------------------------------------------*/
command = REQ_VENDOR(req);
bulkState.command.bulkCommand = command;
bulkState.dataSize = ((dword)(REQ_VALUE(req).lsw)|(((dword)(REQ_INDEX(req).msw)) << 16));
bulkState.numOfErrors = 0;
switch (command)
{
case BULK_SEND_IMM_BACK:
bulkState.restToRead = bulkState.dataSize;
bulkState.restToWrite = bulkState.dataSize;
/* It's seems that USB driver don't need zero length packet */
bulkState.zeroPacketNeed = 0 /*!(bulkState.dataSize%TX_BULK_EP_FIFO_SIZE) */;
bulkState.bufferForGetData = 0;
bulkState.bufferForSendData = 0;
bulkState.locBuff[0].getReady = TRUE;
bulkState.locBuff[1].getReady = TRUE;
bulkState.locBuff[0].sendReady = FALSE;
bulkState.locBuff[1].sendReady = FALSE;
bulkState.locBuff[0].nextBuf = 1;
bulkState.locBuff[1].nextBuf = 0;
DISABLE_TX(ENDPOINT_1);
ENABLE_EP(ENDPOINT_2);
ENABLE_RX_INTS(RX_FIFO1);
send_event(EVT_USB_BULK_TX);
break;
case BULK_SEND_AFTER_LAST_BACK:
bulkState.restToRead = bulkState.dataSize;
bulkState.restToWrite = bulkState.dataSize;
/* It's seems that USB driver don't need zero length packet */
bulkState.zeroPacketNeed = 0 /*!(bulkState.dataSize%TX_BULK_EP_FIFO_SIZE) */;
DISABLE_TX(ENDPOINT_1);
ENABLE_EP(ENDPOINT_2);
ENABLE_RX_INTS(RX_FIFO1);
break;
case BULK_GET_DATA:
bulkState.restToRead = bulkState.dataSize;
bulkState.data = (REQ_LENGTH(req)&0x00ff);
/*------------------------------------------
* enable endpoint 6 for ping-pong transfer
*-----------------------------------------*/
write_usb(EPC_ADDR(ENDPOINT_6), (byte)ENDPOINT_2 | EP_EN) ;
ENABLE_RX(ENDPOINT_6);
if (endpoint_stat[ENDPOINT_2]->toggle_bit)
/*------------------------------------------
* next packet is data1 (toggle bit is 1).
* First packet must enter to the endpoint 6
*-----------------------------------------*/
DISABLE_EP(ENDPOINT_2);
else
/*------------------------------------------
* next packet is data0 (toggle bit is 1).
* First packet must enter to the endpoint 2
*-----------------------------------------*/
ENABLE_EP(ENDPOINT_2);
/*-----------------------------------
* Disable interrupte
* This test will work in polling mode
*-----------------------------------*/
DISABLE_RX_INTS(RX_FIFO1|RX_FIFO3);
send_event(EVT_PING_PONG);
/* DMA init
DISABLE_RX_INTS(RX_FIFO1);
USB_init_dma(ENDPOINT_2);
USB_start_dma(9); */
break;
case BULK_SEND_DATA:
bulkState.restToWrite = bulkState.dataSize;
bulkState.data = (REQ_LENGTH(req)&0x00ff);
/* It's seems that USB driver don't need zero length packet */
bulkState.zeroPacketNeed = 0 /*!(bulkState.dataSize%TX_BULK_EP_FIFO_SIZE) */;
DISABLE_TX(ENDPOINT_1);
send_event(EVT_USB_BULK_TX);
/* DMA init
DISABLE_TX_INTS(TX_FIFO1);
USB_init_dma(ENDPOINT_1);
USB_start_dma(9); */
break;
default :
break;
}
zero_length_data_response(ENDPOINT_0);
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void Iso_Parser(USB_request_t *req)
*
* Parameters
* req - pointer to structure representing host request
*
* Returns
* none
*
* Description
* Parses an imcoming isochronous command
----------------------------------------------------------------------------------------------*/
void Iso_Parser(USB_request_t *req)
{
byte command;
int i;
/*-------------------------------------------------------------------------------------------
* Read the command, parse it and update relevant fields in the isochronous state structure.
*------------------------------------------------------------------------------------------*/
command = REQ_VENDOR(req);
isoState.command.isoCommand = command;
isoState.dataSize = ((dword)(REQ_VALUE(req).lsw)|(((dword)(REQ_INDEX(req).msw)) << 16));
isoState.numOfErrors = 0;
switch (command)
{
case ISOCH_SEND_IMM_BACK:
isoState.restToRead = isoState.dataSize;
isoState.restToWrite = isoState.dataSize;
isoState.zeroPacketNeed = 0/*!(isoState.dataSize%TX_ISO_EP_FIFO_SIZE)*/;
isoState.bufferForGetData = 0;
isoState.bufferForSendData = 0;
for (i = 0; i < 4 ; i++)
{
isoState.locBuff[i].getReady = TRUE;
isoState.locBuff[i].sendReady = FALSE;
isoState.locBuff[i].nextBuf = (i==3)? 0 : i+1;
}
DISABLE_TX(ENDPOINT_3);
send_event(EVT_USB_ISO_TX);
break;
case ISOCH_GET_DATA:
isoState.restToRead = isoState.dataSize;
isoState.data = (REQ_LENGTH(req)&0x00ff);
/* DMA init
DISABLE_RX_INTS(RX_FIFO2);
USB_init_dma(ENDPOINT_4);
USB_start_dma(9); */
break;
case ISOCH_SEND_DATA:
isoState.restToWrite = isoState.dataSize;
isoState.data = (REQ_LENGTH(req)&0x00ff);
isoState.zeroPacketNeed = 0 /* !(isoState.dataSize%TX_ISO_EP_FIFO_SIZE)*/;
DISABLE_TX(ENDPOINT_3);
send_event(EVT_USB_ISO_TX);
/* DMA init
DISABLE_TX_INTS(TX_FIFO2);
USB_init_dma(ENDPOINT_3);
USB_start_dma(9); */
break;
default :
break;
}
zero_length_data_response(ENDPOINT_0);
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void Interrupt_Parser(USB_request_t *req)
*
* Parameters
* req - pointer to structure representing host request
*
* Returns
* None
*
* Description
* Parses an imcoming interrupt command
----------------------------------------------------------------------------------------------*/
void Interrupt_Parser(USB_request_t *req)
{
byte command;
/*-----------------------------------------------------------------------------------
* Read the command, parse it and update relevant fields in the interrupt state structure.
*----------------------------------------------------------------------------------*/
command = REQ_VENDOR(req);
interruptState.interruptCommand = command;
switch( command )
{
case INTERRUPT_GET_INT:
interruptState.interruptNum = (word) REQ_VALUE(req).lsw;
interruptState.interval = (word)REQ_INDEX(req).msw;
interruptState.restToSend = interruptState.interruptNum;
/*----------------------------------------------------
* Initialize and start timer for interrupts generation
* using interval determined by the host
*----------------------------------------------------*/
FLUSH_TXEP(ENDPOINT_5);
TOUCH_WATCHDOG(interruptState.interval);
WATCHDOG_START;
break;
default :
break;
}
zero_length_data_response(ENDPOINT_0);
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void Gen_Parser(USB_request_t *req)
*
* Parameters
* req - pointer to structure representing host request
*
* Returns
* None
*
* Description
* Parses an imcoming general command
----------------------------------------------------------------------------------------------*/
void Gen_Parser(USB_request_t *req)
{
byte command;
byte regAddress;
byte regVal;
command = REQ_VENDOR(req);
switch (command)
{
case GET_BULK_FEEDBACK:
if (bulkState.command.bulkCommand == BULK_GET_DATA)
{
/*----------------------------------------------
* number of bytes received in the last request
-----------------------------------------------*/
*((dword *)&feedback[0]) = bulkState.dataSize - bulkState.restToRead ;
*((dword *)&feedback[4]) = bulkState.numOfErrors;
device_buffers.zero_data=1;
send_control_data(feedback,8);
}
break;
case GET_ISO_FEEDBACK:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -