summaryrefslogtreecommitdiffstats
path: root/libopencm3/lib/lpc43xx
diff options
context:
space:
mode:
Diffstat (limited to 'libopencm3/lib/lpc43xx')
-rw-r--r--libopencm3/lib/lpc43xx/gpio.c53
-rw-r--r--libopencm3/lib/lpc43xx/i2c.c102
-rw-r--r--libopencm3/lib/lpc43xx/ipc.c58
-rw-r--r--libopencm3/lib/lpc43xx/m0/Makefile43
-rw-r--r--libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld0
-rw-r--r--libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld96
-rw-r--r--libopencm3/lib/lpc43xx/m4/Makefile50
-rw-r--r--libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld127
-rw-r--r--libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld139
-rw-r--r--libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld128
-rw-r--r--libopencm3/lib/lpc43xx/m4/vector_chipset.c48
-rw-r--r--libopencm3/lib/lpc43xx/scu.c52
-rw-r--r--libopencm3/lib/lpc43xx/ssp.c140
-rw-r--r--libopencm3/lib/lpc43xx/timer.c72
-rw-r--r--libopencm3/lib/lpc43xx/uart.c243
15 files changed, 1351 insertions, 0 deletions
diff --git a/libopencm3/lib/lpc43xx/gpio.c b/libopencm3/lib/lpc43xx/gpio.c
new file mode 100644
index 0000000..935feb3
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/gpio.c
@@ -0,0 +1,53 @@
+/** @defgroup gpio_file GPIO
+
+@ingroup LPC43xx
+
+@brief <b>libopencm3 LPC43xx General Purpose I/O</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2009 Uwe Hermann <uwe@hermann-uwe.de>
+
+LGPL License Terms @ref lgpl_license
+*/
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**@{*/
+
+#include <libopencm3/lpc43xx/gpio.h>
+
+void gpio_set(uint32_t gpioport, uint32_t gpios)
+{
+ GPIO_SET(gpioport) = gpios;
+}
+
+void gpio_clear(uint32_t gpioport, uint32_t gpios)
+{
+ GPIO_CLR(gpioport) = gpios;
+}
+
+void gpio_toggle(uint32_t gpioport, uint32_t gpios)
+{
+ GPIO_NOT(gpioport) = gpios;
+}
+
+/**@}*/
+
diff --git a/libopencm3/lib/lpc43xx/i2c.c b/libopencm3/lib/lpc43xx/i2c.c
new file mode 100644
index 0000000..0d6c4c6
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/i2c.c
@@ -0,0 +1,102 @@
+/** @defgroup i2c_file I2C
+
+@ingroup LPC43xx
+
+@brief <b>libopencm3 LPC43xx I2C</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2012 Michael Ossmann <mike@ossmann.com>
+
+LGPL License Terms @ref lgpl_license
+*/
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This is a very minimal I2C driver just to make sure we can get the
+ * peripheral working.
+ */
+
+/**@{*/
+
+#include <libopencm3/lpc43xx/i2c.h>
+#include <libopencm3/lpc43xx/scu.h>
+#include <libopencm3/lpc43xx/cgu.h>
+
+void i2c0_init(const uint16_t duty_cycle_count)
+{
+ /* enable input on SCL and SDA pins */
+ SCU_SFSI2C0 = SCU_I2C0_NOMINAL;
+
+ I2C0_SCLH = duty_cycle_count;
+ I2C0_SCLL = duty_cycle_count;
+
+ /* clear the control bits */
+ I2C0_CONCLR = (I2C_CONCLR_AAC | I2C_CONCLR_SIC
+ | I2C_CONCLR_STAC | I2C_CONCLR_I2ENC);
+
+ /* enable I2C0 */
+ I2C0_CONSET = I2C_CONSET_I2EN;
+}
+
+/* transmit start bit */
+void i2c0_tx_start(void)
+{
+ I2C0_CONCLR = I2C_CONCLR_SIC;
+ I2C0_CONSET = I2C_CONSET_STA;
+ while (!(I2C0_CONSET & I2C_CONSET_SI));
+ I2C0_CONCLR = I2C_CONCLR_STAC;
+}
+
+/* transmit data byte */
+void i2c0_tx_byte(uint8_t byte)
+{
+ if (I2C0_CONSET & I2C_CONSET_STA) {
+ I2C0_CONCLR = I2C_CONCLR_STAC;
+ }
+ I2C0_DAT = byte;
+ I2C0_CONCLR = I2C_CONCLR_SIC;
+ while (!(I2C0_CONSET & I2C_CONSET_SI));
+}
+
+/* receive data byte */
+uint8_t i2c0_rx_byte(void)
+{
+ if (I2C0_CONSET & I2C_CONSET_STA) {
+ I2C0_CONCLR = I2C_CONCLR_STAC;
+ }
+ I2C0_CONCLR = I2C_CONCLR_SIC;
+ while (!(I2C0_CONSET & I2C_CONSET_SI));
+ return I2C0_DAT;
+}
+
+/* transmit stop bit */
+void i2c0_stop(void)
+{
+ if (I2C0_CONSET & I2C_CONSET_STA) {
+ I2C0_CONCLR = I2C_CONCLR_STAC;
+ }
+ I2C0_CONSET = I2C_CONSET_STO;
+ I2C0_CONCLR = I2C_CONCLR_SIC;
+}
+
+/**@}*/
+
diff --git a/libopencm3/lib/lpc43xx/ipc.c b/libopencm3/lib/lpc43xx/ipc.c
new file mode 100644
index 0000000..c26931f
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/ipc.c
@@ -0,0 +1,58 @@
+/*
+* This file is part of the libopencm3 project.
+*
+* Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+*
+* This library is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libopencm3/lpc43xx/ipc.h>
+#include <libopencm3/lpc43xx/creg.h>
+#include <libopencm3/lpc43xx/rgu.h>
+
+/* Set M0 in reset mode */
+void ipc_halt_m0(void)
+{
+ volatile uint32_t rst_active_status1;
+
+ /* Check if M0 is reset by reading status */
+ rst_active_status1 = RESET_ACTIVE_STATUS1;
+
+ /* If the M0 has reset not asserted, halt it... */
+ while (rst_active_status1 & RESET_CTRL1_M0APP_RST) {
+ RESET_CTRL1 = ((~rst_active_status1) | RESET_CTRL1_M0APP_RST);
+ rst_active_status1 = RESET_ACTIVE_STATUS1;
+ }
+}
+
+void ipc_start_m0(uint32_t cm0_baseaddr)
+{
+ volatile uint32_t rst_active_status1;
+
+ /* Set M0 memory mapping to point to start of M0 image */
+ CREG_M0APPMEMMAP = cm0_baseaddr;
+
+ /* Start/run M0 core */
+
+ /* Release Slave from reset, first read status */
+ rst_active_status1 = RESET_ACTIVE_STATUS1;
+
+ /* If the M0 is being held in reset, release it */
+ /* 1 = no reset, 0 = reset */
+ while (!(rst_active_status1 & RESET_CTRL1_M0APP_RST)) {
+ RESET_CTRL1 = ((~rst_active_status1) & ~RESET_CTRL1_M0APP_RST);
+ rst_active_status1 = RESET_ACTIVE_STATUS1;
+ }
+}
+
diff --git a/libopencm3/lib/lpc43xx/m0/Makefile b/libopencm3/lib/lpc43xx/m0/Makefile
new file mode 100644
index 0000000..65114c2
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/m0/Makefile
@@ -0,0 +1,43 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+## Copyright (C) 2012/2013 Benjamin Vernoux <titanmkd@gmail.com>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+LIBNAME = libopencm3_lpc43xx_m0
+SRCLIBDIR ?= ../..
+
+PREFIX ?= arm-none-eabi
+#PREFIX ?= arm-elf
+CC = $(PREFIX)-gcc
+AR = $(PREFIX)-ar
+CFLAGS = -O2 -g3 -Wall -Wextra -I../../../include -fno-common \
+ -mcpu=cortex-m0 -mthumb -Wstrict-prototypes \
+ -ffunction-sections -fdata-sections -MD -DLPC43XX -DLPC43XX_M0
+# ARFLAGS = rcsv
+ARFLAGS = rcs
+
+# LPC43xx common files for M4 / M0
+OBJ_LPC43XX = gpio.o scu.o i2c.o ssp.o uart.o timer.o
+
+#LPC43xx M0 specific file + Generic LPC43xx M4/M0 files
+OBJS = $(OBJ_LPC43XX)
+
+VPATH += ../:../../cm3
+
+include ../../Makefile.include
diff --git a/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld b/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld
diff --git a/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld b/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld
new file mode 100644
index 0000000..fedd3e1
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld
@@ -0,0 +1,96 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+ * Copyright (C) 2012 Jared Boone <jared@sharebrained.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Generic linker script for LPC43XX targets using libopencm3. */
+
+/* Memory regions must be defined in the ld script which includes this one. */
+
+/* Enforce emmition of the vector table. */
+EXTERN (vector_table)
+
+/* Define the entry point of the output file. */
+ENTRY(reset_handler)
+
+/* Define sections. */
+SECTIONS
+{
+ . = ORIGIN(ram_ahb2);
+
+ .text : {
+ . = ALIGN(0x400);
+ *(.vectors) /* Vector table */
+ *(.text*) /* Program code */
+ . = ALIGN(4);
+ *(.rodata*) /* Read-only data */
+ . = ALIGN(4);
+ } >ram_ahb2
+
+ /* exception index - required due to libgcc.a issuing /0 exceptions */
+ __exidx_start = .;
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > ram_ahb2
+ __exidx_end = .;
+
+ _etext = .;
+
+ . = ORIGIN(ram_ahb2);
+
+ .data : {
+ *(.data*) /* Read-write initialized data */
+ . = ALIGN(4);
+ } >ram_ahb2
+
+ _data = .;
+ _edata = .;
+
+ .bss : {
+ _bss = .;
+ *(.bss*) /* Read-write zero initialized data */
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram_ahb2
+
+ /* exception unwind data - required due to libgcc.a issuing /0 exceptions */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >ram_ahb2
+
+ /*
+ * The .eh_frame section appears to be used for C++ exception handling.
+ * You may need to fix this if you're using C++.
+ */
+ /DISCARD/ : { *(.eh_frame) }
+
+ /*
+ * Another section used by C++ stuff, appears when using newlib with
+ * 64bit (long long) printf support - discard it for now.
+ */
+ /DISCARD/ : { *(.ARM.exidx) }
+
+ end = .;
+
+ /* Leave room above stack for IAP to run. */
+ __StackTop = ORIGIN(ram_ahb2) + LENGTH(ram_ahb2) - 32;
+ PROVIDE(_stack = __StackTop);
+}
diff --git a/libopencm3/lib/lpc43xx/m4/Makefile b/libopencm3/lib/lpc43xx/m4/Makefile
new file mode 100644
index 0000000..a3d3b03
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/m4/Makefile
@@ -0,0 +1,50 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+## Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+## Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+LIBNAME = libopencm3_lpc43xx
+SRCLIBDIR ?= ../..
+
+FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16
+PREFIX ?= arm-none-eabi
+
+CC = $(PREFIX)-gcc
+AR = $(PREFIX)-ar
+CFLAGS = -O2 -g3 \
+ -Wall -Wextra -Wimplicit-function-declaration \
+ -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
+ -Wundef -Wshadow \
+ -I../../../include -fno-common \
+ -mcpu=cortex-m4 -mthumb -Wstrict-prototypes \
+ -ffunction-sections -fdata-sections -MD \
+ $(FP_FLAGS) -DLPC43XX -DLPC43XX_M4
+
+ARFLAGS = rcs
+
+# LPC43xx common files for M4 / M0
+OBJ_LPC43XX = gpio.o scu.o i2c.o ssp.o uart.o timer.o
+
+#LPC43xx M4 specific file + Generic LPC43xx M4/M0 files
+OBJS = $(OBJ_LPC43XX) ipc.o
+
+VPATH += ../:../../cm3
+
+include ../../Makefile.include
diff --git a/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld b/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld
new file mode 100644
index 0000000..c289b35
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+ * Copyright (C) 2012 Jared Boone <jared@sharebrained.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Generic linker script for LPC43XX targets using libopencm3. */
+
+/* Memory regions must be defined in the ld script which includes this one. */
+
+/* Enforce emmition of the vector table. */
+EXTERN (vector_table)
+
+/* Define the entry point of the output file. */
+ENTRY(reset_handler)
+
+/* Define sections. */
+SECTIONS
+{
+ .text : {
+ . = ALIGN(0x400);
+ _text_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */
+ *(.vectors) /* Vector table */
+ *(.text*) /* Program code */
+ . = ALIGN(4);
+ *(.rodata*) /* Read-only data */
+ . = ALIGN(4);
+ } >rom
+
+ /* C++ Static constructors/destructors, also used for __attribute__
+ * ((constructor)) and the likes */
+ .preinit_array : {
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+ } >rom
+ .init_array : {
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+ } >rom
+ .fini_array : {
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+ } >rom
+
+ /*
+ * Another section used by C++ stuff, appears when using newlib with
+ * 64bit (long long) printf support
+ */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >rom
+
+ /* exception index - required due to libgcc.a issuing /0 exceptions */
+ .ARM.exidx : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >rom
+
+ . = ALIGN(4);
+ _etext = .;
+ _etext_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */
+ _etext_rom = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */
+
+ . = ORIGIN(ram_local2);
+
+ .data : {
+ _data = .;
+ *(.data*) /* Read-write initialized data */
+ . = ALIGN(4);
+ _edata = .;
+ } >ram_local2 AT >rom
+ _data_loadaddr = LOADADDR(.data);
+
+ _data_rom = LOADADDR (.data) + ORIGIN(rom);
+ _edata_rom = _data_rom + SIZEOF (.data);
+
+ .bss : {
+ _bss = .;
+ *(.bss*) /* Read-write zero initialized data */
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram_local2
+
+ /* exception unwind data - required due to libgcc.a issuing /0 exceptions */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >ram_local2
+
+ /*
+ * The .eh_frame section appears to be used for C++ exception handling.
+ * You may need to fix this if you're using C++.
+ */
+ /DISCARD/ : { *(.eh_frame) }
+
+ . = ALIGN(4);
+ end = .;
+
+ /* Leave room above stack for IAP to run. */
+ __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32;
+ PROVIDE(_stack = __StackTop);
+}
diff --git a/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld b/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld
new file mode 100644
index 0000000..5bcdea6
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld
@@ -0,0 +1,139 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+ * Copyright (C) 2012 Jared Boone <jared@sharebrained.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Generic linker script for LPC43XX targets using libopencm3. */
+
+/* Memory regions must be defined in the ld script which includes this one. */
+
+/* Enforce emmition of the vector table. */
+EXTERN (vector_table)
+
+/* Define the entry point of the output file. */
+ENTRY(reset_handler)
+
+/* Define sections. */
+SECTIONS
+{
+ . = ORIGIN(ram_local1);
+
+ .text : {
+ . = ALIGN(0x400);
+ _text_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */
+ *(.vectors) /* Vector table */
+ *(.text*) /* Program code */
+ . = ALIGN(4);
+ *(.rodata*) /* Read-only data */
+ . = ALIGN(4);
+ } >ram_local1
+
+ /* C++ Static constructors/destructors, also used for __attribute__
+ * ((constructor)) and the likes */
+ .preinit_array : {
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+ } >ram_local1
+ .init_array : {
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+ } >ram_local1
+ .fini_array : {
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+ } >ram_local1
+
+ /*
+ * Another section used by C++ stuff, appears when using newlib with
+ * 64bit (long long) printf support
+ */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >ram_local1
+
+ /* exception index - required due to libgcc.a issuing /0 exceptions */
+ __exidx_start = .;
+ .ARM.exidx : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } > ram_local1
+
+ . = ALIGN(4);
+ _etext = .;
+ _etext_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */
+ _etext_rom = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */
+
+ . = ORIGIN(ram_local2);
+
+ .data : {
+ _data = .;
+ *(.data*) /* Read-write initialized data */
+ . = ALIGN(4);
+ _edata = .;
+ } >ram_local2
+ _data_loadaddr = LOADADDR(.data);
+
+ /* Running from RAM only, loading the .elf will initialize data for us. */
+ _data_rom = .;
+ _edata_rom = .;
+
+ _data = .;
+ _edata = .;
+
+ .bss : {
+ _bss = .;
+ *(.bss*) /* Read-write zero initialized data */
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram_local2
+
+ /* exception unwind data - required due to libgcc.a issuing /0 exceptions */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >ram_local2
+
+ /*
+ * The .eh_frame section appears to be used for C++ exception handling.
+ * You may need to fix this if you're using C++.
+ */
+ /DISCARD/ : { *(.eh_frame) }
+
+ /*
+ * Another section used by C++ stuff, appears when using newlib with
+ * 64bit (long long) printf support - discard it for now.
+ */
+ /DISCARD/ : { *(.ARM.exidx) }
+
+ end = .;
+
+ /* Leave room above stack for IAP to run. */
+ __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32;
+ PROVIDE(_stack = __StackTop);
+}
diff --git a/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld b/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld
new file mode 100644
index 0000000..e50040e
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld
@@ -0,0 +1,128 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+ * Copyright (C) 2012 Jared Boone <jared@sharebrained.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Generic linker script for LPC43XX targets using libopencm3. */
+
+/* Memory regions must be defined in the ld script which includes this one. */
+
+/* Enforce emmition of the vector table. */
+EXTERN (vector_table)
+
+/* Define the entry point of the output file. */
+ENTRY(reset_handler)
+
+/* Define sections. */
+SECTIONS
+{
+ .text : {
+ . = ALIGN(0x400);
+ _text_ram = (. - ORIGIN(rom)) + ORIGIN(ram_local1); /* Start of Code in RAM */
+
+ *(.vectors) /* Vector table */
+ *(.text*) /* Program code */
+ . = ALIGN(4);
+ *(.rodata*) /* Read-only data */
+ . = ALIGN(4);
+ } >rom
+
+ /* C++ Static constructors/destructors, also used for __attribute__
+ * ((constructor)) and the likes */
+ .preinit_array : {
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+ } >rom
+ .init_array : {
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+ } >rom
+ .fini_array : {
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+ } >rom
+
+ /*
+ * Another section used by C++ stuff, appears when using newlib with
+ * 64bit (long long) printf support
+ */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >rom
+
+ /* exception index - required due to libgcc.a issuing /0 exceptions */
+ .ARM.exidx : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >rom
+
+ . = ALIGN(4);
+ _etext = .;
+ _etext_ram = (. - ORIGIN(rom)) + ORIGIN(ram_local1);
+ _etext_rom = (. - ORIGIN(rom)) + ORIGIN(rom_flash);
+
+ . = ORIGIN(ram_local2);
+
+ .data : {
+ _data = .;
+ *(.data*) /* Read-write initialized data */
+ . = ALIGN(4);
+ _edata = .;
+ } >ram_local2 AT >rom
+ _data_loadaddr = LOADADDR(.data);
+
+ _data_rom = LOADADDR (.data) + ORIGIN(rom_flash);
+ _edata_rom = _data_rom + SIZEOF (.data);
+
+ .bss : {
+ _bss = .;
+ *(.bss*) /* Read-write zero initialized data */
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram_local2
+
+ /* exception unwind data - required due to libgcc.a issuing /0 exceptions */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >ram_local2
+
+ /*
+ * The .eh_frame section appears to be used for C++ exception handling.
+ * You may need to fix this if you're using C++.
+ */
+ /DISCARD/ : { *(.eh_frame) }
+
+ . = ALIGN(4);
+ end = .;
+
+ /* Leave room above stack for IAP to run. */
+ __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32;
+ PROVIDE(_stack = __StackTop);
+}
diff --git a/libopencm3/lib/lpc43xx/m4/vector_chipset.c b/libopencm3/lib/lpc43xx/m4/vector_chipset.c
new file mode 100644
index 0000000..270e30e
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/m4/vector_chipset.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
+ * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/cm3/common.h>
+
+extern unsigned _etext_ram, _text_ram, _etext_rom;
+
+#define CREG_M4MEMMAP MMIO32((0x40043000U + 0x100))
+
+static void pre_main(void)
+{
+ volatile unsigned *src, *dest;
+
+ /* Copy the code from ROM to Real RAM (if enabled) */
+ if ((&_etext_ram-&_text_ram) > 0) {
+ src = &_etext_rom-(&_etext_ram-&_text_ram);
+ /* Change Shadow memory to ROM (for Debug Purpose in case Boot
+ * has not set correctly the M4MEMMAP because of debug)
+ */
+ CREG_M4MEMMAP = (unsigned long)src;
+
+ for (dest = &_text_ram; dest < &_etext_ram; ) {
+ *dest++ = *src++;
+ }
+
+ /* Change Shadow memory to Real RAM */
+ CREG_M4MEMMAP = (unsigned long)&_text_ram;
+
+ /* Continue Execution in RAM */
+ }
+}
diff --git a/libopencm3/lib/lpc43xx/scu.c b/libopencm3/lib/lpc43xx/scu.c
new file mode 100644
index 0000000..c20cd84
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/scu.c
@@ -0,0 +1,52 @@
+/** @defgroup scu_file System Control Unit
+
+@ingroup LPC43xx
+
+@brief <b>libopencm3 LPC43xx System Control Unit</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2012 Benjamin Vernoux <titanmkd@gmail.com>
+
+LGPL License Terms @ref lgpl_license
+*/
+
+/*
+* This file is part of the libopencm3 project.
+*
+* Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+*
+* This library is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**@{*/
+
+#include <libopencm3/lpc43xx/scu.h>
+
+/* For pin_conf_normal value see scu.h define SCU_CONF_XXX or Configuration for
+ * different I/O pins types
+ */
+void scu_pinmux(scu_grp_pin_t group_pin, uint32_t scu_conf)
+{
+ MMIO32(group_pin) = scu_conf;
+}
+
+/* For other special SCU register USB1, I2C0, ADC0/1, DAC, EMC clock delay See
+ * scu.h
+ */
+
+/* For Pin interrupt select register see scu.h SCU_PINTSEL0 & SCU_PINTSEL1 */
+
+/**@}*/
+
diff --git a/libopencm3/lib/lpc43xx/ssp.c b/libopencm3/lib/lpc43xx/ssp.c
new file mode 100644
index 0000000..b63ec9b
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/ssp.c
@@ -0,0 +1,140 @@
+/** @defgroup ssp_file SSP
+
+@ingroup LPC43xx
+
+@brief <b>libopencm3 LPC43xx SSP</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2012 Benjamin Vernoux <titanmkd@gmail.com>
+
+LGPL License Terms @ref lgpl_license
+*/
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**@{*/
+
+#include <libopencm3/lpc43xx/ssp.h>
+#include <libopencm3/lpc43xx/cgu.h>
+
+/* Disable SSP */
+void ssp_disable(ssp_num_t ssp_num)
+{
+ uint32_t ssp_port;
+
+ if (ssp_num == SSP0_NUM) {
+ ssp_port = SSP0;
+ } else {
+ ssp_port = SSP1;
+ }
+ /* Disable SSP */
+ SSP_CR1(ssp_port) = 0x0;
+}
+
+/*
+* SSP Init function
+*/
+void ssp_init(ssp_num_t ssp_num,
+ ssp_datasize_t data_size,
+ ssp_frame_format_t frame_format,
+ ssp_cpol_cpha_t cpol_cpha_format,
+ uint8_t serial_clock_rate,
+ uint8_t clk_prescale,
+ ssp_mode_t mode,
+ ssp_master_slave_t master_slave,
+ ssp_slave_option_t slave_option)
+{
+ uint32_t ssp_port;
+ uint32_t clock;
+
+ if (ssp_num == SSP0_NUM) {
+ ssp_port = SSP0;
+ } else {
+ ssp_port = SSP1;
+ }
+
+ /* use PLL1 as clock source for SSP1 */
+ CGU_BASE_SSP1_CLK =
+ CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1)
+ | CGU_BASE_SSP1_CLK_AUTOBLOCK;
+
+ /* Disable SSP before to configure it */
+ SSP_CR1(ssp_port) = 0x0;
+
+ /* Configure SSP */
+ clock = serial_clock_rate;
+ SSP_CPSR(ssp_port) = clk_prescale;
+ SSP_CR0(ssp_port) =
+ (data_size | frame_format | cpol_cpha_format | (clock<<8));
+
+ /* Enable SSP */
+ SSP_CR1(ssp_port) = (SSP_ENABLE | mode | master_slave | slave_option);
+}
+
+static void ssp_wait_until_not_busy(ssp_num_t ssp_num)
+{
+ uint32_t ssp_port;
+
+ if (ssp_num == SSP0_NUM) {
+ ssp_port = SSP0;
+ } else {
+ ssp_port = SSP1;
+ }
+
+ while ((SSP_SR(ssp_port) & SSP_SR_BSY));
+}
+
+/* This Function Wait Data TX Ready, and Write Data to SSP */
+uint16_t ssp_transfer(ssp_num_t ssp_num, uint16_t data)
+{
+ uint32_t ssp_port;
+
+ if (ssp_num == SSP0_NUM) {
+ ssp_port = SSP0;
+ } else {
+ ssp_port = SSP1;
+ }
+
+ /* Wait Until FIFO not full */
+ while ((SSP_SR(ssp_port) & SSP_SR_TNF) == 0);
+
+ SSP_DR(ssp_port) = data;
+
+ /* Wait for not busy, since we're controlling CS# of
+ * devices manually and need to wait for the data to
+ * be sent. It may also be important to wait here
+ * in case we're configuring devices via SPI and also
+ * with GPIO control -- we need to know when SPI
+ * commands are effective before altering a device's
+ * state with GPIO. I'm thinking the MAX2837, for
+ * example...
+ */
+ ssp_wait_until_not_busy(ssp_num);
+
+ /* Wait Until Data Received (Rx FIFO not Empty) */
+ while ((SSP_SR(ssp_port) & SSP_SR_RNE) == 0);
+
+ return SSP_DR(ssp_port);
+}
+
+
+/**@}*/
+
diff --git a/libopencm3/lib/lpc43xx/timer.c b/libopencm3/lib/lpc43xx/timer.c
new file mode 100644
index 0000000..f263c24
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/timer.c
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Ben Gamari <bgamari@physics.umass.edu>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This provides the code for the "next gen" EXTI block provided in F2/F4/L1
+ * devices. (differences only in the source selection)
+ */
+
+#include <libopencm3/lpc43xx/timer.h>
+
+void timer_reset(uint32_t timer_peripheral)
+{
+ TIMER_TCR(timer_peripheral) |= TIMER_TCR_CRST;
+ TIMER_TCR(timer_peripheral) &= ~TIMER_TCR_CRST;
+}
+
+void timer_enable_counter(uint32_t timer_peripheral)
+{
+ TIMER_TCR(timer_peripheral) |= TIMER_TCR_CEN;
+}
+
+void timer_disable_counter(uint32_t timer_peripheral)
+{
+ TIMER_TCR(timer_peripheral) &= ~TIMER_TCR_CEN;
+}
+
+void timer_set_counter(uint32_t timer_peripheral, uint32_t count)
+{
+ TIMER_TC(timer_peripheral) = count;
+}
+
+uint32_t timer_get_counter(uint32_t timer_peripheral)
+{
+ return TIMER_TC(timer_peripheral);
+}
+
+uint32_t timer_get_prescaler(uint32_t timer_peripheral)
+{
+ return TIMER_PR(timer_peripheral);
+}
+
+void timer_set_prescaler(uint32_t timer_peripheral, uint32_t prescaler)
+{
+ TIMER_PR(timer_peripheral) = prescaler;
+}
+
+void timer_set_mode(uint32_t timer_peripheral, uint32_t mode)
+{
+ TIMER_CTCR(timer_peripheral) = mode |
+ (TIMER_CTCR(timer_peripheral) & TIMER_CTCR_MODE_MASK);
+}
+
+void timer_set_count_input(uint32_t timer_peripheral, uint32_t input)
+{
+ TIMER_CTCR(timer_peripheral) = input |
+ (TIMER_CTCR(timer_peripheral) & TIMER_CTCR_CINSEL_MASK);
+}
+
diff --git a/libopencm3/lib/lpc43xx/uart.c b/libopencm3/lib/lpc43xx/uart.c
new file mode 100644
index 0000000..3168ce2
--- /dev/null
+++ b/libopencm3/lib/lpc43xx/uart.c
@@ -0,0 +1,243 @@
+/*
+* This file is part of the libopencm3 project.
+*
+* Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
+*
+* This library is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libopencm3/lpc43xx/uart.h>
+#include <libopencm3/lpc43xx/cgu.h>
+
+#define UART_SRC_32K 0x00
+#define UART_SRC_IRC 0x01
+#define UART_SRC_ENET_RX 0x02
+#define UART_SRC_ENET_TX 0x03
+#define UART_SRC_GP_CLKIN 0x04
+#define UART_SRC_XTAL 0x06
+#define UART_SRC_PLL0USB 0x07
+#define UART_SRC_PLL0AUDIO 0x08
+#define UART_SRC_PLL1 0x09
+#define UART_SRC_IDIVA 0x0C
+#define UART_SRC_IDIVB 0x0D
+#define UART_SRC_IDIVC 0x0E
+#define UART_SRC_IDIVD 0x0F
+#define UART_SRC_IDIVE 0x10
+
+#define UART_CGU_AUTOBLOCK_CLOCK_BIT 11
+/* clock source selection (5 bits) */
+#define UART_CGU_BASE_CLK_SEL_SHIFT 24
+
+uint32_t dummy_read;
+
+/*
+* UART Init function
+*/
+void uart_init(uart_num_t uart_num, uart_databit_t data_nb_bits,
+ uart_stopbit_t data_nb_stop, uart_parity_t data_parity,
+ uint16_t uart_divisor, uint8_t uart_divaddval, uint8_t uart_mulval)
+{
+ uint32_t lcr_config;
+ uint32_t uart_port;
+
+ uart_port = uart_num;
+
+ switch (uart_num) {
+ case UART0_NUM:
+ /* use PLL1 as clock source for UART0 */
+ CGU_BASE_UART0_CLK = (1<<UART_CGU_AUTOBLOCK_CLOCK_BIT) |
+ (CGU_SRC_PLL1<<UART_CGU_BASE_CLK_SEL_SHIFT);
+ break;
+
+ case UART1_NUM:
+ /* use PLL1 as clock source for UART1 */
+ CGU_BASE_UART1_CLK = (1<<UART_CGU_AUTOBLOCK_CLOCK_BIT) |
+ (CGU_SRC_PLL1<<UART_CGU_BASE_CLK_SEL_SHIFT);
+ break;
+
+ case UART2_NUM:
+ /* use PLL1 as clock source for UART2 */
+ CGU_BASE_UART2_CLK = (1<<UART_CGU_AUTOBLOCK_CLOCK_BIT) |
+ (CGU_SRC_PLL1<<UART_CGU_BASE_CLK_SEL_SHIFT);
+ break;
+
+ case UART3_NUM:
+ /* use PLL1 as clock source for UART3 */
+ CGU_BASE_UART3_CLK = (1<<UART_CGU_AUTOBLOCK_CLOCK_BIT) |
+ (CGU_SRC_PLL1<<UART_CGU_BASE_CLK_SEL_SHIFT);
+ break;
+
+ default:
+ return; /* error */
+ }
+
+ /* FIFOs RX/TX Enabled and Reset RX/TX FIFO (DMA Mode is also cleared)*/
+ UART_FCR(uart_port) = (UART_FCR_FIFO_EN | UART_FCR_RX_RS |
+ UART_FCR_TX_RS);
+ /* Disable FIFO */
+ UART_FCR(uart_port) = 0;
+
+ /* Dummy read (to clear existing data) */
+ while (UART_LSR(uart_port) & UART_LSR_RDR) {
+ dummy_read = UART_RBR(uart_port);
+ }
+
+ /* Wait end of TX & disable TX */
+ UART_TER(uart_port) = UART_TER_TXEN;
+
+ /* Wait for current transmit complete */
+ while (!(UART_LSR(uart_port) & UART_LSR_THRE));
+
+ /* Disable Tx */
+ UART_TER(uart_port) = 0;
+
+ /* Disable interrupt */
+ UART_IER(uart_port) = 0;
+
+ /* Set LCR to default state */
+ UART_LCR(uart_port) = 0;
+
+ /* Set ACR to default state */
+ UART_ACR(uart_port) = 0;
+
+ /* Dummy Read to Clear Status */
+ dummy_read = UART_LSR(uart_port);
+
+ /*
+ Table 835. USART Fractional Divider Register:
+ UARTbaudrate = PCLK / ( 16* (((256*DLM)+ DLL)*(1+(DivAddVal/MulVal))) )
+ The value of MULVAL and DIVADDVAL should comply to the following
+ conditions:
+ 1. 1 <= MULVAL <= 15
+ 2. 0 <= DIVADDVAL <= 14
+ 3. DIVADDVAL < MULVAL
+ */
+
+ /* Set DLAB Bit */
+ UART_LCR(uart_port) |= UART_LCR_DLAB_EN;
+ UART_DLM(uart_port) = UART_LOAD_DLM(uart_divisor);
+ UART_DLL(uart_port) = UART_LOAD_DLL(uart_divisor);
+ /* Clear DLAB Bit */
+ UART_LCR(uart_port) &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
+ UART_FDR(uart_port) = UART_FDR_BITMASK &
+ (UART_FDR_MULVAL(uart_mulval) | UART_FDR_DIVADDVAL(uart_divaddval));
+
+ /* Read LCR config & Force Enable of Divisor Latches Access */
+ lcr_config = (UART_LCR(uart_port) & UART_LCR_DLAB_EN) &
+ UART_LCR_BITMASK;
+ lcr_config |= data_nb_bits; /* Set Nb Data Bits */
+ lcr_config |= data_nb_stop; /* Set Nb Stop Bits */
+ lcr_config |= data_parity; /* Set Data Parity */
+
+ /* Write LCR (only 8bits) */
+ UART_LCR(uart_port) = (lcr_config & UART_LCR_BITMASK);
+
+ /* Enable TX */
+ UART_TER(uart_port) = UART_TER_TXEN;
+}
+
+/*
+* This Function return if data are received or not received.
+*/
+uart_rx_data_ready_t uart_rx_data_ready(uart_num_t uart_num)
+{
+ uint32_t uart_port;
+ uint8_t uart_status;
+ uart_rx_data_ready_t data_ready;
+
+ uart_port = uart_num;
+
+ uart_status = UART_LSR(uart_port) & 0xFF;
+
+ /* Check Error */
+ if ((uart_status & UART_LSR_ERROR_MASK) == 0) {
+ /* No errors check if data is ready */
+ if ((uart_status & UART_LSR_RDR) == 0) {
+ data_ready = UART_RX_NO_DATA;
+ } else {
+ data_ready = UART_RX_DATA_READY;
+ }
+ } else {
+ /* UART Error */
+ data_ready = UART_RX_DATA_ERROR;
+ }
+
+ return data_ready;
+}
+
+/*
+* This Function Wait until Data RX Ready, and return Data Read from UART.
+*/
+uint8_t uart_read(uart_num_t uart_num)
+{
+ uint32_t uart_port;
+ uint8_t uart_val;
+
+ uart_port = uart_num;
+
+ /* Wait Until Data Received (Rx Data Not Ready) */
+ while ((UART_LSR(uart_port) & UART_LSR_RDR) == 0);
+
+ uart_val = (UART_RBR(uart_port) & UART_RBR_MASKBIT);
+
+ return uart_val;
+}
+
+/*
+* This Function Wait until Data RX Ready, and return Data Read from UART.
+*/
+uint8_t uart_read_timeout(uart_num_t uart_num, uint32_t rx_timeout_nb_cycles,
+ uart_error_t *error)
+{
+ uint32_t uart_port;
+ uint8_t uart_val;
+ uint32_t counter;
+
+ uart_port = uart_num;
+
+ /* Wait Until Data Received (Rx Data Not Ready) */
+ counter = 0;
+ while ((UART_LSR(uart_port) & UART_LSR_RDR) == 0) {
+ if (rx_timeout_nb_cycles > 0) {
+ counter++;
+ if (counter >= rx_timeout_nb_cycles) {
+ *error = UART_TIMEOUT_ERROR;
+ return 0;
+ }
+ }
+ }
+
+ uart_val = (UART_RBR(uart_port) & UART_RBR_MASKBIT);
+
+ /* Clear error */
+ *error = UART_NO_ERROR;
+
+ return uart_val;
+}
+
+/* This Function Wait Data TX Ready, and Write Data to UART
+ if rx_timeout_nb_cycles = 0 Infinite wait
+*/
+void uart_write(uart_num_t uart_num, uint8_t data)
+{
+ uint32_t uart_port;
+
+ uart_port = uart_num;
+
+ /* Wait Until FIFO not full */
+ while ((UART_LSR(uart_port) & UART_LSR_THRE) == 0);
+
+ UART_THR(uart_port) = data;
+}
+