159 lines
4.9 KiB
C
159 lines
4.9 KiB
C
#include "tasoller.h"
|
|
|
|
#ifdef stdout
|
|
// Unnecessary for compilation, but clangd can get a bit confused
|
|
#undef stdout
|
|
#endif
|
|
// For picolibc
|
|
FILE *const stdout = NULL;
|
|
|
|
void SYS_ResetModule(uint32_t u32ModuleIndex) {
|
|
// Generate reset signal to the corresponding module
|
|
*(volatile uint32_t *)((uint32_t)&SYS->IPRSTC1 + (u32ModuleIndex >> 24)) |=
|
|
1 << (u32ModuleIndex & 0x00ffffff);
|
|
|
|
// Release corresponding module from reset state
|
|
*(volatile uint32_t *)((uint32_t)&SYS->IPRSTC1 + (u32ModuleIndex >> 24)) &=
|
|
~(1 << (u32ModuleIndex & 0x00ffffff));
|
|
}
|
|
|
|
void SYS_Init(void) {
|
|
// Enable XT1_OUT (PF.0) and XT1_IN (PF.1)
|
|
SYS->GPF_MFP &= ~(SYS_GPF_MFP_PF0_Msk | SYS_GPF_MFP_PF1_Msk);
|
|
SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;
|
|
|
|
// Enable Internal RC 22.1184 MHz clock
|
|
CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
|
|
CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
|
|
|
|
// Switch HCLK clock source to Internal RC and HCLK source divide 1
|
|
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
|
|
|
|
// Enable external XTAL 12 MHz clock
|
|
CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
|
|
CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
|
|
|
|
// Set core clock
|
|
CLK_SetCoreClock(72000000);
|
|
|
|
// Enable module clocks
|
|
CLK_EnableModuleClock(UART1_MODULE);
|
|
CLK_EnableModuleClock(USBD_MODULE);
|
|
CLK_EnableModuleClock(TMR0_MODULE);
|
|
CLK_EnableModuleClock(I2C1_MODULE);
|
|
// Select module clock sources
|
|
CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
|
|
CLK_SetModuleClock(USBD_MODULE, 0, CLK_CLKDIV_USB(3));
|
|
CLK_SetModuleClock(TMR0_MODULE, 0, 0);
|
|
CLK_SetModuleClock(I2C1_MODULE, 0, 0);
|
|
|
|
// Set GPB multi-function pins for UART1 RXD(PB4) and TXD(PB5)
|
|
SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB4_Msk | SYS_GPB_MFP_PB5_Msk);
|
|
SYS->GPB_MFP |= SYS_GPB_MFP_PB4_UART1_RXD | SYS_GPB_MFP_PB5_UART1_TXD;
|
|
|
|
GPIO_SetMode(_PIN_SDA, GPIO_PMD_OUTPUT);
|
|
GPIO_SetMode(_PIN_SCL, GPIO_PMD_OUTPUT);
|
|
PIN_SDA = 1;
|
|
PIN_SCL = 1;
|
|
|
|
// Configure our GPIO pins
|
|
GPIO_SetMode(_PIN_EC1, GPIO_PMD_INPUT);
|
|
GPIO_SetMode(_PIN_RX2, GPIO_PMD_INPUT);
|
|
GPIO_SetMode(_PIN_RX3, GPIO_PMD_INPUT);
|
|
GPIO_SetMode(_PIN_RX4, GPIO_PMD_INPUT);
|
|
GPIO_SetMode(_PIN_EC2, GPIO_PMD_INPUT);
|
|
GPIO_SetMode(_PIN_EC3, GPIO_PMD_INPUT);
|
|
GPIO_SetMode(_PIN_USB_MUX_SEL, GPIO_PMD_OUTPUT);
|
|
GPIO_SetMode(_PIN_USB_MUX_EN, GPIO_PMD_OUTPUT);
|
|
GPIO_SetMode(_PIN_LED_WING_PWR, GPIO_PMD_OUTPUT);
|
|
GPIO_SetMode(_PIN_LED_GROUND_PWR, GPIO_PMD_OUTPUT);
|
|
|
|
PIN_LED_WING_PWR = 1;
|
|
PIN_LED_GROUND_PWR = 1;
|
|
|
|
GPIO_SetMode(_PIN_FN2, GPIO_PMD_INPUT);
|
|
// TODO:
|
|
if (PIN_FN2 == 0) {
|
|
PIN_USB_MUX_SEL = USB_MUX_LEDS;
|
|
PIN_USB_MUX_EN = USB_MUX_ENABLE;
|
|
GPIO_SetMode(_PIN_SDA, GPIO_PMD_OUTPUT);
|
|
GPIO_SetMode(_PIN_SCL, GPIO_PMD_OUTPUT);
|
|
PIN_SDA = 0;
|
|
PIN_SCL = 0;
|
|
return;
|
|
}
|
|
|
|
// Set GPA multi-function pins for I2C1 SDA and SCL
|
|
SYS->GPA_MFP &= ~(SYS_GPA_MFP_PA10_Msk | SYS_GPA_MFP_PA11_Msk);
|
|
SYS->GPA_MFP |= (SYS_GPA_MFP_PA10_I2C1_SDA | SYS_GPA_MFP_PA11_I2C1_SCL);
|
|
SYS->ALT_MFP &= ~(SYS_ALT_MFP_PA10_Msk | SYS_ALT_MFP_PA11_Msk);
|
|
SYS->ALT_MFP |= (SYS_ALT_MFP_PA10_I2C1_SDA | SYS_ALT_MFP_PA11_I2C1_SCL);
|
|
|
|
PIN_USB_MUX_EN = USB_MUX_ENABLE;
|
|
PIN_USB_MUX_SEL = USB_MUX_HOST;
|
|
}
|
|
|
|
void SYS_ModuleInit(void) {
|
|
// Setup UART1
|
|
SYS_ResetModule(UART1_RST);
|
|
UART_Open(UART1, 460800);
|
|
/* Enable interrupts for:
|
|
* - Receive data available
|
|
* - Receive line status
|
|
* - RX time-out
|
|
*/
|
|
UART1->IER = (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk | UART_IER_RTO_IEN_Msk);
|
|
NVIC_EnableIRQ(UART1_IRQn);
|
|
|
|
// Set NVIC priorities
|
|
NVIC_SetPriority(USBD_IRQn, 1);
|
|
NVIC_SetPriority(TMR0_IRQn, 2);
|
|
NVIC_SetPriority(I2S_IRQn, 3);
|
|
NVIC_SetPriority(I2C0_IRQn, 4);
|
|
|
|
CLK_SysTickDelay(10 ms);
|
|
|
|
// For communication with the LED MCU
|
|
LED_I2C1_Init();
|
|
|
|
// Timer 0: Used for HID, PSoC processing and slider outbound
|
|
// This timer runs at 4kHz, but only sets the 1ms flag every 4 calls
|
|
TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 4 kHz);
|
|
TIMER_EnableInt(TIMER0);
|
|
NVIC_EnableIRQ(TMR0_IRQn);
|
|
TIMER_Start(TIMER0);
|
|
|
|
// Setup our USB stack
|
|
Tas_USBD_Open();
|
|
Tas_USBD_Init();
|
|
Tas_USBD_Start();
|
|
NVIC_EnableIRQ(USBD_IRQn);
|
|
}
|
|
|
|
// Define a dedicated symbol for this, so we can easily trap it with a debugger!
|
|
void HardFault_Handler() {
|
|
while (1)
|
|
;
|
|
}
|
|
|
|
void SYS_Bootloader_Check() {
|
|
FMC_Open();
|
|
while (FMC_Read(BOOTLOADER_MAGIC_ADDR) != BOOTLOADER_MAGIC)
|
|
;
|
|
FMC_Close();
|
|
}
|
|
|
|
volatile uint8_t gu8Do250usTick = 0;
|
|
volatile uint8_t gu8Do1msTick = 0;
|
|
void TMR0_IRQHandler(void) {
|
|
static uint32_t su32Counter;
|
|
if (TIMER_GetIntFlag(TIMER0)) {
|
|
TIMER_ClearIntFlag(TIMER0);
|
|
gu8Do250usTick = 1;
|
|
if (++su32Counter == 4) {
|
|
su32Counter = 0;
|
|
gu8Do1msTick = 1;
|
|
}
|
|
}
|
|
}
|