diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp index 27cd6428c3..f021ee8bd5 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -25,6 +25,8 @@ #define STACK_SIZE 512 #elif defined(TARGET_XDOT_L151CC) #define STACK_SIZE 1024 +#elif defined(TARGET_HI2110) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/PeripheralNames.h b/targets/TARGET_ublox/TARGET_HI2110/PeripheralNames.h new file mode 100644 index 0000000000..1dea196718 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/PeripheralNames.h @@ -0,0 +1,87 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define STDIO_UART_TX UART0_TX +#define STDIO_UART_RX UART0_RX + +typedef enum { + SERIAL_CONFIG_UARTLP_RX_UART0_TX, + SERIAL_CONFIG_UART0_RX_UART0_TX, + SERIAL_CONFIG_UART1_RX_UART1_TX, + MAX_NUM_SERIAL_CONFIGS +} SerialConfig; + +typedef enum { + PIN_FUNCTION_UNCLAIMED = 0, + PIN_FUNCTION_GPIO = 1, + PIN_FUNCTION_PWM0 = 2, + PIN_FUNCTION_PWM0B = 3, + PIN_FUNCTION_PWM1 = 4, + PIN_FUNCTION_PWM1B = 5, + PIN_FUNCTION_SSP0TXD = 6, + PIN_FUNCTION_SSP0RXD = 7, + PIN_FUNCTION_SSP0TRX = 8, + PIN_FUNCTION_SSP0CLK = 9, + PIN_FUNCTION_SSP0FSS = 10, + PIN_FUNCTION_SSP1CLK = 11, + PIN_FUNCTION_SSP1FSS = 12, + PIN_FUNCTION_SSP1TXD = 13, + PIN_FUNCTION_SSP1RXD = 14, + PIN_FUNCTION_SSP1TRX = 15, + PIN_FUNCTION_I2C0 = 16, + PIN_FUNCTION_I2C1 = 17, + PIN_FUNCTION_UART0_TXD = 18, + PIN_FUNCTION_UART0_TXIR = 19, + PIN_FUNCTION_UART0_O2 = 20, + PIN_FUNCTION_UART0_O1 = 21, + PIN_FUNCTION_UART0_RTS = 22, + PIN_FUNCTION_UART0_DTR = 23, + PIN_FUNCTION_UART0_RXD = 24, + PIN_FUNCTION_UART0_RXIR = 25, + PIN_FUNCTION_UART0_CTS = 26, + PIN_FUNCTION_UART0_DCD = 27, + PIN_FUNCTION_UART0_DSR = 28, + PIN_FUNCTION_UART0_RI = 29, + PIN_FUNCTION_UART1_TXD = 30, + PIN_FUNCTION_UART1_TXIR = 31, + PIN_FUNCTION_UART1_O2 = 32, + PIN_FUNCTION_UART1_O1 = 33, + PIN_FUNCTION_UART1_RTS = 34, + PIN_FUNCTION_UART1_DTR = 35, + PIN_FUNCTION_UART1_RXD = 36, + PIN_FUNCTION_UART1_RXIR = 37, + PIN_FUNCTION_UART1_CTS = 38, + PIN_FUNCTION_UART1_DCD = 39, + PIN_FUNCTION_UART1_DSR = 40, + PIN_FUNCTION_UART1_RI = 41, + PIN_FUNCTION_LP_UART = 42, + PIN_FUNCTION_MAX_NUMBER +} PinFunction; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/PortNames.h b/targets/TARGET_ublox/TARGET_HI2110/PortNames.h new file mode 100644 index 0000000000..68bbc8c3c1 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/PortNames.h @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, //GPIO pins 0-19 + PortMaxNumber +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/PinNames.h b/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/PinNames.h new file mode 100644 index 0000000000..175bec97d5 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/PinNames.h @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +typedef enum { + p0 = 0, + p1 = 1, + p2 = 2, + p3 = 3, + p4 = 4, + p5 = 5, + p6 = 6, + p7 = 7, + p8 = 8, + p9 = 9, + p10 = 10, + p11 = 11, + p12 = 12, + p13 = 13, + p14 = 14, + p15 = 15, + p16 = 16, + p17 = 17, + p18 = 18, + p19 = 19, + + UART0_RX = p13, + UART0_TX = p18, + UART0_CTS = p12, + UART0_RTS = p11, + I2C_SCL = p0, + I2C_SDA = p1, + SPI_CS = p2, + SPI_CLK = p3, + SPI_MOSI = p4, + SPI_MISO = p5, + UART1_RX = p7, + UART1_TX = p6, + LED1 = p2, + LED2 = p3, + LED3 = p4, + LED4 = p5, + + // mBed interface Pins + USBTX = UART0_TX, + USBRX = UART0_RX, + + P0_0 = p0, + P0_1 = p1, + P0_2 = p2, + P0_3 = p3, + P0_4 = p4, + P0_5 = p5, + P0_6 = p6, + P0_7 = p7, + P0_8 = p8, + P0_9 = p9, + P0_10 = p10, + P0_11 = p11, + P0_12 = p12, + P0_13 = p13, + P0_14 = p14, + P0_15 = p15, + P0_16 = p16, + P0_17 = p17, + P0_18 = p18, + P0_19 = p19, + NUM_PINS, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullNone = 0, + PullDown = 1, + PullUp = 0xff, /* TODO: current HI2110 chip does not have pull-up */ + PullDefault = PullDown /* TODO: mbed requires PullUp as default but HI2110 doesn't have it */ +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif // MBED_PINNAMES_H diff --git a/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/device.h b/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/device.h new file mode 100644 index 0000000000..493844b801 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/TARGET_SARA_NBIOT/device.h @@ -0,0 +1,23 @@ +// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. +// Check the 'features' section of the target description in 'targets.json' for more details. +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#include "objects.h" + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/hi2110.sct b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/hi2110.sct new file mode 100644 index 0000000000..d7d9d47213 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/hi2110.sct @@ -0,0 +1,15 @@ +LR_IROM1 0x00000000 0x20000 { + ER_IROM1 0x00000000 0x20000 { + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM_VTABLE 0x01000000 EMPTY 128 { + } + RW_IRAM1 +0 (0x5000 - 256) { + .ANY (+RW +ZI) + } + RW_IPCRAM +0 256 { + ipc.o (+RW) + } +} \ No newline at end of file diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/startup_hi2110.s b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/startup_hi2110.s new file mode 100644 index 0000000000..2bc9ff7703 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/startup_hi2110.s @@ -0,0 +1,163 @@ +; mbed Microcontroller Library +; Copyright (c) 2016 u-blox. +;Licensed under the Apache License, Version 2.0 (the "License"); +;you may not use this file except in compliance with the License. +;You may obtain a copy of the License at +;http://www.apache.org/licenses/LICENSE-2.0 +;Unless required by applicable law or agreed to in writing, software +;distributed under the License is distributed on an "AS IS" BASIS, +;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;See the License for the specific language governing permissions and +;limitations under the License. + +; Description message + +__initial_sp EQU (0x01000000 + 0x5000 - 256) + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; External Interrupts + DCD IRQ0_RTC_Handler + DCD IRQ1_TMR0_Handler + DCD IRQ2_SECURITY_Handler + DCD IRQ3_PROTOCOL_Handler + DCD IRQ4_APPS_Handler + DCD IRQ5_GPIO_Handler + DCD IRQ6_DMA_Handler + DCD IRQ7_UART0_Handler + DCD IRQ8_UART1_Handler + DCD IRQ9_SSP0_Handler + DCD IRQ10_SSP1_Handler + DCD IRQ11_PWM0IN_Handler + DCD IRQ12_PWM0OUT_Handler + DCD IRQ13_PWM1IN_Handler + DCD IRQ14_PWM1OUT_Handler + DCD IRQ15_I2C_Handler + DCD IRQ16_LPUART_Handler + DCD IRQ17_CAP_Handler + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT IRQ0_RTC_Handler [WEAK] + EXPORT IRQ1_TMR0_Handler [WEAK] + EXPORT IRQ2_SECURITY_Handler [WEAK] + EXPORT IRQ3_PROTOCOL_Handler [WEAK] + EXPORT IRQ4_APPS_Handler [WEAK] + EXPORT IRQ5_GPIO_Handler [WEAK] + EXPORT IRQ6_DMA_Handler [WEAK] + EXPORT IRQ7_UART0_Handler [WEAK] + EXPORT IRQ8_UART1_Handler [WEAK] + EXPORT IRQ9_SSP0_Handler [WEAK] + EXPORT IRQ10_SSP1_Handler [WEAK] + EXPORT IRQ11_PWM0IN_Handler [WEAK] + EXPORT IRQ12_PWM0OUT_Handler [WEAK] + EXPORT IRQ13_PWM1IN_Handler [WEAK] + EXPORT IRQ14_PWM1OUT_Handler [WEAK] + EXPORT IRQ15_I2C_Handler [WEAK] + EXPORT IRQ16_LPUART_Handler [WEAK] + EXPORT IRQ17_CAP_Handler [WEAK] +IRQ0_RTC_Handler +IRQ1_TMR0_Handler +IRQ2_SECURITY_Handler +IRQ3_PROTOCOL_Handler +IRQ4_APPS_Handler +IRQ5_GPIO_Handler +IRQ6_DMA_Handler +IRQ7_UART0_Handler +IRQ8_UART1_Handler +IRQ9_SSP0_Handler +IRQ10_SSP1_Handler +IRQ11_PWM0IN_Handler +IRQ12_PWM0OUT_Handler +IRQ13_PWM1IN_Handler +IRQ14_PWM1OUT_Handler +IRQ15_I2C_Handler +IRQ16_LPUART_Handler +IRQ17_CAP_Handler + + B . + ENDP + ALIGN + END diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/sys.cpp new file mode 100644 index 0000000000..6e74061d9a --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_ARM_STD/sys.cpp @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library - stackheap + * Copyright (C) 2009-2016 ARM Limited. All rights reserved. + * + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern char Image$$RW_IRAM1$$ZI$$Limit[]; + +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t sp_limit = __current_sp(); + + zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned + + struct __initial_stackheap r; + r.heap_base = zi_limit; + r.heap_limit = sp_limit; + return r; +} + +#ifdef __cplusplus +} +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/hi2110.ld b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/hi2110.ld new file mode 100644 index 0000000000..c39ec675a3 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/hi2110.ld @@ -0,0 +1,170 @@ +/* mbed Microcontroller Library */ +/* Copyright (c) 2016 u-blox. */ + +OUTPUT_FORMAT("elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) +MEMORY +{ + FLASH_VECTORS : ORIGIN = 0, LENGTH = 192 + FLASH : ORIGIN = (0 + 192), LENGTH = (0x20000 - 192) + RAM_VECTORS : ORIGIN = 0, LENGTH = 128 /* Reserve space for dynamic vectors mapped to RAM (see cmsis_nvic.c) */ + RAM : ORIGIN = 0x01000000 + 128, LENGTH = 0x5000 - 256 + IPC_MAILBOX : ORIGIN = (0x01000000 + 128 + 0x5000 - 256), LENGTH = 256 +} +SECTIONS +{ + /* Vector table in FLASH */ + . = 0; + startup : + { + KEEP (*(.isr_vector)) + } > FLASH_VECTORS + + /* Code and const data */ + .text : + { + . = ALIGN(4); + *(.text) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata) + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + __etext = .; + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __RAM_START__ = ORIGIN(RAM); + __RAM_SIZE__ = LENGTH(RAM); + + /* Initialised data */ + .data : + { + FILL(0xFF) + __data_load__ = LOADADDR(.data); + __data_start__ = .; + *(.data) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + __data_end__ = .; + } > RAM AT > FLASH + + __data_size__ = __data_end__ - __data_start__; + + /* Uninitialised data */ + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + __bss_size__ = __bss_end__ - __bss_start__; + + .resume (NOLOAD): + { + . = ALIGN(4); + *(preserve) + } > RAM + + /* Heap fills the rest of the space up to the start of the stack */ + .heap (NOLOAD): + { + __end__ = .; + end = __end__; + __HeapBase = .; + *(.heap*) + . = ORIGIN(RAM) + LENGTH(RAM) - Stack_Size; /* Remember that LENGTH(RAM) is already reduced by the IPC block */ + __HeapLimit = .; + } > RAM + + PROVIDE(__heap_start = ADDR(.heap)); + PROVIDE(__heap_size = SIZEOF(.heap)); + PROVIDE(__mbed_sbrk_start = ADDR(.heap)); + PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap)); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + __SYSTEM_STACK_START__ = .; + *(.stack*) + __SYSTEM_STACK_END__ = .; + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); /* Remember that LENGTH(RAM) is already reduced by the IPC block */ + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + /* IPC mailboxes at the top of RAM */ + /* The size of this section (256 bytes) is already taken off the size of RAM so there is no danger of the heap overflowing into it */ + .ipc_mailbox (NOLOAD): + { + . = ALIGN(4); + __ipc_mailbox_start__ = .; + *(.ipc_mailbox) + *(.ipc_mailbox*) + __ipc_mailbox_end__ = .; + } > IPC_MAILBOX +} \ No newline at end of file diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s new file mode 100644 index 0000000000..b1de07a1d1 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s @@ -0,0 +1,254 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + .syntax unified + .cpu cortex-m0 + .fpu softvfp + .thumb + +/* Setup the stack + * Since it grows downward the stack_system is the first location is the highest address + * The first other usage should therefore be at stack_system + 4 + * Should the stack overflow, there would be a hard fault in the core + */ + + .section .stacks,"aw",%progbits + +#ifdef __STACK_SIZE + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 1024 +#endif + .globl Stack_Size + .globl __StackTop + .globl __StackLimit + .align 2 + .type stack_system, %object + .size stack_system, Stack_Size +stack_system_end: + .space Stack_Size - 4 +stack_system: + .space 4 + + +/* This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + */ + .section .text.Reset_Handler,"ax",%progbits + .weak Reset_Handler + .type Reset_Handler, %function + .thumb + .func Reset_Handler +Reset_Handler: + + /* Make sure SP is really at the start of the stack */ + ldr r0, =stack_system + msr msp, r0 + + /* Prefill the system stack with 0xefbeadde (or deafbeef in little endian) */ + ldr r1, =__SYSTEM_STACK_START__ + ldr r3, =__SYSTEM_STACK_END__ + subs r3, r3, r1 + beq .stack_fill_loop_end + ldr r2, =0xefbeadde +.stack_fill_loop: + str r2, [r1, #0] /* Store the quad octet initialisation value in r2 into address in r1 */ + adds r1, r1, #4 /* Increased address in r1 by a quad octet */ + subs r3, r3, #4 /* Decrease the number of bytes to do by a quad octet */ + bgt .stack_fill_loop /* Keep going until it is all done */ +.stack_fill_loop_end: + + /* setup .data section */ + ldr r1, =__data_start__ + ldr r2, =__data_load__ + ldr r3, =__data_size__ + cmp r3, #0 + beq .end_set_data_loop + +.set_data_loop: + ldrb r4, [r2, #0] /* Load the octet value into r4 from address in r2 */ + strb r4, [r1, #0] /* Store the octet value in r4 to address in r1 */ + adds r2, r2, #1 /* Move onto next octet */ + adds r1, r1, #1 + subs r3, r3, #1 /* Decrease the number of bytes to do by an octet */ + bgt .set_data_loop /* Keep going until it is all done */ +.end_set_data_loop: + + /* Call init function */ + ldr r0, =SystemInit + blx r0 + + /* Call C++ startup */ + ldr r0, =_start + bx r0 + bl . + + .size Reset_Handler, .-Reset_Handler + .endfunc + +/* This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + */ + .section .text.Default_Handler,"ax",%progbits + .global Default_Handler + .func Default_Handler +Default_Handler: +Infinite_Loop: + b Infinite_Loop + + .endfunc + .size Default_Handler, .-Default_Handler + +/****************************************************************************** + * The minimal vector table for a Cortex M0+. Note that the proper constructs + * must be placed on this to ensure that it ends up at physical address 0x0000.0000. + *******************************************************************************/ + + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + .global g_pfnVectors + +g_pfnVectors: + .word stack_system + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word 0 + .word 0 + .word PendSV_Handler + .word SysTick_Handler + +/* External Interrupts */ + .word IRQ0_RTC_Handler + .word IRQ1_TMR0_Handler + .word IRQ2_SECURITY_Handler + .word IRQ3_PROTOCOL_Handler + .word IRQ4_APPS_Handler + .word IRQ5_GPIO_Handler + .word IRQ6_DMA_Handler + .word IRQ7_UART0_Handler + .word IRQ8_UART1_Handler + .word IRQ9_SSP0_Handler + .word IRQ10_SSP1_Handler + .word IRQ11_PWM0IN_Handler + .word IRQ12_PWM0OUT_Handler + .word IRQ13_PWM1IN_Handler + .word IRQ14_PWM1OUT_Handler + .word IRQ15_I2C_Handler + .word IRQ16_LPUART_Handler + .word IRQ17_CAP_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + +/******************************************************************************* + * Provide weak aliases for each Exception handler to the Default_Handler. + * As they are weak aliases, any function with the same name will override this definition. + * Note: For system exception handlers we don't want those references to be weak + * - we want to force someone to write those handlers. + *******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak IRQ0_RTC_Handler + .thumb_set IRQ0_RTC_Handler,Default_Handler + + .weak IRQ1_TMR0_Handler + .thumb_set IRQ1_TMR0_Handler,Default_Handler + + .weak IRQ2_SECURITY_Handler + .thumb_set IRQ2_SECURITY_Handler,Default_Handler + + .weak IRQ3_PROTOCOL_Handler + .thumb_set IRQ3_PROTOCOL_Handler,Default_Handler + + .weak IRQ4_APPS_Handler + .thumb_set IRQ4_APPS_Handler,Default_Handler + + .weak IRQ5_GPIO_Handler + .thumb_set IRQ5_GPIO_Handler,Default_Handler + + .weak IRQ6_DMA_Handler + .thumb_set IRQ6_DMA_Handler,Default_Handler + + .weak IRQ7_UART0_Handler + .thumb_set IRQ7_UART0_Handler,Default_Handler + + .weak IRQ8_UART1_Handler + .thumb_set IRQ8_UART1_Handler,Default_Handler + + .weak IRQ9_SSP0_Handler + .thumb_set IRQ9_SSP0_Handler,Default_Handler + + .weak IRQ10_SSP1_Handler + .thumb_set IRQ10_SSP1_Handler,Default_Handler + + .weak IRQ11_PWM0IN_Handler + .thumb_set IRQ11_PWM0IN_Handler,Default_Handler + + .weak IRQ12_PWM0OUT_Handler + .thumb_set IRQ12_PWM0OUT_Handler,Default_Handler + + .weak IRQ13_PWM1IN_Handler + .thumb_set IRQ13_PWM1IN_Handler,Default_Handler + + .weak IRQ14_PWM1OUT_Handler + .thumb_set IRQ14_PWM1OUT_Handler,Default_Handler + + .weak IRQ15_I2C_Handler + .thumb_set IRQ15_I2C_Handler,Default_Handler + + .weak IRQ16_LPUART_Handler + .thumb_set IRQ16_LPUART_Handler,Default_Handler + + .weak IRQ17_CAP_Handler + .thumb_set IRQ17_CAP_Handler,Default_Handler + diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/hi2110.icf b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/hi2110.icf new file mode 100644 index 0000000000..356658423a --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/hi2110.icf @@ -0,0 +1,60 @@ +/* Sizes and locations */ + +define symbol __start_flash__ = 0x00000000; +define symbol __size_flash__ = 0x20000; +define symbol __start_ram__ = 0x01000000; +define symbol __size_ram__ = 0x5000; +define symbol __size_flash_vtable__ = 192; +define symbol __size_ram_vtable__ = 128; /* Reserve space for dynamic vectors mapped to RAM (see cmsis_nvic.c) */ +define symbol __size_ipc__ = 256; + +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 1024; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = (1024 * 8); +} + +/* Memory regions */ + +define symbol __region_INTVEC_FLASH_start__ = __start_flash__; +define symbol __region_INTVEC_FLASH_end__ = __start_flash__ + __size_flash_vtable__ - 1; +define symbol __region_TEXT_start__ = __start_flash__ + __size_flash_vtable__; /* Leave room for flash vector table at start */ +define symbol __region_TEXT_end__ = __start_flash__ + __size_flash__ - 1; +define symbol __region_INTVEC_RAM_start__ = __start_ram__; +define symbol __region_DATA_start__ = __start_ram__ + __size_ram_vtable__; /* Leave room for RAM vector table at start */ +define symbol __region_DATA_end__ = __start_ram__ + __size_ram__ - __size_cstack__ - __size_ipc__ - 1; /* Leave room for IPC and stack at end */ +define symbol __region_CSTACK_start__ = __start_ram__ + __size_ram__ - __size_cstack__ - __size_ipc__; +define symbol __region_CSTACK_end__ = __start_ram__ + __size_ram__ - __size_ipc__ - 1; +define symbol __region_IPC_start__ = __start_ram__ + __size_ram__ - __size_ipc__; +define symbol __region_IPC_end__ = __start_ram__ + __size_ram__ - 1; + +define memory mem with size = 4G; +define region FLASH_region = mem:[from __region_INTVEC_FLASH_start__ to __region_INTVEC_FLASH_end__] | mem:[from __region_TEXT_start__ to __region_TEXT_end__]; +define region DATA_region = mem:[from __region_DATA_start__ to __region_DATA_end__]; +define region CSTACK_region = mem:[from __region_CSTACK_start__ to __region_CSTACK_end__]; +define region IPC_region = mem:[from __region_IPC_start__ to __region_IPC_end__]; + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +/* Place sections */ + +initialize by copy { readwrite }; +do not initialize { section .noinit }; +do not initialize { section .ipc }; + +place at address mem:__region_INTVEC_FLASH_start__ { readonly section .intvec }; +place in FLASH_region { readonly }; +place in DATA_region { block RW }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in IPC_region { section .ipc }; diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/startup_hi2110.s b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/startup_hi2110.s new file mode 100644 index 0000000000..0c69cc0541 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_IAR/startup_hi2110.s @@ -0,0 +1,202 @@ +; mbed Microcontroller Library +; Copyright (c) 2016 u-blox. +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; http://www.apache.org/licenses/LICENSE-2.0 +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +; Description message + + MODULE ?cstartup + + ; Stack size default : 1024 + ; Heap size default : 2048 + + ; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler + DCD 0 + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + +; External Interrupts + DCD IRQ0_RTC_Handler + DCD IRQ1_TMR0_Handler + DCD IRQ2_SECURITY_Handler + DCD IRQ3_PROTOCOL_Handler + DCD IRQ4_APPS_Handler + DCD IRQ5_GPIO_Handler + DCD IRQ6_DMA_Handler + DCD IRQ7_UART0_Handler + DCD IRQ8_UART1_Handler + DCD IRQ9_SSP0_Handler + DCD IRQ10_SSP1_Handler + DCD IRQ11_PWM0IN_Handler + DCD IRQ12_PWM0OUT_Handler + DCD IRQ13_PWM1IN_Handler + DCD IRQ14_PWM1OUT_Handler + DCD IRQ15_I2C_Handler + DCD IRQ16_LPUART_Handler + DCD IRQ17_CAP_Handler + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD 0 + +__Vectors_End +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + +; Default handlers. + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + ; Dummy exception handlers + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + ; Dummy interrupt handlers + + PUBWEAK IRQ0_RTC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ0_RTC_Handler + B . + PUBWEAK IRQ1_TMR0_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ1_TMR0_Handler + B . + PUBWEAK IRQ2_SECURITY_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ2_SECURITY_Handler + B . + PUBWEAK IRQ3_PROTOCOL_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ3_PROTOCOL_Handler + B . + PUBWEAK IRQ4_APPS_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ4_APPS_Handler + B . + PUBWEAK IRQ5_GPIO_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ5_GPIO_Handler + B . + PUBWEAK IRQ6_DMA_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ6_DMA_Handler + B . + PUBWEAK IRQ7_UART0_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ7_UART0_Handler + B . + PUBWEAK IRQ8_UART1_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ8_UART1_Handler + B . + PUBWEAK IRQ9_SSP0_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ9_SSP0_Handler + B . + PUBWEAK IRQ10_SSP1_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ10_SSP1_Handler + B . + PUBWEAK IRQ11_PWM0IN_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ11_PWM0IN_Handler + B . + PUBWEAK IRQ12_PWM0OUT_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ12_PWM0OUT_Handler + B . + PUBWEAK IRQ13_PWM1IN_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ13_PWM1IN_Handler + B . + PUBWEAK IRQ14_PWM1OUT_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ14_PWM1OUT_Handler + B . + PUBWEAK IRQ15_I2C_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ15_I2C_Handler + B . + PUBWEAK IRQ16_LPUART_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ16_LPUART_Handler + B . + PUBWEAK IRQ17_CAP_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +IRQ17_CAP_Handler + + END diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis.h b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis.h new file mode 100644 index 0000000000..b14157ad41 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis.h @@ -0,0 +1,27 @@ +/* + * PackageLicenseDeclared: Apache-2.0 + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "hi2110.h" +#include "cmsis_nvic.h" + +/** Reference clock in Hz */ +#define CLOCKS_REFERENCE_CLOCK_FREQ 32768 + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c new file mode 100644 index 0000000000..86531fc09d --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c @@ -0,0 +1,50 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2011 ARM Limited. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of ARM Limited nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis_nvic.h" + +#define NVIC_RAM_VECTOR_ADDRESS (0x01000000) // Location of vectors in RAM +#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { + // Space for dynamic vectors, initialised to allocate in R/W + static volatile uint32_t* vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; + + // Set the vector + vectors[IRQn + 16] = vector; +} + +uint32_t NVIC_GetVector(IRQn_Type IRQn) { + // We can always read vectors at 0x0, as the addresses are remapped + uint32_t *vectors = (uint32_t*)0; + + // Return the vector + return vectors[IRQn + 16]; +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h new file mode 100644 index 0000000000..46ee73e063 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h @@ -0,0 +1,38 @@ +/* + * PackageLicenseDeclared: Apache-2.0 + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_USER_IRQ_OFFSET 16 + +#include "cmsis.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/hi2110.h b/targets/TARGET_ublox/TARGET_HI2110/device/hi2110.h new file mode 100644 index 0000000000..bbc1a08c35 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/hi2110.h @@ -0,0 +1,492 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HI2110_H +#define HI2110_H + +#ifdef __cplusplus + extern "C" { +#endif + +/******************************************************************************/ +/* Processor and Core Peripherals */ +/******************************************************************************/ + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +typedef enum IRQn +{ +/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/ + Thread_mode = -16, /*!< 0 Thread mode */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 Hard Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/****** Device Specific Interrupt Numbers ********************************************************/ + RTC_IRQn = 0, /*!< RTC Interrupt */ + Timer_IRQn = 1, /*!< Timer Interrupt */ + Security_IRQn = 2, /*!< From Security Interrupt */ + Protocol_IRQn = 3, /*!< From Protocol Interrupt */ + Apps_IRQn = 4, /*!< Core Self Interrupt */ + GPIO_IRQn = 5, /*!< GPIO Interrupt */ + DMA_IRQn = 6, /*!< DMA Interrupt */ + UART0_IRQn = 7, /*!< UART0 Interrupt */ + UART1_IRQn = 8, /*!< UART1 Interrupt */ + SSP0_IRQn = 9, /*!< SPI0 Interrupt */ + SSP1_IRQn = 10, /*!< SPI1 Interrupt */ + PWM0_Inner_IRQn = 11, /*!< PW0 Inner Interrupt */ + PWM0_Outer_IRQn = 12, /*!< PW0 Outer Interrupt */ + PWM1_Inner_IRQn = 13, /*!< PW1 Inner Interrupt */ + PWM1_Outer_IRQn = 14, /*!< PW1 Outer Interrupt */ + I2C_IRQn = 15, /*!< I2C Interrupt */ + LPUART_IRQn = 16, /*!< Low Power UART Interrupt */ + CAP_IRQn = 17, /*!< CAP Interrupt */ + COMP_IRQn = 18, /*!< COMP Interrupt */ + EDGE_IRQn = 19, /*!< EDGE Interrupt */ + Pulse_SWD_IRQn = 23, /*!< SWD Pulse Interrupt */ + +} IRQn_Type; + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/* Configuration of the Cortex-M# Processor and Core Peripherals */ +#define __CM0_REV 0x0000 /*!< Core Revision r2p1 */ +#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __FPU_PRESENT 0 /*!< FPU present or not */ + +#include /* Cortex-M# processor and core peripherals */ + +/******************************************************************************/ +/* Device Specific Peripheral registers structures */ +/******************************************************************************/ + +/* UART */ +typedef struct { + uint32_t UARTDR; + uint32_t UARTRSR; + uint32_t res0; + uint32_t res1; + uint32_t res2; + uint32_t res3; + uint32_t UARTFR; + uint32_t res4; + uint32_t UARTILPR; + uint32_t UARTIBRD; // Integer baud divider + uint32_t UARTFBRD; // Fractional Baud divider + uint32_t UARTLCR_H; + uint32_t UARTCR; + uint32_t UARTIFLS; + uint32_t UARTIMSC; + uint32_t UARTRIS; + uint32_t UARTMIS; + uint32_t UARTICR; + uint32_t UARTDMACR; +} uart_ctrl_t; + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ + +#define RTC_IRQ_TIME_LSBS (*(volatile uint32_t *)(0x40002000)) +#define RTC_IRQ_TIME_LSBS_BITSET (*(volatile uint32_t *)(0x40002400)) +#define RTC_IRQ_TIME_LSBS_BITCLR (*(volatile uint32_t *)(0x40002800)) +#define RTC_IRQ_TIME_LSBS_BITTOG (*(volatile uint32_t *)(0x40002C00)) +#define RTC_IRQ_TIME_MSBS (*(volatile uint32_t *)(0x40002004)) +#define RTC_IRQ_TIME_MSBS_BITSET (*(volatile uint32_t *)(0x40002404)) +#define RTC_IRQ_TIME_MSBS_BITCLR (*(volatile uint32_t *)(0x40002804)) +#define RTC_IRQ_TIME_MSBS_BITTOG (*(volatile uint32_t *)(0x40002C04)) +#define RTC_IRQ_CLR (*(volatile uint32_t *)(0x40002008)) +#define RTC_IRQ_CLR_BITSET (*(volatile uint32_t *)(0x40002408)) +#define RTC_IRQ_CLR_BITCLR (*(volatile uint32_t *)(0x40002808)) +#define RTC_IRQ_CLR_BITTOG (*(volatile uint32_t *)(0x40002C08)) +#define TIMER0_LOAD (*(volatile uint32_t *)(0x4000200C)) +#define TIMER0_LOAD_BITSET (*(volatile uint32_t *)(0x4000240C)) +#define TIMER0_LOAD_BITCLR (*(volatile uint32_t *)(0x4000280C)) +#define TIMER0_LOAD_BITTOG (*(volatile uint32_t *)(0x40002C0C)) +#define TIMER0_CTRL (*(volatile uint32_t *)(0x40002010)) +#define TIMER0_CTRL_BITSET (*(volatile uint32_t *)(0x40002410)) +#define TIMER0_CTRL_BITCLR (*(volatile uint32_t *)(0x40002810)) +#define TIMER0_CTRL_BITTOG (*(volatile uint32_t *)(0x40002C10)) +#define TIMER0_TIME (*(volatile uint32_t *)(0x40002014)) +#define ARM_IRQ_REG (*(volatile uint32_t *)(0x40002018)) +#define ARM_IRQ_REG_BITSET (*(volatile uint32_t *)(0x40002418)) +#define ARM_IRQ_REG_BITCLR (*(volatile uint32_t *)(0x40002818)) +#define ARM_IRQ_REG_BITTOG (*(volatile uint32_t *)(0x40002C18)) +#define PIO_FUNC0 (*(volatile uint32_t *)(0x4000201C)) +#define PIO_FUNC0_BITSET (*(volatile uint32_t *)(0x4000241C)) +#define PIO_FUNC0_BITCLR (*(volatile uint32_t *)(0x4000281C)) +#define PIO_FUNC0_BITTOG (*(volatile uint32_t *)(0x40002C1C)) +#define PIO_FUNC1 (*(volatile uint32_t *)(0x40002020)) +#define PIO_FUNC1_BITSET (*(volatile uint32_t *)(0x40002420)) +#define PIO_FUNC1_BITCLR (*(volatile uint32_t *)(0x40002820)) +#define PIO_FUNC1_BITTOG (*(volatile uint32_t *)(0x40002C20)) +#define PIO_FUNC2 (*(volatile uint32_t *)(0x40002024)) +#define PIO_FUNC2_BITSET (*(volatile uint32_t *)(0x40002424)) +#define PIO_FUNC2_BITCLR (*(volatile uint32_t *)(0x40002824)) +#define PIO_FUNC2_BITTOG (*(volatile uint32_t *)(0x40002C24)) +#define PIO_FUNC3 (*(volatile uint32_t *)(0x40002028)) +#define PIO_FUNC3_BITSET (*(volatile uint32_t *)(0x40002428)) +#define PIO_FUNC3_BITCLR (*(volatile uint32_t *)(0x40002828)) +#define PIO_FUNC3_BITTOG (*(volatile uint32_t *)(0x40002C28)) +#define PIO_FUNC4 (*(volatile uint32_t *)(0x4000202C)) +#define PIO_FUNC4_BITSET (*(volatile uint32_t *)(0x4000242C)) +#define PIO_FUNC4_BITCLR (*(volatile uint32_t *)(0x4000282C)) +#define PIO_FUNC4_BITTOG (*(volatile uint32_t *)(0x40002C2C)) +#define GPIO_DIR (*(volatile uint32_t *)(0x40002030)) +#define GPIO_DIR_BITSET (*(volatile uint32_t *)(0x40002430)) +#define GPIO_DIR_BITCLR (*(volatile uint32_t *)(0x40002830)) +#define GPIO_DIR_BITTOG (*(volatile uint32_t *)(0x40002C30)) +#define GPIO_OUT (*(volatile uint32_t *)(0x40002034)) +#define GPIO_OUT_BITSET (*(volatile uint32_t *)(0x40002434)) +#define GPIO_OUT_BITCLR (*(volatile uint32_t *)(0x40002834)) +#define GPIO_OUT_BITTOG (*(volatile uint32_t *)(0x40002C34)) +#define GPIO_DRIVE (*(volatile uint32_t *)(0x40002038)) +#define GPIO_DRIVE_BITSET (*(volatile uint32_t *)(0x40002438)) +#define GPIO_DRIVE_BITCLR (*(volatile uint32_t *)(0x40002838)) +#define GPIO_DRIVE_BITTOG (*(volatile uint32_t *)(0x40002C38)) +#define GPIO_PULLEN (*(volatile uint32_t *)(0x4000203C)) +#define GPIO_PULLEN_BITSET (*(volatile uint32_t *)(0x4000243C)) +#define GPIO_PULLEN_BITCLR (*(volatile uint32_t *)(0x4000283C)) +#define GPIO_PULLEN_BITTOG (*(volatile uint32_t *)(0x40002C3C)) +#define GPIO_INT_RISE (*(volatile uint32_t *)(0x40002040)) +#define GPIO_INT_RISE_BITSET (*(volatile uint32_t *)(0x40002440)) +#define GPIO_INT_RISE_BITCLR (*(volatile uint32_t *)(0x40002840)) +#define GPIO_INT_RISE_BITTOG (*(volatile uint32_t *)(0x40002C40)) +#define GPIO_INT_FALL (*(volatile uint32_t *)(0x40002044)) +#define GPIO_INT_FALL_BITSET (*(volatile uint32_t *)(0x40002444)) +#define GPIO_INT_FALL_BITCLR (*(volatile uint32_t *)(0x40002844)) +#define GPIO_INT_FALL_BITTOG (*(volatile uint32_t *)(0x40002C44)) +#define GPIO_INT_HIGH (*(volatile uint32_t *)(0x40002048)) +#define GPIO_INT_HIGH_BITSET (*(volatile uint32_t *)(0x40002448)) +#define GPIO_INT_HIGH_BITCLR (*(volatile uint32_t *)(0x40002848)) +#define GPIO_INT_HIGH_BITTOG (*(volatile uint32_t *)(0x40002C48)) +#define GPIO_INT_LOW (*(volatile uint32_t *)(0x4000204C)) +#define GPIO_INT_LOW_BITSET (*(volatile uint32_t *)(0x4000244C)) +#define GPIO_INT_LOW_BITCLR (*(volatile uint32_t *)(0x4000284C)) +#define GPIO_INT_LOW_BITTOG (*(volatile uint32_t *)(0x40002C4C)) +#define GPIO_INT_CLR (*(volatile uint32_t *)(0x40002050)) +#define GPIO_INT_CLR_BITSET (*(volatile uint32_t *)(0x40002450)) +#define GPIO_INT_CLR_BITCLR (*(volatile uint32_t *)(0x40002850)) +#define GPIO_INT_CLR_BITTOG (*(volatile uint32_t *)(0x40002C50)) +#define GPIO_VALUE (*(volatile uint32_t *)(0x40002054)) +#define GPIO_IRQ (*(volatile uint32_t *)(0x40002058)) +#define WDT_INTERVAL (*(volatile uint32_t *)(0x4000205C)) +#define WDT_INTERVAL_BITSET (*(volatile uint32_t *)(0x4000245C)) +#define WDT_INTERVAL_BITCLR (*(volatile uint32_t *)(0x4000285C)) +#define WDT_INTERVAL_BITTOG (*(volatile uint32_t *)(0x40002C5C)) +#define WDT_CTRL (*(volatile uint32_t *)(0x40002060)) +#define WDT_CTRL_BITSET (*(volatile uint32_t *)(0x40002460)) +#define WDT_CTRL_BITCLR (*(volatile uint32_t *)(0x40002860)) +#define WDT_CTRL_BITTOG (*(volatile uint32_t *)(0x40002C60)) +#define WDT_TIME (*(volatile uint32_t *)(0x40002064)) +#define RESET_CAUSE (*(volatile uint32_t *)(0x40002134)) +#define PWM0_CTRL (*(volatile uint32_t *)(0x40002068)) +#define PWM0_CTRL_BITSET (*(volatile uint32_t *)(0x40002468)) +#define PWM0_CTRL_BITCLR (*(volatile uint32_t *)(0x40002868)) +#define PWM0_CTRL_BITTOG (*(volatile uint32_t *)(0x40002C68)) +#define PWM0_COUNT (*(volatile uint32_t *)(0x4000206C)) +#define PWM0_COUNT_BITSET (*(volatile uint32_t *)(0x4000246C)) +#define PWM0_COUNT_BITCLR (*(volatile uint32_t *)(0x4000286C)) +#define PWM0_COUNT_BITTOG (*(volatile uint32_t *)(0x40002C6C)) +#define PWM1_CTRL (*(volatile uint32_t *)(0x40002070)) +#define PWM1_CTRL_BITSET (*(volatile uint32_t *)(0x40002470)) +#define PWM1_CTRL_BITCLR (*(volatile uint32_t *)(0x40002870)) +#define PWM1_CTRL_BITTOG (*(volatile uint32_t *)(0x40002C70)) +#define PWM1_COUNT (*(volatile uint32_t *)(0x40002074)) +#define PWM1_COUNT_BITSET (*(volatile uint32_t *)(0x40002474)) +#define PWM1_COUNT_BITCLR (*(volatile uint32_t *)(0x40002874)) +#define PWM1_COUNT_BITTOG (*(volatile uint32_t *)(0x40002C74)) +#define PWM_STATUS (*(volatile uint32_t *)(0x40002078)) +#define CLKEN_REG (*(volatile uint32_t *)(0x4000207C)) +#define CLKEN_REG_BITSET (*(volatile uint32_t *)(0x4000247C)) +#define CLKEN_REG_BITCLR (*(volatile uint32_t *)(0x4000287C)) +#define CLKEN_REG_BITTOG (*(volatile uint32_t *)(0x40002C7C)) +#define I2C_INTERRUPT_STATUS (*(volatile uint32_t *)(0x40002080)) +#define I2C_INTERRUPT_CLEAR (*(volatile uint32_t *)(0x40002084)) +#define I2C_INTERRUPT_CLEAR_BITSET (*(volatile uint32_t *)(0x40002484)) +#define I2C_INTERRUPT_CLEAR_BITCLR (*(volatile uint32_t *)(0x40002884)) +#define I2C_INTERRUPT_CLEAR_BITTOG (*(volatile uint32_t *)(0x40002C84)) +#define I2C_INTERRUPT_ENABLE (*(volatile uint32_t *)(0x40002088)) +#define I2C_INTERRUPT_ENABLE_BITSET (*(volatile uint32_t *)(0x40002488)) +#define I2C_INTERRUPT_ENABLE_BITCLR (*(volatile uint32_t *)(0x40002888)) +#define I2C_INTERRUPT_ENABLE_BITTOG (*(volatile uint32_t *)(0x40002C88)) +#define I2C_MODE (*(volatile uint32_t *)(0x4000208C)) +#define I2C_MODE_BITSET (*(volatile uint32_t *)(0x4000248C)) +#define I2C_MODE_BITCLR (*(volatile uint32_t *)(0x4000288C)) +#define I2C_MODE_BITTOG (*(volatile uint32_t *)(0x40002C8C)) +#define I2C_TX_DATA (*(volatile uint32_t *)(0x40002090)) +#define I2C_TX_DATA_BITSET (*(volatile uint32_t *)(0x40002490)) +#define I2C_TX_DATA_BITCLR (*(volatile uint32_t *)(0x40002890)) +#define I2C_TX_DATA_BITTOG (*(volatile uint32_t *)(0x40002C90)) +#define I2C_RX_DATA (*(volatile uint32_t *)(0x40002144)) +#define I2C_TX_RD_WRB (*(volatile uint32_t *)(0x40002094)) +#define I2C_TX_RD_WRB_BITSET (*(volatile uint32_t *)(0x40002494)) +#define I2C_TX_RD_WRB_BITCLR (*(volatile uint32_t *)(0x40002894)) +#define I2C_TX_RD_WRB_BITTOG (*(volatile uint32_t *)(0x40002C94)) +#define I2C_TX_NO_BYTES (*(volatile uint32_t *)(0x40002098)) +#define I2C_TX_NO_BYTES_BITSET (*(volatile uint32_t *)(0x40002498)) +#define I2C_TX_NO_BYTES_BITCLR (*(volatile uint32_t *)(0x40002898)) +#define I2C_TX_NO_BYTES_BITTOG (*(volatile uint32_t *)(0x40002C98)) +#define I2C_RX_NO_BYTES (*(volatile uint32_t *)(0x4000209C)) +#define I2C_RX_NO_BYTES_MASTER (*(volatile uint32_t *)(0x400020A0)) +#define I2C_RX_NO_BYTES_MASTER_BITSET (*(volatile uint32_t *)(0x400024A0)) +#define I2C_RX_NO_BYTES_MASTER_BITCLR (*(volatile uint32_t *)(0x400028A0)) +#define I2C_RX_NO_BYTES_MASTER_BITTOG (*(volatile uint32_t *)(0x40002CA0)) +#define I2C_GO (*(volatile uint32_t *)(0x400020A4)) +#define I2C_GO_BITSET (*(volatile uint32_t *)(0x400024A4)) +#define I2C_GO_BITCLR (*(volatile uint32_t *)(0x400028A4)) +#define I2C_GO_BITTOG (*(volatile uint32_t *)(0x40002CA4)) +#define I2C_RX_EARLY_THRESHOLD (*(volatile uint32_t *)(0x400020A8)) +#define I2C_RX_EARLY_THRESHOLD_BITSET (*(volatile uint32_t *)(0x400024A8)) +#define I2C_RX_EARLY_THRESHOLD_BITCLR (*(volatile uint32_t *)(0x400028A8)) +#define I2C_RX_EARLY_THRESHOLD_BITTOG (*(volatile uint32_t *)(0x40002CA8)) +#define I2C_RX_AUTO_NAG_BYTE_CNT (*(volatile uint32_t *)(0x400020AC)) +#define I2C_RX_AUTO_NAG_BYTE_CNT_BITSET (*(volatile uint32_t *)(0x400024AC)) +#define I2C_RX_AUTO_NAG_BYTE_CNT_BITCLR (*(volatile uint32_t *)(0x400028AC)) +#define I2C_RX_AUTO_NAG_BYTE_CNT_BITTOG (*(volatile uint32_t *)(0x40002CAC)) +#define I2C_HALF_TIME (*(volatile uint32_t *)(0x400020B0)) +#define I2C_HALF_TIME_BITSET (*(volatile uint32_t *)(0x400024B0)) +#define I2C_HALF_TIME_BITCLR (*(volatile uint32_t *)(0x400028B0)) +#define I2C_HALF_TIME_BITTOG (*(volatile uint32_t *)(0x40002CB0)) +#define I2C_ADDRESS (*(volatile uint32_t *)(0x400020B4)) +#define I2C_ADDRESS_BITSET (*(volatile uint32_t *)(0x400024B4)) +#define I2C_ADDRESS_BITCLR (*(volatile uint32_t *)(0x400028B4)) +#define I2C_ADDRESS_BITTOG (*(volatile uint32_t *)(0x40002CB4)) +#define I2C_ADDR_TYPE (*(volatile uint32_t *)(0x400020B8)) +#define I2C_ADDR_TYPE_BITSET (*(volatile uint32_t *)(0x400024B8)) +#define I2C_ADDR_TYPE_BITCLR (*(volatile uint32_t *)(0x400028B8)) +#define I2C_ADDR_TYPE_BITTOG (*(volatile uint32_t *)(0x40002CB8)) +#define I2C_SOFT_RESET (*(volatile uint32_t *)(0x400020BC)) +#define I2C_SOFT_RESET_BITSET (*(volatile uint32_t *)(0x400024BC)) +#define I2C_SOFT_RESET_BITCLR (*(volatile uint32_t *)(0x400028BC)) +#define I2C_SOFT_RESET_BITTOG (*(volatile uint32_t *)(0x40002CBC)) +#define I2C_SLAVE_RWB (*(volatile uint32_t *)(0x400020C0)) +#define I2C_MASTER_SM (*(volatile uint32_t *)(0x400020C4)) +#define I2C_SLAVE_SM (*(volatile uint32_t *)(0x400020C8)) +#define I2C_SLAVE_ENABLE (*(volatile uint32_t *)(0x400020CC)) +#define I2C_SLAVE_ENABLE_BITSET (*(volatile uint32_t *)(0x400024CC)) +#define I2C_SLAVE_ENABLE_BITCLR (*(volatile uint32_t *)(0x400028CC)) +#define I2C_SLAVE_ENABLE_BITTOG (*(volatile uint32_t *)(0x40002CCC)) +#define I2C_MASTER_SEND_RESTART (*(volatile uint32_t *)(0x400020D0)) +#define I2C_MASTER_SEND_RESTART_BITSET (*(volatile uint32_t *)(0x400024D0)) +#define I2C_MASTER_SEND_RESTART_BITCLR (*(volatile uint32_t *)(0x400028D0)) +#define I2C_MASTER_SEND_RESTART_BITTOG (*(volatile uint32_t *)(0x40002CD0)) +#define DMA_MUX (*(volatile uint32_t *)(0x400020D4)) +#define DMA_MUX_BITSET (*(volatile uint32_t *)(0x400024D4)) +#define DMA_MUX_BITCLR (*(volatile uint32_t *)(0x400028D4)) +#define DMA_MUX_BITTOG (*(volatile uint32_t *)(0x40002CD4)) +#define DMA_CTRL_STAT (*(volatile uint32_t *)(0x400020D8)) +#define COMP_CTRL (*(volatile uint32_t *)(0x400020DC)) +#define COMP_CTRL_BITSET (*(volatile uint32_t *)(0x400024DC)) +#define COMP_CTRL_BITCLR (*(volatile uint32_t *)(0x400028DC)) +#define COMP_CTRL_BITTOG (*(volatile uint32_t *)(0x40002CDC)) +#define COMP_STAT (*(volatile uint32_t *)(0x400020E0)) +#define LP_UART_CTRL (*(volatile uint32_t *)(0x400020E4)) +#define LP_UART_CTRL_BITSET (*(volatile uint32_t *)(0x400024E4)) +#define LP_UART_CTRL_BITCLR (*(volatile uint32_t *)(0x400028E4)) +#define LP_UART_CTRL_BITTOG (*(volatile uint32_t *)(0x40002CE4)) +#define LP_UART_STATUS (*(volatile uint32_t *)(0x400020E8)) +#define LP_UART_DATA (*(volatile uint32_t *)(0x40002154)) +#define CAP_FILT_CONF (*(volatile uint32_t *)(0x400020EC)) +#define CAP_FILT_CONF_BITSET (*(volatile uint32_t *)(0x400024EC)) +#define CAP_FILT_CONF_BITCLR (*(volatile uint32_t *)(0x400028EC)) +#define CAP_FILT_CONF_BITTOG (*(volatile uint32_t *)(0x40002CEC)) +#define CAP_IRQ_CONF (*(volatile uint32_t *)(0x400020F0)) +#define CAP_IRQ_CONF_BITSET (*(volatile uint32_t *)(0x400024F0)) +#define CAP_IRQ_CONF_BITCLR (*(volatile uint32_t *)(0x400028F0)) +#define CAP_IRQ_CONF_BITTOG (*(volatile uint32_t *)(0x40002CF0)) +#define CAP_STATUS (*(volatile uint32_t *)(0x400020F4)) +#define CORE_ENABLE_SWD_ACCESS_APPS (*(volatile uint32_t *)(0x400020F8)) +#define CORE_ENABLE_SWD_ACCESS_APPS_BITSET (*(volatile uint32_t *)(0x400024F8)) +#define CORE_ENABLE_SWD_ACCESS_APPS_BITCLR (*(volatile uint32_t *)(0x400028F8)) +#define CORE_ENABLE_SWD_ACCESS_APPS_BITTOG (*(volatile uint32_t *)(0x40002CF8)) +#define APPS_DEBUGGER_TO_CORE_DATA (*(volatile uint32_t *)(0x400020FC)) +#define APPS_CORE_TO_DEBUGGER_DATA (*(volatile uint32_t *)(0x40002100)) +#define APPS_CORE_TO_DEBUGGER_DATA_BITSET (*(volatile uint32_t *)(0x40002500)) +#define APPS_CORE_TO_DEBUGGER_DATA_BITCLR (*(volatile uint32_t *)(0x40002900)) +#define APPS_CORE_TO_DEBUGGER_DATA_BITTOG (*(volatile uint32_t *)(0x40002D00)) +#define APPS_DEBUG_DATA_TO_CORE_AVAILABLE (*(volatile uint32_t *)(0x40002104)) +#define APPS_DEBUG_DATA_TO_CORE_ACCEPTED (*(volatile uint32_t *)(0x40002108)) +#define APPS_DEBUG_DATA_TO_CORE_ACCEPTED_BITSET (*(volatile uint32_t *)(0x40002508)) +#define APPS_DEBUG_DATA_TO_CORE_ACCEPTED_BITCLR (*(volatile uint32_t *)(0x40002908)) +#define APPS_DEBUG_DATA_TO_CORE_ACCEPTED_BITTOG (*(volatile uint32_t *)(0x40002D08)) +#define APPS_CORE_DATA_TO_DEBUGGER_AVAILABLE (*(volatile uint32_t *)(0x4000210C)) +#define APPS_CORE_DATA_TO_DEBUGGER_AVAILABLE_BITSET (*(volatile uint32_t *)(0x4000250C)) +#define APPS_CORE_DATA_TO_DEBUGGER_AVAILABLE_BITCLR (*(volatile uint32_t *)(0x4000290C)) +#define APPS_CORE_DATA_TO_DEBUGGER_AVAILABLE_BITTOG (*(volatile uint32_t *)(0x40002D0C)) +#define APPS_CORE_DATA_TO_DEBUGGER_ACCEPTED (*(volatile uint32_t *)(0x40002110)) +#define SWD_REQUEST (*(volatile uint32_t *)(0x40002114)) +#define EDGE_CTRL0 (*(volatile uint32_t *)(0x40002118)) +#define EDGE_CTRL0_BITSET (*(volatile uint32_t *)(0x40002518)) +#define EDGE_CTRL0_BITCLR (*(volatile uint32_t *)(0x40002918)) +#define EDGE_CTRL0_BITTOG (*(volatile uint32_t *)(0x40002D18)) +#define EDGE_CTRL1 (*(volatile uint32_t *)(0x4000211C)) +#define EDGE_CTRL1_BITSET (*(volatile uint32_t *)(0x4000251C)) +#define EDGE_CTRL1_BITCLR (*(volatile uint32_t *)(0x4000291C)) +#define EDGE_CTRL1_BITTOG (*(volatile uint32_t *)(0x40002D1C)) +#define EDGE_COUNT (*(volatile uint32_t *)(0x40002120)) +#define RESET_REG (*(volatile uint32_t *)(0x40002124)) +#define RESET_REG_BITSET (*(volatile uint32_t *)(0x40002524)) +#define RESET_REG_BITCLR (*(volatile uint32_t *)(0x40002924)) +#define RESET_REG_BITTOG (*(volatile uint32_t *)(0x40002D24)) +#define DIGITAL_VERSION (*(volatile uint32_t *)(0x40000000)) +#define CLK_FREQ_DAC (*(volatile uint32_t *)(0x40000004)) +#define CLK_FREQ_SET (*(volatile uint32_t *)(0x40000008)) +#define CLK_FREQ_SET_BITSET (*(volatile uint32_t *)(0x40000408)) +#define CLK_FREQ_SET_BITCLR (*(volatile uint32_t *)(0x40000808)) +#define CLK_FREQ_SET_BITTOG (*(volatile uint32_t *)(0x40000C08)) +#define CLK_FREQ_NREFCLKS (*(volatile uint32_t *)(0x4000000C)) +#define CLK_FREQ_NREFCLKS_BITSET (*(volatile uint32_t *)(0x4000040C)) +#define CLK_FREQ_NREFCLKS_BITCLR (*(volatile uint32_t *)(0x4000080C)) +#define CLK_FREQ_NREFCLKS_BITTOG (*(volatile uint32_t *)(0x40000C0C)) +#define CLK_FREQ_REF_SEL (*(volatile uint32_t *)(0x40000010)) +#define CLK_FREQ_REF_SEL_BITSET (*(volatile uint32_t *)(0x40000410)) +#define CLK_FREQ_REF_SEL_BITCLR (*(volatile uint32_t *)(0x40000810)) +#define CLK_FREQ_REF_SEL_BITTOG (*(volatile uint32_t *)(0x40000C10)) +#define CLK_FREQ_DIG_CLKS (*(volatile uint32_t *)(0x40000014)) +#define CLK_FREQ_HIGHTARGET (*(volatile uint32_t *)(0x40000018)) +#define CLK_FREQ_HIGHTARGET_BITSET (*(volatile uint32_t *)(0x40000418)) +#define CLK_FREQ_HIGHTARGET_BITCLR (*(volatile uint32_t *)(0x40000818)) +#define CLK_FREQ_HIGHTARGET_BITTOG (*(volatile uint32_t *)(0x40000C18)) +#define CLK_FREQ_LOWTARGET (*(volatile uint32_t *)(0x4000001C)) +#define CLK_FREQ_LOWTARGET_BITSET (*(volatile uint32_t *)(0x4000041C)) +#define CLK_FREQ_LOWTARGET_BITCLR (*(volatile uint32_t *)(0x4000081C)) +#define CLK_FREQ_LOWTARGET_BITTOG (*(volatile uint32_t *)(0x40000C1C)) +#define CLK_FREQ_LP_BACKOFF (*(volatile uint32_t *)(0x40000020)) +#define CLK_FREQ_LP_BACKOFF_BITSET (*(volatile uint32_t *)(0x40000420)) +#define CLK_FREQ_LP_BACKOFF_BITCLR (*(volatile uint32_t *)(0x40000820)) +#define CLK_FREQ_LP_BACKOFF_BITTOG (*(volatile uint32_t *)(0x40000C20)) +#define CLK_FREQ_ENABLE (*(volatile uint32_t *)(0x40000024)) +#define CLK_FREQ_ENABLE_BITSET (*(volatile uint32_t *)(0x40000424)) +#define CLK_FREQ_ENABLE_BITCLR (*(volatile uint32_t *)(0x40000824)) +#define CLK_FREQ_ENABLE_BITTOG (*(volatile uint32_t *)(0x40000C24)) +#define CLK_GATE_SYS (*(volatile uint32_t *)(0x40000028)) +#define CLK_GATE_SYS_BITSET (*(volatile uint32_t *)(0x40000428)) +#define CLK_GATE_SYS_BITCLR (*(volatile uint32_t *)(0x40000828)) +#define CLK_GATE_SYS_BITTOG (*(volatile uint32_t *)(0x40000C28)) +#define CLK_GATE_MODEM (*(volatile uint32_t *)(0x4000002C)) +#define CLK_GATE_MODEM_BITSET (*(volatile uint32_t *)(0x4000042C)) +#define CLK_GATE_MODEM_BITCLR (*(volatile uint32_t *)(0x4000082C)) +#define CLK_GATE_MODEM_BITTOG (*(volatile uint32_t *)(0x40000C2C)) +#define CLK_GATE_RADIO (*(volatile uint32_t *)(0x40000030)) +#define CLK_GATE_RADIO_BITSET (*(volatile uint32_t *)(0x40000430)) +#define CLK_GATE_RADIO_BITCLR (*(volatile uint32_t *)(0x40000830)) +#define CLK_GATE_RADIO_BITTOG (*(volatile uint32_t *)(0x40000C30)) +#define CLK_GATE_DEBUG (*(volatile uint32_t *)(0x40000034)) +#define CLK_GATE_DEBUG_BITSET (*(volatile uint32_t *)(0x40000434)) +#define CLK_GATE_DEBUG_BITCLR (*(volatile uint32_t *)(0x40000834)) +#define CLK_GATE_DEBUG_BITTOG (*(volatile uint32_t *)(0x40000C34)) +#define CLK_GATE_RBIST (*(volatile uint32_t *)(0x40000038)) +#define CLK_GATE_RBIST_BITSET (*(volatile uint32_t *)(0x40000438)) +#define CLK_GATE_RBIST_BITCLR (*(volatile uint32_t *)(0x40000838)) +#define CLK_GATE_RBIST_BITTOG (*(volatile uint32_t *)(0x40000C38)) +#define LPC_CTRL (*(volatile uint32_t *)(0x4000003C)) +#define LPC_CTRL_BITSET (*(volatile uint32_t *)(0x4000043C)) +#define LPC_CTRL_BITCLR (*(volatile uint32_t *)(0x4000083C)) +#define LPC_CTRL_BITTOG (*(volatile uint32_t *)(0x40000C3C)) +#define LPC_TEST (*(volatile uint32_t *)(0x40000040)) +#define LPC_TEST_BITSET (*(volatile uint32_t *)(0x40000440)) +#define LPC_TEST_BITCLR (*(volatile uint32_t *)(0x40000840)) +#define LPC_TEST_BITTOG (*(volatile uint32_t *)(0x40000C40)) +#define FPGA_FLASH_WR (*(volatile uint32_t *)(0x40000044)) +#define FPGA_FLASH_WR_BITSET (*(volatile uint32_t *)(0x40000444)) +#define FPGA_FLASH_WR_BITCLR (*(volatile uint32_t *)(0x40000844)) +#define FPGA_FLASH_WR_BITTOG (*(volatile uint32_t *)(0x40000C44)) +#define FPGA_FLASH_RD (*(volatile uint32_t *)(0x40000048)) +#define PMU_CTRL (*(volatile uint32_t *)(0x4000004C)) +#define PMU_CTRL_BITSET (*(volatile uint32_t *)(0x4000044C)) +#define PMU_CTRL_BITCLR (*(volatile uint32_t *)(0x4000084C)) +#define PMU_CTRL_BITTOG (*(volatile uint32_t *)(0x40000C4C)) +#define APP_CTRL0 (*(volatile uint32_t *)(0x40000050)) +#define APP_CTRL0_BITSET (*(volatile uint32_t *)(0x40000450)) +#define APP_CTRL0_BITCLR (*(volatile uint32_t *)(0x40000850)) +#define APP_CTRL0_BITTOG (*(volatile uint32_t *)(0x40000C50)) +#define APP_CTRL1 (*(volatile uint32_t *)(0x40000054)) +#define APP_CTRL1_BITSET (*(volatile uint32_t *)(0x40000454)) +#define APP_CTRL1_BITCLR (*(volatile uint32_t *)(0x40000854)) +#define APP_CTRL1_BITTOG (*(volatile uint32_t *)(0x40000C54)) +#define APP_CTRL2 (*(volatile uint32_t *)(0x40000058)) +#define APP_CTRL2_BITSET (*(volatile uint32_t *)(0x40000458)) +#define APP_CTRL2_BITCLR (*(volatile uint32_t *)(0x40000858)) +#define APP_CTRL2_BITTOG (*(volatile uint32_t *)(0x40000C58)) +#define APP_CTRL3 (*(volatile uint32_t *)(0x4000005C)) +#define APP_CTRL3_BITSET (*(volatile uint32_t *)(0x4000045C)) +#define APP_CTRL3_BITCLR (*(volatile uint32_t *)(0x4000085C)) +#define APP_CTRL3_BITTOG (*(volatile uint32_t *)(0x40000C5C)) +#define PMU_STAT (*(volatile uint32_t *)(0x40000060)) +#define PMUBIST_ADC_CONF (*(volatile uint32_t *)(0x40000064)) +#define PMUBIST_ADC_CONF_BITSET (*(volatile uint32_t *)(0x40000464)) +#define PMUBIST_ADC_CONF_BITCLR (*(volatile uint32_t *)(0x40000864)) +#define PMUBIST_ADC_CONF_BITTOG (*(volatile uint32_t *)(0x40000C64)) +#define PMUBIST_ADC_DATA (*(volatile uint32_t *)(0x40000068)) +#define STATUS (*(volatile uint32_t *)(0x4000006C)) +#define LPC_STATUS (*(volatile uint32_t *)(0x40000070)) +#define LPC_PDTIMER (*(volatile uint32_t *)(0x40000074)) +#define LPC_PDTIMER_BITSET (*(volatile uint32_t *)(0x40000474)) +#define LPC_PDTIMER_BITCLR (*(volatile uint32_t *)(0x40000874)) +#define LPC_PDTIMER_BITTOG (*(volatile uint32_t *)(0x40000C74)) +#define PIO_OWNER0 (*(volatile uint32_t *)(0x40000078)) +#define PIO_OWNER1 (*(volatile uint32_t *)(0x4000007C)) +#define RTC_TIME_LSBS (*(volatile uint32_t *)(0x40000080)) +#define RTC_TIME_MSBS (*(volatile uint32_t *)(0x40000084)) +#define DEBUG_SEL (*(volatile uint32_t *)(0x40000088)) +#define DEBUG_SEL_BITSET (*(volatile uint32_t *)(0x40000488)) +#define DEBUG_SEL_BITCLR (*(volatile uint32_t *)(0x40000888)) +#define DEBUG_SEL_BITTOG (*(volatile uint32_t *)(0x40000C88)) +#define FLASH_STATUS (*(volatile uint32_t *)(0x4000008C)) +#define CHIP_WDT_INTERVAL (*(volatile uint32_t *)(0x40000090)) +#define CHIP_WDT_INTERVAL_BITSET (*(volatile uint32_t *)(0x40000490)) +#define CHIP_WDT_INTERVAL_BITCLR (*(volatile uint32_t *)(0x40000890)) +#define CHIP_WDT_INTERVAL_BITTOG (*(volatile uint32_t *)(0x40000C90)) +#define CHIP_WDT_CTRL (*(volatile uint32_t *)(0x40000094)) +#define CHIP_WDT_CTRL_BITSET (*(volatile uint32_t *)(0x40000494)) +#define CHIP_WDT_CTRL_BITCLR (*(volatile uint32_t *)(0x40000894)) +#define CHIP_WDT_CTRL_BITTOG (*(volatile uint32_t *)(0x40000C94)) +#define CHIP_WDT_TIME (*(volatile uint32_t *)(0x40000098)) +#define CHIP_RESET (*(volatile uint32_t *)(0x4000009C)) +#define CHIP_RESET_BITSET (*(volatile uint32_t *)(0x4000049C)) +#define CHIP_RESET_BITCLR (*(volatile uint32_t *)(0x4000089C)) +#define CHIP_RESET_BITTOG (*(volatile uint32_t *)(0x40000C9C)) +#define SWD_PIN_CFG (*(volatile uint32_t *)(0x400000A0)) +#define SWD_PIN_CFG_BITSET (*(volatile uint32_t *)(0x400004A0)) +#define SWD_PIN_CFG_BITCLR (*(volatile uint32_t *)(0x400008A0)) +#define SWD_PIN_CFG_BITTOG (*(volatile uint32_t *)(0x40000CA0)) + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ + +/* UART Defines */ +#define UART0_BASE 0x50003000 +#define UART1_BASE 0x50004000 + +#ifdef __cplusplus +} +#endif + +#endif /* HI2110_H */ diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.c b/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.c new file mode 100644 index 0000000000..b082e7abef --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.c @@ -0,0 +1,86 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "system_hi2110.h" +#include "cmsis.h" + +/*lint ++flb "Enter library region" */ + +#define __SYSTEM_CLOCK (48000000UL) + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK; +} + +/* Restart the core if we're in an interrupt context to ensure a known state. + * Also reset any PIOs and ensure interrupts are disabled. */ +void SystemInit(void) +{ + uint32_t x = __get_xPSR(); + + /* Check for interrupt context and reboot needed. */ + if (x & 0x3f) { + /* Processor is in an interrupt context, reset the core by triggering + * the reset vector using the SYSRESETREQ bit in the AIRCR register */ + x = SCB->AIRCR; + x &= 0xffff; /* Mask out the top 16 bits */ + x |= 0x05fa0000; /* Must write with this value for the write to take effect */ + x |= 0x04; /* Set the SYSRESETREQ bit */ + SCB->AIRCR = x; /* Reset the core */ + } + + /* Release claim on any pins */ + PIO_FUNC0_BITCLR = 0xFFFFFFFF; + PIO_FUNC1_BITCLR = 0xFFFFFFFF; + PIO_FUNC2_BITCLR = 0xFFFFFFFF; + PIO_FUNC3_BITCLR = 0xFFFFFFFF; + PIO_FUNC4_BITCLR = 0xFFFFFFFF; + + /* Disable all IRQ interrupts */ + NVIC->ICER[0] = 0xffffffff; + + /* Ensure interrupts are enabled */ + __set_PRIMASK(0); + + /* Allow sleep */ + SystemAllowSleep(true); +} + +void SystemAllowSleep(bool sleepAllowed) +{ + if (sleepAllowed) { + /* Set deep sleep, though not on exit */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; + } else { + /* Unset deep sleep */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + } +} + +/*lint --flb "Leave library region" */ diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.h b/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.h new file mode 100644 index 0000000000..0f8b78aee5 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/device/system_hi2110.h @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_HI2110_H +#define SYSTEM_HI2110_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + + +/** + * Allow the system to go to sleep, shutting down clocks, etc. + * or not. If the system is allowed to sleep it will awake + * and restore clocks automatically on an interrupt however + * there will be a 200 to 300 usecond delay. + * + * @param sleepAllowed if true then sleep is allowed. + * @return none + * + * @brief Allow full sleep, or not. + */ +extern void SystemAllowSleep(bool sleepAllowed); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_HI2110_H */ diff --git a/targets/TARGET_ublox/TARGET_HI2110/gpio_api.c b/targets/TARGET_ublox/TARGET_HI2110/gpio_api.c new file mode 100644 index 0000000000..7024631750 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/gpio_api.c @@ -0,0 +1,80 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +void gpio_init(gpio_t *obj, PinName pin) +{ + if (pin == (PinName)NC) { + return; + } + + MBED_ASSERT (pin < NUM_PINS); + + obj->pin = pin; + obj->mask = (1ul << pin); + + obj->reg_set = &GPIO_OUT_BITSET; + obj->reg_clr = &GPIO_OUT_BITCLR; + obj->reg_val = &GPIO_VALUE; + obj->reg_dir = &GPIO_DIR; + + /* Claim the pin */ + pin_function(pin, PIN_FUNCTION_GPIO); +} + +void gpio_mode(gpio_t *obj, PinMode mode) +{ + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) +{ + MBED_ASSERT(obj->pin != (PinName)NC); + + switch (direction) { + case PIN_INPUT: + { + *(obj->reg_dir) &= ~(obj->mask); + } + break; + case PIN_OUTPUT: + { + *(obj->reg_dir) |= obj->mask; + } + break; + /* TODO: looks as though the default is + * not normally trapped here */ + } +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/gpio_irq_api.c b/targets/TARGET_ublox/TARGET_HI2110/gpio_irq_api.c new file mode 100644 index 0000000000..ab8d0812cc --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/gpio_irq_api.c @@ -0,0 +1,148 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* TODO: this needs testing */ + +#include +#include "cmsis.h" + +#include "gpio_irq_api.h" +#include "mbed_error.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* Each GPIO pin is given an ID, if the ID is 0 the pin can be ignored. */ +static uint8_t channel_ids[20] = {0}; +static gpio_irq_handler irq_handler; + +static bool initialised = false; + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +void IRQ5_GPIO_Handler() +{ + if (initialised) { + for (uint8_t i = 0; i < sizeof (channel_ids) / sizeof (channel_ids[0]); i++) { + uint8_t id = channel_ids[i]; + uint32_t mask = 1 << id; + + if (id != 0) { + if (GPIO_IRQ | mask) { + if (GPIO_INT_RISE | mask) { + irq_handler(id, IRQ_RISE); + } else if (GPIO_INT_FALL | mask) { + irq_handler(id, IRQ_FALL); + } + } + } + } + } + + /* Clear all the interrupt bits (rather than wasting time on + * each individual one), or we might get stuck if a spurious + * one should arrive. */ + GPIO_INT_CLR = 0xFFFFFFFF; +} + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) +{ + bool return_value = -1; + + if (initialised) { + return_value = 0; + } else { + if (pin != NC) { + MBED_ASSERT (pin < NUM_PINS); + + irq_handler = handler; + obj->ch = pin; + channel_ids[pin] = id; + + uint32_t mask = 1 << obj->ch; + + /* Remove any existing setting */ + GPIO_INT_RISE_BITCLR &= ~mask; + GPIO_INT_FALL_BITCLR &= ~mask; + GPIO_INT_LOW_BITCLR &= ~mask; + GPIO_INT_HIGH_BITCLR &= ~mask; + + initialised = true; + NVIC_EnableIRQ (GPIO_IRQn); + + return_value = 0; + } + } + + return return_value; +} + +void gpio_irq_free(gpio_irq_t *obj) +{ + channel_ids[obj->ch] = 0; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) +{ + uint32_t mask = 1 << obj->ch; + + if (enable) { + if (event == IRQ_RISE) { + GPIO_INT_RISE_BITSET |= mask; + } else if (event == IRQ_FALL) { + GPIO_INT_FALL_BITSET |= mask; + } + } + else + { + if (event == IRQ_RISE) { + GPIO_INT_RISE_BITSET &= ~mask; + } else if (event == IRQ_FALL) { + GPIO_INT_FALL_BITSET &= ~mask; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) +{ + (void) obj; + NVIC_EnableIRQ (GPIO_IRQn); +} + +void gpio_irq_disable(gpio_irq_t *obj) +{ + (void) obj; + NVIC_DisableIRQ (GPIO_IRQn); +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/gpio_object.h b/targets/TARGET_ublox/TARGET_HI2110/gpio_object.h new file mode 100644 index 0000000000..2be82b78b9 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/gpio_object.h @@ -0,0 +1,57 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_val; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) { + *obj->reg_set = obj->mask; + } else { + *obj->reg_clr = obj->mask; + } +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_val & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.c b/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.c new file mode 100644 index 0000000000..281034c7cc --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.c @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "mbed_assert.h" +#include "cmsis.h" +#include "hi2110_init.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static uint8_t get_owner(uint8_t pin); + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* Determine which core owns a given pin + * 0: None + * 1: security core + * 2: protocol core + * 3: apps core */ +static uint8_t get_owner(uint8_t pin) +{ + uint8_t value; + uint8_t pio_owner_shift = (pin & 0x0F) << 1; + volatile uint32_t * pio_owner_reg = (&PIO_OWNER0 + (pin >> 4)); + + value = 0x03 & (*pio_owner_reg >> pio_owner_shift); + + return value; +} + +/* ---------------------------------------------------------------- + * MBED API FUNCTIONS + * ----------------------------------------------------------------*/ + +void HI2110_init(void) +{ + __attribute__ ((unused)) uint8_t owner[20]; + + /* This purely for diagnostics to see who owns which PIO pin. + * Put a break-point at the end of this function and take a look + * at the array. + * Any items marked as 1 or 2 belong to the security or protocol + * cores. Otherwise they are up for grabs. */ + for (uint8_t x = 0; x < 20; x++) { + owner[x] = get_owner(x); + } +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.h b/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.h new file mode 100644 index 0000000000..a2da23e2b4 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/hi2110_init.h @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HI2110_INIT_H +#define HI2110_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +void HI2110_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c b/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c new file mode 100644 index 0000000000..205e68b898 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c @@ -0,0 +1,340 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The LP Ticker performs two functions for mbed: + * + * 1. Allows tracking of the passage of time. + * 2. Allows the system to enter the lowest power + * state for a given time. + * + * For this to work the single RTC interrupt needs + * to perform two functions. It needs to increment + * an overflow counter at every 32-bit overflow without + * otherwise affecting the system state (i.e. not waking it + * up and not putting it to sleep) and, when requested, + * it *also* needs to wake the system up from sleep + * at a specific time. Note also that the units of time + * from an mbed perspective are useconds, whereas the RTC + * is clocked at 32 kHz, hence there is conversion to be done. + * + * Since it is not possible to reset the RTC, we maintain + * a 32-bit window on it, starting at g_last_32bit_overflow_value + * and ending at g_next_32bit_overflow_value. All values + * fed back up to mbed are relative to g_last_32bit_overflow_value. + */ + +#include "lp_ticker_api.h" +#include "sleep_api.h" +#include "critical.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* The maximum value of the RTC (48 bits) */ +#define RTC_MAX 0x0000FFFFFFFFFFFFULL + +/* RTC modulo */ +#define RTC_MODULO (RTC_MAX + 1) + +/* The 32-bit overflow value */ +#define MODULO_32BIT 0x100000000ULL + +/* Macro to increment a 64-bit RTC value x by y, with wrap */ +#define INCREMENT_MOD(x, y) (x = ((uint64_t) x + (uint64_t) y) % RTC_MODULO) + +/* Macro to get MSBs from a 64-bit integer */ +#define MSBS(x) ((uint32_t) ((uint64_t) (x) >> 32)) + +/* Macro to get LSBs from a 64-bit integer */ +#define LSBS(x) ((uint32_t) (x)) + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* Incremented each time the RTC goes over 32 bits */ +static uint32_t g_overflow_count = 0; + +/* Set when a user interrupt has been requested but an overflow + * interrupt needs to happen first */ +static bool g_user_interrupt_pending = false; + +/* Set when a user interrupt is the next interrupt to happen */ +static bool g_user_interrupt_set = false; + +/* Initialised flag, used to protect against interrupts going + * off before we're initialised */ +static bool g_initialised = false; + +/* The next overflow value to be used */ +static uint64_t g_next_32bit_overflow_value; + +/* The next match-compare value to be used */ +static uint64_t g_next_compare_value; + +/* Keep track of the previous 32-bit overflow + * value so that we can report 32-bit time + * correctly */ +static uint64_t g_last_32bit_overflow_value; + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static void set_interrupt_to_32bit_overflow(void); +static void set_interrupt_to_user_value(void); + +/* ---------------------------------------------------------------- + * STATIC FUNCTIONS + * ----------------------------------------------------------------*/ + +/* Convert a tick value (32,768 Hz) into a microsecond value */ +static inline uint32_t ticksToUSeconds(uint32_t x) +{ + /* TODO: find a way to avoid the multiply by 1000000 + * Shift by 20 would introduce a 5% error, which is + * probably too much */ + uint64_t result = ((((uint64_t) x) * 1000000) >> 15); + + if (result > 0xFFFFFFFF) { + result = 0xFFFFFFFF; + } + + return (uint32_t) result; +} + +/* Convert a microsecond value into a tick value (32,768 Hz) */ +static inline uint32_t uSecondsToTicks(uint32_t x) +{ + /* TODO: find a way to avoid the divide by 1000000 + * Shift by 20 would introduce a 5% error, which is + * probably too much */ + return (uint32_t) ((((uint64_t) x) << 15) / 1000000); +} + +/* Take g_next_32bit_overflow_value and apply it to g_next_compare_value and + * then the chip registers + * NOTE: the RTC interrupt should be disabled when calling this function */ +static inline void set_interrupt_to_32bit_overflow() +{ + /* Load up the values */ + g_next_compare_value = g_next_32bit_overflow_value; + + /* Set up the match register values */ + RTC_IRQ_TIME_MSBS = MSBS(g_next_compare_value); + RTC_IRQ_TIME_LSBS = LSBS(g_next_compare_value); +} + +/* Take g_next_compare_value and apply it to the chip registers + * NOTE: the RTC interrupt should be disabled when calling this function */ +static inline void set_interrupt_to_user_value() +{ + g_user_interrupt_set = true; + + /* Write MSBS first, then the value is latched on LSBS write */ + RTC_IRQ_TIME_MSBS = MSBS(g_next_compare_value); + RTC_IRQ_TIME_LSBS = LSBS(g_next_compare_value); +} + +/* Get the RTC value + * NOTE: the RTC interrupt should be disabled when calling this function */ +static inline uint64_t get_rtc_value() +{ + uint64_t rtc_value; + + rtc_value = ((uint64_t) RTC_TIME_MSBS) << 32; + rtc_value |= RTC_TIME_LSBS; + + return rtc_value; +} + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* RTC handler */ +void IRQ0_RTC_Handler(void) +{ + /* Have seen this interrupt occurring before initialisation, so guard + * against that */ + if (g_initialised) { + if (g_user_interrupt_pending) { + /* If there was a user interrupt pending, set it now */ + set_interrupt_to_user_value(); + + /* Reset the pending flag */ + g_user_interrupt_pending = false; + + /* This must have been a 32-bit overflow interrupt so + * increment the count */ + g_overflow_count++; + g_last_32bit_overflow_value = g_next_32bit_overflow_value; + INCREMENT_MOD(g_next_32bit_overflow_value, MODULO_32BIT); + } else { + if (g_user_interrupt_set) { + /* It's a user interrupt, so wake from sleep but don't + * increment the overflow count as this is not an + * overflow interrupt */ + + /* Reset the user interrupt flag and call mbed */ + g_user_interrupt_set = false; + lp_ticker_irq_handler(); + } else { + /* Increment the count as this was a 32-bit overflow + * interrupt rather than a user interrupt */ + g_overflow_count++; + g_last_32bit_overflow_value = g_next_32bit_overflow_value; + INCREMENT_MOD(g_next_32bit_overflow_value, MODULO_32BIT); + } + + /* Set the next interrupt to be at the 32-bit overflow */ + set_interrupt_to_32bit_overflow(); + } + } + + /* Clear the interrupt */ + RTC_IRQ_CLR = 0xFFFFFFFF; +} + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +/* This will be called once at start of day to get the RTC running */ +void lp_ticker_init(void) +{ + if (!g_initialised) { + /* Reset the overflow count and the flags */ + g_overflow_count = 0; + g_user_interrupt_pending = false; + g_user_interrupt_set = false; + + /* Setup the next natural 32-bit overflow value */ + g_next_32bit_overflow_value = get_rtc_value(); + g_last_32bit_overflow_value = g_next_32bit_overflow_value; + INCREMENT_MOD(g_next_32bit_overflow_value, MODULO_32BIT); + + /* Clear the interrupt */ + RTC_IRQ_CLR = 0xFFFFFFFF; + + /* Interrupt at 32-bit overflow */ + set_interrupt_to_32bit_overflow(); + + /* Enable the interrupt */ + g_initialised = true; + NVIC_EnableIRQ(RTC_IRQn); + } +} + +uint32_t lp_ticker_read(void) +{ + uint64_t rtcNow; + + /* Disable interrupts to avoid collisions */ + core_util_critical_section_enter(); + + /* Just in case this is called before initialisation has been performed */ + if (!g_initialised) { + lp_ticker_init(); + } + + /* What mbed expects here is a 32 bit timer value. There is no + * way to reset the RTC so, to pretend it is 32 bits, we have to + * maintain a 32-bit window on it using the remembered overflow + * value */ + rtcNow = get_rtc_value(); + + /* Put interrupts back */ + core_util_critical_section_exit(); + + return ticksToUSeconds(rtcNow - g_last_32bit_overflow_value); +} + +void lp_ticker_set_interrupt(timestamp_t time) +{ + uint32_t timeNow = get_rtc_value() - g_last_32bit_overflow_value; + uint32_t timeOffset = uSecondsToTicks(time) - timeNow; + + /* Disable interrupts to avoid collisions */ + core_util_critical_section_enter(); + + g_user_interrupt_pending = false; + g_user_interrupt_set = false; + + /* Handle time slipping into the past */ + if (timeOffset > 0xEFFFFFFF) { + timeOffset = 100; + } + + /* Read the current time */ + g_next_compare_value = get_rtc_value(); + + /* Add the offset */ + INCREMENT_MOD(g_next_compare_value, timeOffset); + + /* We must let the normal overflow interrupt occur as + * well as setting this interrupt so, if the value + * of 'time' would occur after the overflow point, + * put the change of compare-value off until afterwards. */ + /* TODO: this needs proper testing. */ + if (g_next_32bit_overflow_value > g_next_compare_value) { + /* The easy case, no overlap */ + } else { + /* Could be because g_next_compare_value has wrapped (around the + * 48-bit limit of the RTC) */ + if (g_next_32bit_overflow_value - g_next_compare_value >= MODULO_32BIT) { + /* The wrap case, we're OK */ + } else { + /* There is an overlap, apply the value later */ + g_user_interrupt_pending = true; + + if (g_next_32bit_overflow_value == g_next_compare_value) { + /* If they are on top of each other, bump this + * one forward to avoid losing the interrupt */ + INCREMENT_MOD(g_next_compare_value, 2); + } + } + } + + if (!g_user_interrupt_pending) { + /* Make the change immediately */ + set_interrupt_to_user_value(); + } + + /* Put interrupts back */ + core_util_critical_section_exit(); +} + +void lp_ticker_disable_interrupt(void) +{ + /* Can't disable interrupts as we need them to manage + * overflow. Instead, switch off the user part. */ + g_user_interrupt_pending = false; + g_user_interrupt_set = false; +} + +void lp_ticker_clear_interrupt(void) +{ + /* Can't disable interrupts as we need them to manage + * overflow. Instead, switch off the user part. */ + g_user_interrupt_pending = false; + g_user_interrupt_set = false; +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/mbed_overrides.c b/targets/TARGET_ublox/TARGET_HI2110/mbed_overrides.c new file mode 100644 index 0000000000..bbc29831c0 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/mbed_overrides.c @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hi2110_init.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * MBED API FUNCTIONS + * ----------------------------------------------------------------*/ + +void mbed_sdk_init(void) +{ + HI2110_init(); +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/objects.h b/targets/TARGET_ublox/TARGET_HI2110/objects.h new file mode 100644 index 0000000000..b189e083a4 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/objects.h @@ -0,0 +1,73 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + IRQ_NOT_SET, + IRQ_ON, + IRQ_OFF +} irq_setting_t; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_out; + __IO uint32_t *reg_val; + __IO uint32_t *reg_drv; + PortName port; + uint32_t mask; +}; + +struct gpio_irq_s { + /* Don't bother with having a port number here as there's only one */ + uint32_t ch; /* Corresponds to the interrupt pin */ +}; + +struct serial_s { + SerialConfig config; + PinName rx_pin; + PinName tx_pin; + volatile uart_ctrl_t *reg_base; + uint8_t index; + uint32_t baud_rate; + bool format_set; /* If true then the struct that follows is populated */ + struct { + uint8_t stop_bits; + uint8_t data_bits; + uint8_t parity; + } format; + irq_setting_t irq_rx_setting; + irq_setting_t irq_tx_setting; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/pinmap.c b/targets/TARGET_ublox/TARGET_HI2110/pinmap.c new file mode 100644 index 0000000000..81535f511e --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/pinmap.c @@ -0,0 +1,145 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* As well as claiming and setting pins, the functions here also need + * to take into account the way the pins are powered. On the Boudica + * chip they are arranged in three banks, PIO 0:5, PIO 6:10 and + * PIO 11:19. + * + * The arrangement for which PIO bank is powered is determined by the module + * in which the HI2110 chip is mounted, hence the use of conditional + * compilation below. + */ + +#include "stdbool.h" +#include "mbed_assert.h" +#include "mbed_error.h" +#include "pinmap.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +#define HAL_PIO_MASK_FUNC (0xFF) +#define HAL_PIO_MODULO_4_MASK (0x3) + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static inline uint32_t clr_mask (PinName pin); +static inline uint32_t set_mask (PinName pin, int function); +static inline volatile uint32_t * func_reg (PinName pin); + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +// Return the clear mask for a pin +static inline uint32_t clr_mask (PinName pin) +{ + return HAL_PIO_MASK_FUNC << ((pin & HAL_PIO_MODULO_4_MASK) << 3); +} + +// Return the set mask for a pin and a given function +static inline uint32_t set_mask (PinName pin, int function) +{ + return function << ((pin & HAL_PIO_MODULO_4_MASK) << 3); +} + +// Return the function register for a pin +static inline volatile uint32_t * func_reg (PinName pin) +{ + return &PIO_FUNC0 + (pin >> 2); +} + +// Return the owner of a pin +// 0: None +// 1: security core +// 2: protocol core +// 3: apps core +static inline uint8_t get_owner(PinName pin) +{ + uint8_t pio_owner_shift = (pin & 0x0F) << 1; + volatile uint32_t * pio_owner_reg = (&PIO_OWNER0 + (pin >> 4)); + + return 0x03 & (*pio_owner_reg >> pio_owner_shift); +} + +/* ---------------------------------------------------------------- + * MBED "INTERNAL" API CALLS + * ----------------------------------------------------------------*/ + +void pin_function(PinName pin, int function) +{ + volatile uint32_t *pio_func_reg; + + /* Set the function for the given pin */ + pio_func_reg = func_reg (pin); + *pio_func_reg = (*pio_func_reg & ~(clr_mask(pin))) | set_mask(pin, function); + + /* Power the pin */ +#ifdef TARGET_SARA_NBIOT + /* On Sara NBIoT, GPIO pin 19 has to be high to power GPIO pins 0 to 10 */ + if ((pin >= p0) && (pin <= p10)) { + /* Grab pin 19 as a GPIO if we don't have it already */ + if (get_owner(p19) != 0x03) { + pio_func_reg = func_reg (p19); + *pio_func_reg = (*pio_func_reg & ~(clr_mask(p19))) | set_mask(p19, 1); /* 1 == PIN_FUNCTION_GPIO */ + + MBED_ASSERT (get_owner(p19) == 0x03); + } + + /* Set pin 19 to be an output and to be high */ + GPIO_DIR |= (1ul << p19); + GPIO_OUT_BITSET = (1ul << p19); + + /* Note: the level on pins 6 to 10 is controlled by the protocol + * processor to be the VCC level required by the SIM. The + * application has no control over this. */ + } + /* The power to GPIOs 11 to 19 is fed directly from pin 51 of the module */ +#endif +} + +void pin_mode(PinName pin, PinMode mode) +{ + MBED_ASSERT(pin != (PinName)NC); + + switch (mode) { + case PullUp: + { + MBED_ASSERT(false); /* Not currently supported on HI2100 */ + } + break; + case PullDown: + { + GPIO_PULLEN_BITSET = 1U << pin; + } + break; + case PullNone: + { + GPIO_PULLEN_BITCLR = 1U << pin; + } + break; + default: + break; + } +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/port_api.c b/targets/TARGET_ublox/TARGET_HI2110/port_api.c new file mode 100644 index 0000000000..05e8b2f878 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/port_api.c @@ -0,0 +1,103 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* TODO: this needs testing */ + +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +PinName port_pin(PortName port, int pin_n) +{ + MBED_ASSERT (port < PortMaxNumber); + + (void) port; + return (PinName)(pin_n); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) +{ + MBED_ASSERT (port < PortMaxNumber); + + obj->port = port; + obj->mask = mask; + + obj->reg_dir = &GPIO_DIR; + obj->reg_out = &GPIO_OUT; + obj->reg_val = &GPIO_VALUE; + obj->reg_drv = &GPIO_DRIVE; + + /* Claim the pins */ + for (uint8_t x = 0; x < NUM_PINS; x++) { + if (mask & (1ul << x)) { + pin_function((PinName) x, PIN_FUNCTION_GPIO); + } + } + + /* Set up the pins */ + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) +{ + switch (mode) { + case PullUp: + { + MBED_ASSERT(false); /* Not currently supported on HI2110 */ + } + break; + case PullDown: + { + GPIO_PULLEN_BITSET |= obj->mask; + } + break; + case PullNone: + { + GPIO_PULLEN_BITCLR &= ~(obj->mask); + } + break; + default: + break; + } +} + +void port_dir(port_t *obj, PinDirection dir) +{ + switch (dir) { + case PIN_INPUT: + { + *(obj->reg_dir) &= ~(obj->mask); + } + break; + case PIN_OUTPUT: + { + *(obj->reg_dir) |= obj->mask; + /* TODO: do we need to set the drive strength? If so, how do we decide which way? */ + /* obj->reg_drv |= obj->mask; */ + } + break; + } +} + +void port_write(port_t *obj, int value) +{ + *(obj->reg_out) = value; +} + +int port_read(port_t *obj) +{ + return *(obj->reg_val); +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/serial_api.c b/targets/TARGET_ublox/TARGET_HI2110/serial_api.c new file mode 100644 index 0000000000..2670f5b3fb --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/serial_api.c @@ -0,0 +1,819 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The serial driver connects UART HW to mbed and also associates the UART + * HW with physical pins. Any physical pin can be linked to any UART, + * however the mbed serial port initialisation API makes no mention of + * which UART HW is to be used (only the pins) and hence the driver needs + * to make some decisions for itself. + * + * There are two and a half UARTs on the chip: UART0, UART1 and a + * lower-power, receive-only UART that is clocked from 32 kHz and can + * therefore be awake while the rest of the chip is sleeping peacefully. + * This provides maximal power saving, however the LP UART can only run + * at 9600 bits/s (which is quite sufficient for all NB-IoT needs). + * + * So, if the baud rate is 9600 the driver code configures the LP UART + * for Rx and UART0 for Tx. If the baud rate is not 9600 then it configures + * UART0 for both Rx and Tx. Unless... the Tx pin is the pin UART1_TX (it + * is an mbed convention to use the Tx pin), which is p6, in which case UART1 + * is configured instead. This latter is not the normal case as this pin + * is intended to be used as a GPIO. + * + * If the baud rate is changed the driver reconfigures to match. + * + * TODO: implement asynchronous and flow control APIs. + */ + +#include "mbed_assert.h" +#include "serial_api.h" +#include "pinmap.h" + +#include "cmsis.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* Registers banks for the standard UARTs */ +#define UART0_REG (*(volatile uart_ctrl_t *) UART0_BASE) +#define UART1_REG (*(volatile uart_ctrl_t *) UART1_BASE) + +/* Masks for the UART control bits in the reset and clock enable registers */ +#define UART0_CTRL (1 << 3) +#define UART1_CTRL (1 << 4) +#define UARTLP_CTRL (1 << 6) + +/* Convert number of data bits to register values */ +#define MIN_NUM_UART_DATA_BITS 5 +#define MAX_NUM_UART_DATA_BITS 8 +#define REGISTER_DATA_BITS(x) ((x) - MIN_NUM_UART_DATA_BITS) + +/* Number of stop bits */ +#define NUM_UART_STOP_BITS_1 1 +#define NUM_UART_STOP_BITS_2 2 + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* Enum to identify the interrupt to the UART handler */ +typedef enum { + IRQ_UART_ID_0_AND_LP, + IRQ_UART_ID_1, + NUM_IRQ_IDS +} irq_uart_id_t; + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* The IRQ configuration variables, set up and named by mbed */ +static uint32_t serial_irq_ids[NUM_IRQ_IDS] = {0}; +static uart_irq_handler irq_handler = NULL; + +/* RTX needs these */ +int stdio_uart_inited = 0; +serial_t stdio_uart; + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static void init_config(serial_t *obj); +static void deinit_config(serial_t *obj); +static void set_baud(serial_t *obj, uint32_t baud_rate); +static void irq_enable(serial_t *obj); +static void irq_disable(serial_t *obj); + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* Initialise the given serial config by setting the pin functions + * and then resetting the relevant HW */ +static void init_config(serial_t *obj) +{ + uint32_t x; + + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + pin_function(obj->rx_pin, PIN_FUNCTION_LP_UART); + pin_function(obj->tx_pin, PIN_FUNCTION_UART0_TXD); + CLKEN_REG_BITSET = UARTLP_CTRL | UART0_CTRL; + obj->reg_base = &UART0_REG; + obj->index = IRQ_UART_ID_0_AND_LP; + /* Reset the LPUART and UART0 HW */ + /* NOTE: RESET_REG_BITTOG doesn't have the desired + * effect, need to use BITSET and then BITCLR */ + RESET_REG_BITSET |= 1ul << 6; + RESET_REG_BITCLR |= 1ul << 6; + RESET_REG_BITSET |= 1ul << 3; + RESET_REG_BITCLR |= 1ul << 3; + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + { + pin_function(obj->rx_pin, PIN_FUNCTION_UART0_RXD); + pin_function(obj->tx_pin, PIN_FUNCTION_UART0_TXD); + CLKEN_REG_BITSET = UART0_CTRL; + obj->reg_base = &UART0_REG; + obj->index = IRQ_UART_ID_0_AND_LP; + /* Reset the UART0 HW */ + RESET_REG_BITSET |= 1ul << 3; + RESET_REG_BITCLR |= 1ul << 3; + } + break; + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + pin_function(obj->rx_pin, PIN_FUNCTION_UART1_RXD); + pin_function(obj->tx_pin, PIN_FUNCTION_UART1_TXD); + CLKEN_REG_BITSET = UART1_CTRL; + obj->reg_base = &UART1_REG; + obj->index = IRQ_UART_ID_1; + /* Reset the UART1 HW */ + RESET_REG_BITSET |= 1ul << 4; + RESET_REG_BITCLR |= 1ul << 4; + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + /* Tickle the UART control register to make sure it is updated */ + x = obj->reg_base->UARTLCR_H; + obj->reg_base->UARTLCR_H = x; + + /* Set the FIFO. The meaning of the three FIFO interrupt-level + * bits are as follows: + * + * 0 = 1/8 full + * 1 = 1/4 full + * 2 = 1/2 full + * 3 = 3/4 full + * 4 = 7/8 full + * + * Set up the Rx FIFO to be used fully (but we will also set + * a timeout to get immediate notice) and also the Tx FIFO + * to be fully used. */ + obj->reg_base->UARTIFLS = (obj->reg_base->UARTIFLS & ~(0x07 << 0)) | (4 << 0); + obj->reg_base->UARTIFLS = (obj->reg_base->UARTIFLS & ~(0x07 << 3)) | (4 << 3); + obj->reg_base->UARTLCR_H |= 1 << 4; + + /* Enable for Tx and Rx (TODO: add CTS when we add flow control) */ + obj->reg_base->UARTCR |= (1 << 8) | (1 << 9); + + /* Now enable it */ + obj->reg_base->UARTCR |= 1 << 0; + + obj->format_set = false; + obj->baud_rate = 0; + obj->irq_rx_setting = IRQ_NOT_SET; + obj->irq_tx_setting = IRQ_NOT_SET; +} + +/* Release a serial port */ +static void deinit_config(serial_t *obj) +{ + pin_function(obj->rx_pin, PIN_FUNCTION_UNCLAIMED); + pin_function(obj->tx_pin, PIN_FUNCTION_UNCLAIMED); + + /* Disable UART */ + obj->reg_base->UARTCR &= ~(1 << 0); + + /* Flush transmit FIFO */ + obj->reg_base->UARTLCR_H = 0; + + /* Disable everything */ + obj->reg_base->UARTCR = 0; + + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + CLKEN_REG_BITCLR = UARTLP_CTRL | UART0_CTRL; + LP_UART_CTRL &= ~(0xF << 20); /* Disable all LP interrupts */ + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + { + CLKEN_REG_BITCLR = UART0_CTRL; + } + break; + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + CLKEN_REG_BITCLR = UART1_CTRL; + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + obj->config = MAX_NUM_SERIAL_CONFIGS; + obj->reg_base = NULL; +} + +/* Set the baud rate for either of the two (non-LP) UARTS */ +static void set_baud(serial_t *obj, uint32_t baud_rate) +{ + uint32_t baud_rate_divider_i; + uint32_t baud_rate_divider_f; + uint32_t remainder; + uint32_t core_clock; + uint32_t x; + + /* Baud rate divider calculation: + * + * The integer part is: clock / (16 * baud) + * + * The fractional part is: round (decimal_part * 64), + * ...where decimal part is, for example, 0.085 + * + * decimal_part is: remainder / (16 * baud), + * ...where: remainder = core_clock % (baud * 16), + * + * So the fractional part becomes: + * round (decimal_part * 64) = round (remainder * 64 / (16 * baud)) = round (remainder * 4 / baud) + */ + + /* Get the mean clock frequency */ + core_clock = (CLK_FREQ_HIGHTARGET >> 1) + (CLK_FREQ_LOWTARGET >> 1); + /* Work out the actual clock frequency */ + core_clock = (core_clock * CLOCKS_REFERENCE_CLOCK_FREQ) / (((CLK_FREQ_NREFCLKS + 1) & 0xFFFF) * (CLK_GATE_SYS & 0xFF)); + baud_rate_divider_i = core_clock / (baud_rate << 4); + remainder = core_clock % (baud_rate << 4); + baud_rate_divider_f = ((remainder << 3) / baud_rate) >> 1; + /* Round it */ + baud_rate_divider_f += ((remainder << 3) / baud_rate) & 1; + + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + obj->reg_base->UARTIBRD = baud_rate_divider_i; + obj->reg_base->UARTFBRD = baud_rate_divider_f; + + /* Make IBRD and FBRD update */ + x = obj->reg_base->UARTLCR_H; + obj->reg_base->UARTLCR_H = x; + + /* Now enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; +} + +/* Set the NVIC bits */ +static void irq_enable(serial_t *obj) +{ + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + NVIC_EnableIRQ(UART0_IRQn); + NVIC_EnableIRQ(LPUART_IRQn); + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + { + NVIC_EnableIRQ(UART0_IRQn); + } + break; + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + NVIC_EnableIRQ(UART1_IRQn); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } +} + +/* Unset the NVIC bits */ +static void irq_disable(serial_t *obj) +{ + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + NVIC_DisableIRQ(UART0_IRQn); + NVIC_DisableIRQ(LPUART_IRQn); + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + { + NVIC_DisableIRQ(UART0_IRQn); + } + break; + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + NVIC_DisableIRQ(UART1_IRQn); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } +} + +/* UART0 IRQ */ +void IRQ7_UART0_Handler() +{ + uint32_t id = serial_irq_ids[IRQ_UART_ID_0_AND_LP]; + + /* Check Rx and Rx Timeout bit */ + if (UART0_REG.UARTMIS & ((1 << 4) | (1 << 6))) { + if (id != 0) { + irq_handler(id, RxIrq); + /* Reading the character clears the interrupt, + * no way to protect against another arriving + * while processing one */ + } + } + /* Check Tx bit */ + if (UART0_REG.UARTMIS & (1 << 5)) { + if (id != 0) { + irq_handler(id, TxIrq); + } + /* Not sure what clears the interrupt so clear it explicitly */ + NVIC_ClearPendingIRQ(UART1_IRQn); + } +} + +/* UART1 IRQ */ +void IRQ8_UART1_Handler() +{ + uint32_t id = serial_irq_ids[IRQ_UART_ID_1]; + + /* Check Rx and Rx Timeout bit */ + if (UART1_REG.UARTMIS & ((1 << 4) | (1 << 6))) { + if (id != 0) { + irq_handler(id, RxIrq); + } + /* Reading the character clears the interrupt, + * no way to protect against another arriving + * while processing one */ + } + /* Check Tx bit */ + if (UART1_REG.UARTMIS & (1 << 5)) { + if (id != 0) { + irq_handler(id, TxIrq); + } + /* Not sure what clears the interrupt so clear it explicitly */ + NVIC_ClearPendingIRQ(UART1_IRQn); + } +} + +/* LP UART IRQ, receive only */ +void IRQ16_LPUART_Handler() +{ + uint32_t id = serial_irq_ids[IRQ_UART_ID_0_AND_LP]; + + if (id != 0) { + irq_handler(id, RxIrq); + + /* Another character might have arrived while + * we are processing the last, so + * check status bits 8 to 10 again and pend + * interrupt if there's something there */ + if (((LP_UART_STATUS >> 8) & 0x07) != 0) { + NVIC_SetPendingIRQ(LPUART_IRQn); + } else { + LP_UART_CTRL |= 1 << 27; /* Clear the interrupt */ + } + } +} + +/* ---------------------------------------------------------------- + * MBED API CALLS: SETUP FUNCTIONS + * ----------------------------------------------------------------*/ + +void serial_init(serial_t *obj, PinName tx, PinName rx) +{ + uint32_t clock = CLK_FREQ_DIG_CLKS; + + /* There are two and a half UARTs on the chip. The normal + * configuration is to use the LP_UART for Rx and UART0 for + * Tx. This gives maximal power saving in that the chip can + * wake up on receipt of data. However, this only works if the + * data rate is 9600 because that's the only data rate that + * the 32 kHz (i.e. RTC) clock driving the LP UART can support. + * + * So, if the data rate is 9600, use the LP_UART/UART0 + * combination, otherwise use UART0 for both Rx and Tx. However, + * we don't know the data rate at this point so assume LP_UART + * (as this works at the default baud rate) and we can change + * our minds later. + * + * There is another serial port, UART1, which is normally used + * by the modem processor to send out debug. We only initialise + * that here if the Tx pin is UART1_TX. */ + + /* Wait for the clock to be stable */ + while ((clock < CLK_FREQ_LOWTARGET) || (clock > CLK_FREQ_HIGHTARGET)) { + clock = CLK_FREQ_DIG_CLKS; + } + + if (tx == UART1_TX) { + /* Use UART1 for Rx and Tx */ + obj->config = SERIAL_CONFIG_UART1_RX_UART1_TX; + } else { + /* Use LP_UART for Rx, UART0 for Tx */ + obj->config = SERIAL_CONFIG_UARTLP_RX_UART0_TX; + } + + obj->rx_pin = rx; + obj->tx_pin = tx; + init_config(obj); + + /* TODO: set rx pin Pull mode ? */ + + /* set default baud rate and format */ + serial_baud(obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + if (tx == UART0_TX) { + /* The UART0 pins are the stdio pins */ + stdio_uart_inited = 1; + stdio_uart = *obj; + } +} + +void serial_free(serial_t *obj) +{ + if (obj->tx_pin == UART0_TX) { + stdio_uart_inited = 0; + } + + serial_irq_ids[obj->index] = 0; + + /* Release the port HW */ + deinit_config(obj); +} + +void serial_baud(serial_t *obj, int baudrate) +{ + bool switch_port_config = false; + bool format_set = obj->format_set; + uint8_t stop_bits = obj->format.stop_bits; + uint8_t data_bits = obj->format.data_bits; + SerialParity parity = (SerialParity) obj->format.parity; + irq_setting_t irq_rx_setting = obj->irq_rx_setting; + irq_setting_t irq_tx_setting = obj->irq_tx_setting; + + if ((obj->config == SERIAL_CONFIG_UARTLP_RX_UART0_TX) && (baudrate != 9600)) { + /* If we were on LP UART but the baud rate is not 9600 then + * switch to the standard UART (as the LP UART can't go any higher + * because it's clocked from 32 kHz) */ + deinit_config(obj); + obj->config = SERIAL_CONFIG_UART0_RX_UART0_TX; + init_config(obj); + switch_port_config = true; + } else if ((obj->config == SERIAL_CONFIG_UART0_RX_UART0_TX) && (baudrate == 9600)) { + /* If we were on UART0 but the baud rate is 9600 then switch to the + * LP UART for receive */ + deinit_config(obj); + obj->config = SERIAL_CONFIG_UARTLP_RX_UART0_TX; + init_config(obj); + switch_port_config = true; + } + + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + if (switch_port_config) { + /* If the port was switched, switch the port configuration also */ + if (format_set) { + /* This serial port has been previously set up so switch the + * settings across to this new configuration */ + serial_format(obj, data_bits, parity, stop_bits); + } + if (irq_rx_setting != IRQ_NOT_SET) { + /* Do the same for Rx interrupts, if they were set */ + serial_irq_set(obj, RxIrq, (irq_rx_setting == IRQ_ON)); + } + if (irq_tx_setting != IRQ_NOT_SET) { + /* Do the same for Tx interrupts, if they were set */ + serial_irq_set(obj, TxIrq, (irq_tx_setting == IRQ_ON)); + } + } + + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + /* Set LP UART to 9600 (numerator 75 (0x4B), denominator 256 (00 == 256)) */ + LP_UART_CTRL = (LP_UART_CTRL & ~0xFFFF) | 0x004B; + set_baud(obj, baudrate); + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + set_baud(obj, baudrate); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; + + obj->baud_rate = baudrate; +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) +{ + bool lp_also = false; + + MBED_ASSERT(data_bits >= MIN_NUM_UART_DATA_BITS); + MBED_ASSERT(data_bits <= MAX_NUM_UART_DATA_BITS); + MBED_ASSERT(stop_bits >= NUM_UART_STOP_BITS_1); + MBED_ASSERT(stop_bits <= NUM_UART_STOP_BITS_2); + + /* The LP UART is different to UARTs 0 and 1 so deal with it + * explicitly when required */ + if (obj->config == SERIAL_CONFIG_UARTLP_RX_UART0_TX) { + lp_also = true; + } + + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + /* Set data bits (bits 5 and 6 of the UART0/1 register, bits 18 and 19 of the LP UART register) */ + obj->reg_base->UARTLCR_H = (obj->reg_base->UARTLCR_H & ~(0x03 << 5)) | (REGISTER_DATA_BITS(data_bits) << 5); + if (lp_also) { + LP_UART_CTRL = (LP_UART_CTRL & ~(0x03 << 18)) | (REGISTER_DATA_BITS(data_bits) << 18); + } + obj->format.data_bits = (uint8_t) data_bits; + + /* Set stop bits (bit 7 of the UART0/1 register) (there is no such setting for the LP UART) */ + if (stop_bits == NUM_UART_STOP_BITS_1) { + /* Clear 2-stop-bits bit */ + obj->reg_base->UARTLCR_H &= ~(1 << 7); + } else { + /* Set 2-stop-bits bit */ + obj->reg_base->UARTLCR_H |= 1 << 7; + } + obj->format.stop_bits = (uint8_t) stop_bits; + + /* Set parity */ + switch (parity) { + case ParityNone: + { + /* Disable parity */ + obj->reg_base->UARTLCR_H &= ~0x02; + if (lp_also) + { + LP_UART_CTRL &= ~(1 << 24); + } + } + break; + case ParityOdd: + { + /* Set even bit and enable parity */ + obj->reg_base->UARTLCR_H = (obj->reg_base->UARTLCR_H | (1 << 3)) | (1 << 2); + if (lp_also) + { + LP_UART_CTRL |= (1 << 24) | (1 << 25); + } + } + break; + case ParityEven: + { + /* Clear even bit and enable parity */ + obj->reg_base->UARTLCR_H = (obj->reg_base->UARTLCR_H & ~(1 << 3)) | (1 << 2); + if (lp_also) + { + LP_UART_CTRL &= ~(1 << 25); + LP_UART_CTRL |= 1 << 24; + } + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; + + obj->format.parity = (uint8_t) parity; + obj->format_set = true; +} + +/* ---------------------------------------------------------------- + * MBED API CALLS: INTERRUPT FUNCTIONS + * ----------------------------------------------------------------*/ + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) +{ + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) +{ + bool lp_also = false; + + if (obj->config == SERIAL_CONFIG_UARTLP_RX_UART0_TX) { + lp_also = true; + } + + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + if (enable) { + switch (irq) { + case RxIrq: + { + /* Bit 4 for Rx and bit 6 for Rx Timeout */ + obj->reg_base->UARTIMSC |= (1 << 4) | (1 << 6); + if (lp_also) + { + /* "Word Received" IRQ */ + LP_UART_CTRL |= 1 << 23; + } + obj->irq_rx_setting = IRQ_ON; + irq_enable(obj); + } + break; + case TxIrq: + { + /* Bit 5 */ + obj->reg_base->UARTIMSC |= 1 << 5; + obj->irq_tx_setting = IRQ_ON; + irq_enable(obj); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + } else { + switch (irq) { + case RxIrq: + { + /* Bit 4 for Rx and bit 6 for Rx Timeout */ + obj->reg_base->UARTIMSC &= ~((1 << 4) | (1 << 6)); + if (lp_also) + { + /* "Word Received" IRQ */ + LP_UART_CTRL &= ~(1 << 23); + } + obj->irq_rx_setting = IRQ_OFF; + } + break; + case TxIrq: + { + /* Bit 5 */ + obj->reg_base->UARTIMSC &= ~(1 << 5); + obj->irq_tx_setting = IRQ_OFF; + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + if ((obj->irq_rx_setting == IRQ_OFF) && (obj->irq_tx_setting == IRQ_OFF)) { + irq_disable(obj); + } + } + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; +} + +/* ---------------------------------------------------------------- + * MBED API CALLS: TRANSMIT AND RECEIVE FUNCTIONS + * ----------------------------------------------------------------*/ + +int serial_getc(serial_t *obj) +{ + uint8_t data = 0; + + /* Block until there is data to read */ + while (!serial_readable(obj)) {} + + /* Read the data */ + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + data = (uint8_t) LP_UART_DATA; + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + data = (uint8_t) obj->reg_base->UARTDR; + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + return (int) data; +} + +void serial_putc(serial_t *obj, int c) +{ + /* Block until there is room to write */ + while (!serial_writable(obj)) {} + + /* Write the data */ + obj->reg_base->UARTDR = (uint8_t) c; +} + +int serial_readable(serial_t *obj) +{ + bool readable = false; + + switch (obj->config) { + case SERIAL_CONFIG_UARTLP_RX_UART0_TX: + { + /* Check the status register, bits 8 to 10 indicate + * the number of Rx bytes (make sure it's the status + * register not the data register as a read from that + * register would clear the Rx interrupt) */ + readable = (((LP_UART_STATUS >> 8) & 0x07) != 0); + } + break; + case SERIAL_CONFIG_UART0_RX_UART0_TX: + case SERIAL_CONFIG_UART1_RX_UART1_TX: + { + /* Check the Rx FIFO Empty bit */ + readable = ((obj->reg_base->UARTFR & (1 << 4)) != (1 << 4)); + } + break; + default: + { + MBED_ASSERT(false); + } + break; + } + + return (int) readable; +} + +int serial_writable(serial_t *obj) +{ + /* Check the "UART TX FIFO full" bit: + * only if this is 0 can we transmit */ + return (obj->reg_base->UARTFR & (1 << 5)) != (1 << 5); +} + +void serial_break_set(serial_t *obj) +{ + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + /* Set bit 1 of the line control register */ + obj->reg_base->UARTLCR_H |= 1 << 0; + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; +} + +void serial_break_clear(serial_t *obj) +{ + /* Disable UART while writing to control registers */ + obj->reg_base->UARTCR &= ~(1 << 0); + + /* Clear bit 1 of the line control register */ + obj->reg_base->UARTLCR_H &= ~(1 << 0); + + /* Enable the UART again */ + obj->reg_base->UARTCR |= 1 << 0; +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/sleep.c b/targets/TARGET_ublox/TARGET_HI2110/sleep.c new file mode 100644 index 0000000000..9a5eb80950 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/sleep.c @@ -0,0 +1,53 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sleep_api.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * STATIC FUNCTIONS + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +void sleep(void) +{ + __DSB(); + __WFI(); + __ISB(); +} + +void deepsleep() +{ + sleep(); +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c b/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c new file mode 100644 index 0000000000..72f5468385 --- /dev/null +++ b/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c @@ -0,0 +1,247 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The usecond ticker is mapped to TIMER0. A few issues must be dealt + * with in this driver: + * + * 1. The us_ticker API must count upwards, not down. + * 2. The expected range/resolution is 32 bits each of 1 usecond, + * whereas TIMER0 runs at 48 MHz (not 1 MHz) and so actually + * has a range/resolution of 26 bits at 0.02 useconds. Software + * has to compensate for this. + */ + +#include "us_ticker_api.h" +#include "critical.h" + +/* ---------------------------------------------------------------- + * MACROS + * ----------------------------------------------------------------*/ + +/* TIMER0 clock is 48 MHz */ +#define CLOCK_TICKS_PER_US 48 + +/* The number of clock ticks in a full-run of + * TIMER0, scaled to represent useconds */ +#define USECONDS_PER_FULL_TIMER0_RUN 89478485 + +/* ---------------------------------------------------------------- + * TYPES + * ----------------------------------------------------------------*/ + +/* ---------------------------------------------------------------- + * GLOBAL VARIABLES + * ----------------------------------------------------------------*/ + +/* Are we ready? */ +static bool g_initialised = false; + +/* Keep track of the number of useconds elapsed. */ +static uint32_t g_us_overflow = 0; + +/* The number of useconds to increment the by at each interrupt */ +static uint32_t g_us_overflow_increment = USECONDS_PER_FULL_TIMER0_RUN; + +/* Keep track of extra loops required to represent a particular time + * as the HW timer runs faster than 1 MHz */ +static uint32_t g_timer_extra_loops_required = 0; +static uint32_t g_timer_extra_loops_done = 0; + +/* Keep track of any adjustment due to user interrupts . */ +static uint32_t g_user_interrupt_offset = 0; + +/* Flag that a user timer is running */ +static bool g_user_interrupt = false; + +/* ---------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ----------------------------------------------------------------*/ + +static inline uint32_t divide_by_48(uint32_t x); + +/* ---------------------------------------------------------------- + * NON-API FUNCTIONS + * ----------------------------------------------------------------*/ + +/* Perform a divide-by-48 operation. + * This is done as a multiply-shift operation to take advantage of + * the ARM 32 bit single-cycle multiply and avoid using division; + * 1/48 is equivalent to 1365/2^16. It is also done in two halves + * to make sure that the multiplies fit into 32 bits. + * + * The principle is: + * - divide the top 16 bits by 48 using multiply-shift (=> x1), + * - work out the remainder of that operation and divide that by 48 (=> x1r), + * - divide the bottom 16 bits by 48 using multiply-shift (=> x2), + * - add the lot together to get the result. + * + * The cost is 29 instructions. + */ +static inline uint32_t divide_by_48(uint32_t x) +{ + uint32_t x1 = ((x >> 16) * 1365) >> 16; + uint32_t x1r = ((x & 0xFFFF0000) - ((x1 * 48) << 16)); + x1r = (x1r * 1365) >> 16; + uint32_t x2 = ((x & 0xFFFF) * 1365) >> 16; + + return (x1 << 16) + x1r + x2; +} + +/* Timer0 handler */ +void IRQ1_TMR0_Handler(void) +{ + if (g_initialised) { + /* Increment the overflow count and set the increment + * value for next time */ + g_us_overflow += g_us_overflow_increment; + g_us_overflow_increment = USECONDS_PER_FULL_TIMER0_RUN; + + /* Now handle the user interrupt case */ + if (g_user_interrupt) { + if (g_timer_extra_loops_done < g_timer_extra_loops_required) { + /* Let the timer go round again */ + g_timer_extra_loops_done++; + } else { + /* We've done with looping around for a user interrupt */ + g_user_interrupt = false; + + /* Call the mbed API */ + us_ticker_irq_handler(); + } + } + } + + NVIC_ClearPendingIRQ(Timer_IRQn); +} + +/* ---------------------------------------------------------------- + * MBED API CALLS + * ----------------------------------------------------------------*/ + +void us_ticker_init(void) +{ + if (!g_initialised) { + /* Reset the globals */ + g_timer_extra_loops_done = 0; + g_timer_extra_loops_required = 0; + g_us_overflow = 0; + g_us_overflow_increment = USECONDS_PER_FULL_TIMER0_RUN; + g_user_interrupt_offset = 0; + g_user_interrupt = false; + + /* Get the timer running (starting at what is zero, + * once inverted), with repeat */ + NVIC_ClearPendingIRQ(Timer_IRQn); + TIMER0_LOAD = 0xFFFFFFFF; + TIMER0_CTRL = 0x03; + NVIC_EnableIRQ(Timer_IRQn); + + g_initialised = true; + } +} + +uint32_t us_ticker_read() +{ + uint32_t timeValue; + + /* This can be called before initialisation has been performed */ + if (!g_initialised) { + us_ticker_init(); + } + + /* Disable interrupts to avoid collisions */ + core_util_critical_section_enter(); + + /* Get the timer value, adding the offset in case we've been moved + * around by user activity, inverting it (as a count-up timer is + * expected), then scaling it to useconds and finally adding the + * usecond overflow value to make up the 32-bit usecond total */ + timeValue = divide_by_48(~(TIMER0_TIME + g_user_interrupt_offset)) + g_us_overflow; + + /* Put interrupts back */ + core_util_critical_section_exit(); + + return timeValue; +} + +/* NOTE: it seems to be an accepted fact that users + * will never ask for a timeout of more than 2^31 useconds + * and hence it's possible to do signed arithmetic + */ +void us_ticker_set_interrupt(timestamp_t timestamp) +{ + g_timer_extra_loops_required = 0; + g_timer_extra_loops_done = 0; + int32_t timeDelta; + + /* Disable interrupts to avoid collisions */ + core_util_critical_section_enter(); + + /* Establish how far we're being asked to move */ + timeDelta = (int32_t) ((uint32_t) timestamp - us_ticker_read()); + + if (timeDelta <= 0) { + /* Make delta positive if it's not, it will expire pretty quickly */ + /* Note: can't just call us_ticker_irq_handler() directly as we + * may already be in it and will overflow the stack */ + timeDelta = 1; + } + + /* The TIMER0 clock source is greater than 1 MHz, so + * work out how many times we have to go around + * and what the remainder is */ + g_timer_extra_loops_required = (uint32_t) timeDelta / USECONDS_PER_FULL_TIMER0_RUN; + timeDelta -= g_timer_extra_loops_required * USECONDS_PER_FULL_TIMER0_RUN; + + /* Next time we hit the interrupt the increment will be smaller */ + g_us_overflow_increment = (uint32_t) timeDelta; + + /* We're about to modify the timer value; work out the + * difference so that we can compensate for it when + * the time is read */ + timeDelta = timeDelta * CLOCK_TICKS_PER_US; + g_user_interrupt_offset += TIMER0_TIME - timeDelta; + + /* Run for the remainder first, then we can loop for the full + * USECONDS_PER_FULL_TIMER0_RUN afterwards */ + TIMER0_LOAD = timeDelta; + + /* A user interrupt is now running */ + g_user_interrupt = true; + + /* Put interrupts back */ + core_util_critical_section_exit(); +} + +void us_ticker_disable_interrupt(void) +{ + /* Can't actually disable the interrupt here + * as we need it to manage the timer overflow, + * instead switch off the user interrupt part */ + g_user_interrupt = false; + g_timer_extra_loops_required = 0; + g_us_overflow_increment = 0; +} + +void us_ticker_clear_interrupt(void) +{ + /* As above, can't clear the interrupt as it + * may just be an overflow interrupt, instead + * clear the variables */ + g_user_interrupt = false; + g_timer_extra_loops_required = 0; + g_us_overflow_increment = 0; +} diff --git a/targets/TARGET_ublox/mbed_rtx.h b/targets/TARGET_ublox/mbed_rtx.h new file mode 100644 index 0000000000..98cf1d6d75 --- /dev/null +++ b/targets/TARGET_ublox/mbed_rtx.h @@ -0,0 +1,37 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 u-blox + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_MBED_RTX_H +#define MBED_MBED_RTX_H + +#if defined(TARGET_HI2110) + +#ifndef INITIAL_SP +#define INITIAL_SP (0x01000000 + 0x05000 - 256) +#endif + +#ifndef OS_TASKCNT +#define OS_TASKCNT 6 +#endif +#ifndef OS_MAINSTKSIZE +#define OS_MAINSTKSIZE 128 +#endif +#ifndef OS_CLOCK +#define OS_CLOCK 48000000 +#endif +#endif + +#endif // MBED_MBED_RTX_H diff --git a/targets/targets.json b/targets/targets.json index 8ae47e5e42..bce5b2c5d4 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -2109,5 +2109,31 @@ "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"], "release_versions": ["2", "5"], "device_name": "M453VG6AE" + }, + "HI2110": { + "inherits": ["Target"], + "core": "Cortex-M0", + "default_toolchain": "GCC_ARM", + "supported_toolchains": ["GCC_ARM", "ARM", "IAR"], + "extra_labels": ["ublox"], + "macros": ["TARGET_PROCESSOR_FAMILY_BOUDICA", "BOUDICA_SARA", "NDEBUG=1"], + "public": false, + "target_overrides": { + "*": { + "core.stdio-flush-at-exit": false + } + }, + "device_has": ["INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "SERIAL", "SLEEP", "STDIO_MESSAGES"], + "default_lib": "std", + "release_versions": ["5"] + }, + "SARA_NBIOT": { + "inherits": ["HI2110"], + "extra_labels": ["ublox", "HI2110"], + "public": false + }, + "SARA_NBIOT_EVK": { + "inherits": ["SARA_NBIOT"], + "extra_labels": ["ublox", "HI2110", "SARA_NBIOT"] } }