mirror of https://github.com/ARMmbed/mbed-os.git
KL05 - target ARM - gpio, us_ticker
- cmsis - only one type of MCG at the moment - HAL - gpio pins - us_tickerpull/11/head
parent
31ee5e5f29
commit
a14d88f156
|
@ -0,0 +1,14 @@
|
|||
|
||||
LR_IROM1 0x00000000 0x8000 { ; load region size_region (32k)
|
||||
ER_IROM1 0x00000000 0x8000 { ; load address = execution address
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
}
|
||||
; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0
|
||||
; 0x1000 - 0xC0 = 0xF40
|
||||
RW_IRAM1 0x1FFFFCC0 0xF40 {
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
;/*****************************************************************************
|
||||
; * @file: startup_MKL25Z4.s
|
||||
; * @purpose: CMSIS Cortex-M0plus Core Device Startup File for the
|
||||
; * MKL05Z4
|
||||
; * @version: 1.1
|
||||
; * @date: 2012-6-21
|
||||
; *
|
||||
; * Copyright: 1997 - 2012 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
;*
|
||||
; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
; *
|
||||
; *****************************************************************************/
|
||||
|
||||
|
||||
__initial_sp EQU 0x20000C00 ; Top of RAM
|
||||
|
||||
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 DMA0_IRQHandler ; DMA channel 0 transfer complete/error interrupt
|
||||
DCD DMA1_IRQHandler ; DMA channel 1 transfer complete/error interrupt
|
||||
DCD DMA2_IRQHandler ; DMA channel 2 transfer complete/error interrupt
|
||||
DCD DMA3_IRQHandler ; DMA channel 3 transfer complete/error interrupt
|
||||
DCD Reserved20_IRQHandler ; Reserved interrupt 20
|
||||
DCD FTFA_IRQHandler ; FTFA command complete/read collision interrupt
|
||||
DCD LVD_LVW_IRQHandler ; Low Voltage Detect, Low Voltage Warning
|
||||
DCD LLW_IRQHandler ; Low Leakage Wakeup
|
||||
DCD I2C0_IRQHandler ; I2C0 interrupt
|
||||
DCD Reserved_25_IRQHandler ; Reserved interrupt 25
|
||||
DCD SPI0_IRQHandler ; SPI0 interrupt
|
||||
DCD Reserved_27_IRQHandler ; Reserved interrupt 27
|
||||
DCD UART0_IRQHandler ; UART0 status and error interrupt
|
||||
DCD Reserved_29_IRQHandler ; Reserved interrupt 29
|
||||
DCD Reserved_30_IRQHandler ; Reserved interrupt 30
|
||||
DCD ADC0_IRQHandler ; ADC0 interrupt
|
||||
DCD CMP0_IRQHandler ; CMP0 interrupt
|
||||
DCD TPM0_IRQHandler ; TPM0 fault, overflow and channels interrupt
|
||||
DCD TPM1_IRQHandler ; TPM1 fault, overflow and channels interrupt
|
||||
DCD Reserved_35_IRQHandler ; Reserved interrupt 35
|
||||
DCD RTC_IRQHandler ; RTC interrupt
|
||||
DCD RTC_Seconds_IRQHandler ; RTC seconds interrupt
|
||||
DCD PIT_IRQHandler ; PIT timer channel 0 interrupt
|
||||
DCD Reserved_39_IRQHandler ; Reserved interrupt 39
|
||||
DCD Reserved_40_IRQHandler ; Reserved interrupt 40
|
||||
DCD DAC0_IRQHandler ; DAC0 interrupt
|
||||
DCD TSI0_IRQHandler ; TSI0 interrupt
|
||||
DCD MCG_IRQHandler ; MCG interrupt
|
||||
DCD LPTimer_IRQHandler ; LPTimer interrupt
|
||||
DCD Reserved_45_IRQHandler ; Reserved interrupt 45
|
||||
DCD PORTA_IRQHandler ; Port A interrupt
|
||||
DCD PORTD_IRQHandler ; Port D interrupt
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
; <h> Flash Configuration
|
||||
; <i> 16-byte flash configuration field that stores default protection settings (loaded on reset)
|
||||
; <i> and security information that allows the MCU to restrict acces to the FTFL module.
|
||||
; <h> Backdoor Comparison Key
|
||||
; <o0> Backdoor Key 0 <0x0-0xFF:2>
|
||||
; <o1> Backdoor Key 1 <0x0-0xFF:2>
|
||||
; <o2> Backdoor Key 2 <0x0-0xFF:2>
|
||||
; <o3> Backdoor Key 3 <0x0-0xFF:2>
|
||||
; <o4> Backdoor Key 4 <0x0-0xFF:2>
|
||||
; <o5> Backdoor Key 5 <0x0-0xFF:2>
|
||||
; <o6> Backdoor Key 6 <0x0-0xFF:2>
|
||||
; <o7> Backdoor Key 7 <0x0-0xFF:2>
|
||||
BackDoorK0 EQU 0xFF
|
||||
BackDoorK1 EQU 0xFF
|
||||
BackDoorK2 EQU 0xFF
|
||||
BackDoorK3 EQU 0xFF
|
||||
BackDoorK4 EQU 0xFF
|
||||
BackDoorK5 EQU 0xFF
|
||||
BackDoorK6 EQU 0xFF
|
||||
BackDoorK7 EQU 0xFF
|
||||
; </h>
|
||||
; <h> Program flash protection bytes (FPROT)
|
||||
; <i> Each program flash region can be protected from program and erase operation by setting the associated PROT bit.
|
||||
; <i> Each bit protects a 1/32 region of the program flash memory.
|
||||
; <h> FPROT0
|
||||
; <i> Program flash protection bytes
|
||||
; <i> 1/32 - 8/32 region
|
||||
; <o.0> FPROT0.0
|
||||
; <o.1> FPROT0.1
|
||||
; <o.2> FPROT0.2
|
||||
; <o.3> FPROT0.3
|
||||
; <o.4> FPROT0.4
|
||||
; <o.5> FPROT0.5
|
||||
; <o.6> FPROT0.6
|
||||
; <o.7> FPROT0.7
|
||||
nFPROT0 EQU 0x00
|
||||
FPROT0 EQU nFPROT0:EOR:0xFF
|
||||
; </h>
|
||||
; <h> FPROT1
|
||||
; <i> Program Flash Region Protect Register 1
|
||||
; <i> 9/32 - 16/32 region
|
||||
; <o.0> FPROT1.0
|
||||
; <o.1> FPROT1.1
|
||||
; <o.2> FPROT1.2
|
||||
; <o.3> FPROT1.3
|
||||
; <o.4> FPROT1.4
|
||||
; <o.5> FPROT1.5
|
||||
; <o.6> FPROT1.6
|
||||
; <o.7> FPROT1.7
|
||||
nFPROT1 EQU 0x00
|
||||
FPROT1 EQU nFPROT1:EOR:0xFF
|
||||
; </h>
|
||||
; <h> FPROT2
|
||||
; <i> Program Flash Region Protect Register 2
|
||||
; <i> 17/32 - 24/32 region
|
||||
; <o.0> FPROT2.0
|
||||
; <o.1> FPROT2.1
|
||||
; <o.2> FPROT2.2
|
||||
; <o.3> FPROT2.3
|
||||
; <o.4> FPROT2.4
|
||||
; <o.5> FPROT2.5
|
||||
; <o.6> FPROT2.6
|
||||
; <o.7> FPROT2.7
|
||||
nFPROT2 EQU 0x00
|
||||
FPROT2 EQU nFPROT2:EOR:0xFF
|
||||
; </h>
|
||||
; <h> FPROT3
|
||||
; <i> Program Flash Region Protect Register 3
|
||||
; <i> 25/32 - 32/32 region
|
||||
; <o.0> FPROT3.0
|
||||
; <o.1> FPROT3.1
|
||||
; <o.2> FPROT3.2
|
||||
; <o.3> FPROT3.3
|
||||
; <o.4> FPROT3.4
|
||||
; <o.5> FPROT3.5
|
||||
; <o.6> FPROT3.6
|
||||
; <o.7> FPROT3.7
|
||||
nFPROT3 EQU 0x00
|
||||
FPROT3 EQU nFPROT3:EOR:0xFF
|
||||
; </h>
|
||||
; </h>
|
||||
; </h>
|
||||
; <h> Flash nonvolatile option byte (FOPT)
|
||||
; <i> Allows the user to customize the operation of the MCU at boot time.
|
||||
; <o.0> LPBOOT0
|
||||
; <0=> Core and system clock divider (OUTDIV1) is 0x7 (divide by 8) or 0x3 (divide by 4)
|
||||
; <1=> Core and system clock divider (OUTDIV1) is 0x1 (divide by 2) or 0x0 (divide by 1)
|
||||
; <o.4> LPBOOT1
|
||||
; <0=> Core and system clock divider (OUTDIV1) is 0x7 (divide by 8) or 0x1 (divide by 2)
|
||||
; <1=> Core and system clock divider (OUTDIV1) is 0x3 (divide by 4) or 0x0 (divide by 1)
|
||||
; <o.2> NMI_DIS
|
||||
; <0=> NMI interrupts are always blocked
|
||||
; <1=> NMI pin/interrupts reset default to enabled
|
||||
; <o.3> RESET_PIN_CFG
|
||||
; <0=> RESET pin is disabled following a POR and cannot be enabled as RESET function
|
||||
; <1=> RESET pin is dedicated
|
||||
; <o.3> FAST_INIT
|
||||
; <0=> Slower initialization
|
||||
; <1=> Fast Initialization
|
||||
FOPT EQU 0xFF
|
||||
; </h>
|
||||
; <h> Flash security byte (FSEC)
|
||||
; <i> WARNING: If SEC field is configured as "MCU security status is secure" and MEEN field is configured as "Mass erase is disabled",
|
||||
; <i> MCU's security status cannot be set back to unsecure state since Mass erase via the debugger is blocked !!!
|
||||
; <o.0..1> SEC
|
||||
; <2=> MCU security status is unsecure
|
||||
; <3=> MCU security status is secure
|
||||
; <i> Flash Security
|
||||
; <i> This bits define the security state of the MCU.
|
||||
; <o.2..3> FSLACC
|
||||
; <2=> Freescale factory access denied
|
||||
; <3=> Freescale factory access granted
|
||||
; <i> Freescale Failure Analysis Access Code
|
||||
; <i> This bits define the security state of the MCU.
|
||||
; <o.4..5> MEEN
|
||||
; <2=> Mass erase is disabled
|
||||
; <3=> Mass erase is enabled
|
||||
; <i> Mass Erase Enable Bits
|
||||
; <i> Enables and disables mass erase capability of the FTFL module
|
||||
; <o.6..7> KEYEN
|
||||
; <2=> Backdoor key access enabled
|
||||
; <3=> Backdoor key access disabled
|
||||
; <i> Backdoor key Security Enable
|
||||
; <i> These bits enable and disable backdoor key access to the FTFL module.
|
||||
FSEC EQU 0xFE
|
||||
; </h>
|
||||
|
||||
IF :LNOT::DEF:RAM_TARGET
|
||||
AREA |.ARM.__at_0x400|, CODE, READONLY
|
||||
DCB BackDoorK0, BackDoorK1, BackDoorK2, BackDoorK3
|
||||
DCB BackDoorK4, BackDoorK5, BackDoorK6, BackDoorK7
|
||||
DCB FPROT0, FPROT1, FPROT2, FPROT3
|
||||
DCB FSEC, FOPT, 0xFF, 0xFF
|
||||
ENDIF
|
||||
|
||||
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 DMA0_IRQHandler [WEAK]
|
||||
EXPORT DMA1_IRQHandler [WEAK]
|
||||
EXPORT DMA2_IRQHandler [WEAK]
|
||||
EXPORT DMA3_IRQHandler [WEAK]
|
||||
EXPORT Reserved20_IRQHandler [WEAK]
|
||||
EXPORT FTFA_IRQHandler [WEAK]
|
||||
EXPORT LVD_LVW_IRQHandler [WEAK]
|
||||
EXPORT LLW_IRQHandler [WEAK]
|
||||
EXPORT I2C0_IRQHandler [WEAK]
|
||||
EXPORT Reserved_25_IRQHandler [WEAK]
|
||||
EXPORT SPI0_IRQHandler [WEAK]
|
||||
EXPORT Reserved_27_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT Reserved_29_IRQHandler [WEAK]
|
||||
EXPORT Reserved_30_IRQHandler [WEAK]
|
||||
EXPORT ADC0_IRQHandler [WEAK]
|
||||
EXPORT CMP0_IRQHandler [WEAK]
|
||||
EXPORT TPM0_IRQHandler [WEAK]
|
||||
EXPORT TPM1_IRQHandler [WEAK]
|
||||
EXPORT Reserved_35_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT RTC_Seconds_IRQHandler [WEAK]
|
||||
EXPORT PIT_IRQHandler [WEAK]
|
||||
EXPORT Reserved_39_IRQHandler [WEAK]
|
||||
EXPORT Reserved_40_IRQHandler [WEAK]
|
||||
EXPORT DAC0_IRQHandler [WEAK]
|
||||
EXPORT TSI0_IRQHandler [WEAK]
|
||||
EXPORT MCG_IRQHandler [WEAK]
|
||||
EXPORT LPTimer_IRQHandler [WEAK]
|
||||
EXPORT Reserved_45_IRQHandler [WEAK]
|
||||
EXPORT PORTA_IRQHandler [WEAK]
|
||||
EXPORT PORTD_IRQHandler [WEAK]
|
||||
EXPORT DefaultISR [WEAK]
|
||||
|
||||
DMA0_IRQHandler
|
||||
DMA1_IRQHandler
|
||||
DMA2_IRQHandler
|
||||
DMA3_IRQHandler
|
||||
Reserved20_IRQHandler
|
||||
FTFA_IRQHandler
|
||||
LVD_LVW_IRQHandler
|
||||
LLW_IRQHandler
|
||||
I2C0_IRQHandler
|
||||
Reserved_25_IRQHandler
|
||||
SPI0_IRQHandler
|
||||
Reserved_27_IRQHandler
|
||||
UART0_IRQHandler
|
||||
Reserved_29_IRQHandler
|
||||
Reserved_30_IRQHandler
|
||||
ADC0_IRQHandler
|
||||
CMP0_IRQHandler
|
||||
TPM0_IRQHandler
|
||||
TPM1_IRQHandler
|
||||
Reserved_35_IRQHandler
|
||||
RTC_IRQHandler
|
||||
RTC_Seconds_IRQHandler
|
||||
PIT_IRQHandler
|
||||
Reserved_39_IRQHandler
|
||||
Reserved_40_IRQHandler
|
||||
DAC0_IRQHandler
|
||||
TSI0_IRQHandler
|
||||
MCG_IRQHandler
|
||||
LPTimer_IRQHandler
|
||||
Reserved_45_IRQHandler
|
||||
PORTA_IRQHandler
|
||||
PORTD_IRQHandler
|
||||
DefaultISR
|
||||
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
END
|
|
@ -0,0 +1,31 @@
|
|||
/* mbed Microcontroller Library - stackheap
|
||||
* Copyright (C) 2009-2011 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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
|||
/* mbed Microcontroller Library - CMSIS
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* A generic CMSIS include header, pulling in KL05 specifics
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_H
|
||||
#define MBED_CMSIS_H
|
||||
|
||||
#include "MKL05Z4.h"
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
/* mbed Microcontroller Library - cmsis_nvic for LPC11U24
|
||||
* Copyright (c) 2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*/
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
|
||||
#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFFC00) // Vectors positioned at start of RAM
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
|
||||
static volatile uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
|
||||
uint32_t i;
|
||||
|
||||
// Copy and switch to dynamic vectors if the first time called
|
||||
if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) {
|
||||
uint32_t *old_vectors = (uint32_t*)SCB->VTOR;
|
||||
for (i=0; i<NVIC_NUM_VECTORS; i++) {
|
||||
vectors[i] = old_vectors[i];
|
||||
}
|
||||
SCB->VTOR = (uint32_t)vectors;
|
||||
}
|
||||
|
||||
vectors[IRQn + 16] = vector;
|
||||
}
|
||||
|
||||
uint32_t NVIC_GetVector(IRQn_Type IRQn) {
|
||||
uint32_t *vectors = (uint32_t*)SCB->VTOR;
|
||||
return vectors[IRQn + 16];
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* mbed Microcontroller Library - cmsis_nvic
|
||||
* Copyright (c) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_NVIC_H
|
||||
#define MBED_CMSIS_NVIC_H
|
||||
|
||||
#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
|
|
@ -0,0 +1,279 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm0.c
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Source File
|
||||
* @version V2.00
|
||||
* @date 10. September 2010
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* define compiler specific symbols */
|
||||
#if defined ( __CC_ARM )
|
||||
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
__ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
__ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM void __CLREX(void)
|
||||
{
|
||||
clrex
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
|
||||
/* obsolete */
|
||||
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
|
||||
/* obsolete */
|
||||
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
|
||||
/* obsolete */
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_CONTROL(void)
|
||||
{
|
||||
mrs r0, control
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
msr control, r0
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get ISPR Register
|
||||
|
||||
This function returns the content of the ISPR Register.
|
||||
|
||||
\return ISPR Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_IPSR(void)
|
||||
{
|
||||
mrs r0, ipsr
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_APSR(void)
|
||||
{
|
||||
mrs r0, apsr
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_xPSR(void)
|
||||
{
|
||||
mrs r0, xpsr
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_PSP(void)
|
||||
{
|
||||
mrs r0, psp
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
msr psp, r0
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_MSP(void)
|
||||
{
|
||||
mrs r0, msp
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM void __set_MSP(uint32_t mainStackPointer)
|
||||
{
|
||||
msr msp, r0
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
mrs r0, primask
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
msr primask, r0
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
|
||||
/* obsolete */
|
||||
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
|
||||
/* obsolete */
|
||||
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
|
||||
/* obsolete */
|
||||
#endif
|
|
@ -0,0 +1,778 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm0plus.h
|
||||
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
|
||||
* @version V3.02
|
||||
* @date 05. November 2012
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM0PLUS_H_GENERIC
|
||||
#define __CORE_CM0PLUS_H_GENERIC
|
||||
|
||||
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/** \ingroup Cortex-M0+
|
||||
@{
|
||||
*/
|
||||
|
||||
/* CMSIS CM0P definitions */
|
||||
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM0PLUS_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \
|
||||
__CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0x00) /*!< Cortex-M Core */
|
||||
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||
#define __STATIC_INLINE static __inline
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
|
||||
#define __STATIC_INLINE static inline
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
|
||||
#endif
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
|
||||
*/
|
||||
#define __FPU_USED 0
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h> /* standard types definitions */
|
||||
#include <core_cmInstr.h> /* Core Instruction Access */
|
||||
#include <core_cmFunc.h> /* Core Function Access */
|
||||
|
||||
#endif /* __CORE_CM0PLUS_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM0PLUS_H_DEPENDANT
|
||||
#define __CORE_CM0PLUS_H_DEPENDANT
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM0PLUS_REV
|
||||
#define __CM0PLUS_REV 0x0000
|
||||
#warning "__CM0PLUS_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __MPU_PRESENT
|
||||
#define __MPU_PRESENT 0
|
||||
#warning "__MPU_PRESENT not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __VTOR_PRESENT
|
||||
#define __VTOR_PRESENT 0
|
||||
#warning "__VTOR_PRESENT not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2
|
||||
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 0
|
||||
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/*@} end of group Cortex-M0+ */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
Core Register contain:
|
||||
- Core Register
|
||||
- Core NVIC Register
|
||||
- Core SCB Register
|
||||
- Core SysTick Register
|
||||
- Core MPU Register
|
||||
******************************************************************************/
|
||||
/** \defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||
*/
|
||||
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
#if (__CORTEX_M != 0x04)
|
||||
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
|
||||
#else
|
||||
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
|
||||
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
|
||||
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
|
||||
#endif
|
||||
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
|
||||
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} IPSR_Type;
|
||||
|
||||
|
||||
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
#if (__CORTEX_M != 0x04)
|
||||
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||
#else
|
||||
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
|
||||
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
|
||||
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
|
||||
#endif
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
|
||||
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} xPSR_Type;
|
||||
|
||||
|
||||
/** \brief Union type to access the Control Registers (CONTROL).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
|
||||
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
|
||||
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CONTROL_Type;
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||
\brief Type definitions for the NVIC Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31];
|
||||
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RSERVED1[31];
|
||||
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31];
|
||||
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31];
|
||||
uint32_t RESERVED4[64];
|
||||
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||
} NVIC_Type;
|
||||
|
||||
/*@} end of group CMSIS_NVIC */
|
||||
|
||||
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||
\brief Type definitions for the System Control Block Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \brief Structure type to access the System Control Block (SCB).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||
#if (__VTOR_PRESENT == 1)
|
||||
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
|
||||
#else
|
||||
uint32_t RESERVED0;
|
||||
#endif
|
||||
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||
uint32_t RESERVED1;
|
||||
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||
} SCB_Type;
|
||||
|
||||
/* SCB CPUID Register Definitions */
|
||||
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
|
||||
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||
|
||||
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
|
||||
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||
|
||||
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
|
||||
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||
|
||||
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
|
||||
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||
|
||||
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
|
||||
#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
|
||||
|
||||
/* SCB Interrupt Control State Register Definitions */
|
||||
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
|
||||
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
|
||||
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
|
||||
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
|
||||
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
|
||||
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
|
||||
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
|
||||
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
|
||||
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
|
||||
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||
|
||||
#if (__VTOR_PRESENT == 1)
|
||||
/* SCB Interrupt Control State Register Definitions */
|
||||
#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
|
||||
#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
|
||||
#endif
|
||||
|
||||
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||
|
||||
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
|
||||
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||
|
||||
/* SCB System Control Register Definitions */
|
||||
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
|
||||
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
|
||||
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
|
||||
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||
|
||||
/* SCB Configuration Control Register Definitions */
|
||||
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
|
||||
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||
|
||||
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
|
||||
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||
|
||||
/* SCB System Handler Control and State Register Definitions */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCB */
|
||||
|
||||
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||
\brief Type definitions for the System Timer Registers.
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \brief Structure type to access the System Timer (SysTick).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||
} SysTick_Type;
|
||||
|
||||
/* SysTick Control / Status Register Definitions */
|
||||
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
|
||||
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||
|
||||
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
|
||||
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||
|
||||
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
|
||||
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||
|
||||
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
|
||||
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
|
||||
|
||||
/* SysTick Reload Register Definitions */
|
||||
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
|
||||
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
|
||||
|
||||
/* SysTick Current Register Definitions */
|
||||
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
|
||||
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
|
||||
|
||||
/* SysTick Calibration Register Definitions */
|
||||
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
|
||||
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||
|
||||
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
|
||||
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||
|
||||
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
|
||||
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
|
||||
|
||||
/*@} end of group CMSIS_SysTick */
|
||||
|
||||
#if (__MPU_PRESENT == 1)
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
|
||||
\brief Type definitions for the Memory Protection Unit (MPU)
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \brief Structure type to access the Memory Protection Unit (MPU).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
|
||||
__IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
|
||||
__IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
|
||||
__IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
|
||||
__IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
|
||||
} MPU_Type;
|
||||
|
||||
/* MPU Type Register */
|
||||
#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
||||
#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
|
||||
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
|
||||
|
||||
#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
|
||||
#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
|
||||
|
||||
/* MPU Control Register */
|
||||
#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
|
||||
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
|
||||
|
||||
#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
|
||||
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
|
||||
|
||||
#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
|
||||
#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
|
||||
|
||||
/* MPU Region Number Register */
|
||||
#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
|
||||
#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
|
||||
|
||||
/* MPU Region Base Address Register */
|
||||
#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */
|
||||
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
|
||||
|
||||
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
|
||||
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
|
||||
|
||||
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
|
||||
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
|
||||
|
||||
/* MPU Region Attribute and Size Register */
|
||||
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
|
||||
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
|
||||
|
||||
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
|
||||
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
|
||||
|
||||
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
|
||||
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
|
||||
|
||||
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
|
||||
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
|
||||
|
||||
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
|
||||
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
|
||||
|
||||
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
|
||||
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
|
||||
|
||||
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
|
||||
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
|
||||
|
||||
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
|
||||
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
|
||||
|
||||
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
|
||||
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
|
||||
|
||||
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
|
||||
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
|
||||
|
||||
/*@} end of group CMSIS_MPU */
|
||||
#endif
|
||||
|
||||
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR)
|
||||
are only accessible over DAP and not via processor. Therefore
|
||||
they are not covered by the Cortex-M0 header file.
|
||||
@{
|
||||
*/
|
||||
/*@} end of group CMSIS_CoreDebug */
|
||||
|
||||
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_base Core Definitions
|
||||
\brief Definitions for base addresses, unions, and structures.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Memory mapping of Cortex-M0+ Hardware */
|
||||
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||
|
||||
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||
|
||||
#if (__MPU_PRESENT == 1)
|
||||
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
|
||||
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
|
||||
#endif
|
||||
|
||||
/*@} */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
Core Function Interface contains:
|
||||
- Core NVIC Functions
|
||||
- Core SysTick Functions
|
||||
- Core Register Access Functions
|
||||
******************************************************************************/
|
||||
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ########################## NVIC functions #################################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Interrupt Priorities are WORD accessible only under ARMv6M */
|
||||
/* The following MACROS handle generation of the register offset and byte masks */
|
||||
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
|
||||
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
|
||||
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
|
||||
|
||||
|
||||
/** \brief Enable External Interrupt
|
||||
|
||||
The function enables a device-specific interrupt in the NVIC interrupt controller.
|
||||
|
||||
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable External Interrupt
|
||||
|
||||
The function disables a device-specific interrupt in the NVIC interrupt controller.
|
||||
|
||||
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Pending Interrupt
|
||||
|
||||
The function reads the pending register in the NVIC and returns the pending bit
|
||||
for the specified interrupt.
|
||||
|
||||
\param [in] IRQn Interrupt number.
|
||||
|
||||
\return 0 Interrupt status is not pending.
|
||||
\return 1 Interrupt status is pending.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Pending Interrupt
|
||||
|
||||
The function sets the pending bit of an external interrupt.
|
||||
|
||||
\param [in] IRQn Interrupt number. Value cannot be negative.
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Clear Pending Interrupt
|
||||
|
||||
The function clears the pending bit of an external interrupt.
|
||||
|
||||
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Interrupt Priority
|
||||
|
||||
The function sets the priority of an interrupt.
|
||||
|
||||
\note The priority cannot be set for every core interrupt.
|
||||
|
||||
\param [in] IRQn Interrupt number.
|
||||
\param [in] priority Priority to set.
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
if(IRQn < 0) {
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
|
||||
else {
|
||||
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Interrupt Priority
|
||||
|
||||
The function reads the priority of an interrupt. The interrupt
|
||||
number can be positive to specify an external (device specific)
|
||||
interrupt, or negative to specify an internal (core) interrupt.
|
||||
|
||||
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Interrupt Priority. Value is aligned automatically to the implemented
|
||||
priority bits of the microcontroller.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
|
||||
if(IRQn < 0) {
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
|
||||
else {
|
||||
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
|
||||
}
|
||||
|
||||
|
||||
/** \brief System Reset
|
||||
|
||||
The function initiates a system reset request to reset the MCU.
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_SystemReset(void)
|
||||
{
|
||||
__DSB(); /* Ensure all outstanding memory accesses included
|
||||
buffered write are completed before reset */
|
||||
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
while(1); /* wait until reset */
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
|
||||
|
||||
/* ################################## SysTick function ############################################ */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||
\brief Functions that configure the System.
|
||||
@{
|
||||
*/
|
||||
|
||||
#if (__Vendor_SysTickConfig == 0)
|
||||
|
||||
/** \brief System Tick Configuration
|
||||
|
||||
The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
Counter is in free running mode to generate periodic interrupts.
|
||||
|
||||
\param [in] ticks Number of ticks between two interrupts.
|
||||
|
||||
\return 0 Function succeeded.
|
||||
\return 1 Function failed.
|
||||
|
||||
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
must contain a vendor-specific implementation of this function.
|
||||
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
{
|
||||
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
|
||||
|
||||
SysTick->LOAD = ticks - 1; /* set reload register */
|
||||
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0; /* Load the SysTick Counter Value */
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||
return (0); /* Function successful */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,616 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmFunc.h
|
||||
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||
* @version V3.02
|
||||
* @date 24. May 2012
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CORE_CMFUNC_H
|
||||
#define __CORE_CMFUNC_H
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* intrinsic void __enable_irq(); */
|
||||
/* intrinsic void __disable_irq(); */
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get IPSR Register
|
||||
|
||||
This function returns the content of the IPSR Register.
|
||||
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & (uint32_t)1);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief Enable IRQ Interrupts
|
||||
|
||||
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie i" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable IRQ Interrupts
|
||||
|
||||
This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid i" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
__ASM volatile ("MSR control, %0" : : "r" (control) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get IPSR Register
|
||||
|
||||
This function returns the content of the IPSR Register.
|
||||
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie f" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid f" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all instrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||
|
||||
|
||||
#endif /* __CORE_CMFUNC_H */
|
|
@ -0,0 +1,643 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V3.03
|
||||
* @date 29. August 2012
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CORE_CMINSTR_H
|
||||
#define __CORE_CMINSTR_H
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() __isb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() __dsb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() __dmb(0xF)
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __rbit
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
__ASM volatile ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
|
||||
{
|
||||
__ASM volatile ("sev");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
|
||||
__ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
|
||||
return(op1);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint16_t result;
|
||||
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H */
|
|
@ -0,0 +1,102 @@
|
|||
#include <stdint.h>
|
||||
#include "MKL05Z4.h"
|
||||
|
||||
#define DISABLE_WDOG 1
|
||||
|
||||
#define CLOCK_SETUP 0
|
||||
/* Predefined clock setups
|
||||
0 ... Multipurpose Clock Generator (MCG) in FLL Engaged Internal (FEI) mode
|
||||
Reference clock source for MCG module is the slow internal clock source 32.768kHz
|
||||
Core clock = 41.94MHz, BusClock = 13.98MHz
|
||||
1 ... Multipurpose Clock Generator (MCG) in PLL Engaged External (PEE) mode
|
||||
Reference clock source for MCG module is an external crystal 8MHz
|
||||
Core clock = 48MHz, BusClock = 24MHz
|
||||
2 ... Multipurpose Clock Generator (MCG) in Bypassed Low Power External (BLPE) mode
|
||||
Core clock/Bus clock derived directly from an external crystal 8MHz with no multiplication
|
||||
Core clock = 8MHz, BusClock = 8MHz
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clock source values
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if (CLOCK_SETUP == 0)
|
||||
#define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
|
||||
#define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
|
||||
#define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
|
||||
#define DEFAULT_SYSTEM_CLOCK 41943040u /* Default System clock value */
|
||||
#elif (CLOCK_SETUP == 1)
|
||||
#define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
|
||||
#define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
|
||||
#define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
|
||||
#define DEFAULT_SYSTEM_CLOCK 48000000u /* Default System clock value */
|
||||
#elif (CLOCK_SETUP == 2)
|
||||
#define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
|
||||
#define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
|
||||
#define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
|
||||
#define DEFAULT_SYSTEM_CLOCK 8000000u /* Default System clock value */
|
||||
#endif /* (CLOCK_SETUP == 2) */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- Core clock
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemInit()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemInit (void) {
|
||||
#if (DISABLE_WDOG)
|
||||
/* Disable the WDOG module */
|
||||
/* SIM_COPC: COPT=0,COPCLKS=0,COPW=0 */
|
||||
SIM->COPC = (uint32_t)0x00u;
|
||||
#endif /* (DISABLE_WDOG) */
|
||||
#if (CLOCK_SETUP == 0)
|
||||
/* System clock initialization */
|
||||
/* SIM_SCGC5: PORTB=1,PORTA=1 */
|
||||
SIM->SCGC5 |= (SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTA_MASK); /* Enable clock gate for ports to enable pin routing */
|
||||
/* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
|
||||
SIM->CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x00)); /* Update system prescalers */
|
||||
/* SIM_SOPT1: OSC32KSEL=3 */
|
||||
SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */
|
||||
/* SIM_SOPT2: TPMSRC=1 */
|
||||
SIM->SOPT2 = (uint32_t)((SIM->SOPT2 & (uint32_t)~(uint32_t)(
|
||||
SIM_SOPT2_TPMSRC(0x02)
|
||||
)) | (uint32_t)(
|
||||
SIM_SOPT2_TPMSRC(0x01)
|
||||
)); /* Set the TPM clock */
|
||||
/* Switch to FEI Mode */
|
||||
/* MCG_C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
|
||||
MCG->C1 = MCG_C1_CLKS(0x00) |
|
||||
MCG_C1_FRDIV(0x00) |
|
||||
MCG_C1_IREFS_MASK |
|
||||
MCG_C1_IRCLKEN_MASK;
|
||||
/* MCG_C2: LOCRE0=0,??=0,RANGE0=0,HGO0=0,EREFS0=0,LP=0,IRCS=0 */
|
||||
MCG->C2 = MCG_C2_RANGE0(0x00);
|
||||
/* MCG_C4: DMX32=0,DRST_DRS=0 */
|
||||
MCG->C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
|
||||
/* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
|
||||
OSC0->CR = OSC_CR_ERCLKEN_MASK;
|
||||
while((MCG->S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */
|
||||
}
|
||||
while((MCG->S & 0x0CU) != 0x00U) { /* Wait until output of the FLL is selected */
|
||||
}
|
||||
#elif (CLOCK_SETUP == 1)
|
||||
|
||||
#elif (CLOCK_SETUP == 2)
|
||||
|
||||
#endif /* (CLOCK_SETUP == 2) */
|
||||
}
|
||||
|
||||
// Make sure we are pulling in the retargeting module at link time
|
||||
extern int stdio_retargeting_module;
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemCoreClockUpdate()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemCoreClockUpdate (void) {
|
||||
/* TODO */
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processor: MKL05Z128VLK4
|
||||
** Compilers: ARM Compiler
|
||||
** Freescale C/C++ for Embedded ARM
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
**
|
||||
** Reference manual: KL05RM, Rev.1, Jun 2012
|
||||
** Version: rev. 1.1, 2012-06-21
|
||||
**
|
||||
** Abstract:
|
||||
** Provides a system configuration function and a global variable that
|
||||
** contains the system frequency. It configures the device and initializes
|
||||
** the oscillator (PLL) that is part of the microcontroller device.
|
||||
**
|
||||
** Copyright: 2012 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
**
|
||||
** http: www.freescale.com
|
||||
** mail: support@freescale.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2012-06-13)
|
||||
** Initial version.
|
||||
** - rev. 1.1 (2012-06-21)
|
||||
** Update according to reference manual rev. 1.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file MKL05Z4
|
||||
* @version 1.1
|
||||
* @date 2012-06-21
|
||||
* @brief Device specific configuration file for MKL05Z4 (header file)
|
||||
*
|
||||
* Provides a system configuration function and a global variable that contains
|
||||
* the system frequency. It configures the device and initializes the oscillator
|
||||
* (PLL) that is part of the microcontroller device.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_MKL05Z4_H_
|
||||
#define SYSTEM_MKL05Z4_H_ /**< Symbol preventing repeated inclusion */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief System clock frequency (core clock)
|
||||
*
|
||||
* The system clock frequency supplied to the SysTick timer and the processor
|
||||
* core clock. This variable can be used by the user application to setup the
|
||||
* SysTick timer or configure other parameters. It may also be used by debugger to
|
||||
* query the frequency of the debug timer or configure the trace clock speed
|
||||
* SystemCoreClock is initialized with a correct predefined value.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
*
|
||||
* Typically this function configures the oscillator (PLL) that is part of the
|
||||
* microcontroller device. For systems with variable clock speed it also updates
|
||||
* the variable SystemCoreClock. SystemInit is called from startup_device file.
|
||||
*/
|
||||
void SystemInit (void);
|
||||
|
||||
/**
|
||||
* @brief Updates the SystemCoreClock variable.
|
||||
*
|
||||
* It must be called whenever the core clock is changed during program
|
||||
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
|
||||
* the current core clock.
|
||||
*/
|
||||
void SystemCoreClockUpdate (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #if !defined(SYSTEM_MKL05Z4_H_) */
|
|
@ -0,0 +1,82 @@
|
|||
/* 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_PERIPHERALNAMES_H
|
||||
#define MBED_PERIPHERALNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UART_0 = (int)UART0_BASE
|
||||
} UARTName;
|
||||
#define STDIO_UART_TX USBTX
|
||||
#define STDIO_UART_RX USBRX
|
||||
#define STDIO_UART UART_0
|
||||
|
||||
typedef enum {
|
||||
I2C_0 = (int)I2C0_BASE
|
||||
} I2CName;
|
||||
|
||||
#define TPM_SHIFT 8
|
||||
typedef enum {
|
||||
PWM_1 = (0 << TPM_SHIFT) | (0), // TPM0 CH0
|
||||
PWM_2 = (0 << TPM_SHIFT) | (1), // TPM0 CH1
|
||||
PWM_3 = (0 << TPM_SHIFT) | (2), // TPM0 CH2
|
||||
PWM_4 = (0 << TPM_SHIFT) | (3), // TPM0 CH3
|
||||
PWM_5 = (0 << TPM_SHIFT) | (4), // TPM0 CH4
|
||||
PWM_6 = (0 << TPM_SHIFT) | (5), // TPM0 CH5
|
||||
|
||||
PWM_7 = (1 << TPM_SHIFT) | (0), // TPM1 CH0
|
||||
PWM_8 = (1 << TPM_SHIFT) | (1), // TPM1 CH1
|
||||
|
||||
PWM_9 = (2 << TPM_SHIFT) | (0), // TPM2 CH0
|
||||
PWM_10 = (2 << TPM_SHIFT) | (1) // TPM2 CH1
|
||||
} PWMName;
|
||||
|
||||
typedef enum {
|
||||
ADC0_SE0 = 0,
|
||||
ADC0_SE3 = 3,
|
||||
ADC0_SE4b = 4,
|
||||
ADC0_SE5b = 5,
|
||||
ADC0_SE6b = 6,
|
||||
ADC0_SE7b = 7,
|
||||
ADC0_SE8 = 8,
|
||||
ADC0_SE9 = 9,
|
||||
ADC0_SE11 = 11,
|
||||
ADC0_SE12 = 12,
|
||||
ADC0_SE13 = 13,
|
||||
ADC0_SE14 = 14,
|
||||
ADC0_SE15 = 15,
|
||||
ADC0_SE23 = 23
|
||||
} ADCName;
|
||||
|
||||
typedef enum {
|
||||
DAC_0 = 0
|
||||
} DACName;
|
||||
|
||||
|
||||
typedef enum {
|
||||
SPI_0 = (int)SPI0_BASE
|
||||
} SPIName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,128 @@
|
|||
/* 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_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 12
|
||||
|
||||
typedef enum {
|
||||
PTA0 = 0x0,
|
||||
PTA1 = 0x4,
|
||||
PTA2 = 0x8,
|
||||
PTA3 = 0xc,
|
||||
PTA4 = 0x10,
|
||||
PTA5 = 0x14,
|
||||
PTA6 = 0x18,
|
||||
PTA7 = 0x1c,
|
||||
PTA8 = 0x20,
|
||||
PTA9 = 0x24,
|
||||
PTA10 = 0x28,
|
||||
PTA11 = 0x2c,
|
||||
PTA12 = 0x30,
|
||||
PTA13 = 0x34,
|
||||
PTA14 = 0x38,
|
||||
PTA15 = 0x3c,
|
||||
PTA16 = 0x40,
|
||||
PTA17 = 0x44,
|
||||
PTA18 = 0x48,
|
||||
PTA19 = 0x4c,
|
||||
PTB0 = 0x1000,
|
||||
PTB1 = 0x1004,
|
||||
PTB2 = 0x1008,
|
||||
PTB3 = 0x100c,
|
||||
PTB4 = 0x1010,
|
||||
PTB5 = 0x1014,
|
||||
PTB6 = 0x1018,
|
||||
PTB7 = 0x101c,
|
||||
PTB8 = 0x1020,
|
||||
PTB9 = 0x1024,
|
||||
PTB10 = 0x1028,
|
||||
PTB11 = 0x102c,
|
||||
PTB12 = 0x1030,
|
||||
PTB13 = 0x1034,
|
||||
PTB14 = 0x1038,
|
||||
PTB15 = 0x103c,
|
||||
PTB16 = 0x1040,
|
||||
PTB17 = 0x1044,
|
||||
PTB18 = 0x1048,
|
||||
PTB19 = 0x104c,
|
||||
PTB20 = 0x1050,
|
||||
|
||||
LED_RED = PTB8,
|
||||
LED_GREEN = PTB9,
|
||||
LED_BLUE = PTB10,
|
||||
|
||||
// mbed original LED naming
|
||||
LED1 = LED_BLUE,
|
||||
LED2 = LED_GREEN,
|
||||
LED3 = LED_RED,
|
||||
LED4 = LED_RED,
|
||||
|
||||
// USB Pins
|
||||
USBTX = PTB2,
|
||||
USBRX = PTB1,
|
||||
|
||||
// Arduino Headers
|
||||
D0 = PTB2,
|
||||
D1 = PTB1,
|
||||
D2 = PTA11,
|
||||
D3 = PTB5,
|
||||
D4 = PTA10,
|
||||
D5 = PTA12,
|
||||
D6 = PTB6,
|
||||
D7 = PTB7,
|
||||
D8 = PTA10,
|
||||
D9 = PTB11,
|
||||
D10 = PTA5,
|
||||
D11 = PTA7,
|
||||
D12 = PTA6,
|
||||
D13 = PTB0,
|
||||
D14 = PTB4,
|
||||
D15 = PTB3,
|
||||
|
||||
A0 = PTB8,
|
||||
A1 = PTB9,
|
||||
A2 = PTA8,
|
||||
A3 = PTA0,
|
||||
A4 = PTA9,
|
||||
A5 = PTB13,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 2,
|
||||
PullUp = 3,
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
/* 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_PORTNAMES_H
|
||||
#define MBED_PORTNAMES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PortA = 0,
|
||||
PortB = 1
|
||||
} PortName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,87 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "analogin_api.h"
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
static const PinMap PinMap_ADC[] = {
|
||||
{PTE20, ADC0_SE0, 0},
|
||||
{PTE22, ADC0_SE3, 0},
|
||||
{PTE29, ADC0_SE4b, 0},
|
||||
{PTE30, ADC0_SE23, 0},
|
||||
{PTB0, ADC0_SE8, 0},
|
||||
{PTB1, ADC0_SE9, 0},
|
||||
{PTB2, ADC0_SE12, 0},
|
||||
{PTB3, ADC0_SE13, 0},
|
||||
{PTC0, ADC0_SE14, 0},
|
||||
{PTC1, ADC0_SE15, 0},
|
||||
{PTC2, ADC0_SE11, 0},
|
||||
{PTD1, ADC0_SE5b, 0},
|
||||
{PTD5, ADC0_SE6b, 0},
|
||||
{PTD6, ADC0_SE7b, 0},
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
void analogin_init(analogin_t *obj, PinName pin) {
|
||||
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
|
||||
if (obj->adc == (uint32_t)NC) {
|
||||
error("ADC pin mapping failed");
|
||||
}
|
||||
|
||||
SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
|
||||
|
||||
uint32_t port = (uint32_t)pin >> PORT_SHIFT;
|
||||
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
|
||||
|
||||
ADC0->SC1[1] = ADC_SC1_ADCH(obj->adc);
|
||||
|
||||
ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration
|
||||
| ADC_CFG1_ADIV(3) // Clock Divide Select: (Input Clock)/8
|
||||
| ADC_CFG1_ADLSMP_MASK // Long Sample Time
|
||||
| ADC_CFG1_MODE(3) // (16)bits Resolution
|
||||
| ADC_CFG1_ADICLK(1); // Input Clock: (Bus Clock)/2
|
||||
|
||||
ADC0->CFG2 = ADC_CFG2_MUXSEL_MASK // ADxxb channels are selected
|
||||
| ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable
|
||||
| ADC_CFG2_ADHSC_MASK // High-Speed Configuration
|
||||
| ADC_CFG2_ADLSTS(0); // Long Sample Time Select
|
||||
|
||||
ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference
|
||||
|
||||
ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable
|
||||
| ADC_SC3_AVGS(0); // 4 Samples Averaged
|
||||
|
||||
pinmap_pinout(pin, PinMap_ADC);
|
||||
}
|
||||
|
||||
uint16_t analogin_read_u16(analogin_t *obj) {
|
||||
// start conversion
|
||||
ADC0->SC1[0] = ADC_SC1_ADCH(obj->adc);
|
||||
|
||||
// Wait Conversion Complete
|
||||
while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
|
||||
|
||||
// Return value
|
||||
return (uint16_t)ADC0->R[0];
|
||||
}
|
||||
|
||||
float analogin_read(analogin_t *obj) {
|
||||
uint16_t value = analogin_read_u16(obj);
|
||||
return (float)value * (1.0f / (float)0xFFFF);
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "analogout_api.h"
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
#define RANGE_12BIT 0xFFF
|
||||
|
||||
static const PinMap PinMap_DAC[] = {
|
||||
{PTE30, DAC_0, 0},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
void analogout_init(dac_t *obj, PinName pin) {
|
||||
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
|
||||
if (obj->dac == (uint32_t)NC) {
|
||||
error("DAC pin mapping failed");
|
||||
}
|
||||
|
||||
SIM->SCGC6 |= SIM_SCGC6_DAC0_MASK;
|
||||
|
||||
uint32_t port = (uint32_t)pin >> PORT_SHIFT;
|
||||
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
|
||||
|
||||
DAC0->DAT[obj->dac].DATH = 0;
|
||||
DAC0->DAT[obj->dac].DATL = 0;
|
||||
|
||||
DAC0->C1 = DAC_C1_DACBFMD_MASK; // One-Time Scan Mode
|
||||
|
||||
DAC0->C0 = DAC_C0_DACEN_MASK // Enable
|
||||
| DAC_C0_DACSWTRG_MASK; // Software Trigger
|
||||
|
||||
pinmap_pinout(pin, PinMap_DAC);
|
||||
|
||||
analogout_write_u16(obj, 0);
|
||||
}
|
||||
|
||||
void analogout_free(dac_t *obj) {}
|
||||
|
||||
static inline void dac_write(dac_t *obj, int value) {
|
||||
DAC0->DAT[obj->dac].DATL = (uint8_t)( value & 0xFF);
|
||||
DAC0->DAT[obj->dac].DATH = (uint8_t)((value >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
static inline int dac_read(dac_t *obj) {
|
||||
return ((DAC0->DAT[obj->dac].DATH << 8) | DAC0->DAT[obj->dac].DATL);
|
||||
}
|
||||
|
||||
void analogout_write(dac_t *obj, float value) {
|
||||
if (value < 0.0) {
|
||||
dac_write(obj, 0);
|
||||
} else if (value > 1.0) {
|
||||
dac_write(obj, RANGE_12BIT);
|
||||
} else {
|
||||
dac_write(obj, value * (float)RANGE_12BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
|
||||
dac_write(obj, value >> 4); // 12-bit
|
||||
}
|
||||
|
||||
float analogout_read(dac_t *obj) {
|
||||
uint32_t value = dac_read(obj);
|
||||
return (float)value * (1.0f / (float)RANGE_12BIT);
|
||||
}
|
||||
|
||||
uint16_t analogout_read_u16(dac_t *obj) {
|
||||
uint32_t value = dac_read(obj); // 12-bit
|
||||
return (value << 4) | ((value >> 8) & 0x003F);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/* 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
|
||||
|
||||
#define DEVICE_PORTIN 1
|
||||
#define DEVICE_PORTOUT 1
|
||||
#define DEVICE_PORTINOUT 1
|
||||
|
||||
#define DEVICE_INTERRUPTIN 1
|
||||
|
||||
#define DEVICE_ANALOGIN 1
|
||||
#define DEVICE_ANALOGOUT 1
|
||||
|
||||
#define DEVICE_SERIAL 1
|
||||
|
||||
#define DEVICE_I2C 1
|
||||
#define DEVICE_I2CSLAVE 1
|
||||
|
||||
#define DEVICE_SPI 1
|
||||
#define DEVICE_SPISLAVE 1
|
||||
|
||||
#define DEVICE_CAN 0
|
||||
|
||||
#define DEVICE_RTC 1
|
||||
|
||||
#define DEVICE_ETHERNET 0
|
||||
|
||||
#define DEVICE_PWMOUT 1
|
||||
|
||||
#define DEVICE_SEMIHOST 1
|
||||
#define DEVICE_LOCALFILESYSTEM 0
|
||||
#define DEVICE_ID_LENGTH 24
|
||||
|
||||
#define DEVICE_SLEEP 0
|
||||
|
||||
#define DEVICE_DEBUG_AWARENESS 0
|
||||
|
||||
#define DEVICE_STDIO_MESSAGES 1
|
||||
|
||||
#define DEVICE_ERROR_RED 1
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "gpio_api.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
uint32_t gpio_set(PinName pin) {
|
||||
pin_function(pin, 1);
|
||||
return 1 << ((pin & 0x7F) >> 2);
|
||||
}
|
||||
|
||||
void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
|
||||
if(pin == NC) return;
|
||||
|
||||
obj->pin = pin;
|
||||
obj->mask = gpio_set(pin);
|
||||
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
|
||||
FGPIO_Type *reg = (FGPIO_Type *)(FPTA_BASE + port * 0x40);
|
||||
obj->reg_set = ®->PSOR;
|
||||
obj->reg_clr = ®->PCOR;
|
||||
obj->reg_in = ®->PDIR;
|
||||
obj->reg_dir = ®->PDDR;
|
||||
|
||||
gpio_dir(obj, direction);
|
||||
switch (direction) {
|
||||
case PIN_OUTPUT: pin_mode(pin, PullNone); break;
|
||||
case PIN_INPUT : pin_mode(pin, PullDown); break;
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_mode(gpio_t *obj, PinMode mode) {
|
||||
pin_mode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_dir(gpio_t *obj, PinDirection direction) {
|
||||
switch (direction) {
|
||||
case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break;
|
||||
case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "cmsis.h"
|
||||
|
||||
#include "gpio_irq_api.h"
|
||||
#include "error.h"
|
||||
|
||||
#define CHANNEL_NUM 64
|
||||
|
||||
static uint32_t channel_ids[CHANNEL_NUM] = {0};
|
||||
static gpio_irq_handler irq_handler;
|
||||
|
||||
#define IRQ_DISABLED (0)
|
||||
#define IRQ_RAISING_EDGE PORT_PCR_IRQC(9)
|
||||
#define IRQ_FALLING_EDGE PORT_PCR_IRQC(10)
|
||||
#define IRQ_EITHER_EDGE PORT_PCR_IRQC(11)
|
||||
|
||||
static void handle_interrupt_in(PORT_Type *port, int ch_base) {
|
||||
uint32_t mask = 0, i;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
uint32_t pmask = (1 << i);
|
||||
if (port->ISFR & pmask) {
|
||||
mask |= pmask;
|
||||
uint32_t id = channel_ids[ch_base + i];
|
||||
if (id == 0) continue;
|
||||
|
||||
FGPIO_Type *gpio;
|
||||
gpio_irq_event event = IRQ_NONE;
|
||||
switch (port->PCR[i] & PORT_PCR_IRQC_MASK) {
|
||||
case IRQ_RAISING_EDGE:
|
||||
event = IRQ_RISE;
|
||||
break;
|
||||
|
||||
case IRQ_FALLING_EDGE:
|
||||
event = IRQ_FALL;
|
||||
break;
|
||||
|
||||
case IRQ_EITHER_EDGE:
|
||||
/* TODO */
|
||||
/* gpio = (port == PORTA) ? (FPTA) : (FPTD);*/
|
||||
event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL);
|
||||
break;
|
||||
}
|
||||
if (event != IRQ_NONE)
|
||||
irq_handler(id, event);
|
||||
}
|
||||
}
|
||||
port->ISFR = mask;
|
||||
}
|
||||
|
||||
void gpio_irqA(void) {handle_interrupt_in(PORTA, 0);}
|
||||
/* TODO void gpio_irqD(void) {handle_interrupt_in(PORTD, 32);} */
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
|
||||
if (pin == NC) return -1;
|
||||
|
||||
irq_handler = handler;
|
||||
|
||||
obj->port = pin >> PORT_SHIFT;
|
||||
obj->pin = (pin & 0x7F) >> 2;
|
||||
|
||||
uint32_t ch_base, vector;
|
||||
IRQn_Type irq_n;
|
||||
switch (obj->port) {
|
||||
case PortA:
|
||||
ch_base = 0; irq_n = PORTA_IRQn; vector = (uint32_t)gpio_irqA;
|
||||
break;
|
||||
/*
|
||||
case PortD:
|
||||
ch_base = 32; irq_n = PORTD_IRQn; vector = (uint32_t)gpio_irqD;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
error("gpio_irq only supported on port A and D\n");
|
||||
break;
|
||||
}
|
||||
NVIC_SetVector(irq_n, vector);
|
||||
NVIC_EnableIRQ(irq_n);
|
||||
|
||||
obj->ch = ch_base + obj->pin;
|
||||
channel_ids[obj->ch] = id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
PORT_Type *port = (PORT_Type *)(PORTA_BASE + 0x1000 * obj->port);
|
||||
|
||||
uint32_t irq_settings = IRQ_DISABLED;
|
||||
|
||||
switch (port->PCR[obj->pin] & PORT_PCR_IRQC_MASK) {
|
||||
case IRQ_DISABLED:
|
||||
if (enable) {
|
||||
irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_FALLING_EDGE);
|
||||
}
|
||||
break;
|
||||
|
||||
case IRQ_RAISING_EDGE:
|
||||
if (enable) {
|
||||
irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_EITHER_EDGE);
|
||||
} else {
|
||||
if (event == IRQ_FALL)
|
||||
irq_settings = IRQ_RAISING_EDGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IRQ_FALLING_EDGE:
|
||||
if (enable) {
|
||||
irq_settings = (event == IRQ_FALL) ? (IRQ_FALLING_EDGE) : (IRQ_EITHER_EDGE);
|
||||
} else {
|
||||
if (event == IRQ_RISE)
|
||||
irq_settings = IRQ_FALLING_EDGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IRQ_EITHER_EDGE:
|
||||
if (enable) {
|
||||
irq_settings = IRQ_EITHER_EDGE;
|
||||
} else {
|
||||
irq_settings = (event == IRQ_RISE) ? (IRQ_FALLING_EDGE) : (IRQ_RAISING_EDGE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Interrupt configuration and clear interrupt
|
||||
port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* 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
|
||||
|
||||
#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_in;
|
||||
} gpio_t;
|
||||
|
||||
static inline void gpio_write(gpio_t *obj, int value) {
|
||||
if (value)
|
||||
*obj->reg_set = obj->mask;
|
||||
else
|
||||
*obj->reg_clr = obj->mask;
|
||||
}
|
||||
|
||||
static inline int gpio_read(gpio_t *obj) {
|
||||
return ((*obj->reg_in & obj->mask) ? 1 : 0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,406 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "i2c_api.h"
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
static const PinMap PinMap_I2C_SDA[] = {
|
||||
{PTE25, I2C_0, 5},
|
||||
{PTC9, I2C_0, 2},
|
||||
/* {PTE0, I2C_1, 6},*/
|
||||
{PTB1, I2C_0, 2},
|
||||
{PTB3, I2C_0, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_I2C_SCL[] = {
|
||||
{PTE24, I2C_0, 5},
|
||||
{PTC8, I2C_0, 2},
|
||||
/* {PTE1, I2C_1, 6},*/
|
||||
{PTB0, I2C_0, 2},
|
||||
{PTB2, I2C_0, 2},
|
||||
{NC , NC, 0}
|
||||
};
|
||||
|
||||
static const uint16_t ICR[0x40] = {
|
||||
20, 22, 24, 26, 28,
|
||||
30, 34, 40, 28, 32,
|
||||
36, 40, 44, 48, 56,
|
||||
68, 48, 56, 64, 72,
|
||||
80, 88, 104, 128, 80,
|
||||
96, 112, 128, 144, 160,
|
||||
192, 240, 160, 192, 224,
|
||||
256, 288, 320, 384, 480,
|
||||
320, 384, 448, 512, 576,
|
||||
640, 768, 960, 640, 768,
|
||||
896, 1024, 1152, 1280, 1536,
|
||||
1920, 1280, 1536, 1792, 2048,
|
||||
2304, 2560, 3072, 3840
|
||||
};
|
||||
|
||||
static uint8_t first_read;
|
||||
|
||||
|
||||
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
||||
// determine the I2C to use
|
||||
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
|
||||
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
|
||||
obj->i2c = (I2C_Type*)pinmap_merge(i2c_sda, i2c_scl);
|
||||
if ((int)obj->i2c == NC) {
|
||||
error("I2C pin mapping failed");
|
||||
}
|
||||
|
||||
// enable power
|
||||
switch ((int)obj->i2c) {
|
||||
case I2C_0: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 6; break;
|
||||
/*case I2C_1: SIM->SCGC5 |= 1 << 11; SIM->SCGC4 |= 1 << 7; break;*/
|
||||
}
|
||||
|
||||
// set default frequency at 100k
|
||||
i2c_frequency(obj, 100000);
|
||||
|
||||
// enable I2C interface
|
||||
obj->i2c->C1 |= 0x80;
|
||||
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
|
||||
first_read = 1;
|
||||
}
|
||||
|
||||
int i2c_start(i2c_t *obj) {
|
||||
// if we are in the middle of a transaction
|
||||
// activate the repeat_start flag
|
||||
if (obj->i2c->S & I2C_S_BUSY_MASK) {
|
||||
obj->i2c->C1 |= 0x04;
|
||||
} else {
|
||||
obj->i2c->C1 |= I2C_C1_MST_MASK;
|
||||
obj->i2c->C1 |= I2C_C1_TX_MASK;
|
||||
}
|
||||
first_read = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c_stop(i2c_t *obj) {
|
||||
volatile uint32_t n = 0;
|
||||
obj->i2c->C1 &= ~I2C_C1_MST_MASK;
|
||||
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
|
||||
|
||||
// It seems that there are timing problems
|
||||
// when there is no waiting time after a STOP.
|
||||
// This wait is also included on the samples
|
||||
// code provided with the freedom board
|
||||
for (n = 0; n < 100; n++) __NOP();
|
||||
first_read = 1;
|
||||
}
|
||||
|
||||
static int timeout_status_poll(i2c_t *obj, uint32_t mask) {
|
||||
uint32_t i, timeout = 1000;
|
||||
|
||||
for (i = 0; i < timeout; i++) {
|
||||
if (obj->i2c->S & mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// this function waits the end of a tx transfer and return the status of the transaction:
|
||||
// 0: OK ack received
|
||||
// 1: OK ack not received
|
||||
// 2: failure
|
||||
static int i2c_wait_end_tx_transfer(i2c_t *obj) {
|
||||
|
||||
// wait for the interrupt flag
|
||||
if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
obj->i2c->S |= I2C_S_IICIF_MASK;
|
||||
|
||||
// wait transfer complete
|
||||
if (timeout_status_poll(obj, I2C_S_TCF_MASK)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
// check if we received the ACK or not
|
||||
return obj->i2c->S & I2C_S_RXAK_MASK ? 1 : 0;
|
||||
}
|
||||
|
||||
// this function waits the end of a rx transfer and return the status of the transaction:
|
||||
// 0: OK
|
||||
// 1: failure
|
||||
static int i2c_wait_end_rx_transfer(i2c_t *obj) {
|
||||
// wait for the end of the rx transfer
|
||||
if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
obj->i2c->S |= I2C_S_IICIF_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_send_nack(i2c_t *obj) {
|
||||
obj->i2c->C1 |= I2C_C1_TXAK_MASK; // NACK
|
||||
}
|
||||
|
||||
static void i2c_send_ack(i2c_t *obj) {
|
||||
obj->i2c->C1 &= ~I2C_C1_TXAK_MASK; // ACK
|
||||
}
|
||||
|
||||
static int i2c_do_write(i2c_t *obj, int value) {
|
||||
// write the data
|
||||
obj->i2c->D = value;
|
||||
|
||||
// init and wait the end of the transfer
|
||||
return i2c_wait_end_tx_transfer(obj);
|
||||
}
|
||||
|
||||
static int i2c_do_read(i2c_t *obj, char * data, int last) {
|
||||
if (last)
|
||||
i2c_send_nack(obj);
|
||||
else
|
||||
i2c_send_ack(obj);
|
||||
|
||||
*data = (obj->i2c->D & 0xFF);
|
||||
|
||||
// start rx transfer and wait the end of the transfer
|
||||
return i2c_wait_end_rx_transfer(obj);
|
||||
}
|
||||
|
||||
void i2c_frequency(i2c_t *obj, int hz) {
|
||||
uint8_t icr = 0;
|
||||
uint8_t mult = 0;
|
||||
uint32_t error = 0;
|
||||
uint32_t p_error = 0xffffffff;
|
||||
uint32_t ref = 0;
|
||||
uint8_t i, j;
|
||||
// bus clk
|
||||
uint32_t PCLK = 24000000u;
|
||||
uint32_t pulse = PCLK / (hz * 2);
|
||||
|
||||
// we look for the values that minimize the error
|
||||
|
||||
// test all the MULT values
|
||||
for (i = 1; i < 5; i*=2) {
|
||||
for (j = 0; j < 0x40; j++) {
|
||||
ref = PCLK / (i*ICR[j]);
|
||||
error = (ref > hz) ? ref - hz : hz - ref;
|
||||
if (error < p_error) {
|
||||
icr = j;
|
||||
mult = i/2;
|
||||
p_error = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
pulse = icr | (mult << 6);
|
||||
|
||||
// I2C Rate
|
||||
obj->i2c->F = pulse;
|
||||
}
|
||||
|
||||
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
||||
uint8_t count;
|
||||
char dummy_read, *ptr;
|
||||
|
||||
if (i2c_start(obj)) {
|
||||
i2c_stop(obj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (i2c_do_write(obj, (address | 0x01))) {
|
||||
i2c_stop(obj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// set rx mode
|
||||
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
|
||||
|
||||
// Read in bytes
|
||||
for (count = 0; count < (length); count++) {
|
||||
ptr = (count == 0) ? &dummy_read : &data[count - 1];
|
||||
uint8_t stop_ = (count == (length - 1)) ? 1 : 0;
|
||||
if (i2c_do_read(obj, ptr, stop_)) {
|
||||
i2c_stop(obj);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
// last read
|
||||
data[count-1] = obj->i2c->D;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
|
||||
int i;
|
||||
|
||||
if (i2c_start(obj)) {
|
||||
i2c_stop(obj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (i2c_do_write(obj, (address & 0xFE))) {
|
||||
i2c_stop(obj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if(i2c_do_write(obj, data[i])) {
|
||||
i2c_stop(obj);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c_reset(i2c_t *obj) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
int i2c_byte_read(i2c_t *obj, int last) {
|
||||
char data;
|
||||
|
||||
// set rx mode
|
||||
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
|
||||
|
||||
if(first_read) {
|
||||
// first dummy read
|
||||
i2c_do_read(obj, &data, 0);
|
||||
first_read = 0;
|
||||
}
|
||||
|
||||
if (last) {
|
||||
// set tx mode
|
||||
obj->i2c->C1 |= I2C_C1_TX_MASK;
|
||||
return obj->i2c->D;
|
||||
}
|
||||
|
||||
i2c_do_read(obj, &data, last);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
int i2c_byte_write(i2c_t *obj, int data) {
|
||||
first_read = 1;
|
||||
|
||||
// set tx mode
|
||||
obj->i2c->C1 |= I2C_C1_TX_MASK;
|
||||
|
||||
return !i2c_do_write(obj, (data & 0xFF));
|
||||
}
|
||||
|
||||
|
||||
#if DEVICE_I2CSLAVE
|
||||
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
|
||||
if (enable_slave) {
|
||||
// set slave mode
|
||||
obj->i2c->C1 &= ~I2C_C1_MST_MASK;
|
||||
obj->i2c->C1 |= I2C_C1_IICIE_MASK;
|
||||
} else {
|
||||
// set master mode
|
||||
obj->i2c->C1 |= I2C_C1_MST_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
int i2c_slave_receive(i2c_t *obj) {
|
||||
switch(obj->i2c->S) {
|
||||
// read addressed
|
||||
case 0xE6: return 1;
|
||||
|
||||
// write addressed
|
||||
case 0xE2: return 3;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int i2c_slave_read(i2c_t *obj, char *data, int length) {
|
||||
uint8_t dummy_read, count;
|
||||
uint8_t * ptr;
|
||||
|
||||
// set rx mode
|
||||
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
|
||||
|
||||
// first dummy read
|
||||
dummy_read = obj->i2c->D;
|
||||
if(i2c_wait_end_rx_transfer(obj)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read address
|
||||
dummy_read = obj->i2c->D;
|
||||
if(i2c_wait_end_rx_transfer(obj)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read (length - 1) bytes
|
||||
for (count = 0; count < (length - 1); count++) {
|
||||
data[count] = obj->i2c->D;
|
||||
if(i2c_wait_end_rx_transfer(obj)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// read last byte
|
||||
ptr = (length == 0) ? &dummy_read : (uint8_t *)&data[count];
|
||||
*ptr = obj->i2c->D;
|
||||
|
||||
return (length) ? (count + 1) : 0;
|
||||
}
|
||||
|
||||
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
|
||||
uint32_t i, count = 0;
|
||||
|
||||
// set tx mode
|
||||
obj->i2c->C1 |= I2C_C1_TX_MASK;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if(i2c_do_write(obj, data[count++]) == 2) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// set rx mode
|
||||
obj->i2c->C1 &= ~I2C_C1_TX_MASK;
|
||||
|
||||
// dummy rx transfer needed
|
||||
// otherwise the master cannot generate a stop bit
|
||||
obj->i2c->D;
|
||||
if(i2c_wait_end_rx_transfer(obj) == 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
|
||||
obj->i2c->A1 = address & 0xfe;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* 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_OBJECTS_H
|
||||
#define MBED_OBJECTS_H
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "PortNames.h"
|
||||
#include "PeripheralNames.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct gpio_irq_s {
|
||||
uint32_t port;
|
||||
uint32_t pin;
|
||||
uint32_t ch;
|
||||
};
|
||||
|
||||
struct port_s {
|
||||
__IO uint32_t *reg_dir;
|
||||
__IO uint32_t *reg_out;
|
||||
__I uint32_t *reg_in;
|
||||
PortName port;
|
||||
uint32_t mask;
|
||||
};
|
||||
|
||||
struct pwmout_s {
|
||||
__IO uint32_t *MOD;
|
||||
__IO uint32_t *CNT;
|
||||
__IO uint32_t *CnV;
|
||||
};
|
||||
|
||||
struct serial_s {
|
||||
UARTLP_Type *uart;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct analogin_s {
|
||||
ADCName adc;
|
||||
};
|
||||
|
||||
struct dac_s {
|
||||
DACName dac;
|
||||
};
|
||||
|
||||
struct i2c_s {
|
||||
I2C_Type *i2c;
|
||||
};
|
||||
|
||||
struct spi_s {
|
||||
SPI_Type *spi;
|
||||
};
|
||||
|
||||
#include "gpio_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
void pin_function(PinName pin, int function) {
|
||||
if (pin == (uint32_t)NC) return;
|
||||
|
||||
uint32_t port_n = (uint32_t)pin >> PORT_SHIFT;
|
||||
uint32_t pin_n = (uint32_t)(pin & 0x7C) >> 2;
|
||||
|
||||
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port_n);
|
||||
__IO uint32_t* pin_pcr = &(((PORT_Type *)(PORTA_BASE + 0x1000 * port_n)))->PCR[pin_n];
|
||||
|
||||
// pin mux bits: [10:8] -> 11100000000 = (0x700)
|
||||
*pin_pcr = (*pin_pcr & ~0x700) | (function << 8);
|
||||
}
|
||||
|
||||
void pin_mode(PinName pin, PinMode mode) {
|
||||
if (pin == (uint32_t)NC) { return; }
|
||||
|
||||
__IO uint32_t* pin_pcr = (__IO uint32_t*)(PORTA_BASE + pin);
|
||||
|
||||
// pin pullup bits: [1:0] -> 11 = (0x3)
|
||||
*pin_pcr = (*pin_pcr & ~0x3) | mode;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "port_api.h"
|
||||
#include "pinmap.h"
|
||||
#include "gpio_api.h"
|
||||
|
||||
PinName port_pin(PortName port, int pin_n) {
|
||||
return (PinName)((port << PORT_SHIFT) | (pin_n << 2));
|
||||
}
|
||||
|
||||
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
|
||||
obj->port = port;
|
||||
obj->mask = mask;
|
||||
|
||||
FGPIO_Type *reg = (FGPIO_Type *)(FPTA_BASE + port * 0x40);
|
||||
|
||||
obj->reg_out = ®->PDOR;
|
||||
obj->reg_in = ®->PDIR;
|
||||
obj->reg_dir = ®->PDDR;
|
||||
|
||||
uint32_t i;
|
||||
// The function is set per pin: reuse gpio logic
|
||||
for (i=0; i<32; i++) {
|
||||
if (obj->mask & (1<<i)) {
|
||||
gpio_set(port_pin(obj->port, i));
|
||||
}
|
||||
}
|
||||
|
||||
port_dir(obj, dir);
|
||||
}
|
||||
|
||||
void port_mode(port_t *obj, PinMode mode) {
|
||||
uint32_t i;
|
||||
// The mode is set per pin: reuse pinmap logic
|
||||
for (i=0; i<32; i++) {
|
||||
if (obj->mask & (1<<i)) {
|
||||
pin_mode(port_pin(obj->port, i), mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void port_write(port_t *obj, int value) {
|
||||
*obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask);
|
||||
}
|
||||
|
||||
int port_read(port_t *obj) {
|
||||
return (*obj->reg_in & obj->mask);
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "pwmout_api.h"
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
static const PinMap PinMap_PWM[] = {
|
||||
// LEDs
|
||||
{LED_RED , PWM_9 , 3}, // PTB18, TPM2 CH0
|
||||
{LED_GREEN, PWM_10, 3}, // PTB19, TPM2 CH1
|
||||
{LED_BLUE , PWM_2 , 4}, // PTD1 , TPM0 CH1
|
||||
|
||||
// Arduino digital pinout
|
||||
{D0, PWM_9 , 3}, // PTA1 , TPM2 CH0
|
||||
{D1, PWM_10, 3}, // PTA2 , TPM2 CH1
|
||||
{D2, PWM_5 , 4}, // PTD4 , TPM0 CH4
|
||||
{D3, PWM_7 , 3}, // PTA12, TPM1 CH0
|
||||
{D4, PWM_2 , 3}, // PTA4 , TPM0 CH1
|
||||
{D5, PWM_3 , 3}, // PTA5 , TPM0 CH2
|
||||
{D6, PWM_5 , 3}, // PTC8 , TPM0 CH4
|
||||
{D7, PWM_6 , 3}, // PTC9 , TPM0 CH5
|
||||
{D8, PWM_8 , 3}, // PTA13, TPM1 CH1
|
||||
{D9, PWM_6 , 4}, // PTD5 , TPM0 CH5
|
||||
{D10, PWM_1 , 4}, // PTD0 , TPM0 CH0
|
||||
{D11, PWM_3 , 4}, // PTD2 , TPM0 CH2
|
||||
{D12, PWM_4 , 4}, // PTD3 , TPM0 CH3
|
||||
{D13, PWM_2 , 4}, // PTD1 , TPM0 CH1
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
#define PWM_CLOCK_MHZ (0.75) // (48)MHz / 64 = (0.75)MHz
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
// determine the channel
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
if (pwm == (uint32_t)NC)
|
||||
error("PwmOut pin mapping failed");
|
||||
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
unsigned int tpm_n = (pwm >> TPM_SHIFT);
|
||||
unsigned int ch_n = (pwm & 0xFF);
|
||||
|
||||
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
|
||||
SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n);
|
||||
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
|
||||
|
||||
TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
|
||||
tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(6); // (48)MHz / 64 = (0.75)MHz
|
||||
tpm->CONTROLS[ch_n].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); /* No Interrupts; High True pulses on Edge Aligned PWM */
|
||||
|
||||
obj->CnV = &tpm->CONTROLS[ch_n].CnV;
|
||||
obj->MOD = &tpm->MOD;
|
||||
obj->CNT = &tpm->CNT;
|
||||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write (obj, 0);
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
if (value < 0.0) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0) {
|
||||
value = 1.0;
|
||||
}
|
||||
|
||||
*obj->CnV = (uint32_t)((float)(*obj->MOD) * value);
|
||||
*obj->CNT = 0;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
float v = (float)(*obj->CnV) / (float)(*obj->MOD);
|
||||
return (v > 1.0) ? (1.0) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
float dc = pwmout_read(obj);
|
||||
*obj->MOD = PWM_CLOCK_MHZ * us;
|
||||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
*obj->CnV = PWM_CLOCK_MHZ * us;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "rtc_api.h"
|
||||
|
||||
#if DEVICE_RTC
|
||||
|
||||
static void init(void) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void rtc_init(void) {
|
||||
init();
|
||||
|
||||
//Configure the TSR. default value: 1
|
||||
RTC->TSR = 1;
|
||||
|
||||
// enable counter
|
||||
RTC->SR |= RTC_SR_TCE_MASK;
|
||||
}
|
||||
|
||||
void rtc_free(void) {
|
||||
// [TODO]
|
||||
}
|
||||
|
||||
/*
|
||||
* Little check routine to see if the RTC has been enabled
|
||||
* 0 = Disabled, 1 = Enabled
|
||||
*/
|
||||
int rtc_isenabled(void) {
|
||||
// even if the RTC module is enabled,
|
||||
// as we use RTC_CLKIN and an external clock,
|
||||
// we need to reconfigure the pins. That is why we
|
||||
// call init() if the rtc is enabled
|
||||
|
||||
// if RTC not enabled return 0
|
||||
/* SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;*/
|
||||
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
|
||||
if ((RTC->SR & RTC_SR_TCE_MASK) == 0)
|
||||
return 0;
|
||||
|
||||
init();
|
||||
return 1;
|
||||
}
|
||||
|
||||
time_t rtc_read(void) {
|
||||
return RTC->TSR;
|
||||
}
|
||||
|
||||
void rtc_write(time_t t) {
|
||||
// disable counter
|
||||
RTC->SR &= ~RTC_SR_TCE_MASK;
|
||||
|
||||
// we do not write 0 into TSR
|
||||
// to avoid invalid time
|
||||
if (t == 0)
|
||||
t = 1;
|
||||
|
||||
// write seconds
|
||||
RTC->TSR = t;
|
||||
|
||||
// re-enable counter
|
||||
RTC->SR |= RTC_SR_TCE_MASK;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,118 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "serial_api.h"
|
||||
|
||||
// math.h required for floating point operations for baud rate calculation
|
||||
#include <math.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
/******************************************************************************
|
||||
* INITIALIZATION
|
||||
******************************************************************************/
|
||||
static const PinMap PinMap_UART_TX[] = {
|
||||
|
||||
};
|
||||
|
||||
static const PinMap PinMap_UART_RX[] = {
|
||||
|
||||
};
|
||||
|
||||
#define UART_NUM 3
|
||||
static uint32_t serial_irq_ids[UART_NUM] = {0};
|
||||
static uart_irq_handler irq_handler;
|
||||
|
||||
int stdio_uart_inited = 0;
|
||||
serial_t stdio_uart;
|
||||
|
||||
void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
||||
|
||||
}
|
||||
|
||||
void serial_free(serial_t *obj) {
|
||||
|
||||
}
|
||||
|
||||
// serial_baud
|
||||
//
|
||||
// set the baud rate, taking in to account the current SystemFrequency
|
||||
//
|
||||
// The LPC2300 and LPC1700 have a divider and a fractional divider to control the
|
||||
// baud rate. The formula is:
|
||||
//
|
||||
// Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal)
|
||||
// where:
|
||||
// 1 < MulVal <= 15
|
||||
// 0 <= DivAddVal < 14
|
||||
// DivAddVal < MulVal
|
||||
//
|
||||
void serial_baud(serial_t *obj, int baudrate) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* INTERRUPTS HANDLING
|
||||
******************************************************************************/
|
||||
static inline void uart_irq(uint8_t status, uint32_t index) {
|
||||
|
||||
}
|
||||
|
||||
void uart0_irq() {
|
||||
|
||||
}
|
||||
|
||||
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
|
||||
|
||||
}
|
||||
|
||||
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* READ/WRITE
|
||||
******************************************************************************/
|
||||
int serial_getc(serial_t *obj) {
|
||||
|
||||
}
|
||||
|
||||
void serial_putc(serial_t *obj, int c) {
|
||||
|
||||
}
|
||||
|
||||
int serial_readable(serial_t *obj) {
|
||||
|
||||
}
|
||||
|
||||
int serial_writable(serial_t *obj) {
|
||||
|
||||
}
|
||||
|
||||
void serial_clear(serial_t *obj) {
|
||||
}
|
||||
|
||||
void serial_pinout_tx(PinName tx) {
|
||||
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include "spi_api.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
static const PinMap PinMap_SPI_SCLK[] = {
|
||||
{PTC5, SPI_0, 2},
|
||||
{PTD1, SPI_0, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MOSI[] = {
|
||||
{PTC6, SPI_0, 2},
|
||||
{PTD2, SPI_0, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MISO[] = {
|
||||
{PTC7, SPI_0, 2},
|
||||
{PTD3, SPI_0, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_SSEL[] = {
|
||||
{PTC4, SPI_0, 2},
|
||||
{PTD0, SPI_0, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
|
||||
// determine the SPI to use
|
||||
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
|
||||
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
|
||||
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
|
||||
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
|
||||
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
|
||||
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
|
||||
|
||||
obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl);
|
||||
if ((int)obj->spi == NC) {
|
||||
error("SPI pinout mapping failed");
|
||||
}
|
||||
|
||||
// enable power and clocking
|
||||
switch ((int)obj->spi) {
|
||||
case SPI_0: SIM->SCGC5 |= 1 << 11; SIM->SCGC4 |= 1 << 22; break;
|
||||
}
|
||||
|
||||
// set default format and frequency
|
||||
if (ssel == NC) {
|
||||
spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
|
||||
} else {
|
||||
spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
|
||||
}
|
||||
spi_frequency(obj, 1000000);
|
||||
|
||||
// enable SPI
|
||||
obj->spi->C1 |= SPI_C1_SPE_MASK;
|
||||
|
||||
// pin out the spi pins
|
||||
pinmap_pinout(mosi, PinMap_SPI_MOSI);
|
||||
pinmap_pinout(miso, PinMap_SPI_MISO);
|
||||
pinmap_pinout(sclk, PinMap_SPI_SCLK);
|
||||
if (ssel != NC) {
|
||||
pinmap_pinout(ssel, PinMap_SPI_SSEL);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_free(spi_t *obj) {
|
||||
// [TODO]
|
||||
}
|
||||
void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
||||
if (bits != 8) {
|
||||
error("Only 8bits SPI supported");
|
||||
}
|
||||
|
||||
if ((mode < 0) || (mode > 3)) {
|
||||
error("SPI mode unsupported");
|
||||
}
|
||||
|
||||
uint8_t polarity = (mode & 0x2) ? 1 : 0;
|
||||
uint8_t phase = (mode & 0x1) ? 1 : 0;
|
||||
uint8_t c1_data = ((!slave) << 4) | (polarity << 3) | (phase << 2);
|
||||
|
||||
// clear MSTR, CPOL and CPHA bits
|
||||
obj->spi->C1 &= ~(0x7 << 2);
|
||||
|
||||
// write new value
|
||||
obj->spi->C1 |= c1_data;
|
||||
}
|
||||
|
||||
void spi_frequency(spi_t *obj, int hz) {
|
||||
uint32_t error = 0;
|
||||
uint32_t p_error = 0xffffffff;
|
||||
uint32_t ref = 0;
|
||||
uint8_t spr = 0;
|
||||
uint8_t ref_spr = 0;
|
||||
uint8_t ref_prescaler = 0;
|
||||
|
||||
// bus clk
|
||||
uint32_t PCLK = 48000000u;
|
||||
uint8_t prescaler = 1;
|
||||
uint8_t divisor = 2;
|
||||
|
||||
for (prescaler = 1; prescaler <= 8; prescaler++) {
|
||||
divisor = 2;
|
||||
for (spr = 0; spr <= 8; spr++) {
|
||||
ref = PCLK / (prescaler*divisor);
|
||||
error = (ref > hz) ? ref - hz : hz - ref;
|
||||
if (error < p_error) {
|
||||
ref_spr = spr;
|
||||
ref_prescaler = prescaler - 1;
|
||||
p_error = error;
|
||||
}
|
||||
divisor *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
// set SPPR and SPR
|
||||
obj->spi->BR = ((ref_prescaler & 0x7) << 4) | (ref_spr & 0xf);
|
||||
}
|
||||
|
||||
static inline int spi_writeable(spi_t * obj) {
|
||||
return (obj->spi->S & SPI_S_SPTEF_MASK) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline int spi_readable(spi_t * obj) {
|
||||
return (obj->spi->S & SPI_S_SPRF_MASK) ? 1 : 0;
|
||||
}
|
||||
|
||||
int spi_master_write(spi_t *obj, int value) {
|
||||
// wait tx buffer empty
|
||||
while(!spi_writeable(obj));
|
||||
obj->spi->D = (value & 0xff);
|
||||
|
||||
// wait rx buffer full
|
||||
while (!spi_readable(obj));
|
||||
return obj->spi->D & 0xff;
|
||||
}
|
||||
|
||||
int spi_slave_receive(spi_t *obj) {
|
||||
return spi_readable(obj);
|
||||
}
|
||||
|
||||
int spi_slave_read(spi_t *obj) {
|
||||
return obj->spi->D;
|
||||
}
|
||||
|
||||
void spi_slave_write(spi_t *obj, int value) {
|
||||
while (!spi_writeable(obj));
|
||||
obj->spi->D = value;
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/* 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.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "us_ticker_api.h"
|
||||
#include "PeripheralNames.h"
|
||||
|
||||
static void pit_init(void);
|
||||
static void lptmr_init(void);
|
||||
|
||||
static int us_ticker_inited = 0;
|
||||
|
||||
void us_ticker_init(void) {
|
||||
if (us_ticker_inited) return;
|
||||
us_ticker_inited = 1;
|
||||
|
||||
pit_init();
|
||||
lptmr_init();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Timer for us timing.
|
||||
******************************************************************************/
|
||||
static void pit_init(void) {
|
||||
SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT
|
||||
PIT->MCR = 0; // Enable PIT
|
||||
|
||||
// Channel 1
|
||||
PIT->CHANNEL[1].LDVAL = 0xFFFFFFFF;
|
||||
PIT->CHANNEL[1].TCTRL = PIT_TCTRL_CHN_MASK; // Chain to timer 0, disable Interrupts
|
||||
PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 1
|
||||
|
||||
// Use channel 0 as a prescaler for channel 1
|
||||
PIT->CHANNEL[0].LDVAL = 23;
|
||||
PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // Start timer 0, disable interrupts
|
||||
}
|
||||
|
||||
uint32_t us_ticker_read() {
|
||||
if (!us_ticker_inited)
|
||||
us_ticker_init();
|
||||
|
||||
// The PIT is a countdown timer
|
||||
return ~(PIT->CHANNEL[1].CVAL);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Timer Event
|
||||
*
|
||||
* It schedules interrupts at given (32bit)us interval of time.
|
||||
* It is implemented used the 16bit Low Power Timer that remains powered in all
|
||||
* power modes.
|
||||
******************************************************************************/
|
||||
static void lptmr_isr(void);
|
||||
|
||||
static void lptmr_init(void) {
|
||||
/* Clock the timer */
|
||||
SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK;
|
||||
|
||||
/* Reset */
|
||||
LPTMR0->CSR = 0;
|
||||
|
||||
/* Set interrupt handler */
|
||||
NVIC_SetVector(LPTimer_IRQn, (uint32_t)lptmr_isr);
|
||||
NVIC_EnableIRQ(LPTimer_IRQn);
|
||||
|
||||
/* Clock at (1)MHz -> (1)tick/us */
|
||||
LPTMR0->PSR = LPTMR_PSR_PCS(3); // OSCERCLK -> 8MHz
|
||||
LPTMR0->PSR |= LPTMR_PSR_PRESCALE(2); // divide by 8
|
||||
}
|
||||
|
||||
void us_ticker_disable_interrupt(void) {
|
||||
LPTMR0->CSR &= ~LPTMR_CSR_TIE_MASK;
|
||||
}
|
||||
|
||||
void us_ticker_clear_interrupt(void) {
|
||||
// we already clear interrupt in lptmr_isr
|
||||
}
|
||||
|
||||
static uint32_t us_ticker_int_counter = 0;
|
||||
static uint16_t us_ticker_int_remainder = 0;
|
||||
|
||||
static void lptmr_set(unsigned short count) {
|
||||
/* Reset */
|
||||
LPTMR0->CSR = 0;
|
||||
|
||||
/* Set the compare register */
|
||||
LPTMR0->CMR = count;
|
||||
|
||||
/* Enable interrupt */
|
||||
LPTMR0->CSR |= LPTMR_CSR_TIE_MASK;
|
||||
|
||||
/* Start the timer */
|
||||
LPTMR0->CSR |= LPTMR_CSR_TEN_MASK;
|
||||
}
|
||||
|
||||
static void lptmr_isr(void) {
|
||||
// write 1 to TCF to clear the LPT timer compare flag
|
||||
LPTMR0->CSR |= LPTMR_CSR_TCF_MASK;
|
||||
|
||||
if (us_ticker_int_counter > 0) {
|
||||
lptmr_set(0xFFFF);
|
||||
us_ticker_int_counter--;
|
||||
|
||||
} else {
|
||||
if (us_ticker_int_remainder > 0) {
|
||||
lptmr_set(us_ticker_int_remainder);
|
||||
us_ticker_int_remainder = 0;
|
||||
} else {
|
||||
// This function is going to disable the interrupts if there are
|
||||
// no other events in the queue
|
||||
us_ticker_irq_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void us_ticker_set_interrupt(unsigned int timestamp) {
|
||||
int delta = (int)(timestamp - us_ticker_read());
|
||||
if (delta <= 0) {
|
||||
// This event was in the past:
|
||||
us_ticker_irq_handler();
|
||||
return;
|
||||
}
|
||||
|
||||
us_ticker_int_counter = (uint32_t)(delta >> 16);
|
||||
us_ticker_int_remainder = (uint16_t)(0xFFFF & delta);
|
||||
if (us_ticker_int_counter > 0) {
|
||||
lptmr_set(0xFFFF);
|
||||
us_ticker_int_counter--;
|
||||
} else {
|
||||
lptmr_set(us_ticker_int_remainder);
|
||||
us_ticker_int_remainder = 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue