NUC200LE3AN_Card/src/main.c

133 lines
4.0 KiB
C

#include <stdio.h>
#include "FreeRTOS.h"
#include "NUC200Series.h"
#include "task.h"
/**
* This function enables external crystal oscillator,
* configures internal PLL and switch CPU and Bus clock
* to PLL frequency.
*/
static void system_clock_config(void) {
/**
* Configure External crystal input
* Note: This register is guarded.
*/
SYS_UnlockReg();
CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk; /* Enable XTL12M */
SYS_LockReg();
while (!(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk)) {
/* Wait until external crystal stabilized */
}
/**
* Configure PLL
* NUC200 series has 1 PLL, up to 50MHz.
* We set up PLL running at 48MHz, which is default.
* PLLCON register:
* OUT_DV = 3, NO = 4
* IN_DV = 1, NR = 3
* FB_DV = 46, NF = 48
* PLL FOUT = FIN * (NF / NR) * (1 / NO) = 12MHz * (48 / 3) * (1 / 4) = 48MHz
*/
CLK->PLLCON = (CLK_PLLCON_IN_DV_Msk & (1U << CLK_PLLCON_IN_DV_Pos)) |
(CLK_PLLCON_FB_DV_Msk & (46U << CLK_PLLCON_FB_DV_Pos)) |
(CLK_PLLCON_OUT_DV_Msk & (3U << CLK_PLLCON_OUT_DV_Pos));
CLK->PLLCON &= ~CLK_PLLCON_OE_Msk; /* Enable PLL FOUT output. NOTE: This bit is active-low! */
while (!(CLK->CLKSTATUS & CLK_CLKSTATUS_PLL_STB_Msk)) {
/* Wait until PLL clock stabilized */
}
/**
* Configure Clock dividers.
* NUC200 series has 2 divider registers, one for SC peripherals,
* another for everything else.
* ADC: 12MHz
* UART: 12MHz
* USB: 48MHz
* HCLK: 48MHz
* SC0-2: 12MHz
*/
CLK->CLKDIV = CLK_CLKDIV_ADC(4) | CLK_CLKDIV_UART(1) | CLK_CLKDIV_USB(1) | CLK_CLKDIV_HCLK(1);
CLK->CLKDIV1 = CLK_CLKDIV1_SC2(4) | CLK_CLKDIV1_SC1(4) | CLK_CLKDIV1_SC0(4);
/**
* Configure Clock selectors.
* Some of these register bits (in CLKSEL0) are guarded by a latch register,
* however it will not cleared automatically by write operations.
* Clear the latch manually after clock changes.
*/
SYS_UnlockReg();
CLK->CLKSEL0 = CLK_CLKSEL0_HCLK_S_PLL; /* HCLK */
SYS_LockReg();
SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk); /* SysTick */
SysTick->CTRL |= CLK_CLKSEL0_STCLK_S_HCLK;
CLK->CLKSEL1 = 0xFFFFFFFF; /* Reset value */
CLK->CLKSEL1 &= ~CLK_CLKSEL1_SPI0_S_Msk;
CLK->CLKSEL1 |= CLK_CLKSEL1_SPI0_S_HCLK;
CLK->CLKSEL2 = 0x200FFU; /* Reset value */
CLK->CLKSEL3 = 0x3FU; /* Reset value */
CLK_EnableModuleClock(UART0_MODULE);
CLK_EnableModuleClock(SPI0_MODULE);
SystemCoreClockUpdate();
}
static void pinmux_config(void) {
GPIO_SetMode(PA, BIT3, GPIO_PMD_OPEN_DRAIN); /* LED_GREEN */
GPIO_SetMode(PA, BIT4, GPIO_PMD_OPEN_DRAIN); /* LED_RED */
/* UART */
SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
SYS->GPB_MFP |= SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;
/* NFC SPI Port PC0-3 */
SYS->GPC_MFP &= ~(SYS_GPC_MFP_PC0_Msk | SYS_GPC_MFP_PC1_Msk | SYS_GPC_MFP_PC2_Msk | SYS_GPC_MFP_PC3_Msk);
SYS->GPC_MFP |=
SYS_GPC_MFP_PC0_SPI0_SS0 | SYS_GPC_MFP_PC1_SPI0_CLK | SYS_GPC_MFP_PC2_SPI0_MISO0 | SYS_GPC_MFP_PC3_SPI0_MOSI0;
SYS->ALT_MFP &= ~(SYS_ALT_MFP_PC0_Msk | SYS_ALT_MFP_PC1_Msk | SYS_ALT_MFP_PC2_Msk | SYS_ALT_MFP_PC3_Msk);
SYS->ALT_MFP |=
SYS_ALT_MFP_PC0_SPI0_SS0 | SYS_ALT_MFP_PC1_SPI0_CLK | SYS_ALT_MFP_PC2_SPI0_MISO0 | SYS_ALT_MFP_PC3_SPI0_MOSI0;
/* NFC Reset and IRQ */
}
static void hello_task(void *pvParameters) {
PA->DOUT ^= BIT4;
for (;;) {
PA->DOUT ^= BIT3 | BIT4;
printf("Hello?\r\n");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
int main(int argc, const char *argv[]) {
system_clock_config();
pinmux_config();
UART_Open(UART0, 921600);
printf("UART0 opened for stdout operations.\r\n");
if(xTaskCreate(hello_task, "HELLO", 128, NULL, 6, NULL) != pdPASS) {
for(;;) {
//
}
}
vTaskStartScheduler();
for (;;) {
//
}
}