Add u-blox Sara-N target.

pull/3011/head
Rob Meades 2016-10-13 14:01:30 +01:00
parent 7bcc63b202
commit 4e808139d3
33 changed files with 4184 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
}
}

View File

@ -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

View File

@ -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 <rt_misc.h>
#include <stdint.h>
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

View File

@ -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
}

View File

@ -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

View File

@ -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 };

View File

@ -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

View File

@ -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

View File

@ -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];
}

View File

@ -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

View File

@ -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 <core_cm0.h> /* 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 */

View File

@ -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 <stdint.h>
#include <stdbool.h>
#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" */

View File

@ -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 <stdint.h>
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 */

View File

@ -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 */
}
}

View File

@ -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 <stddef.h>
#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);
}

View File

@ -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

View File

@ -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 <stdint.h>
#include <stdbool.h>
#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);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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

View File

@ -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"]
}
}