Prusa-Firmware-MMU/src/modules/usb_cdc.cpp

111 lines
3.5 KiB
C++

/// @file usb_cdc.cpp
#include "usb_cdc.h"
#include "../hal/cpu.h"
#include "../hal/watchdog.h"
#include "debug.h"
extern "C" {
#include "lufa_config.h"
#include "Descriptors.h"
#include "lufa/LUFA/Drivers/USB/USB.h"
/** Standard file stream for the CDC interface when set up, so that the virtual CDC COM port can be
* used like any regular character stream in the C APIs.
*/
static FILE USBSerialStream;
/** LUFA CDC Class driver interface configuration and state information. This structure is
* passed to all CDC Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
*/
USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = {
.Config = {
.ControlInterfaceNumber = INTERFACE_ID_CDC_CCI,
.DataINEndpoint = {
.Address = CDC_TX_EPADDR,
.Size = CDC_TXRX_EPSIZE,
.Type = EP_TYPE_BULK,
.Banks = 2,
},
.DataOUTEndpoint = {
.Address = CDC_RX_EPADDR,
.Size = CDC_TXRX_EPSIZE,
.Type = EP_TYPE_BULK,
.Banks = 2,
},
.NotificationEndpoint = {
.Address = CDC_NOTIFICATION_EPADDR,
.Size = CDC_NOTIFICATION_EPSIZE,
.Type = EP_TYPE_INTERRUPT,
.Banks = 1,
},
},
};
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) {
// dbg_modules_P(PSTR("EVENT_USB_Device_Connect"));
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) {
// dbg_modules_P(PSTR("EVENT_USB_Device_Disconnect"));
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) {
bool ConfigSuccess = true;
ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
// dbg_modules_fP(PSTR("EVENT_USB_Device_ConfigurationChanged:%S"), ConfigSuccess ? PSTR("ready") : PSTR("error"));
}
/** Event handler for the library USB Control Request reception event. */
void EVENT_USB_Device_ControlRequest(void) {
// dbg_modules_P(PSTR("EVENT_USB_Device_ControlRequest"));
CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
}
/** CDC class driver callback function the processing of changes to the virtual
* control lines sent from the host..
*
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
*/
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t *const CDCInterfaceInfo) {
}
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t *const CDCInterfaceInfo) {
if (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 1200) {
// *(uint16_t *)0x0800U = 0x7777; //old bootloader?
*(uint16_t *)(RAMEND - 1) = 0x7777;
hal::cpu::resetPending = true;
hal::watchdog::Enable(hal::watchdog::configuration::compute(250));
}
}
}
namespace modules {
namespace usb {
CDC cdc;
void CDC::Init() {
USB_Init();
/* Create a regular character stream for the interface so that it can be used with the stdio.h functions */
CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream);
stdout = &USBSerialStream;
}
void CDC::Step() {
/* Must throw away unused bytes from the host, or it will lock up while waiting for the device */
CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
USB_USBTask();
}
} // namespace usb
} // namespace modules