diff options
Diffstat (limited to 'libopencm3/lib/lpc43xx')
-rw-r--r-- | libopencm3/lib/lpc43xx/gpio.c | 53 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/i2c.c | 102 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/ipc.c | 58 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/m0/Makefile | 43 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld | 0 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld | 96 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/m4/Makefile | 50 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld | 127 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld | 139 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld | 128 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/m4/vector_chipset.c | 48 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/scu.c | 52 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/ssp.c | 140 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/timer.c | 72 | ||||
-rw-r--r-- | libopencm3/lib/lpc43xx/uart.c | 243 |
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 © @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 © @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 © @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 © @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; +} + |