aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2018-05-07 21:32:27 -0400
committerKevin O'Connor <kevin@koconnor.net>2018-05-25 11:52:13 -0400
commit970831ee0d3b91897196e92270d98b2a3067427f (patch)
tree441c2b329ea669ff5e996a617d7b6bc2c315fa0d /src
parent5ae22a5e51872fd3e6130a3acce68f598bee9ff0 (diff)
downloadkutter-970831ee0d3b91897196e92270d98b2a3067427f.tar.gz
kutter-970831ee0d3b91897196e92270d98b2a3067427f.tar.xz
kutter-970831ee0d3b91897196e92270d98b2a3067427f.zip
lpc176x: Add initial support for LPC176x processors
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r--src/Kconfig3
-rw-r--r--src/lpc176x/Kconfig34
-rw-r--r--src/lpc176x/Makefile42
-rw-r--r--src/lpc176x/gpio.c28
-rw-r--r--src/lpc176x/internal.h7
-rw-r--r--src/lpc176x/main.c31
-rw-r--r--src/lpc176x/serial.c79
-rw-r--r--src/lpc176x/timer.c59
8 files changed, 283 insertions, 0 deletions
diff --git a/src/Kconfig b/src/Kconfig
index cd07ae6b..0a135637 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -8,6 +8,8 @@ choice
bool "Atmega AVR"
config MACH_SAM3X8E
bool "SAM3x8e (Arduino Due)"
+ config MACH_LPC176X
+ bool "LPC176x (Smoothieboard)"
config MACH_STM32F1
bool "STMicroelectronics STM32F103"
config MACH_PRU
@@ -20,6 +22,7 @@ endchoice
source "src/avr/Kconfig"
source "src/sam3x8e/Kconfig"
+source "src/lpc176x/Kconfig"
source "src/stm32f1/Kconfig"
source "src/pru/Kconfig"
source "src/linux/Kconfig"
diff --git a/src/lpc176x/Kconfig b/src/lpc176x/Kconfig
new file mode 100644
index 00000000..d9f15dd1
--- /dev/null
+++ b/src/lpc176x/Kconfig
@@ -0,0 +1,34 @@
+# Kconfig settings for LPC176x processors
+
+if MACH_LPC176X
+
+config LPC_SELECT
+ bool
+ default y
+
+config BOARD_DIRECTORY
+ string
+ default "lpc176x"
+
+choice
+ prompt "Processor model"
+ config MACH_LPC1768
+ bool "lpc1768 (100 Mhz)"
+ config MACH_LPC1769
+ bool "lpc1769 (120 Mhz)"
+endchoice
+
+config CLOCK_FREQ
+ int
+ default 25000000 if MACH_LPC1768 # 100000000 / 4
+ default 30000000 if MACH_LPC1769 # 120000000 / 4
+
+config SERIAL
+ bool
+ default y
+config SERIAL_BAUD
+ depends on SERIAL
+ int "Baud rate for serial port"
+ default 250000
+
+endif
diff --git a/src/lpc176x/Makefile b/src/lpc176x/Makefile
new file mode 100644
index 00000000..2ff7d174
--- /dev/null
+++ b/src/lpc176x/Makefile
@@ -0,0 +1,42 @@
+# lpc176x build rules
+
+# Setup the toolchain
+CROSS_PREFIX=arm-none-eabi-
+
+dirs-y += src/lpc176x src/generic
+dirs-y += lib/lpc176x/device lib/lpc176x/device/TOOLCHAIN_GCC_ARM
+
+CFLAGS += -mthumb -mcpu=cortex-m3
+CFLAGS += -Ilib/lpc176x/device -Ilib/lpc176x/device -Ilib/lpc176x/cmsis
+
+CFLAGS_klipper.elf += -T $(OUT)LPC1768.ld
+CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs
+
+# Add source files
+src-y += lpc176x/main.c lpc176x/timer.c lpc176x/gpio.c
+src-y += generic/crc16_ccitt.c generic/alloc.c
+src-y += generic/armcm_irq.c generic/timer_irq.c
+src-y += ../lib/lpc176x/device/system_LPC17xx.c
+src-$(CONFIG_SERIAL) += lpc176x/serial.c generic/serial_irq.c
+
+# Add the TOOLCHAIN_GCC_ARM files to the build
+$(OUT)%.o: %.S
+ @echo " Assembling $@"
+ $(Q)$(AS) $< -o $@
+
+asmsrc-y := ../lib/lpc176x/device/TOOLCHAIN_GCC_ARM/startup_LPC17xx.S
+
+$(OUT)klipper.elf: $(patsubst %.S, $(OUT)src/%.o,$(asmsrc-y))
+
+target-y := $(OUT)LPC1768.ld $(target-y)
+
+$(OUT)LPC1768.ld: lib/lpc176x/device/TOOLCHAIN_GCC_ARM/LPC1768.ld $(OUT)board-link
+ @echo " Preprocessing $@"
+ $(Q)$(CPP) -P -MD -MT $@ $< -o $@
+
+# Build the additional bin output file
+target-y += $(OUT)klipper.bin
+
+$(OUT)klipper.bin: $(OUT)klipper.elf
+ @echo " Creating bin file $@"
+ $(Q)$(OBJCOPY) -O binary $< $@
diff --git a/src/lpc176x/gpio.c b/src/lpc176x/gpio.c
new file mode 100644
index 00000000..756b0e7b
--- /dev/null
+++ b/src/lpc176x/gpio.c
@@ -0,0 +1,28 @@
+// GPIO functions on lpc176x
+//
+// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "LPC17xx.h" // LPC_PINCON
+#include "internal.h" // gpio_peripheral
+#include "board/irq.h" // irq_save
+
+// Set the mode and extended function of a pin
+void
+gpio_peripheral(int bank, int pin, int func, int pullup)
+{
+ uint32_t bank_pos = bank * 2, pin_pos = pin * 2;
+ if (pin_pos >= 32) {
+ pin_pos -= 32;
+ bank_pos++;
+ }
+ uint32_t sel_bits = (func & 0x03) << pin_pos, mask = ~(0x03 << pin_pos);
+ uint32_t mode_bits = (pullup ? 0x00 : 0x02) << pin_pos;
+ volatile uint32_t *pinsel = &LPC_PINCON->PINSEL0;
+ volatile uint32_t *pinmode = &LPC_PINCON->PINMODE0;
+ irqstatus_t flag = irq_save();
+ pinsel[bank_pos] = (pinsel[bank_pos] & mask) | sel_bits;
+ pinmode[bank_pos] = (pinmode[bank_pos] & mask) | mode_bits;
+ irq_restore(flag);
+}
diff --git a/src/lpc176x/internal.h b/src/lpc176x/internal.h
new file mode 100644
index 00000000..da1f169f
--- /dev/null
+++ b/src/lpc176x/internal.h
@@ -0,0 +1,7 @@
+#ifndef __LPC176X_INTERNAL_H
+#define __LPC176X_INTERNAL_H
+// Local definitions for lpc176x code
+
+void gpio_peripheral(int bank, int pin, int func, int pullup);
+
+#endif // internal.h
diff --git a/src/lpc176x/main.c b/src/lpc176x/main.c
new file mode 100644
index 00000000..24cf6816
--- /dev/null
+++ b/src/lpc176x/main.c
@@ -0,0 +1,31 @@
+// Main starting point for LPC176x boards.
+//
+// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "LPC17xx.h" // NVIC_SystemReset
+#include "command.h" // DECL_CONSTANT
+#include "sched.h" // sched_main
+
+DECL_CONSTANT(MCU, "lpc176x");
+
+
+/****************************************************************
+ * misc functions
+ ****************************************************************/
+
+void
+command_reset(uint32_t *args)
+{
+ NVIC_SystemReset();
+}
+DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset");
+
+// Main entry point
+int
+main(void)
+{
+ sched_main();
+ return 0;
+}
diff --git a/src/lpc176x/serial.c b/src/lpc176x/serial.c
new file mode 100644
index 00000000..7f2a0db9
--- /dev/null
+++ b/src/lpc176x/serial.c
@@ -0,0 +1,79 @@
+// lpc176x serial port
+//
+// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "LPC17xx.h" // LPC_UART0
+#include "autoconf.h" // CONFIG_SERIAL_BAUD
+#include "board/irq.h" // irq_save
+#include "board/serial_irq.h" // serial_rx_data
+#include "internal.h" // gpio_peripheral
+#include "sched.h" // DECL_INIT
+
+void
+serial_init(void)
+{
+ // Setup baud
+ LPC_UART0->LCR = (1<<7); // set DLAB bit
+ LPC_SC->PCLKSEL0 = (LPC_SC->PCLKSEL0 & ~(0x3<<6)) | (0x1<<6);
+ uint32_t pclk = SystemCoreClock;
+ uint32_t div = pclk / (CONFIG_SERIAL_BAUD * 16);
+ LPC_UART0->DLL = div & 0xff;
+ LPC_UART0->DLM = (div >> 8) & 0xff;
+ LPC_UART0->LCR = 3; // 8N1 ; clear DLAB bit
+
+ // Enable fifo
+ LPC_UART0->FCR = 0x01;
+
+ // Setup pins
+ gpio_peripheral(0, 2, 1, 0);
+ gpio_peripheral(0, 3, 1, 0);
+
+ // Enable receive irq
+ NVIC_SetPriority(UART0_IRQn, 0);
+ NVIC_EnableIRQ(UART0_IRQn);
+ LPC_UART0->IER = 0x01;
+}
+DECL_INIT(serial_init);
+
+// Write tx bytes to the serial port
+static void
+kick_tx(void)
+{
+ for (;;) {
+ if (!(LPC_UART0->LSR & (1<<5))) {
+ // Output fifo full - enable tx irq
+ LPC_UART0->IER = 0x03;
+ break;
+ }
+ uint8_t data;
+ int ret = serial_get_tx_byte(&data);
+ if (ret) {
+ // No more data to send - disable tx irq
+ LPC_UART0->IER = 0x01;
+ break;
+ }
+ LPC_UART0->THR = data;
+ }
+}
+
+void __visible
+UART0_IRQHandler(void)
+{
+ uint32_t iir = LPC_UART0->IIR, status = iir & 0x0f;
+ if (status == 0x04)
+ serial_rx_byte(LPC_UART0->RBR);
+ else if (status == 0x02)
+ kick_tx();
+}
+
+void
+serial_enable_tx_irq(void)
+{
+ if (LPC_UART0->LSR & (1<<5)) {
+ irqstatus_t flag = irq_save();
+ kick_tx();
+ irq_restore(flag);
+ }
+}
diff --git a/src/lpc176x/timer.c b/src/lpc176x/timer.c
new file mode 100644
index 00000000..d6d6f9ed
--- /dev/null
+++ b/src/lpc176x/timer.c
@@ -0,0 +1,59 @@
+// lpc176x timer interrupt scheduling
+//
+// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "LPC17xx.h" // LPC_TIM0
+#include "board/irq.h" // irq_disable
+#include "board/misc.h" // timer_read_time
+#include "board/timer_irq.h" // timer_dispatch_many
+#include "sched.h" // DECL_INIT
+
+// Set the next irq time
+static void
+timer_set(uint32_t value)
+{
+ LPC_TIM0->MR0 = value;
+ LPC_TIM0->IR = 0x01;
+}
+
+// Return the current time (in absolute clock ticks).
+uint32_t
+timer_read_time(void)
+{
+ return LPC_TIM0->TC;
+}
+
+// Activate timer dispatch as soon as possible
+void
+timer_kick(void)
+{
+ timer_set(timer_read_time() + 50);
+}
+
+void
+timer_init(void)
+{
+ // Disable timer
+ LPC_TIM0->TCR = 0x02;
+ // Enable interrupts
+ NVIC_SetPriority(TIMER0_IRQn, 1);
+ NVIC_EnableIRQ(TIMER0_IRQn);
+ LPC_TIM0->MCR = 0x01;
+ // Clear counter value
+ LPC_TIM0->TC = 0;
+ timer_kick();
+ // Start timer
+ LPC_TIM0->TCR = 0x01;
+}
+DECL_INIT(timer_init);
+
+void __visible __aligned(16) // aligning helps stabilize perf benchmarks
+TIMER0_IRQHandler(void)
+{
+ irq_disable();
+ uint32_t next = timer_dispatch_many();
+ timer_set(next);
+ irq_enable();
+}