From 0dec187feec43feaf8032c087426f988a2f8dec8 Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Thu, 3 Jan 2013 19:23:39 +0100 Subject: [PATCH] lpc43xx basic IPC for multicore M4 & M0 (with basic examples for hackrf jellybean). --- Makefile | 2 +- include/libopencm3/lpc43xx/ipc.h | 30 +++ lib/lpc43xx/Makefile | 2 +- lib/lpc43xx/ipc.c | 70 ++++++ lib/lpc43xx_m0/Makefile | 71 +++++++ .../libopencm3_lpc43xx_ram_only_m0.ld | 96 +++++++++ lib/lpc43xx_m0/vector.c | 199 ++++++++++++++++++ 7 files changed, 468 insertions(+), 2 deletions(-) create mode 100644 include/libopencm3/lpc43xx/ipc.h create mode 100644 lib/lpc43xx/ipc.c create mode 100644 lib/lpc43xx_m0/Makefile create mode 100644 lib/lpc43xx_m0/libopencm3_lpc43xx_ram_only_m0.ld create mode 100644 lib/lpc43xx_m0/vector.c diff --git a/Makefile b/Makefile index 6be166b6..96d11de6 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ SHAREDIR := $(DESTDIR)/$(PREFIX)/share/libopencm3/scripts INSTALL := install SRCLIBDIR:= $(realpath lib) -TARGETS:= stm32/f1 stm32/f2 stm32/f4 stm32/l1 lpc13xx lpc17xx lpc43xx lm3s lm4f efm32/efm32tg efm32/efm32g efm32/efm32lg efm32/efm32gg sam/3x sam/3n +TARGETS:= stm32/f1 stm32/f2 stm32/f4 stm32/l1 lpc13xx lpc17xx lpc43xx lpc43xx_m0 lm3s lm4f efm32/efm32tg efm32/efm32g efm32/efm32lg efm32/efm32gg sam/3x sam/3n # Be silent per default, but 'make V=1' will show all compiler calls. ifneq ($(V),1) diff --git a/include/libopencm3/lpc43xx/ipc.h b/include/libopencm3/lpc43xx/ipc.h new file mode 100644 index 00000000..4853a4d6 --- /dev/null +++ b/include/libopencm3/lpc43xx/ipc.h @@ -0,0 +1,30 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Benjamin Vernoux +* +* 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 . +*/ + +#ifndef LPC43XX_IPC_H +#define LPC43XX_IPC_H + +#include +#include + +void ipc_halt_m0(void); + +void ipc_start_m0(u32 cm0_baseaddr); + +#endif diff --git a/lib/lpc43xx/Makefile b/lib/lpc43xx/Makefile index 17c1ded0..92aa2d2e 100644 --- a/lib/lpc43xx/Makefile +++ b/lib/lpc43xx/Makefile @@ -35,7 +35,7 @@ CFLAGS = -O2 -g3 \ -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX # ARFLAGS = rcsv ARFLAGS = rcs -OBJS = gpio.o vector.o scu.o i2c.o ssp.o nvic.o systick.o uart.o +OBJS = gpio.o vector.o scu.o i2c.o ssp.o nvic.o systick.o uart.o ipc.o VPATH += ../cm3 diff --git a/lib/lpc43xx/ipc.c b/lib/lpc43xx/ipc.c new file mode 100644 index 00000000..57d6935f --- /dev/null +++ b/lib/lpc43xx/ipc.c @@ -0,0 +1,70 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Benjamin Vernoux +* +* 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 . +*/ + +#include +#include +#include + +/* Set M0 in reset mode */ +void ipc_halt_m0(void) +{ + volatile u32 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... */ + if( (rst_active_status1 & RESET_CTRL1_M0APP_RST) ) + { + RESET_CTRL1 = ((~rst_active_status1) | RESET_CTRL1_M0APP_RST); + rst_active_status1 = RESET_ACTIVE_STATUS1; + /* Check again */ + if( (rst_active_status1 & RESET_CTRL1_M0APP_RST) ) + { + RESET_CTRL1 = ((~rst_active_status1) | RESET_CTRL1_M0APP_RST); + } + } +} + +void ipc_start_m0(u32 cm0_baseaddr) +{ + volatile u32 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 */ + if( !(rst_active_status1 & RESET_CTRL1_M0APP_RST) ) + { + RESET_CTRL1 = ((~rst_active_status1) & (~RESET_CTRL1_M0APP_RST)); + rst_active_status1 = RESET_ACTIVE_STATUS1; + /* Check again */ + if( !(rst_active_status1 & RESET_CTRL1_M0APP_RST) ) + { + RESET_CTRL1 = ((~rst_active_status1) & (~RESET_CTRL1_M0APP_RST)); + } + } +} + diff --git a/lib/lpc43xx_m0/Makefile b/lib/lpc43xx_m0/Makefile new file mode 100644 index 00000000..fe83244a --- /dev/null +++ b/lib/lpc43xx_m0/Makefile @@ -0,0 +1,71 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 Michael Ossmann +## Copyright (C) 2012 Benjamin Vernoux +## +## 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 . +## + +LIBNAME = libopencm3_lpc43xx_m0 + +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 +# ARFLAGS = rcsv +ARFLAGS = rcs + +# LPC43xx common files for M4 / M0 +COPIED_FILE_LPC43XX = ../lpc43xx/gpio.c ../lpc43xx/scu.c ../lpc43xx/i2c.c ../lpc43xx/ssp.c ../lpc43xx/nvic.c ../lpc43xx/uart.c +OBJ_LPC43XX = gpio.o scu.o i2c.o ssp.o nvic.o uart.o +SRC_LPC43XX = $(OBJ_LPC43XX:.o=.c) + +#LPC43xx M0 specific file + Generic LPC43xx M4/M0 files +OBJS = vector.o $(OBJ_LPC43XX) + +# VPATH += ../usb + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +endif + +all: copy_files_lpc43xx $(LIBNAME).a + +copy_files_lpc43xx: $(COPIED_FILE_LPC43XX) + $(Q)cp $^ ./ + +$(LIBNAME).a: $(OBJS) + @printf " AR $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(AR) $(ARFLAGS) $@ $^ + +%.o: %.c + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) -o $@ -c $< + +clean: + @printf " CLEAN lib/lpc43xx_m0\n" + $(Q)rm -f *.o *.d + $(Q)rm -f $(SRC_LPC43XX) + $(Q)rm -f $(LIBNAME).a + +.PHONY: clean + +-include $(OBJS:.o=.d) + diff --git a/lib/lpc43xx_m0/libopencm3_lpc43xx_ram_only_m0.ld b/lib/lpc43xx_m0/libopencm3_lpc43xx_ram_only_m0.ld new file mode 100644 index 00000000..fedd3e1d --- /dev/null +++ b/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 + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * Copyright (C) 2012 Jared Boone + * + * 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 . + */ + +/* 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/lib/lpc43xx_m0/vector.c b/lib/lpc43xx_m0/vector.c new file mode 100644 index 00000000..64b33f5f --- /dev/null +++ b/lib/lpc43xx_m0/vector.c @@ -0,0 +1,199 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski , + * Copyright (C) 2012 chrysn + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +#define WEAK __attribute__ ((weak)) + +/* Symbols exported by the linker script(s): */ +extern unsigned _bss, _ebss, _stack; + +void main(void); +void blocking_handler(void); +void null_handler(void); + +void WEAK reset_handler(void); +void WEAK nmi_handler(void); +void WEAK hard_fault_handler(void); +void WEAK mem_manage_handler(void); +void WEAK bus_fault_handler(void); +void WEAK usage_fault_handler(void); +void WEAK sv_call_handler(void); +void WEAK debug_monitor_handler(void); +void WEAK pend_sv_handler(void); + +void WEAK m0_rtc_isr(void); +void WEAK m0_m4core_isr(void); +void WEAK m0_dma_isr(void); +void WEAK m0_ethernet_isr(void); +void WEAK m0_flasheepromat_isr(void); +void WEAK m0_sdio_isr(void); +void WEAK m0_lcd_isr(void); +void WEAK m0_usb0_isr(void); +void WEAK m0_usb1_isr(void); +void WEAK m0_sct_isr(void); +void WEAK m0_ritimer_or_wwdt_isr(void); +void WEAK m0_timer0_isr(void); +void WEAK m0_gint1_isr(void); +void WEAK m0_pin_int4_isr(void); +void WEAK m0_timer3_isr(void); +void WEAK m0_mcpwm_isr(void); +void WEAK m0_adc0_isr(void); +void WEAK m0_i2c0_or_i2c1_isr(void); +void WEAK m0_sgpio_isr(void); +void WEAK m0_spi_or_dac_isr(void); +void WEAK m0_adc1_isr(void); +void WEAK m0_ssp0_or_ssp1_isr(void); +void WEAK m0_eventrouter_isr(void); +void WEAK m0_usart0_isr(void); +void WEAK m0_uart1_isr(void); +void WEAK m0_usart2_or_c_can1_isr(void); +void WEAK m0_usart3_isr(void); +void WEAK m0_i2s0_or_i2s1_isr(void); +void WEAK m0_c_can0_isr(void); + +/* Initialization template for the interrupt vector table. This definition is + * used by the startup code generator (vector.c) to set the initial values for + * the interrupt handling routines to the chip family specific _isr weak + * symbols. */ +/* See UserManual LPC43xx rev1_4 UM10503 Table 26. Connection of interrupt sources to the Cortex-M0 NVIC */ + +__attribute__ ((section(".vectors"))) +void (*const vector_table[]) (void) = { + /* Cortex-M4 interrupts */ + (void*)&_stack, + reset_handler, + nmi_handler, + hard_fault_handler, + mem_manage_handler, + bus_fault_handler, + usage_fault_handler, + 0, 0, 0, 0, /* reserved */ + sv_call_handler, + debug_monitor_handler, + 0, /* reserved */ + pend_sv_handler, + 0, /* sys_tick_handler not supported on LPC4330 M0 */ + + /* IrqID 0 , ExcNo 16 */ m0_rtc_isr, + /* IrqID 1 , ExcNo 17 */ m0_m4core_isr, + /* IrqID 2 , ExcNo 18 */ m0_dma_isr, + /* IrqID 3 , ExcNo 19 */ 0, + /* IrqID 4 , ExcNo 20 */ m0_flasheepromat_isr, + /* IrqID 5 , ExcNo 21 */ m0_ethernet_isr, + /* IrqID 6 , ExcNo 22 */ m0_sdio_isr, + /* IrqID 7 , ExcNo 23 */ m0_lcd_isr, + /* IrqID 8 , ExcNo 24 */ m0_usb0_isr, + /* IrqID 9 , ExcNo 25 */ m0_usb1_isr, + /* IrqID 10, ExcNo 26 */ m0_sct_isr, + /* IrqID 11, ExcNo 27 */ m0_ritimer_or_wwdt_isr, + /* IrqID 12, ExcNo 28 */ m0_timer0_isr, + /* IrqID 13, ExcNo 29 */ m0_gint1_isr, + /* IrqID 14, ExcNo 30 */ m0_pin_int4_isr, + /* IrqID 15, ExcNo 31 */ m0_timer3_isr, + /* IrqID 16, ExcNo 32 */ m0_mcpwm_isr, + /* IrqID 17, ExcNo 33 */ m0_adc0_isr, + /* IrqID 18, ExcNo 34 */ m0_i2c0_or_i2c1_isr, + /* IrqID 19, ExcNo 35 */ m0_sgpio_isr, + /* IrqID 20, ExcNo 36 */ m0_spi_or_dac_isr, + /* IrqID 21, ExcNo 37 */ m0_adc1_isr, + /* IrqID 22, ExcNo 38 */ m0_ssp0_or_ssp1_isr, + /* IrqID 23, ExcNo 39 */ m0_eventrouter_isr, + /* IrqID 24, ExcNo 40 */ m0_usart0_isr, + /* IrqID 25, ExcNo 41 */ m0_uart1_isr, + /* IrqID 26, ExcNo 42 */ m0_usart2_or_c_can1_isr, + /* IrqID 27, ExcNo 43 */ m0_usart3_isr, + /* IrqID 28, ExcNo 44 */ m0_i2s0_or_i2s1_isr, + /* IrqID 29, ExcNo 45 */ m0_c_can0_isr, + /* IrqID 30, ExcNo 46 */ 0, + /* IrqID 31, ExcNo 47 */ 0 +}; + +#define MMIO32(addr) (*(volatile unsigned long*)(addr)) +#define CREG_M0APPMAP MMIO32( (0x40043404) ) + +void WEAK reset_handler(void) +{ + volatile unsigned long *dest; + volatile unsigned long *src; + __asm__("MSR msp, %0" : : "r"(&_stack)); + + src = (unsigned long*)&vector_table; + /* Change Shadow memory to RAM (vector table) to have access to Vector Table from virtual adr 0x0 */ + CREG_M0APPMAP = (unsigned long)src; + + /* Data does not need to be copied as M4 have already copied the whole bin including code+data */ + + /* Set BSS */ + for (dest = (unsigned long*)(&_bss); dest < (unsigned long*)(&_ebss); ) + *dest++ = 0; + + /* Call the application's entry point. */ + main(); +} + +void blocking_handler(void) +{ + while (1) ; +} + +void null_handler(void) +{ + /* Do nothing. */ +} + +#pragma weak nmi_handler = null_handler +#pragma weak hard_fault_handler = blocking_handler +#pragma weak mem_manage_handler = blocking_handler +#pragma weak bus_fault_handler = blocking_handler +#pragma weak usage_fault_handler = blocking_handler +#pragma weak sv_call_handler = null_handler +#pragma weak debug_monitor_handler = null_handler +#pragma weak pend_sv_handler = null_handler + +/* M0 */ +#pragma weak m0_rtc_isr = blocking_handler +#pragma weak m0_m4core_isr = blocking_handler +#pragma weak m0_dma_isr = blocking_handler +#pragma weak m0_flasheepromat_isr = blocking_handler +#pragma weak m0_ethernet_isr = blocking_handler +#pragma weak m0_sdio_isr = blocking_handler +#pragma weak m0_lcd_isr = blocking_handler +#pragma weak m0_usb0_isr = blocking_handler +#pragma weak m0_usb1_isr = blocking_handler +#pragma weak m0_sct_isr = blocking_handler +#pragma weak m0_ritimer_or_wwdt_isr = blocking_handler +#pragma weak m0_timer0_isr = blocking_handler +#pragma weak m0_gint1_isr = blocking_handler +#pragma weak m0_pin_int4_isr = blocking_handler +#pragma weak m0_timer3_isr = blocking_handler +#pragma weak m0_mcpwm_isr = blocking_handler +#pragma weak m0_adc0_isr = blocking_handler +#pragma weak m0_i2c0_or_i2c1_isr = blocking_handler +#pragma weak m0_sgpio_isr = blocking_handler +#pragma weak m0_spi_or_dac_isr = blocking_handler +#pragma weak m0_adc1_isr = blocking_handler +#pragma weak m0_ssp0_or_ssp1_isr = blocking_handler +#pragma weak m0_eventrouter_isr = blocking_handler +#pragma weak m0_usart0_isr = blocking_handler +#pragma weak m0_uart1_isr = blocking_handler +#pragma weak m0_usart2_or_c_can1_isr = blocking_handler +#pragma weak m0_usart3_isr = blocking_handler +#pragma weak m0_i2s0_or_i2s1_isr = blocking_handler +#pragma weak m0_c_can0_isr = blocking_handler