2023-12-17 11:20:35 -05:00
|
|
|
extern "C" {
|
2024-01-13 12:05:29 -05:00
|
|
|
#include "usb_serial_device_to_host.h"
|
2023-12-17 11:20:35 -05:00
|
|
|
#include "usb_serial_cdc.h"
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "usb_serial_shell.hpp"
|
|
|
|
#include "usb_serial.hpp"
|
|
|
|
#include "portapack.hpp"
|
2024-01-13 12:05:29 -05:00
|
|
|
#include "usb_serial_host_to_device.hpp"
|
2023-12-17 11:20:35 -05:00
|
|
|
|
|
|
|
#include <libopencm3/cm3/common.h>
|
|
|
|
#include <libopencm3/lpc43xx/usb.h>
|
|
|
|
|
|
|
|
namespace portapack {
|
|
|
|
|
|
|
|
void USBSerial::initialize() {
|
|
|
|
enable_xtal();
|
|
|
|
disable_pll0();
|
|
|
|
|
|
|
|
setup_pll0();
|
|
|
|
enable_pll0();
|
|
|
|
|
|
|
|
setup_usb_clock();
|
|
|
|
setup_usb_serial_controller();
|
|
|
|
|
|
|
|
init_serial_usb_driver(&SUSBD1);
|
|
|
|
shellInit();
|
2024-01-13 12:05:29 -05:00
|
|
|
init_host_to_device();
|
2023-12-17 11:20:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::dispatch() {
|
|
|
|
if (!connected)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (shell_created == false) {
|
|
|
|
shell_created = true;
|
2024-01-03 08:06:29 -05:00
|
|
|
create_shell(_eventDispatcher);
|
2023-12-17 11:20:35 -05:00
|
|
|
}
|
|
|
|
|
2024-01-13 12:05:29 -05:00
|
|
|
schedule_host_to_device_transfer();
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::dispatch_transfer() {
|
|
|
|
complete_host_to_device_transfer();
|
2023-12-17 11:20:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::on_channel_opened() {
|
|
|
|
connected = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::on_channel_closed() {
|
|
|
|
connected = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::enable_xtal() {
|
|
|
|
LPC_CGU->XTAL_OSC_CTRL.ENABLE = 0;
|
|
|
|
LPC_CGU->XTAL_OSC_CTRL.HF = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::disable_pll0() {
|
|
|
|
LPC_CGU->PLL0USB_CTRL.PD = 1;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.AUTOBLOCK = 1;
|
|
|
|
|
|
|
|
LPC_CGU->PLL0USB_CTRL.BYPASS = 0;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.DIRECTI = 0;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.DIRECTO = 0;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.CLKEN = 0;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.FRM = 0;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.CLK_SEL = 0x06; // 12MHz internal XTAL
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::setup_pll0() {
|
|
|
|
/* use XTAL_OSC as clock source for PLL0USB */
|
|
|
|
|
|
|
|
while (LPC_CGU->PLL0USB_STAT.LOCK) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// /* configure PLL0USB to produce 480 MHz clock from 12 MHz XTAL_OSC */
|
|
|
|
// /* Values from User Manual v1.4 Table 94, for 12MHz oscillator. */
|
|
|
|
LPC_CGU->PLL0USB_MDIV = 0x06167FFA;
|
|
|
|
LPC_CGU->PLL0USB_NP_DIV = 0x00302062;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.PD = 1;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.DIRECTI = 1;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.DIRECTO = 1;
|
|
|
|
LPC_CGU->PLL0USB_CTRL.CLKEN = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::enable_pll0() {
|
|
|
|
// /* power on PLL0USB and wait until stable */
|
|
|
|
LPC_CGU->PLL0USB_CTRL.PD = 0;
|
|
|
|
|
|
|
|
while (!LPC_CGU->PLL0USB_STAT.LOCK) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBSerial::setup_usb_clock() {
|
|
|
|
/* use PLL0USB as clock source for USB0 */
|
|
|
|
LPC_CGU->BASE_USB0_CLK.AUTOBLOCK = 1;
|
|
|
|
LPC_CGU->BASE_USB0_CLK.CLK_SEL = 0x07;
|
|
|
|
LPC_CGU->BASE_USB0_CLK.PD = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace portapack
|