diff --git a/platform/lpc15xx/debug.c b/platform/lpc15xx/debug.c index b3340006..90b948fe 100644 --- a/platform/lpc15xx/debug.c +++ b/platform/lpc15xx/debug.c @@ -29,76 +29,26 @@ #include #include #include -//#include - -#define DEBUG_UART UART0_BASE +#include static cbuf_t debug_rx_buf; -#if 0 -void lpc_uart0_irq(void) -{ - arm_cm_irq_entry(); - - // - // Get the interrrupt status. - // - unsigned long ulStatus = UARTIntStatus(DEBUG_UART, true); - - // - // Clear the asserted interrupts. - // - UARTIntClear(DEBUG_UART, ulStatus); - - // - // Loop while there are characters in the receive FIFO. - // - bool resched = false; - while (UARTCharsAvail(DEBUG_UART)) { - // - // Read the next character from the UART and write it back to the UART. - // - unsigned char c = UARTCharGetNonBlocking(DEBUG_UART); - cbuf_write_char(&debug_rx_buf, c, false); - - resched = true; - } - - arm_cm_irq_exit(resched); -} -#endif - void lpc_debug_early_init(void) { -#if 0 - SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); + /* Use main clock rate as base for UART baud rate divider */ + Chip_Clock_SetUARTBaseClockRate(Chip_Clock_GetMainClockRate(), false); - /* we only support UART0 right now */ - STATIC_ASSERT(DEBUG_UART == UART0_BASE); - - if (DEBUG_UART == UART0_BASE) { - /* Set GPIO A0 and A1 as UART pins. */ - GPIOPinConfigure(GPIO_PA0_U0RX); - GPIOPinConfigure(GPIO_PA1_U0TX); - GPIOPinTypeUART(GPIO_PORTA_AHB_BASE, GPIO_PIN_0 | GPIO_PIN_1); - } - - UARTConfigSetExpClk(DEBUG_UART, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE); - - UARTEnable(DEBUG_UART); -#endif + /* Setup UART */ + Chip_UART_Init(DEBUG_UART); + Chip_UART_ConfigData(DEBUG_UART, UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE | UART_CFG_STOPLEN_1); + Chip_UART_SetBaud(DEBUG_UART, 115200); + Chip_UART_Enable(DEBUG_UART); + Chip_UART_TXEnable(DEBUG_UART); } void lpc_debug_init(void) { cbuf_initialize(&debug_rx_buf, 16); - -#if 0 - /* Enable the UART interrupt. */ - UARTIntEnable(DEBUG_UART, UART_INT_RX | UART_INT_RT); - - NVIC_EnableIRQ(INT_UART0 - 16); -#endif } void platform_dputc(char c) @@ -107,12 +57,20 @@ void platform_dputc(char c) _dputc('\r'); } -// UARTCharPut(DEBUG_UART, c); + Chip_UART_SendBlocking(DEBUG_UART, &c, 1); } int platform_dgetc(char *c, bool wait) { - return cbuf_read_char(&debug_rx_buf, c, wait); + //return cbuf_read_char(&debug_rx_buf, c, wait); + + uint8_t data; + + if (Chip_UART_Read(DEBUG_UART, &data, 1) == 1) { + *c = data; + return 1; + } + return -1; } void platform_halt(void) diff --git a/platform/lpc15xx/include/platform/platform_cm.h b/platform/lpc15xx/include/platform/platform_cm.h index 861c0d4b..bad6e128 100644 --- a/platform/lpc15xx/include/platform/platform_cm.h +++ b/platform/lpc15xx/include/platform/platform_cm.h @@ -22,20 +22,6 @@ */ #pragma once -typedef enum IRQn { - NonMaskableInt_IRQn = -14, /* 2 Non Maskable Interrupt */ - MemoryManagement_IRQn = -12, /* 4 Cortex-M3 Memory Management Interrupt */ - BusFault_IRQn = -11, /* 5 Cortex-M3 Bus Fault Interrupt */ - UsageFault_IRQn = -10, /* 6 Cortex-M3 Usage Fault Interrupt */ - SVCall_IRQn = -5, /* 11 Cortex-M3 SV Call Interrupt */ - DebugMonitor_IRQn = -4, /* 12 Cortex-M3 Debug Monitor Interrupt */ - PendSV_IRQn = -2, /* 14 Cortex-M3 Pend SV Interrupt */ - SysTick_IRQn = -1, /* 15 Cortex-M3 System Tick Interrupt */ - - // XXX irq list here - - NUM_IRQn, -} IRQn_Type; - -#define __NVIC_PRIO_BITS 3 +/* include cmsis.h in platform/lpc space */ +#include diff --git a/platform/lpc15xx/init.c b/platform/lpc15xx/init.c index 856f599a..5f94a161 100644 --- a/platform/lpc15xx/init.c +++ b/platform/lpc15xx/init.c @@ -41,56 +41,34 @@ void lpc_usbc_init(void); void platform_early_init(void) { + /* set up clocking for a board with an external oscillator */ + Chip_SetupXtalClocking(); + + /* Set USB PLL input to main oscillator */ + Chip_Clock_SetUSBPLLSource(SYSCTL_PLLCLKSRC_MAINOSC); + /* Setup USB PLL (FCLKIN = 12MHz) * 4 = 48MHz + MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2) + FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz + FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */ + Chip_Clock_SetupUSBPLL(3, 1); + + /* Powerup USB PLL */ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPLL_PD); + + /* Wait for PLL to lock */ + while (!Chip_Clock_IsUSBPLLLocked()) {} + + /* Set default system tick divder to 1 */ + Chip_Clock_SetSysTickClockDiv(1); + lpc_timer_early_init(); - lpc_debug_early_init(); - -#if 0 - // - // Enable lazy stacking for interrupt handlers. This allows floating-point - // instructions to be used within interrupt handlers, but at the expense of - // extra stack usage. - // -// FPULazyStackingEnable(); - - // - // Set the clocking to run directly from the crystal. - // - SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN); - - lpc_gpio_early_init(); - - lpc_usbc_early_init(); -#endif } void platform_init(void) { lpc_timer_init(); lpc_debug_init(); - -#if 0 - lpc_gpio_init(); - lpc_usbc_init(); - - // print device information - printf("raw revision registers: 0x%lx 0x%lx\n", HWREG(SYSCTL_DID0), HWREG(SYSCTL_DID1)); - - printf("lpc device class: "); - if (CLASS_IS_SANDSTORM) printf("sandstorm"); - if (CLASS_IS_FURY) printf("fury"); - if (CLASS_IS_DUSTDEVIL) printf("dustdevil"); - if (CLASS_IS_TEMPEST) printf("tempst"); - if (CLASS_IS_FIRESTORM) printf("firestorm"); - if (CLASS_IS_BLIZZARD) printf("blizzard"); - printf("\n"); - - printf("revision register: "); - uint rev = (HWREG(SYSCTL_DID0) & SYSCTL_DID0_MAJ_M) >> 8; - printf("%c", rev + 'A'); - printf("%ld", HWREG(SYSCTL_DID0) & (SYSCTL_DID0_MIN_M)); - printf("\n"); -#endif } // vim: set ts=4 sw=4 expandtab: diff --git a/platform/lpc15xx/timer.c b/platform/lpc15xx/timer.c index 551e3547..5f3a6143 100644 --- a/platform/lpc15xx/timer.c +++ b/platform/lpc15xx/timer.c @@ -29,6 +29,8 @@ #include #include +#include + #define LOCAL_TRACE 0 static volatile uint64_t ticks; @@ -39,9 +41,6 @@ static lk_bigtime_t tick_interval_us; static platform_timer_callback cb; static void *cb_args; -// XXX read actual clock programmatically -#define SYSTEM_CLOCK 12000000 - /* use systick as the kernel tick */ void _systick(void) { @@ -69,7 +68,7 @@ status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg tick_interval_ms = interval; tick_interval_us = interval * 1000; - arm_cm_systick_set_periodic(SYSTEM_CLOCK, interval); + arm_cm_systick_set_periodic(Chip_Clock_GetMainClockRate(), interval); exit_critical_section(); @@ -114,7 +113,7 @@ lk_bigtime_t current_time_hires(void) void lpc_timer_early_init(void) { - uint32_t clock_rate = SYSTEM_CLOCK; + uint32_t clock_rate = Chip_Clock_GetMainClockRate(); tick_rate_mhz = clock_rate / 1000000; #if 0 diff --git a/scripts/do-writelpc b/scripts/do-writelpc new file mode 100755 index 00000000..e08f37c9 --- /dev/null +++ b/scripts/do-writelpc @@ -0,0 +1,34 @@ +#!/bin/sh + +if [ $# != 2 ]; then + echo not enough args + echo usage: $0 file device + exit 1 +fi + +if [ ! -f $1 ]; then + echo input file does not exist + exit 1 +fi + +if [ ! -b $2 ]; then + echo output device does not exist + exit 1 +fi + +UNAME=`uname` + +case `uname` in + Darwin) + set -v + sudo diskutil unmount $2 || exit 1 + sudo dd if=$1 of=$2 bs=2048 seek=1 || exit 1 + sudo diskutil eject $2 || exit 1 + ;; + Linux) + set -v + sudo umount $2 + sudo dd if=$1 of=$2 bs=2048 seek=1 || exit 1 + sudo sync + ;; +esac diff --git a/target/lpcexpresso1549/include/target/debugconfig.h b/target/lpcexpresso1549/include/target/debugconfig.h new file mode 100644 index 00000000..fa581262 --- /dev/null +++ b/target/lpcexpresso1549/include/target/debugconfig.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014 Travis Geiselbrecht + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include + +#define DEBUG_UART LPC_USART0 diff --git a/target/lpcexpresso1549/init.c b/target/lpcexpresso1549/init.c index d8f8f6eb..53de1be1 100644 --- a/target/lpcexpresso1549/init.c +++ b/target/lpcexpresso1549/init.c @@ -27,40 +27,190 @@ #include #include -extern void target_usb_setup(void); +#include + +/* needs to be defined for the lpcopen drivers */ +const uint32_t OscRateIn = 12000000; +const uint32_t RTCOscRateIn = 32768; + +/* The System initialization code is called prior to the application and + initializes the board for run-time operation. Board initialization + includes clock setup and default pin muxing configuration. */ + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/* IOCON setup table, only items that need changing from their default pin + state are in this table. */ +STATIC const PINMUX_GRP_T ioconSetup[] = { + /* LEDs */ + {0, 25, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_25-BREAK_CTRL-RED (low enable) */ + {0, 3, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_3-SCT1_OUT4-GRN */ + {1, 1, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_1-BREAK_STS1-BLUE */ + + /* QEI, motor controler, I2C, CAN */ + {0, 2, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_2-QEI-SCT0_IN */ + {0, 30, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_30-QEI-SCT0_IN */ + {0, 17, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_17-QEI-SCT0_IN */ + {0, 25, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_25-BREAK_CTRL-RED */ + {1, 1, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_1-BREAK_STS1-BLUE */ + {0, 23, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_23-I2C_SDA */ + {0, 22, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_22-I2C_SCL */ + {0, 11, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_11-CAN_RD */ + {0, 31, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_31-CAN_TD */ + + /* ADC */ + {1, 3, (IOCON_MODE_INACT)}, /* PIO1_3-ADC1_5 */ + {0, 4, (IOCON_MODE_INACT)}, /* PIO0_4-ADC0_4 */ + {0, 5, (IOCON_MODE_INACT)}, /* PIO0_5-ADC0_3 */ + {0, 7, (IOCON_MODE_INACT)}, /* PIO0_7-ADC0_1 */ + {0, 8, (IOCON_MODE_INACT)}, /* PIO0_8-ADC0_0 */ + {0, 9, (IOCON_MODE_INACT)}, /* PIO0_9-ADC1_1 */ + {0, 10, (IOCON_MODE_INACT)}, /* PIO0_10-ADC1_2 */ + + /* Joystick */ + {1, 4, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_4-JOY_U */ + {1, 5, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_5-JOY_C */ + {1, 6, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_6-JOY_D */ + {1, 7, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_7-JOY_R */ + {1, 8, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_8-JOY_L */ + + /* UART */ + {0, 13, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_13-ISP_RX */ + {0, 18, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_18-ISP_TX */ + {0, 11, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, + {0, 31, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, + + /* USB related */ + {1, 11, (IOCON_MODE_PULLDOWN | IOCON_DIGMODE_EN)}, /* PIO1_11-ISP_1 (VBUS) */ +}; + +/* SWIM pin assignment definitions for pin assignment/muxing */ +typedef struct { + uint16_t assignedpin : 9; /* Function and mode */ + uint16_t port : 2; /* Pin port */ + uint16_t pin : 5; /* Pin number */ +} SWM_GRP_T; + +/* Pin muxing table, only items that need changing from their default pin + state are in this table. */ +STATIC const SWM_GRP_T swmSetup[] = { + /* USB related */ + {(uint16_t) SWM_USB_VBUS_I, 1, 11}, /* PIO1_11-ISP_1-AIN_CTRL */ + + /* UART */ + {(uint16_t) SWM_UART0_RXD_I, 0, 13}, /* PIO0_13-ISP_RX */ + {(uint16_t) SWM_UART0_TXD_O, 0, 18}, /* PIO0_18-ISP_TX */ +}; + +/* Setup fixed pin functions (GPIOs are fixed) */ +/* No fixed pins except GPIOs */ +#define PINENABLE0_VAL 0xFFFFFFFF + +/* No fixed pins except GPIOs */ +#define PINENABLE1_VAL 0x00FFFFFF + +/* Sets up system pin muxing */ +void Board_SetupMuxing(void) +{ + int i; + + /* Enable SWM and IOCON clocks */ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM); + Chip_SYSCTL_PeriphReset(RESET_IOCON); + + /* IOCON setup */ + Chip_IOCON_SetPinMuxing(LPC_IOCON, ioconSetup, sizeof(ioconSetup) / sizeof(PINMUX_GRP_T)); + + /* SWM assignable pin setup */ + for (i = 0; i < (sizeof(swmSetup) / sizeof(SWM_GRP_T)); i++) { + Chip_SWM_MovablePortPinAssign((CHIP_SWM_PIN_MOVABLE_T) swmSetup[i].assignedpin, + swmSetup[i].port, swmSetup[i].pin); + } + + /* SWM fixed pin setup */ + // LPC_SWM->PINENABLE[0] = PINENABLE0_VAL; + // LPC_SWM->PINENABLE[1] = PINENABLE1_VAL; + + /* Note SWM and IOCON clocks are left on */ +} + +/* Initialize debug output via UART for board */ +void Board_Debug_Init(void) +{ + /* Disables pullups/pulldowns and enable digitial mode */ + Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 13, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 18, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + /* UART signal muxing via SWM */ + Chip_SWM_MovablePortPinAssign(SWM_UART0_RXD_I, 0, 13); + Chip_SWM_MovablePortPinAssign(SWM_UART0_TXD_O, 0, 18); +} + +#define MAXLEDS 3 +static const uint8_t ledpins[MAXLEDS] = {25, 3, 1}; +static const uint8_t ledports[MAXLEDS] = {0, 0, 1}; + +/* Initializes board LED(s) */ +static void Board_LED_Init(void) +{ + int idx; + + Chip_GPIO_Init(LPC_GPIO); + + for (idx = 0; idx < MAXLEDS; idx++) { + /* Set the GPIO as output with initial state off (high) */ + Chip_GPIO_SetPinDIROutput(LPC_GPIO, ledports[idx], ledpins[idx]); + Chip_GPIO_SetPinState(LPC_GPIO, ledports[idx], ledpins[idx], true); + } +} + +/* Sets the state of a board LED to on or off */ +void Board_LED_Set(uint8_t LEDNumber, bool On) +{ + if (LEDNumber < MAXLEDS) { + /* Toggle state, low is on, high is off */ + Chip_GPIO_SetPinState(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber], !On); + } +} + +/* Returns the current state of a board LED */ +bool Board_LED_Test(uint8_t LEDNumber) +{ + bool state = false; + + if (LEDNumber < MAXLEDS) { + state = !Chip_GPIO_GetPinState(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber]); + } + + return state; +} + +/* Toggles the current state of a board LED */ +void Board_LED_Toggle(uint8_t LEDNumber) +{ + Chip_GPIO_SetPinToggle(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber]); +} + void target_early_init(void) { -#if 0 - GPIOPinWrite(GPIO_PORTF_AHB_BASE, GPIO_PIN_1, 0); - GPIOPinWrite(GPIO_PORTF_AHB_BASE, GPIO_PIN_2, 0); - GPIOPinWrite(GPIO_PORTF_AHB_BASE, GPIO_PIN_3, 0); + Board_SetupMuxing(); - GPIOPadConfigSet(GPIO_PORTF_AHB_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); - GPIOPadConfigSet(GPIO_PORTF_AHB_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); - GPIOPadConfigSet(GPIO_PORTF_AHB_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); - GPIODirModeSet(GPIO_PORTF_AHB_BASE, GPIO_PIN_1, GPIO_DIR_MODE_OUT); - GPIODirModeSet(GPIO_PORTF_AHB_BASE, GPIO_PIN_2, GPIO_DIR_MODE_OUT); - GPIODirModeSet(GPIO_PORTF_AHB_BASE, GPIO_PIN_3, GPIO_DIR_MODE_OUT); -#endif + Board_Debug_Init(); + Board_LED_Init(); } void target_init(void) { -#if 0 - target_usb_setup(); -#endif } void target_set_debug_led(unsigned int led, bool on) { -#if 0 - switch (led) { - case 0: gpio_set(GPIO(GPIO_PORT_F, 1), on); break; - case 1: gpio_set(GPIO(GPIO_PORT_F, 2), on); break; - case 2: gpio_set(GPIO(GPIO_PORT_F, 3), on); break; - } -#endif + if (led < 3) + Board_LED_Set(led, on); } -// vim: set ts=4 sw=4 noexpandtab: +// vim: set ts=4 sw=4 expandtab: