mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-19 06:48:34 +03:00
Renamed main folder to firmware
This commit is contained in:
@@ -0,0 +1,455 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**\file
|
||||
* Implementation of the CDCDSerialPort class methods.
|
||||
*/
|
||||
|
||||
/** \addtogroup usbd_cdc
|
||||
*@{
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Headers
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#include <CDCDSerialPort.h>
|
||||
#include <CDCDescriptors.h>
|
||||
#include <USBLib_Trace.h>
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Types
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/** Parse data extention for descriptor parsing */
|
||||
typedef struct _CDCDParseData {
|
||||
/** Pointer to CDCDSerialPort instance */
|
||||
CDCDSerialPort * pCdcd;
|
||||
/** Pointer to found interface descriptor */
|
||||
USBInterfaceDescriptor * pIfDesc;
|
||||
|
||||
} CDCDParseData;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Internal variables
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/** Line coding values */
|
||||
static CDCLineCoding lineCoding;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Internal functions
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Parse descriptors: Interface, Bulk IN/OUT, Interrupt IN.
|
||||
* \param desc Pointer to descriptor list.
|
||||
* \param arg Argument, pointer to AUDDParseData instance.
|
||||
*/
|
||||
static uint32_t _Interfaces_Parse(USBGenericDescriptor *pDesc,
|
||||
CDCDParseData * pArg)
|
||||
{
|
||||
CDCDSerialPort *pCdcd = pArg->pCdcd;
|
||||
|
||||
/* Not a valid descriptor */
|
||||
if (pDesc->bLength == 0)
|
||||
return USBRC_PARAM_ERR;
|
||||
|
||||
/* Find interface descriptor */
|
||||
if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
|
||||
USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor*)pDesc;
|
||||
|
||||
/* Obtain interface from descriptor */
|
||||
if (pCdcd->bInterfaceNdx == 0xFF) {
|
||||
/* First interface is communication */
|
||||
if (pIf->bInterfaceClass ==
|
||||
CDCCommunicationInterfaceDescriptor_CLASS) {
|
||||
pCdcd->bInterfaceNdx = pIf->bInterfaceNumber;
|
||||
pCdcd->bNumInterface = 2;
|
||||
}
|
||||
/* Only data interface */
|
||||
else if(pIf->bInterfaceClass == CDCDataInterfaceDescriptor_CLASS) {
|
||||
pCdcd->bInterfaceNdx = pIf->bInterfaceNumber;
|
||||
pCdcd->bNumInterface = 1;
|
||||
}
|
||||
pArg->pIfDesc = pIf;
|
||||
}
|
||||
else if (pCdcd->bInterfaceNdx <= pIf->bInterfaceNumber
|
||||
&& pCdcd->bInterfaceNdx + pCdcd->bNumInterface
|
||||
> pIf->bInterfaceNumber) {
|
||||
pArg->pIfDesc = pIf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse valid interfaces */
|
||||
if (pArg->pIfDesc == 0)
|
||||
return 0;
|
||||
|
||||
/* Find endpoint descriptors */
|
||||
if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT) {
|
||||
USBEndpointDescriptor *pEp = (USBEndpointDescriptor*)pDesc;
|
||||
switch(pEp->bmAttributes & 0x3) {
|
||||
case USBEndpointDescriptor_INTERRUPT:
|
||||
if (pEp->bEndpointAddress & 0x80)
|
||||
pCdcd->bIntInPIPE = pEp->bEndpointAddress & 0x7F;
|
||||
break;
|
||||
case USBEndpointDescriptor_BULK:
|
||||
if (pEp->bEndpointAddress & 0x80)
|
||||
pCdcd->bBulkInPIPE = pEp->bEndpointAddress & 0x7F;
|
||||
else
|
||||
pCdcd->bBulkOutPIPE = pEp->bEndpointAddress;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pCdcd->bInterfaceNdx != 0xFF
|
||||
&& pCdcd->bBulkInPIPE != 0
|
||||
&& pCdcd->bBulkOutPIPE != 0)
|
||||
return USBRC_FINISHED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function which should be invoked after the data of a
|
||||
* SetLineCoding request has been retrieved. Sends a zero-length packet
|
||||
* to the host for acknowledging the request.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
*/
|
||||
static void _SetLineCodingCallback(CDCDSerialPort * pCdcd)
|
||||
{
|
||||
uint32_t exec = 1;
|
||||
if (pCdcd->fEventHandler) {
|
||||
uint32_t rc = pCdcd->fEventHandler(
|
||||
CDCDSerialPortEvent_SETLINECODING,
|
||||
(uint32_t)(&lineCoding),
|
||||
pCdcd->pArg);
|
||||
if (rc == USBD_STATUS_SUCCESS) {
|
||||
pCdcd->lineCoding.dwDTERate = lineCoding.dwDTERate;
|
||||
pCdcd->lineCoding.bCharFormat = lineCoding.bCharFormat;
|
||||
pCdcd->lineCoding.bParityType = lineCoding.bParityType;
|
||||
pCdcd->lineCoding.bDataBits = lineCoding.bDataBits;
|
||||
}
|
||||
else
|
||||
exec = 0;
|
||||
}
|
||||
if (exec) USBD_Write(0, 0, 0, 0, 0);
|
||||
else USBD_Stall(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives new line coding information from the USB host.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
*/
|
||||
static void _SetLineCoding(CDCDSerialPort * pCdcd)
|
||||
{
|
||||
TRACE_INFO_WP("sLineCoding ");
|
||||
|
||||
USBD_Read(0,
|
||||
(void *) & (lineCoding),
|
||||
sizeof(CDCLineCoding),
|
||||
(TransferCallback)_SetLineCodingCallback,
|
||||
(void*)pCdcd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the current line coding information to the host through Control
|
||||
* endpoint 0.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
*/
|
||||
static void _GetLineCoding(CDCDSerialPort * pCdcd)
|
||||
{
|
||||
TRACE_INFO_WP("gLineCoding ");
|
||||
|
||||
USBD_Write(0,
|
||||
(void *) &(pCdcd->lineCoding),
|
||||
sizeof(CDCLineCoding),
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the state of the serial driver according to the information
|
||||
* sent by the host via a SetControlLineState request, and acknowledges
|
||||
* the request with a zero-length packet.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
* \param request Pointer to a USBGenericRequest instance.
|
||||
*/
|
||||
static void _SetControlLineState(
|
||||
CDCDSerialPort * pCdcd,
|
||||
const USBGenericRequest *request)
|
||||
{
|
||||
uint8_t DTR, RTS;
|
||||
|
||||
DTR = ((request->wValue & CDCControlLineState_DTR) > 0);
|
||||
RTS = ((request->wValue & CDCControlLineState_RTS) > 0);
|
||||
TRACE_INFO_WP("sControlLineState(%d, %d) ", DTR, RTS);
|
||||
|
||||
pCdcd->bControlLineState = (uint8_t)request->wValue;
|
||||
USBD_Write(0, 0, 0, 0, 0);
|
||||
|
||||
if (pCdcd->fEventHandler)
|
||||
pCdcd->fEventHandler(CDCDSerialPortEvent_SETCONTROLLINESTATE,
|
||||
|
||||
(uint32_t)pCdcd->bControlLineState,
|
||||
pCdcd->pArg);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Initializes the USB Device CDC serial port function.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
* \param pUsbd Pointer to USBDDriver instance.
|
||||
* \param fEventHandler Pointer to event handler function.
|
||||
* \param firstInterface First interface index for the function
|
||||
* (0xFF to parse from descriptors).
|
||||
* \param numInterface Number of interfaces for the function.
|
||||
*/
|
||||
void CDCDSerialPort_Initialize(CDCDSerialPort * pCdcd,
|
||||
USBDDriver * pUsbd,
|
||||
CDCDSerialPortEventHandler fEventHandler,
|
||||
void * pArg,
|
||||
uint8_t firstInterface,uint8_t numInterface)
|
||||
{
|
||||
TRACE_INFO("CDCDSerialPort_Initialize\n\r");
|
||||
|
||||
/* Initialize event handler */
|
||||
pCdcd->fEventHandler = fEventHandler;
|
||||
pCdcd->pArg = pArg;
|
||||
|
||||
/* Initialize USB Device Driver interface */
|
||||
pCdcd->pUsbd = pUsbd;
|
||||
pCdcd->bInterfaceNdx = firstInterface;
|
||||
pCdcd->bNumInterface = numInterface;
|
||||
pCdcd->bIntInPIPE = 0;
|
||||
pCdcd->bBulkInPIPE = 0;
|
||||
pCdcd->bBulkOutPIPE = 0;
|
||||
|
||||
/* Initialize Abstract Control Model attributes */
|
||||
pCdcd->bControlLineState = 0;
|
||||
pCdcd->wSerialState = 0;
|
||||
CDCLineCoding_Initialize(&(pCdcd->lineCoding),
|
||||
115200,
|
||||
CDCLineCoding_ONESTOPBIT,
|
||||
CDCLineCoding_NOPARITY,
|
||||
8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CDC Serial Port information for CDCDSerialPort instance.
|
||||
* Accepted interfaces:
|
||||
* - Communication Interface + Data Interface
|
||||
* - Data Interface ONLY
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
* \param pDescriptors Pointer to descriptor list.
|
||||
* \param dwLength Descriptor list size in bytes.
|
||||
*/
|
||||
USBGenericDescriptor *CDCDSerialPort_ParseInterfaces(
|
||||
CDCDSerialPort *pCdcd,
|
||||
USBGenericDescriptor *pDescriptors,
|
||||
uint32_t dwLength)
|
||||
{
|
||||
CDCDParseData parseData;
|
||||
|
||||
parseData.pCdcd = pCdcd;
|
||||
parseData.pIfDesc = 0;
|
||||
|
||||
return USBGenericDescriptor_Parse(
|
||||
pDescriptors, dwLength,
|
||||
(USBDescriptorParseFunction)_Interfaces_Parse,
|
||||
&parseData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles CDC-specific SETUP requests. Should be called from a
|
||||
* re-implementation of USBDCallbacks_RequestReceived() method.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
* \param request Pointer to a USBGenericRequest instance.
|
||||
* \return USBRC_SUCCESS if request handled, otherwise error.
|
||||
*/
|
||||
uint32_t CDCDSerialPort_RequestHandler(
|
||||
CDCDSerialPort *pCdcd,
|
||||
const USBGenericRequest *request)
|
||||
{
|
||||
if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS)
|
||||
return USBRC_PARAM_ERR;
|
||||
|
||||
TRACE_INFO_WP("Cdcs ");
|
||||
|
||||
/* Validate interface */
|
||||
if (request->wIndex >= pCdcd->bInterfaceNdx &&
|
||||
request->wIndex < pCdcd->bInterfaceNdx + pCdcd->bNumInterface) {
|
||||
}
|
||||
else {
|
||||
return USBRC_PARAM_ERR;
|
||||
}
|
||||
|
||||
/* Handle the request */
|
||||
switch (USBGenericRequest_GetRequest(request)) {
|
||||
|
||||
case CDCGenericRequest_SETLINECODING:
|
||||
|
||||
_SetLineCoding(pCdcd);
|
||||
break;
|
||||
|
||||
case CDCGenericRequest_GETLINECODING:
|
||||
|
||||
_GetLineCoding(pCdcd);
|
||||
break;
|
||||
|
||||
case CDCGenericRequest_SETCONTROLLINESTATE:
|
||||
|
||||
_SetControlLineState(pCdcd, request);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return USBRC_PARAM_ERR;
|
||||
}
|
||||
|
||||
return USBRC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives data from the host through the virtual COM port created by
|
||||
* the CDC device serial driver. This function behaves like USBD_Read.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
* \param pData Pointer to the data buffer to put received data.
|
||||
* \param dwSize Size of the data buffer in bytes.
|
||||
* \param fCallback Optional callback function to invoke when the transfer
|
||||
* finishes.
|
||||
* \param pArg Optional argument to the callback function.
|
||||
* \return USBD_STATUS_SUCCESS if the read operation has been started normally;
|
||||
* otherwise, the corresponding error code.
|
||||
*/
|
||||
uint32_t CDCDSerialPort_Read(const CDCDSerialPort * pCdcd,
|
||||
void * pData,uint32_t dwSize,
|
||||
TransferCallback fCallback,void * pArg)
|
||||
{
|
||||
if (pCdcd->bBulkOutPIPE == 0)
|
||||
return USBRC_PARAM_ERR;
|
||||
|
||||
return USBD_Read(pCdcd->bBulkOutPIPE,
|
||||
pData, dwSize,
|
||||
fCallback, pArg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a data buffer through the virtual COM port created by the CDC
|
||||
* device serial driver. This function behaves exactly like USBD_Write.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
* \param pData Pointer to the data buffer to send.
|
||||
* \param dwSize Size of the data buffer in bytes.
|
||||
* \param fCallback Optional callback function to invoke when the transfer
|
||||
* finishes.
|
||||
* \param pArg Optional argument to the callback function.
|
||||
* \return USBD_STATUS_SUCCESS if the read operation has been started normally;
|
||||
* otherwise, the corresponding error code.
|
||||
*/
|
||||
uint32_t CDCDSerialPort_Write(const CDCDSerialPort * pCdcd,
|
||||
void * pData, uint32_t dwSize,
|
||||
TransferCallback fCallback, void * pArg)
|
||||
{
|
||||
if (pCdcd->bBulkInPIPE == 0)
|
||||
return USBRC_PARAM_ERR;
|
||||
|
||||
return USBD_Write(pCdcd->bBulkInPIPE,
|
||||
pData, dwSize,
|
||||
fCallback, pArg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current control line state of the RS-232 line.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
*/
|
||||
uint8_t CDCDSerialPort_GetControlLineState(const CDCDSerialPort * pCdcd)
|
||||
{
|
||||
return pCdcd->bControlLineState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy current line coding settings to pointered space.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
* \param pLineCoding Pointer to CDCLineCoding instance.
|
||||
*/
|
||||
void CDCDSerialPort_GetLineCoding(const CDCDSerialPort * pCdcd,
|
||||
CDCLineCoding* pLineCoding)
|
||||
{
|
||||
if (pLineCoding) {
|
||||
pLineCoding->dwDTERate = pCdcd->lineCoding.dwDTERate;
|
||||
pLineCoding->bCharFormat = pCdcd->lineCoding.bCharFormat;
|
||||
pLineCoding->bParityType = pCdcd->lineCoding.bParityType;
|
||||
pLineCoding->bDataBits = pCdcd->lineCoding.bDataBits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current status of the RS-232 line.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
*/
|
||||
uint16_t CDCDSerialPort_GetSerialState(const CDCDSerialPort * pCdcd)
|
||||
{
|
||||
return pCdcd->wSerialState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current serial state of the device to the given value.
|
||||
* \param pCdcd Pointer to CDCDSerialPort instance.
|
||||
* \param wSerialState New device state.
|
||||
*/
|
||||
void CDCDSerialPort_SetSerialState(CDCDSerialPort * pCdcd,
|
||||
uint16_t wSerialState)
|
||||
{
|
||||
if (pCdcd->bIntInPIPE == 0)
|
||||
return;
|
||||
|
||||
/* If new state is different from previous one, send a notification to the
|
||||
host */
|
||||
if (pCdcd->wSerialState != wSerialState) {
|
||||
|
||||
pCdcd->wSerialState = wSerialState;
|
||||
USBD_Write(pCdcd->bIntInPIPE,
|
||||
&(pCdcd->wSerialState),
|
||||
2,
|
||||
0,
|
||||
0);
|
||||
|
||||
/* Reset one-time flags */
|
||||
pCdcd->wSerialState &= ~(CDCSerialState_OVERRUN
|
||||
| CDCSerialState_PARITY
|
||||
| CDCSerialState_FRAMING
|
||||
| CDCSerialState_RINGSIGNAL
|
||||
| CDCSerialState_BREAK);
|
||||
}
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
Reference in New Issue
Block a user