⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial_driver.c

📁 AT91系列芯片的USB虚拟串口的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    USB_UNICODE('2'),
    USB_UNICODE('3'),
    USB_UNICODE('4'),
    USB_UNICODE('5'),
    USB_UNICODE('6'),
    USB_UNICODE('7'),
    USB_UNICODE('8'),
    USB_UNICODE('9'),
    USB_UNICODE('A'),
    USB_UNICODE('F')
};

//! \brief  List of string descriptors
const char *pStrings[] = {

    (char *) &sLanguageID,
    pManufacturer,
    pProduct,
    pSerialNumber
};

//! \brief List of endpoint descriptors
const S_usb_endpoint_descriptor *pEndpoints[] = {

    &(sConfiguration.sDataOut),
    &(sConfiguration.sDataIn),
    &(sConfiguration.sNotification)
};

//! \brief  Standard descriptors list
const S_std_descriptors sDescriptors = {

    &sDevice,
    (S_usb_configuration_descriptor *) &sConfiguration,
    pStrings,
    pEndpoints
};

//------------------------------------------------------------------------------
//      Internal functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//! \brief  Sets asynchronous line-character formatting properties
//!
//!         This function is used as a callback when receiving the data part
//!         of a SET_LINE_CODING request.
//! \param  pSer         Pointer to a S_ser instance
//! \see    S_ser
//! \see    usbcdc11.pdf - Section 6.2.12
//------------------------------------------------------------------------------
static void ACM_SetLineCoding(const S_ser *pSer)
{
    USB_SendZLP0(pSer->sClass.pUsb, 0, 0);
}

//------------------------------------------------------------------------------
//! \brief  Sends the currently configured line coding to the host
//! \param  pSer               Pointer to a S_ser instance
//! \see    S_ser
//! \see    usbcdc11.pdf - Section 6.2.13
//------------------------------------------------------------------------------
static void ACM_GetLineCoding(const S_ser *pSer)
{
    USB_Write(pSer->sClass.pUsb,
              0,
              (void *) &(pSer->sLineCoding),
              sizeof(S_cdc_line_coding),
              0,
              0);
}

//------------------------------------------------------------------------------
//! \brief  Sets the state of control line parameters.
//! \param  pSer              Pointer to a S_ser instance
//! \param  isActivateCarrier Indicates if the device should activate
//!                           its carrier
//! \param  isDTEPresent      Indicates if the terminal is present
//! \see    S_ser
//! \see    usbcdc11.pdf - Section 6.2.14
//------------------------------------------------------------------------------
static void ACM_SetControlLineState(S_ser *pSer,
                                    bool  isActivateCarrier,
                                    bool  isDTEPresent)
{
    pSer->isCarrierActivated = isActivateCarrier;
    USB_SendZLP0(pSer->sClass.pUsb, 0, 0);
}

//------------------------------------------------------------------------------
//      Exported functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//! \brief  SETUP request handler for an Abstract Control Model device
//! \param  pSer Pointer to a S_ser instance
//! \see    S_ser
//! \see    usbcdc11.pdf - Section 6.2
//------------------------------------------------------------------------------
void SER_RequestHandler(S_ser *pSer)
{
    S_usb_request *pSetup = USB_GetSetup(pSer->sClass.pUsb);

    TRACE_DEBUG_M("NewReq ");

    // Handle the request
    switch (pSetup->bRequest) {

    //-----------------------
    case CDC_SET_LINE_CODING:
    //-----------------------
        TRACE_DEBUG_M("sLineCoding ");

        // Start the read operation with ACM_SetLineCoding as the callback
        USB_Read(pSer->sClass.pUsb,
                 0,
                 (void *) &(pSer->sLineCoding),
                 sizeof(S_cdc_line_coding),
                 (Callback_f) ACM_SetLineCoding,
                 pSer);

        break;

    //-----------------------
    case CDC_GET_LINE_CODING:
    //-----------------------
        TRACE_DEBUG_M("gLineCoding ");
        ACM_GetLineCoding(pSer);

        break;

    //------------------------------
    case CDC_SET_CONTROL_LINE_STATE:
    //------------------------------
        {
            bool isActivateCarrier = false;
            bool isDTEPresent = false;

            TRACE_DEBUG_M("sControlLineState(");

            if (ISSET(pSetup->wValue, CDC_DTE_PRESENT)) {

                isDTEPresent = true;
            }

            if (ISSET(pSetup->wValue, CDC_ACTIVATE_CARRIER)) {

                isActivateCarrier = true;
            }

            TRACE_DEBUG_M("%d,%d) ", isDTEPresent, isActivateCarrier);

            ACM_SetControlLineState(pSer, isActivateCarrier, isDTEPresent);
        }
        break;

    //------
    default:
    //------
        // Forward request to standard request handler
        STD_RequestHandler((S_std_class *) pSer);

        break;
    }
}

//------------------------------------------------------------------------------
//! \brief  Initializes a CDC serial driver
//!
//!         This method sets the standard descriptors of the device and the
//!         default CDC configuration.
//! \param  pSer Pointer to a S_ser instance
//! \param  pUsb Pointer to the S_usb driver instance to use
//! \see    S_ser
//! \see    S_usb
//------------------------------------------------------------------------------
void SER_Init(S_ser *pSer, const S_usb *pUsb)
{
    // Initialize standard class attributes
    pSer->sClass.pUsb = pUsb;
    pSer->sClass.pDescriptors = &sDescriptors;

    // Initialize ACM attributes
    // Line coding
    pSer->sLineCoding.dwDTERate = 0;
    pSer->sLineCoding.bCharFormat = 0;
    pSer->sLineCoding.bParityType = 0;
    pSer->sLineCoding.bDataBits = 0;

    // Carrier
    pSer->isCarrierActivated = false;

    // Initialize the USB driver
    USB_Init(pUsb);
}

//------------------------------------------------------------------------------
//! \brief  Reads data from the Data OUT endpoint
//! \param  pSer      Pointer to a S_ser instance
//! \param  pBuffer   Buffer in which to store the received data
//! \param  dLength   Length of data buffer
//! \param  fCallback Optional callback function
//! \param  pArgument Optional parameter for the callback function
//! \return SER_STATUS_SUCCESS if transfer has started successfully;
//!         SER_STATUS_LOCKED if endpoint is currently in use;
//!         SER_STATUS_ERROR if transfer cannot be started.
//------------------------------------------------------------------------------
unsigned char SER_Read(S_ser *pSer,
                       void *pBuffer,
                       unsigned int dLength,
                       Callback_f fCallback,
                       void *pArgument)
{
    return USB_Read(pSer->sClass.pUsb, SER_EPT_DATA_OUT, pBuffer,
                    dLength, fCallback, pArgument);
}

//------------------------------------------------------------------------------
//! \brief  Sends data through the Data IN endpoint
//! \param  pSer      Pointer to a S_ser instance
//! \param  pBuffer   Buffer holding the data to transmit
//! \param  dLength   Length of data buffer
//! \param  fCallback Optional callback function
//! \param  pArgument Optional parameter for the callback function
//! \return SER_STATUS_SUCCESS if transfer has started successfully;
//!         SER_STATUS_LOCKED if endpoint is currently in use;
//!         SER_STATUS_ERROR if transfer cannot be started.
//------------------------------------------------------------------------------
unsigned char SER_Write(S_ser *pSer,
                        void *pBuffer,
                        unsigned int dLength,
                        Callback_f fCallback,
                        void *pArgument)
{
    return USB_Write(pSer->sClass.pUsb, SER_EPT_DATA_IN, pBuffer,
                     dLength, fCallback, pArgument);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -