void SerialDevice::SetModes(struct termios *tios) { TRACE_FUNCRES(trace_termios, tios); uint8 baud = tios->c_cflag & CBAUD; int32 speed = baud_index_to_speed(baud); if (speed < 0) { baud = B19200; speed = 19200; } // update our master config in full memcpy(&fTTYConfig, tios, sizeof(termios)); fTTYConfig.c_cflag &= ~CBAUD; fTTYConfig.c_cflag |= baud; // only apply the relevant parts to the device side termios config; memset(&config, 0, sizeof(termios)); config.c_cflag = tios->c_cflag; config.c_cflag &= ~CBAUD; config.c_cflag |= baud; // update the termios of the device side gTTYModule->tty_control(fDeviceTTYCookie, TCSETA, &config, sizeof(termios)); usb_cdc_line_coding lineCoding; lineCoding.speed = speed; lineCoding.stopbits = (tios->c_cflag & CSTOPB) ? USB_CDC_LINE_CODING_2_STOPBITS : USB_CDC_LINE_CODING_1_STOPBIT; if (tios->c_cflag & PARENB) { lineCoding.parity = USB_CDC_LINE_CODING_EVEN_PARITY; if (tios->c_cflag & PARODD) lineCoding.parity = USB_CDC_LINE_CODING_ODD_PARITY; } else lineCoding.parity = USB_CDC_LINE_CODING_NO_PARITY; lineCoding.databits = (tios->c_cflag & CS8) ? 8 : 7; if (memcmp(&lineCoding, &fLineCoding, sizeof(usb_cdc_line_coding)) != 0) { fLineCoding.speed = lineCoding.speed; fLineCoding.stopbits = lineCoding.stopbits; fLineCoding.databits = lineCoding.databits; fLineCoding.parity = lineCoding.parity; TRACE("send to modem: speed %d sb: 0x%08x db: 0x%08x parity: 0x%08x\n", fLineCoding.speed, fLineCoding.stopbits, fLineCoding.databits, fLineCoding.parity); SetLineCoding(&fLineCoding); } }
//***************************************************************************** // // Handles CDC driver notifications related to control and setup of the device. // // \param pvCBData is the client-supplied callback pointer for this channel. // \param ui32Event identifies the event we are being notified about. // \param ui32MsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to perform control-related // operations on behalf of the USB host. These functions include setting // and querying the serial communication parameters, setting handshake line // states and sending break conditions. // // \return The return value is event-specific. // //***************************************************************************** uint32_t ControlHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData) { uint32_t ui32IntsOff; // // Which event are we being asked to process? // switch(ui32Event) { // // We are connected to a host and communication is now possible. // case USB_EVENT_CONNECTED: g_bUSBConfigured = true; // // Flush our buffers. // USBBufferFlush(&g_sTxBuffer); USBBufferFlush(&g_sRxBuffer); // // Tell the main loop to update the display. // ui32IntsOff = ROM_IntMasterDisable(); g_pcStatus = "Connected"; g_ui32Flags |= COMMAND_STATUS_UPDATE; if(!ui32IntsOff) { ROM_IntMasterEnable(); } break; // // The host has disconnected. // case USB_EVENT_DISCONNECTED: g_bUSBConfigured = false; ui32IntsOff = ROM_IntMasterDisable(); g_pcStatus = "Disconnected"; g_ui32Flags |= COMMAND_STATUS_UPDATE; if(!ui32IntsOff) { ROM_IntMasterEnable(); } break; // // Return the current serial communication parameters. // case USBD_CDC_EVENT_GET_LINE_CODING: GetLineCoding(pvMsgData); break; // // Set the current serial communication parameters. // case USBD_CDC_EVENT_SET_LINE_CODING: SetLineCoding(pvMsgData); break; // // Set the current serial communication parameters. // case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE: SetControlLineState((uint16_t)ui32MsgValue); break; // // Send a break condition on the serial line. // case USBD_CDC_EVENT_SEND_BREAK: SendBreak(true); break; // // Clear the break condition on the serial line. // case USBD_CDC_EVENT_CLEAR_BREAK: SendBreak(false); break; // // Ignore SUSPEND and RESUME for now. // case USB_EVENT_SUSPEND: case USB_EVENT_RESUME: break; // // We don't expect to receive any other events. Ignore any that show // up in a release build or hang in a debug build. // default: #ifdef DEBUG while(1); #else break; #endif } return(0); }
/** * @brief USBH_CDC_Process * The function is for managing state machine for CDC data transfers * @param phost: Host handle * @retval USBH Status */ static USBH_StatusTypeDef USBH_CDC_Process (USBH_HandleTypeDef *phost) { USBH_StatusTypeDef status = USBH_BUSY; USBH_StatusTypeDef req_status = USBH_OK; CDC_HandleTypeDef *CDC_Handle = (CDC_HandleTypeDef*) phost->pActiveClass->pData; switch(CDC_Handle->state) { case CDC_IDLE_STATE: status = USBH_OK; break; case CDC_SET_LINE_CODING_STATE: req_status = SetLineCoding(phost, CDC_Handle->pUserLineCoding); if(req_status == USBH_OK) { CDC_Handle->state = CDC_GET_LAST_LINE_CODING_STATE; } else if(req_status != USBH_BUSY) { CDC_Handle->state = CDC_ERROR_STATE; } break; case CDC_GET_LAST_LINE_CODING_STATE: req_status = GetLineCoding(phost, &(CDC_Handle->LineCoding)); if(req_status == USBH_OK) { CDC_Handle->state = CDC_IDLE_STATE; if((CDC_Handle->LineCoding.b.bCharFormat == CDC_Handle->pUserLineCoding->b.bCharFormat) && (CDC_Handle->LineCoding.b.bDataBits == CDC_Handle->pUserLineCoding->b.bDataBits) && (CDC_Handle->LineCoding.b.bParityType == CDC_Handle->pUserLineCoding->b.bParityType) && (CDC_Handle->LineCoding.b.dwDTERate == CDC_Handle->pUserLineCoding->b.dwDTERate)) { USBH_CDC_LineCodingChanged(phost); } } else if(req_status != USBH_BUSY) { CDC_Handle->state = CDC_ERROR_STATE; } break; case CDC_TRANSFER_DATA: CDC_ProcessTransmission(phost); CDC_ProcessReception(phost); break; case CDC_ERROR_STATE: req_status = USBH_ClrFeature(phost, 0x00); if(req_status == USBH_OK ) { /*Change the state to waiting*/ CDC_Handle->state = CDC_IDLE_STATE ; } break; default: break; } return status; }
//***************************************************************************** // // Handles CDC driver notifications related to control and setup of the device. // // \param pvCBData is the client-supplied callback pointer for this channel. // \param ulEvent identifies the event we are being notified about. // \param ulMsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to perform control-related // operations on behalf of the USB host. These functions include setting // and querying the serial communication parameters, setting handshake line // states and sending break conditions. // // \return The return value is event-specific. // //***************************************************************************** uint32_t ControlHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData) { // // Which event are we being asked to process? // switch(ui32Event) { // // We are connected to a host and communication is now possible. // case USB_EVENT_CONNECTED: { // // Now connected and ready for normal operation. // HWREGBITW(&g_ui32Flags, FLAG_USB_CONFIGURED) = 1; // // Flush our buffers. // USBBufferFlush(&g_sTxBuffer); USBBufferFlush(&g_sRxBuffer); // // Tell the main loop to update the display. // g_pcStatus = "Host connected."; // // Set the command status update flag. // HWREGBITW(&g_ui32Flags, FLAG_STATUS_UPDATE) = 1; break; } // // The host has disconnected. // case USB_EVENT_DISCONNECTED: { // // No longer connected. // HWREGBITW(&g_ui32Flags, FLAG_USB_CONFIGURED) = 0; g_pcStatus = "Host disconnected."; // // Set the command status update flag. // HWREGBITW(&g_ui32Flags, FLAG_STATUS_UPDATE) = 1; break; } // // Return the current serial communication parameters. // case USBD_CDC_EVENT_GET_LINE_CODING: { GetLineCoding(pvMsgData, UART_CLOCK); break; } // // Set the current serial communication parameters. // case USBD_CDC_EVENT_SET_LINE_CODING: { SetLineCoding(pvMsgData, UART_CLOCK); break; } // // Set the current serial communication parameters. // case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE: { SetControlLineState((uint16_t)ui32MsgValue); break; } // // Send a break condition on the serial line. // case USBD_CDC_EVENT_SEND_BREAK: { SendBreak(true); break; } // // Clear the break condition on the serial line. // case USBD_CDC_EVENT_CLEAR_BREAK: { SendBreak(false); break; } // // Ignore SUSPEND and RESUME for now. // case USB_EVENT_SUSPEND: case USB_EVENT_RESUME: { break; } // // We don't expect to receive any other events. Ignore any that show // up in a release build or hang in a debug build. // default: { #ifdef DEBUG while(1); #else break; #endif } } return(0); }
//***************************************************************************** // // Handles CDC driver notifications related to control and setup of the device. // // \param pvCBData is the client-supplied callback pointer for this channel. // \param ulEvent identifies the notification event. // \param ulMsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to perform control-related // operations on behalf of the USB host. These functions include setting // and querying the serial communication parameters, setting handshake line // states and sending break conditions. // // \return The return value is event-specific. // //***************************************************************************** unsigned long ControlHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue, void *pvMsgData) { // // Which event was sent? // switch(ulEvent) { // // The host has connected. // case USB_EVENT_CONNECTED: { // // Turn on the user LED. // GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_PIN_0); // // Flush the buffers. // USBBufferFlush(&g_sTxBuffer); USBBufferFlush(&g_sRxBuffer); break; } // // The host has disconnected. // case USB_EVENT_DISCONNECTED: { // // Turn off the user LED. // GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0); break; } // // Return the current serial communication parameters. // case USBD_CDC_EVENT_GET_LINE_CODING: { GetLineCoding(pvMsgData); break; } // // Set the current serial communication parameters. // case USBD_CDC_EVENT_SET_LINE_CODING: { SetLineCoding(pvMsgData); break; } // // Set the current serial communication parameters. // case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE: { break; } // // Send a break condition on the serial line. // case USBD_CDC_EVENT_SEND_BREAK: { SendBreak(true); break; } // // Clear the break condition on the serial line. // case USBD_CDC_EVENT_CLEAR_BREAK: { SendBreak(false); break; } // // Ignore SUSPEND and RESUME for now. // case USB_EVENT_SUSPEND: case USB_EVENT_RESUME: { break; } // // Other events can be safely ignored. // default: { break; } } return(0); }
void SerialDevice::SetModes() { struct termios tios; memcpy(&tios, &fTTY.t, sizeof(struct termios)); uint16 newControl = fControlOut; TRACE_FUNCRES(trace_termios, &tios); static uint32 baudRates[] = { 0x00000000, //B0 0x00000032, //B50 0x0000004B, //B75 0x0000006E, //B110 0x00000086, //B134 0x00000096, //B150 0x000000C8, //B200 0x0000012C, //B300 0x00000258, //B600 0x000004B0, //B1200 0x00000708, //B1800 0x00000960, //B2400 0x000012C0, //B4800 0x00002580, //B9600 0x00004B00, //B19200 0x00009600, //B38400 0x0000E100, //B57600 0x0001C200, //B115200 0x00038400, //B230400 0x00070800, //460800 0x000E1000, //921600 }; uint32 baudCount = sizeof(baudRates) / sizeof(baudRates[0]); uint32 baudIndex = tios.c_cflag & CBAUD; if (baudIndex > baudCount) baudIndex = baudCount - 1; usb_serial_line_coding lineCoding; lineCoding.speed = baudRates[baudIndex]; lineCoding.stopbits = (tios.c_cflag & CSTOPB) ? LC_STOP_BIT_2 : LC_STOP_BIT_1; if (tios.c_cflag & PARENB) { lineCoding.parity = LC_PARITY_EVEN; if (tios.c_cflag & PARODD) lineCoding.parity = LC_PARITY_ODD; } else lineCoding.parity = LC_PARITY_NONE; lineCoding.databits = (tios.c_cflag & CS8) ? 8 : 7; if (lineCoding.speed == 0) { newControl &= 0xfffffffe; lineCoding.speed = fLineCoding.speed; } else newControl = CLS_LINE_DTR; if (fControlOut != newControl) { fControlOut = newControl; TRACE("newctrl send to modem: 0x%08x\n", newControl); SetControlLineState(newControl); } if (memcmp(&lineCoding, &fLineCoding, sizeof(usb_serial_line_coding)) != 0) { fLineCoding.speed = lineCoding.speed; fLineCoding.stopbits = lineCoding.stopbits; fLineCoding.databits = lineCoding.databits; fLineCoding.parity = lineCoding.parity; TRACE("send to modem: speed %d sb: 0x%08x db: 0x%08x parity: 0x%08x\n", fLineCoding.speed, fLineCoding.stopbits, fLineCoding.databits, fLineCoding.parity); SetLineCoding(&fLineCoding); } }
//***************************************************************************** // // Handles CDC driver notifications related to control and setup of the device. // // \param pvCBData is the client-supplied callback pointer for this channel. // \param ulEvent identifies the event we are being notified about. // \param ulMsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to perform control-related // operations on behalf of the USB host. These functions include setting // and querying the serial communication parameters, setting handshake line // states and sending break conditions. // // \return The return value is event-specific. // //***************************************************************************** unsigned long ControlHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue, void *pvMsgData) { // // Which event are we being asked to process? // switch(ulEvent) { // // We are connected to a host and communication is now possible. // case USB_EVENT_CONNECTED: { g_bUSBDevConnected = true; // // Flush our buffers. // USBBufferFlush(&g_sTxBuffer); USBBufferFlush(&g_sRxBuffer); break; } // // The host has disconnected. // case USB_EVENT_DISCONNECTED: { g_bUSBDevConnected = false; break; } // // Return the current serial communication parameters. // case USBD_CDC_EVENT_GET_LINE_CODING: { GetLineCoding(pvMsgData); break; } // // Set the current serial communication parameters. // case USBD_CDC_EVENT_SET_LINE_CODING: { SetLineCoding(pvMsgData); break; } // // The following line control events can be ignored because there is // no physical serial port to manage. // case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE: case USBD_CDC_EVENT_SEND_BREAK: case USBD_CDC_EVENT_CLEAR_BREAK: { break; } // // Ignore SUSPEND and RESUME for now. // case USB_EVENT_SUSPEND: case USB_EVENT_RESUME: { break; } // // An unknown event occurred. // default: { break; } } // // Return control to USB stack // return(0); }
/****************************************************************************** * * * \brief Handles CDC driver notifications related to control and setup of * * the device.\n * * * * \param pvCBData is the client-supplied callback pointer for this channel. * * * * \param ulEvent identifies the event we are being notified about. * * * * \param ulMsgValue is an event-specific value. * * * * \param pvMsgData is an event-specific pointer. * * * * \return The return value is event-specific. * * * ******************************************************************************/ unsigned int ControlHandler(void *pvCBData, unsigned int ulEvent, unsigned int ulMsgValue, void *pvMsgData) { unsigned char ulIntsOff; /* Which event are we being asked to process? */ switch(ulEvent) { /* We are connected to a host and communication is now possible. */ case USB_EVENT_CONNECTED: /* Flush our buffers. */ USBBufferFlush(&g_sTxBuffer); USBBufferFlush(&g_sRxBuffer); ulIntsOff = IntDisable(); g_pcStatus = "Host connected."; g_ulFlags |= COMMAND_STATUS_UPDATE; IntEnable(ulIntsOff); break; /* The host has disconnected. */ case USB_EVENT_DISCONNECTED: ulIntsOff = IntDisable(); g_pcStatus = "Host disconnected."; g_ulFlags |= COMMAND_STATUS_UPDATE; IntEnable(ulIntsOff); break; /* Return the current serial communication parameters. */ case USBD_CDC_EVENT_GET_LINE_CODING: GetLineCoding(pvMsgData); break; /* Set the current serial communication parameters. */ case USBD_CDC_EVENT_SET_LINE_CODING: SetLineCoding(pvMsgData); break; /* Set the current serial communication parameters. */ case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE: SetControlLineState((unsigned short)ulMsgValue); break; /* Send a break condition on the serial line.*/ case USBD_CDC_EVENT_SEND_BREAK: SendBreak(true); break; /* Clear the break condition on the serial line. */ case USBD_CDC_EVENT_CLEAR_BREAK: SendBreak(false); break; /* Ignore SUSPEND and RESUME for now. */ case USB_EVENT_SUSPEND: case USB_EVENT_RESUME: break; /* We don't expect to receive any other events. Ignore any that show up in a release build or hang in a debug build. */ default: break; } return(0); }