- Added support for the GCC compiler on target ARMCM3_EFM32, including demos.
git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@36 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
parent
4eda0f2e1f
commit
9ddc8b2dba
|
@ -1,6 +1,6 @@
|
|||
[sci]
|
||||
port=3
|
||||
baudrate=3
|
||||
baudrate=8
|
||||
[xcp]
|
||||
seedkey=
|
||||
t1=1000
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,229 @@
|
|||
|
||||
bin/openbtl_olimex_efm32g880.elf: file format elf32-littlearm
|
||||
bin/openbtl_olimex_efm32g880.elf
|
||||
architecture: arm, flags 0x00000112:
|
||||
EXEC_P, HAS_SYMS, D_PAGED
|
||||
start address 0x00000000
|
||||
|
||||
Program Header:
|
||||
LOAD off 0x00008000 vaddr 0x00000000 paddr 0x00000000 align 2**15
|
||||
filesz 0x000015d3 memsz 0x000015d3 flags r-x
|
||||
LOAD off 0x00010000 vaddr 0x20000000 paddr 0x000015d3 align 2**15
|
||||
filesz 0x00000138 memsz 0x00000728 flags rwx
|
||||
private flags = 5000000: [Version5 EABI]
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
0 .text 000015d3 00000000 00000000 00008000 2**3
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
1 .data 00000138 20000000 000015d3 00010000 2**2
|
||||
CONTENTS, ALLOC, LOAD, CODE
|
||||
2 .bss 000005f0 20000138 0000170b 00010138 2**2
|
||||
ALLOC
|
||||
3 .debug_abbrev 00003f13 00000000 00000000 00010138 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
4 .debug_info 0000d7e9 00000000 00000000 0001404b 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
5 .debug_line 00005915 00000000 00000000 00021834 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
6 .debug_pubtypes 00001800 00000000 00000000 00027149 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
7 .debug_str 000055da 00000000 00000000 00028949 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
8 .comment 0000002a 00000000 00000000 0002df23 2**0
|
||||
CONTENTS, READONLY
|
||||
9 .ARM.attributes 00000031 00000000 00000000 0002df4d 2**0
|
||||
CONTENTS, READONLY
|
||||
10 .debug_loc 00006519 00000000 00000000 0002df7e 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
11 .debug_pubnames 00001513 00000000 00000000 00034497 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
12 .debug_aranges 00000c70 00000000 00000000 000359aa 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
13 .debug_ranges 00000af8 00000000 00000000 0003661a 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
14 .debug_frame 00001bdc 00000000 00000000 00037114 2**2
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
SYMBOL TABLE:
|
||||
00000000 l d .text 00000000 .text
|
||||
20000000 l d .data 00000000 .data
|
||||
20000138 l d .bss 00000000 .bss
|
||||
00000000 l d .debug_abbrev 00000000 .debug_abbrev
|
||||
00000000 l d .debug_info 00000000 .debug_info
|
||||
00000000 l d .debug_line 00000000 .debug_line
|
||||
00000000 l d .debug_pubtypes 00000000 .debug_pubtypes
|
||||
00000000 l d .debug_str 00000000 .debug_str
|
||||
00000000 l d .comment 00000000 .comment
|
||||
00000000 l d .ARM.attributes 00000000 .ARM.attributes
|
||||
00000000 l d .debug_loc 00000000 .debug_loc
|
||||
00000000 l d .debug_pubnames 00000000 .debug_pubnames
|
||||
00000000 l d .debug_aranges 00000000 .debug_aranges
|
||||
00000000 l d .debug_ranges 00000000 .debug_ranges
|
||||
00000000 l d .debug_frame 00000000 .debug_frame
|
||||
00000000 l df *ABS* 00000000 vectors.c
|
||||
00000000 l df *ABS* 00000000 cstart.c
|
||||
000000e2 l F .text 00000000 zero_loop2
|
||||
0000146e l F .text 00000000 zero_loop
|
||||
00000000 l df *ABS* 00000000 main.c
|
||||
00000000 l df *ABS* 00000000 system_efm32.c
|
||||
20000000 l O .data 00000004 SystemLFXOClock
|
||||
20000004 l O .data 00000004 SystemHFXOClock
|
||||
00000000 l df *ABS* 00000000 efm32_cmu.c
|
||||
000003c0 l F .text 0000000e BITBAND_Peripheral
|
||||
000003d0 l F .text 00000030 CMU_FlashWaitStateMax
|
||||
00000400 l F .text 0000000c CMU_DivToLog2
|
||||
0000040c l F .text 00000054 CMU_FlashWaitStateControl
|
||||
00000460 l F .text 00000018 CMU_Sync
|
||||
00000478 l F .text 0000003c CMU_LFClkGet
|
||||
000014b0 l O .text 00000003 CSWTCH.5
|
||||
000014b3 l O .text 00000003 CSWTCH.8
|
||||
00000000 l df *ABS* 00000000 efm32_emu.c
|
||||
20000138 l O .bss 00000002 cmuStatus
|
||||
00000000 l df *ABS* 00000000 efm32_gpio.c
|
||||
00000000 l df *ABS* 00000000 efm32_leuart.c
|
||||
000009bc l F .text 00000010 LEUART_Sync
|
||||
00000000 l df *ABS* 00000000 efm32_msc.c
|
||||
00000000 l df *ABS* 00000000 efm32_system.c
|
||||
00000000 l df *ABS* 00000000 boot.c
|
||||
00000000 l df *ABS* 00000000 com.c
|
||||
2000013a l O .bss 00000001 comEntryStateConnect
|
||||
2000013b l O .bss 00000040 xcpCtoReqPacket.1375
|
||||
00000000 l df *ABS* 00000000 xcp.c
|
||||
00000ba4 l F .text 0000000c XcpProtectResources
|
||||
00000bb0 l F .text 00000014 XcpSetCtoError
|
||||
000014b6 l O .text 00000008 xcpStationId
|
||||
2000017c l O .bss 0000004c xcpInfo
|
||||
00000000 l df *ABS* 00000000 backdoor.c
|
||||
200001c8 l O .bss 00000001 backdoorOpen
|
||||
00000000 l df *ABS* 00000000 cop.c
|
||||
00000000 l df *ABS* 00000000 assert.c
|
||||
200001cc l O .bss 00000004 assert_failure_file
|
||||
200001d0 l O .bss 00000004 assert_failure_line
|
||||
00000000 l df *ABS* 00000000 cpu.c
|
||||
00000000 l df *ABS* 00000000 uart.c
|
||||
00000e94 l F .text 00000020 UartReceiveByte
|
||||
00000eb4 l F .text 00000030 UartTransmitByte
|
||||
200001d4 l O .bss 00000041 xcpCtoReqPacket.2673
|
||||
20000215 l O .bss 00000001 xcpCtoRxLength.2674
|
||||
20000216 l O .bss 00000001 xcpCtoRxInProgress.2675
|
||||
000014e4 l O .text 00000010 C.4.3618
|
||||
00000000 l df *ABS* 00000000 nvm.c
|
||||
00000000 l df *ABS* 00000000 timer.c
|
||||
20000218 l O .bss 00000002 millisecond_counter
|
||||
00000000 l df *ABS* 00000000 flash.c
|
||||
000010b8 l F .text 00000038 FlashGetSector
|
||||
000010f0 l F .text 00000030 FlashGetSectorBaseAddr
|
||||
00001120 l F .text 0000004e FlashWriteBlock
|
||||
0000116e l F .text 00000026 FlashInitBlock
|
||||
00001194 l F .text 00000040 FlashSwitchBlock
|
||||
000011d4 l F .text 00000080 FlashAddToBlock
|
||||
000014f4 l O .text 000000b4 flashLayout
|
||||
2000021c l O .bss 00000204 bootBlockInfo
|
||||
20000420 l O .bss 00000204 blockInfo
|
||||
00000000 l df *ABS* 00000000 hooks.c
|
||||
00000000 l df *ABS* 00000000 core_cm3.c
|
||||
00000000 l df *ABS* 00000000 efm32_acmp.c
|
||||
00000000 l df *ABS* 00000000 efm32_adc.c
|
||||
00000000 l df *ABS* 00000000 efm32_aes.c
|
||||
00000000 l df *ABS* 00000000 efm32_assert.c
|
||||
00000000 l df *ABS* 00000000 efm32_dac.c
|
||||
00000000 l df *ABS* 00000000 efm32_dbg.c
|
||||
00000000 l df *ABS* 00000000 efm32_dma.c
|
||||
00000000 l df *ABS* 00000000 efm32_ebi.c
|
||||
00000000 l df *ABS* 00000000 efm32_i2c.c
|
||||
00000000 l df *ABS* 00000000 efm32_int.c
|
||||
00000000 l df *ABS* 00000000 efm32_lcd.c
|
||||
00000000 l df *ABS* 00000000 efm32_lesense.c
|
||||
00000000 l df *ABS* 00000000 efm32_letimer.c
|
||||
00000000 l df *ABS* 00000000 efm32_mpu.c
|
||||
00000000 l df *ABS* 00000000 efm32_opamp.c
|
||||
00000000 l df *ABS* 00000000 efm32_pcnt.c
|
||||
00000000 l df *ABS* 00000000 efm32_prs.c
|
||||
00000000 l df *ABS* 00000000 efm32_rmu.c
|
||||
00000000 l df *ABS* 00000000 efm32_rtc.c
|
||||
00000000 l df *ABS* 00000000 efm32_timer.c
|
||||
00000000 l df *ABS* 00000000 efm32_usart.c
|
||||
00000000 l df *ABS* 00000000 efm32_vcmp.c
|
||||
00000000 l df *ABS* 00000000 efm32_wdog.c
|
||||
00001490 l F .text 00000010 __MSC_ErasePage_veneer
|
||||
000014a0 l F .text 00000010 __MSC_WriteWord_veneer
|
||||
00000b38 g F .text 0000002c ComInit
|
||||
00001270 g F .text 00000048 FlashWrite
|
||||
00000900 g F .text 00000018 GPIO_DriveModeSet
|
||||
00000e34 g F .text 00000018 AssertFailure
|
||||
000008ec g F .text 00000014 EMU_UpdateOscConfig
|
||||
00001450 g F .text 00000038 reset_handler
|
||||
000006b8 g F .text 00000128 CMU_ClockFreqGet
|
||||
0000105c g F .text 0000001c TimerUpdate
|
||||
00000bf0 g F .text 00000010 XcpPacketTransmitted
|
||||
00000a14 g F .text 00000018 LEUART_Enable
|
||||
00000a2c g F .text 00000012 LEUART_FreezeEnable
|
||||
00000b64 g F .text 0000001c ComTask
|
||||
00000b94 g F .text 0000000c ComSetConnectEntryState
|
||||
00000b10 g F .text 00000016 BootInit
|
||||
00000e18 g F .text 00000018 BackDoorInit
|
||||
000007e0 g F .text 00000054 CMU_OscillatorEnable
|
||||
00000e32 g F .text 00000002 CopService
|
||||
000015d3 g .text 00000000 _etext
|
||||
0000063c g F .text 0000007c CMU_ClockSelectGet
|
||||
00001050 g F .text 0000000c TimerReset
|
||||
20000624 g O .bss 00000004 SystemCoreClock
|
||||
00000b26 g F .text 00000012 BootTask
|
||||
00001384 g F .text 00000044 FlashWriteChecksum
|
||||
00000b82 g F .text 00000010 ComTransmitPacket
|
||||
000003b4 g F .text 0000000c SystemLFXOClockGet
|
||||
000005c8 g F .text 00000074 CMU_ClockEnable
|
||||
00000a86 g F .text 0000000e LEUART_Rx
|
||||
00000be0 g F .text 00000010 XcpIsConnected
|
||||
0000102c g F .text 00000004 NvmInit
|
||||
00001254 g F .text 0000001c FlashInit
|
||||
20000628 g .bss 00000000 _ebss
|
||||
00000100 g *ABS* 00000000 __STACKSIZE__
|
||||
00001444 g F .text 0000000c UnusedISR
|
||||
00000b80 g F .text 00000002 ComFree
|
||||
00000a3e g F .text 00000048 LEUART_Init
|
||||
20000080 g F .data 000000b4 MSC_WriteWord
|
||||
00000ee4 g F .text 00000094 UartInit
|
||||
00000ad0 g F .text 0000001c MSC_Deinit
|
||||
00000834 g F .text 000000b8 CMU_ClockSelectSet
|
||||
00001034 g F .text 00000004 NvmErase
|
||||
20000138 g .bss 00000000 _bss
|
||||
000002f4 g F .text 00000098 SystemHFClockGet
|
||||
00000c00 g F .text 000001e8 XcpPacketReceived
|
||||
20000008 g F .data 00000078 MSC_ErasePage
|
||||
00001410 g F .text 00000034 FlashDone
|
||||
000000b8 g F .text 0000004c EntryFromProg
|
||||
00000bc4 g F .text 0000001c XcpInit
|
||||
000012b8 g F .text 000000cc FlashErase
|
||||
00000118 g F .text 000001dc main
|
||||
0000103c g F .text 00000012 NvmDone
|
||||
00000f78 g F .text 00000050 UartTransmitPacket
|
||||
00001038 g F .text 00000004 NvmVerifyChecksum
|
||||
00000e70 g F .text 00000020 CpuMemCopy
|
||||
00001078 g F .text 0000000c TimerSet
|
||||
00000918 g F .text 000000a4 GPIO_PinModeSet
|
||||
000003ac g F .text 00000002 SystemInit
|
||||
00000a94 g F .text 0000001a LEUART_Tx
|
||||
000004b4 g F .text 00000114 CMU_ClockDivSet
|
||||
00000fc8 g F .text 00000064 UartReceivePacket
|
||||
20000000 g .data 00000000 _data
|
||||
00000e30 g F .text 00000002 CopInit
|
||||
000003ae g F .text 00000006 SystemLFRCOClockGet
|
||||
00000e90 g F .text 00000004 CpuReset
|
||||
000009cc g F .text 00000048 LEUART_BaudrateSet
|
||||
00000aec g F .text 00000024 SYSTEM_ChipRevisionGet
|
||||
0000038c g F .text 00000020 SystemCoreClockGet
|
||||
00001030 g F .text 00000004 NvmWrite
|
||||
00000e4c g F .text 00000024 CpuStartUserProgram
|
||||
20000728 g .bss 00000000 _estack
|
||||
000013c8 g F .text 00000046 FlashVerifyChecksum
|
||||
20000138 g .data 00000000 _edata
|
||||
00000000 g O .text 000000b8 _vectab
|
||||
00000ba0 g F .text 00000004 ComIsConnected
|
||||
00000de8 g F .text 00000030 BackDoorCheck
|
||||
20000628 g .bss 00000000 _stack
|
||||
000010a8 g F .text 00000010 TimerGet
|
||||
00001084 g F .text 00000024 TimerInit
|
||||
00000ab0 g F .text 00000020 MSC_Init
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
@echo off
|
||||
make --directory=../ all
|
|
@ -0,0 +1,2 @@
|
|||
@echo off
|
||||
make --directory=../ clean
|
|
@ -0,0 +1,108 @@
|
|||
/****************************************************************************************
|
||||
| Description: bootloader configuration header file
|
||||
| File Name: config.h
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| C O P Y R I G H T
|
||||
|----------------------------------------------------------------------------------------
|
||||
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| L I C E N S E
|
||||
|----------------------------------------------------------------------------------------
|
||||
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
||||
| modify it under the terms of the GNU General Public License as published by the Free
|
||||
| Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
| version.
|
||||
|
|
||||
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
| PURPOSE. See the GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License along with OpenBLT.
|
||||
| If not, see <http://www.gnu.org/licenses/>.
|
||||
|
|
||||
| A special exception to the GPL is included to allow you to distribute a combined work
|
||||
| that includes OpenBLT without being obliged to provide the source code for any
|
||||
| proprietary components. The exception text is included at the bottom of the license
|
||||
| file <license.html>.
|
||||
|
|
||||
****************************************************************************************/
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/****************************************************************************************
|
||||
* C P U D R I V E R C O N F I G U R A T I O N
|
||||
****************************************************************************************/
|
||||
/* To properly initialize the baudrate clocks of the communication interface, typically
|
||||
* the speed of the crystal oscillator and/or the speed at which the system runs is
|
||||
* needed. Set these through configurables BOOT_CPU_XTAL_SPEED_KHZ and
|
||||
* BOOT_CPU_SYSTEM_SPEED_KHZ, respectively. To enable data exchange with the host that is
|
||||
* not dependent on the targets architecture, the byte ordering needs to be known.
|
||||
* Setting BOOT_CPU_BYTE_ORDER_MOTOROLA to 1 selects little endian mode and 0 selects
|
||||
* big endian mode.
|
||||
*/
|
||||
#define BOOT_CPU_XTAL_SPEED_KHZ (32000)
|
||||
#define BOOT_CPU_SYSTEM_SPEED_KHZ (14000)
|
||||
#define BOOT_CPU_BYTE_ORDER_MOTOROLA (0)
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* C O M M U N I C A T I O N I N T E R F A C E C O N F I G U R A T I O N
|
||||
****************************************************************************************/
|
||||
/* The UART communication interface is selected by setting the BOOT_COM_UART_ENABLE
|
||||
* configurable to 1. Configurable BOOT_COM_UART_BAUDRATE selects the communication speed
|
||||
* in bits/second. The maximum amount of data bytes in a message for data transmission
|
||||
* and reception is set through BOOT_COM_UART_TX_MAX_DATA and BOOT_COM_UART_RX_MAX_DATA,
|
||||
* respectively. It is common for a microcontroller to have more than 1 UART interface
|
||||
* on board. The zero-based BOOT_COM_UART_CHANNEL_INDEX selects the UART interface.
|
||||
*
|
||||
*/
|
||||
#define BOOT_COM_UART_ENABLE (1)
|
||||
#define BOOT_COM_UART_BAUDRATE (9600)
|
||||
#define BOOT_COM_UART_TX_MAX_DATA (64)
|
||||
#define BOOT_COM_UART_RX_MAX_DATA (64)
|
||||
#define BOOT_COM_UART_CHANNEL_INDEX (1)
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* B A C K D O O R E N T R Y C O N F I G U R A T I O N
|
||||
****************************************************************************************/
|
||||
/* It is possible to implement an application specific method to force the bootloader to
|
||||
* stay active after a reset. Such a backdoor entry into the bootloader is desired in
|
||||
* situations where the user program does not run properly and therefore cannot
|
||||
* reactivate the bootloader. By enabling these hook functions, the application can
|
||||
* implement the backdoor, which overrides the default backdoor entry that is programmed
|
||||
* into the bootloader. When desired for security purposes, these hook functions can
|
||||
* also be implemented in a way that disables the backdoor entry altogether.
|
||||
*/
|
||||
#define BOOT_BACKDOOR_HOOKS_ENABLE (0)
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* N O N - V O L A T I L E M E M O R Y D R I V E R C O N F I G U R A T I O N
|
||||
****************************************************************************************/
|
||||
/* The NVM driver typically supports erase and program operations of the internal memory
|
||||
* present on the microcontroller. Through these hook functions the NVM driver can be
|
||||
* extended to support additional memory types such as external flash memory and serial
|
||||
* eeproms. The size of the internal memory in kilobytes is specified with configurable
|
||||
* BOOT_NVM_SIZE_KB.
|
||||
*/
|
||||
#define BOOT_NVM_HOOKS_ENABLE (0)
|
||||
#define BOOT_NVM_SIZE_KB (128)
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* W A T C H D O G D R I V E R C O N F I G U R A T I O N
|
||||
****************************************************************************************/
|
||||
/* The COP driver cannot be configured internally in the bootloader, because its use
|
||||
* and configuration is application specific. The bootloader does need to service the
|
||||
* watchdog in case it is used. When the application requires the use of a watchdog,
|
||||
* set BOOT_COP_HOOKS_ENABLE to be able to initialize and service the watchdog through
|
||||
* hook functions.
|
||||
*/
|
||||
#define BOOT_COP_HOOKS_ENABLE (0)
|
||||
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
/*********************************** end of config.h ***********************************/
|
|
@ -0,0 +1,179 @@
|
|||
/****************************************************************************************
|
||||
| Description: bootloader callback source file
|
||||
| File Name: hooks.c
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| C O P Y R I G H T
|
||||
|----------------------------------------------------------------------------------------
|
||||
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| L I C E N S E
|
||||
|----------------------------------------------------------------------------------------
|
||||
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
||||
| modify it under the terms of the GNU General Public License as published by the Free
|
||||
| Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
| version.
|
||||
|
|
||||
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
| PURPOSE. See the GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License along with OpenBLT.
|
||||
| If not, see <http://www.gnu.org/licenses/>.
|
||||
|
|
||||
| A special exception to the GPL is included to allow you to distribute a combined work
|
||||
| that includes OpenBLT without being obliged to provide the source code for any
|
||||
| proprietary components. The exception text is included at the bottom of the license
|
||||
| file <license.html>.
|
||||
|
|
||||
****************************************************************************************/
|
||||
|
||||
/****************************************************************************************
|
||||
* Include files
|
||||
****************************************************************************************/
|
||||
#include "boot.h" /* bootloader generic header */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* B A C K D O O R E N T R Y H O O K F U N C T I O N S
|
||||
****************************************************************************************/
|
||||
|
||||
#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0)
|
||||
/****************************************************************************************
|
||||
** NAME: BackDoorInitHook
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Initializes the backdoor entry option.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void BackDoorInitHook(void)
|
||||
{
|
||||
} /*** end of BackDoorInitHook ***/
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: BackDoorEntryHook
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: BLT_TRUE if the backdoor entry is requested, BLT_FALSE otherwise.
|
||||
** DESCRIPTION: Checks if a backdoor entry is requested.
|
||||
**
|
||||
****************************************************************************************/
|
||||
blt_bool BackDoorEntryHook(void)
|
||||
{
|
||||
/* default implementation always activates the bootloader after a reset */
|
||||
return BLT_TRUE;
|
||||
} /*** end of BackDoorEntryHook ***/
|
||||
#endif /* BOOT_BACKDOOR_HOOKS_ENABLE > 0 */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* N O N - V O L A T I L E M E M O R Y D R I V E R H O O K F U N C T I O N S
|
||||
****************************************************************************************/
|
||||
|
||||
#if (BOOT_NVM_HOOKS_ENABLE > 0)
|
||||
/****************************************************************************************
|
||||
** NAME: NvmInitHook
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Callback that gets called at the start of the internal NVM driver
|
||||
** initialization routine.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void NvmInitHook(void)
|
||||
{
|
||||
} /*** end of NvmInitHook ***/
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: NvmWriteHook
|
||||
** PARAMETER: addr start address
|
||||
** len length in bytes
|
||||
** data pointer to the data buffer.
|
||||
** RETURN VALUE: BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is
|
||||
** not within the supported memory range, or BLT_NVM_ERROR is the write
|
||||
** operation failed.
|
||||
** DESCRIPTION: Callback that gets called at the start of the NVM driver write
|
||||
** routine. It allows additional memory to be operated on. If the address
|
||||
** is not within the range of the additional memory, then
|
||||
** BLT_NVM_NOT_IN_RANGE must be returned to indicate that the data hasn't
|
||||
** been written yet.
|
||||
**
|
||||
**
|
||||
****************************************************************************************/
|
||||
blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data)
|
||||
{
|
||||
return BLT_NVM_NOT_IN_RANGE;
|
||||
} /*** end of NvmWriteHook ***/
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: NvmEraseHook
|
||||
** PARAMETER: addr start address
|
||||
** len length in bytes
|
||||
** RETURN VALUE: BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is
|
||||
** not within the supported memory range, or BLT_NVM_ERROR is the erase
|
||||
** operation failed.
|
||||
** DESCRIPTION: Callback that gets called at the start of the NVM driver erase
|
||||
** routine. It allows additional memory to be operated on. If the address
|
||||
** is not within the range of the additional memory, then
|
||||
** BLT_NVM_NOT_IN_RANGE must be returned to indicate that the memory
|
||||
** hasn't been erased yet.
|
||||
**
|
||||
****************************************************************************************/
|
||||
blt_int8u NvmEraseHook(blt_addr addr, blt_int32u len)
|
||||
{
|
||||
return BLT_NVM_NOT_IN_RANGE;
|
||||
} /*** end of NvmEraseHook ***/
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: NvmDoneHook
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: BLT_TRUE is successful, BLT_FALSE otherwise.
|
||||
** DESCRIPTION: Callback that gets called at the end of the NVM programming session.
|
||||
**
|
||||
****************************************************************************************/
|
||||
blt_bool NvmDoneHook(void)
|
||||
{
|
||||
return BLT_TRUE;
|
||||
} /*** end of NvmDoneHook ***/
|
||||
#endif /* BOOT_NVM_HOOKS_ENABLE > 0 */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* W A T C H D O G D R I V E R H O O K F U N C T I O N S
|
||||
****************************************************************************************/
|
||||
|
||||
#if (BOOT_COP_HOOKS_ENABLE > 0)
|
||||
/****************************************************************************************
|
||||
** NAME: CopInitHook
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Callback that gets called at the end of the internal COP driver
|
||||
** initialization routine. It can be used to configure and enable the
|
||||
** watchdog.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void CopInitHook(void)
|
||||
{
|
||||
} /*** end of CopInitHook ***/
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: CopServiceHook
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Callback that gets called at the end of the internal COP driver
|
||||
** service routine. This gets called upon initialization and during
|
||||
** potential long lasting loops and routine. It can be used to service
|
||||
** the watchdog to prevent a watchdog reset.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void CopServiceHook(void)
|
||||
{
|
||||
} /*** end of CopServiceHook ***/
|
||||
#endif /* BOOT_COP_HOOKS_ENABLE > 0 */
|
||||
|
||||
|
||||
/*********************************** end of hooks.c ************************************/
|
|
@ -0,0 +1,211 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CodeLite_Project Name="DemoBoot" InternalType="">
|
||||
<VirtualDirectory Name="Source">
|
||||
<VirtualDirectory Name="ARMCM3_EFM32">
|
||||
<VirtualDirectory Name="GCC">
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/GCC/cstart.c"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/GCC/vectors.c"/>
|
||||
</VirtualDirectory>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/cpu.c"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/cpu.h"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/flash.c"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/flash.h"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/nvm.c"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/nvm.h"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/timer.c"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/timer.h"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/types.h"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/uart.c"/>
|
||||
<File Name="../../../../Source/ARMCM3_EFM32/uart.h"/>
|
||||
</VirtualDirectory>
|
||||
<File Name="../../../../Source/assert.c"/>
|
||||
<File Name="../../../../Source/assert.h"/>
|
||||
<File Name="../../../../Source/backdoor.c"/>
|
||||
<File Name="../../../../Source/backdoor.h"/>
|
||||
<File Name="../../../../Source/boot.c"/>
|
||||
<File Name="../../../../Source/boot.h"/>
|
||||
<File Name="../../../../Source/com.c"/>
|
||||
<File Name="../../../../Source/com.h"/>
|
||||
<File Name="../../../../Source/cop.c"/>
|
||||
<File Name="../../../../Source/cop.h"/>
|
||||
<File Name="../../../../Source/plausibility.h"/>
|
||||
<File Name="../../../../Source/xcp.c"/>
|
||||
<File Name="../../../../Source/xcp.h"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="Demo">
|
||||
<VirtualDirectory Name="ARMCM3_EFM32_Olimex_EM32G880F128STK_GCC">
|
||||
<VirtualDirectory Name="Boot">
|
||||
<VirtualDirectory Name="lib">
|
||||
<VirtualDirectory Name="efm32lib">
|
||||
<VirtualDirectory Name="inc">
|
||||
<File Name="../lib/efm32lib/inc/efm32_acmp.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_adc.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_aes.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_assert.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_bitband.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_chip.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_cmu.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_common.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_dac.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_dbg.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_dma.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_ebi.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_emu.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_gpio.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_i2c.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_int.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_lcd.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_lesense.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_letimer.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_leuart.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_mpu.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_msc.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_opamp.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_pcnt.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_prs.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_rmu.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_rtc.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_system.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_timer.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_usart.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_vcmp.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_wdog.h"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="src">
|
||||
<File Name="../lib/efm32lib/src/efm32_acmp.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_adc.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_aes.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_assert.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_cmu.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_dac.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_dbg.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_dma.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_ebi.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_emu.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_gpio.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_i2c.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_int.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_lcd.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_lesense.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_letimer.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_leuart.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_mpu.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_msc.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_opamp.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_pcnt.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_prs.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_rmu.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_rtc.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_system.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_timer.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_usart.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_vcmp.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_wdog.c"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="CMSIS">
|
||||
<VirtualDirectory Name="CM3">
|
||||
<VirtualDirectory Name="DeviceSupport">
|
||||
<VirtualDirectory Name="EnergyMicro">
|
||||
<VirtualDirectory Name="EFM32">
|
||||
<File Name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32.h"/>
|
||||
<File Name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32g880f128.h"/>
|
||||
<File Name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.c"/>
|
||||
<File Name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.h"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="CoreSupport">
|
||||
<File Name="../lib/CMSIS/CM3/CoreSupport/core_cm3.c"/>
|
||||
<File Name="../lib/CMSIS/CM3/CoreSupport/core_cm3.h"/>
|
||||
<File Name="../lib/CMSIS/CM3/CoreSupport/core_cmFunc.h"/>
|
||||
<File Name="../lib/CMSIS/CM3/CoreSupport/core_cmInstr.h"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<File Name="../config.h"/>
|
||||
<File Name="../hooks.c"/>
|
||||
<File Name="../main.c"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<Plugins>
|
||||
<Plugin Name="qmake">
|
||||
<![CDATA[00010001N0005Debug000000000000]]>
|
||||
</Plugin>
|
||||
</Plugins>
|
||||
<Description/>
|
||||
<Dependencies/>
|
||||
<Settings Type="Dynamic Library">
|
||||
<GlobalSettings>
|
||||
<Compiler Options="" C_Options="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="">
|
||||
<LibraryPath Value="."/>
|
||||
</Linker>
|
||||
<ResourceCompiler Options=""/>
|
||||
</GlobalSettings>
|
||||
<Configuration Name="Debug" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
|
||||
<Compiler Options="-g" C_Options="-g" Required="yes" PreCompiledHeader="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="" Required="yes"/>
|
||||
<ResourceCompiler Options="" Required="no"/>
|
||||
<General OutputFile="" IntermediateDirectory="../obj" Command="openbtl_olimex_lpc_l2294_20mhz.elf" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(WorkspacePath)/../bin" PauseExecWhenProcTerminates="yes"/>
|
||||
<Environment EnvVarSetName="<Use Defaults>" DbgSetName="<Use Defaults>"/>
|
||||
<Debugger IsRemote="yes" RemoteHostName="localhost" RemoteHostPort="3333" DebuggerPath="C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin\arm-none-eabi-gdb.exe">
|
||||
<PostConnectCommands/>
|
||||
<StartupCommands>break main
|
||||
continue
|
||||
</StartupCommands>
|
||||
</Debugger>
|
||||
<PreBuild/>
|
||||
<PostBuild/>
|
||||
<CustomBuild Enabled="yes">
|
||||
<RebuildCommand/>
|
||||
<CleanCommand>make clean</CleanCommand>
|
||||
<BuildCommand>make</BuildCommand>
|
||||
<PreprocessFileCommand/>
|
||||
<SingleFileCommand/>
|
||||
<MakefileGenerationCommand/>
|
||||
<ThirdPartyToolName>None</ThirdPartyToolName>
|
||||
<WorkingDirectory>$(WorkspacePath)/..</WorkingDirectory>
|
||||
</CustomBuild>
|
||||
<AdditionalRules>
|
||||
<CustomPostBuild/>
|
||||
<CustomPreBuild/>
|
||||
</AdditionalRules>
|
||||
</Configuration>
|
||||
<Configuration Name="Release" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
|
||||
<Compiler Options="" C_Options="" Required="yes" PreCompiledHeader="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="-O2" Required="yes"/>
|
||||
<ResourceCompiler Options="" Required="no"/>
|
||||
<General OutputFile="" IntermediateDirectory="./Release" Command="" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
|
||||
<Environment EnvVarSetName="<Use Defaults>" DbgSetName="<Use Defaults>"/>
|
||||
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
|
||||
<PostConnectCommands/>
|
||||
<StartupCommands/>
|
||||
</Debugger>
|
||||
<PreBuild/>
|
||||
<PostBuild/>
|
||||
<CustomBuild Enabled="yes">
|
||||
<RebuildCommand/>
|
||||
<CleanCommand>make clean</CleanCommand>
|
||||
<BuildCommand>make</BuildCommand>
|
||||
<PreprocessFileCommand/>
|
||||
<SingleFileCommand/>
|
||||
<MakefileGenerationCommand/>
|
||||
<ThirdPartyToolName>None</ThirdPartyToolName>
|
||||
<WorkingDirectory>$(WorkspacePath)</WorkingDirectory>
|
||||
</CustomBuild>
|
||||
<AdditionalRules>
|
||||
<CustomPostBuild/>
|
||||
<CustomPreBuild/>
|
||||
</AdditionalRules>
|
||||
</Configuration>
|
||||
</Settings>
|
||||
</CodeLite_Project>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CodeLite_Workspace Name="DemoBoot" Database="./DemoBoot.tags">
|
||||
<Project Name="DemoBoot" Path="DemoBoot.project" Active="Yes"/>
|
||||
<BuildMatrix>
|
||||
<WorkspaceConfiguration Name="Debug" Selected="yes">
|
||||
<Project Name="DemoBoot" ConfigName="Debug"/>
|
||||
</WorkspaceConfiguration>
|
||||
<WorkspaceConfiguration Name="Release" Selected="yes">
|
||||
<Project Name="DemoBoot" ConfigName="Release"/>
|
||||
</WorkspaceConfiguration>
|
||||
</BuildMatrix>
|
||||
</CodeLite_Workspace>
|
|
@ -0,0 +1,4 @@
|
|||
Integrated Development Environment
|
||||
----------------------------------
|
||||
Codelite was used as the editor during the development of this software program. This directory contains the Codelite
|
||||
workspace and project files. Codelite is a cross platform open source C/C++ IDE, available at http://www.codelite.org/.
|
|
@ -0,0 +1,339 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm3.c
|
||||
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
|
||||
* @version V2.00
|
||||
* @date 13. 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 Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
mrs r0, basepri
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
msr basepri, 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 */
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask Register.
|
||||
|
||||
\return Fault Mask value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
mrs r0, faultmask
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Set the Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask Register.
|
||||
|
||||
\param [in] faultMask Fault Mask value value to set
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
__ASM void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
msr faultmask, 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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,851 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmFunc.h
|
||||
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||
* @version V2.01
|
||||
* @date 06. December 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#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 */
|
||||
|
||||
/* 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
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern uint32_t __get_CONTROL(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
#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)
|
||||
extern void __set_CONTROL(uint32_t control);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get ISPR Register
|
||||
|
||||
This function returns the content of the ISPR Register.
|
||||
|
||||
\return ISPR Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern uint32_t __get_IPSR(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern uint32_t __get_APSR(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern uint32_t __get_xPSR(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
#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)
|
||||
extern uint32_t __get_PSP(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
#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)
|
||||
extern void __set_PSP(uint32_t topOfProcStack);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
#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)
|
||||
extern uint32_t __get_MSP(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
#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)
|
||||
extern void __set_MSP(uint32_t topOfMainStack);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
#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)
|
||||
extern uint32_t __get_PRIMASK(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
#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)
|
||||
extern void __set_PRIMASK(uint32_t priMask);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
#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
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern uint32_t __get_BASEPRI(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern void __set_BASEPRI(uint32_t basePri);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xff);
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern uint32_t __get_FAULTMASK(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern void __set_FAULTMASK(uint32_t faultMask);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & 1);
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
#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)
|
||||
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)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
/* Energy Micro: Add support for new versions of IAR */
|
||||
#if __VER__ >= 6020000
|
||||
#include "cmsis_iar.h"
|
||||
#else
|
||||
/* Energy Micro: Fix end */
|
||||
#include <intrinsics.h> /* IAR Intrinsics */
|
||||
|
||||
#pragma diag_suppress=Pe940
|
||||
|
||||
/** \brief Enable IRQ Interrupts
|
||||
|
||||
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_irq __enable_interrupt
|
||||
|
||||
|
||||
/** \brief Disable IRQ Interrupts
|
||||
|
||||
This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_irq __disable_interrupt
|
||||
|
||||
|
||||
/* intrinsic unsigned long __get_CONTROL( void ); (see intrinsic.h) */
|
||||
/* intrinsic void __set_CONTROL( unsigned long ); (see intrinsic.h) */
|
||||
|
||||
|
||||
/** \brief Get ISPR Register
|
||||
|
||||
This function returns the content of the ISPR Register.
|
||||
|
||||
\return ISPR Register value
|
||||
*/
|
||||
static uint32_t __get_IPSR(void)
|
||||
{
|
||||
__ASM("mrs r0, ipsr");
|
||||
}
|
||||
|
||||
/* Energy Micro: This function is present in new IAR versions */
|
||||
#if __VER__ < 6010002
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
static uint32_t __get_APSR(void)
|
||||
{
|
||||
__ASM("mrs r0, apsr");
|
||||
}
|
||||
#endif
|
||||
/* Energy Micro: Fix end */
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
static uint32_t __get_xPSR(void)
|
||||
{
|
||||
__ASM("mrs r0, psr"); // assembler does not know "xpsr"
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
static uint32_t __get_PSP(void)
|
||||
{
|
||||
__ASM("mrs r0, psp");
|
||||
}
|
||||
|
||||
|
||||
/** \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 void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM("msr psp, r0");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
static uint32_t __get_MSP(void)
|
||||
{
|
||||
__ASM("mrs r0, msp");
|
||||
}
|
||||
|
||||
|
||||
/** \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 void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
__ASM("msr msp, r0");
|
||||
}
|
||||
|
||||
|
||||
/* intrinsic unsigned long __get_PRIMASK( void ); (see intrinsic.h) */
|
||||
/* intrinsic void __set_PRIMASK( unsigned long ); (see intrinsic.h) */
|
||||
|
||||
|
||||
#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.
|
||||
*/
|
||||
static __INLINE void __enable_fault_irq(void)
|
||||
{
|
||||
__ASM ("cpsie f");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
static __INLINE void __disable_fault_irq(void)
|
||||
{
|
||||
__ASM ("cpsid f");
|
||||
}
|
||||
|
||||
|
||||
/* intrinsic unsigned long __get_BASEPRI( void ); (see intrinsic.h) */
|
||||
/* intrinsic void __set_BASEPRI( unsigned long ); (see intrinsic.h) */
|
||||
/* intrinsic unsigned long __get_FAULTMASK( void ); (see intrinsic.h) */
|
||||
/* intrinsic void __set_FAULTMASK(unsigned long); (see intrinsic.h) */
|
||||
|
||||
#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 uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM("vmrs r0, fpscr");
|
||||
#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 void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM("vmsr fpscr, r0");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
#pragma diag_default=Pe940
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#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");
|
||||
}
|
||||
|
||||
|
||||
/** \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");
|
||||
}
|
||||
|
||||
|
||||
/** \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 ISPR Register
|
||||
|
||||
This function returns the content of the ISPR Register.
|
||||
|
||||
\return ISPR 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");
|
||||
}
|
||||
|
||||
|
||||
/** \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");
|
||||
}
|
||||
|
||||
|
||||
/** \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)
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %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)
|
||||
__ASM volatile ("MSR 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,782 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V2.01
|
||||
* @date 06. December 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#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 */
|
||||
|
||||
/** \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
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
extern uint32_t __REV16(uint32_t value);
|
||||
#else /* (__ARMCC_VERSION >= 400677) */
|
||||
static __INLINE __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)
|
||||
extern int32_t __REVSH(int32_t value);
|
||||
#else /* (__ARMCC_VERSION >= 400677) */
|
||||
static __INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
#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.
|
||||
|
||||
*/
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
extern void __CLREX(void);
|
||||
#else /* (__ARMCC_VERSION >= 400000) */
|
||||
#define __CLREX __clrex
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
/** \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 */
|
||||
|
||||
/* Energy Micro: Add support for new versions of IAR */
|
||||
#if __VER__ >= 6020000
|
||||
#include "cmsis_iar.h"
|
||||
#else
|
||||
/* Energy Micro: Adpaptation end */
|
||||
#include <intrinsics.h> /* IAR Intrinsics */
|
||||
|
||||
#pragma diag_suppress=Pe940
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __no_operation
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
static __INLINE void __WFI(void)
|
||||
{
|
||||
__ASM ("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.
|
||||
*/
|
||||
static __INLINE void __WFE(void)
|
||||
{
|
||||
__ASM ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
static __INLINE void __SEV(void)
|
||||
{
|
||||
__ASM ("sev");
|
||||
}
|
||||
|
||||
|
||||
/* intrinsic void __ISB(void) (see intrinsics.h) */
|
||||
/* intrinsic void __DSB(void) (see intrinsics.h) */
|
||||
/* intrinsic void __DMB(void) (see intrinsics.h) */
|
||||
/* intrinsic uint32_t __REV(uint32_t value) (see intrinsics.h) */
|
||||
/* intrinsic __SSAT (see intrinsics.h) */
|
||||
/* intrinsic __USAT (see intrinsics.h) */
|
||||
|
||||
|
||||
/** \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
|
||||
*/
|
||||
static uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
__ASM("rev16 r0, r0");
|
||||
}
|
||||
|
||||
|
||||
/* intrinsic uint32_t __REVSH(uint32_t value) (see intrinsics.h */
|
||||
|
||||
|
||||
#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
|
||||
*/
|
||||
static uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
__ASM("rbit r0, r0");
|
||||
}
|
||||
|
||||
|
||||
/** \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)
|
||||
*/
|
||||
static uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
__ASM("ldrexb r0, [r0]");
|
||||
}
|
||||
|
||||
|
||||
/** \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)
|
||||
*/
|
||||
static uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
__ASM("ldrexh r0, [r0]");
|
||||
}
|
||||
|
||||
|
||||
/** \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)
|
||||
*/
|
||||
/* intrinsic unsigned long __LDREX(unsigned long *) (see intrinsics.h) */
|
||||
static uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
__ASM("ldrex r0, [r0]");
|
||||
}
|
||||
|
||||
|
||||
/** \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
|
||||
*/
|
||||
static uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
__ASM("strexb r0, r0, [r1]");
|
||||
}
|
||||
|
||||
|
||||
/** \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
|
||||
*/
|
||||
static uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
__ASM("strexh r0, r0, [r1]");
|
||||
}
|
||||
|
||||
|
||||
/** \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
|
||||
*/
|
||||
/* intrinsic unsigned long __STREX(unsigned long, unsigned long) (see intrinsics.h )*/
|
||||
static uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
__ASM("strex r0, r0, [r1]");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
static __INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM ("clrex");
|
||||
}
|
||||
|
||||
/* intrinsic unsigned char __CLZ( unsigned long ) (see intrinsics.h) */
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
#pragma diag_default=Pe940
|
||||
|
||||
#endif
|
||||
/* Energy Micro: Fix end */
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
#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 instrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H__ */
|
|
@ -0,0 +1,526 @@
|
|||
/**************************************************************************//**
|
||||
* @file
|
||||
* @brief CMSIS Cortex-M0/M3 Peripheral Access Layer for EFM32 device series
|
||||
*
|
||||
* This is a convenience header file for defining the EFM32 part number on the
|
||||
* build command line, instead of specifying the part specific header file.
|
||||
* @verbatim
|
||||
* Example: Add "-DEFM32G890F128" to your build options, to define part
|
||||
* Add "#include "efm32.h" to your source files
|
||||
* @endverbatim
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __EFM32_H
|
||||
#define __EFM32_H
|
||||
|
||||
|
||||
#if defined(EFM32G200F16)
|
||||
#include "efm32g200f16.h"
|
||||
|
||||
#elif defined(EFM32G200F32)
|
||||
#include "efm32g200f32.h"
|
||||
|
||||
#elif defined(EFM32G200F64)
|
||||
#include "efm32g200f64.h"
|
||||
|
||||
#elif defined(EFM32G210F128)
|
||||
#include "efm32g210f128.h"
|
||||
|
||||
#elif defined(EFM32G222F128)
|
||||
#include "efm32g222f128.h"
|
||||
|
||||
#elif defined(EFM32G222F32)
|
||||
#include "efm32g222f32.h"
|
||||
|
||||
#elif defined(EFM32G222F64)
|
||||
#include "efm32g222f64.h"
|
||||
|
||||
#elif defined(EFM32G230F128)
|
||||
#include "efm32g230f128.h"
|
||||
|
||||
#elif defined(EFM32G230F32)
|
||||
#include "efm32g230f32.h"
|
||||
|
||||
#elif defined(EFM32G230F64)
|
||||
#include "efm32g230f64.h"
|
||||
|
||||
#elif defined(EFM32G232F128)
|
||||
#include "efm32g232f128.h"
|
||||
|
||||
#elif defined(EFM32G232F32)
|
||||
#include "efm32g232f32.h"
|
||||
|
||||
#elif defined(EFM32G232F64)
|
||||
#include "efm32g232f64.h"
|
||||
|
||||
#elif defined(EFM32G280F128)
|
||||
#include "efm32g280f128.h"
|
||||
|
||||
#elif defined(EFM32G280F32)
|
||||
#include "efm32g280f32.h"
|
||||
|
||||
#elif defined(EFM32G280F64)
|
||||
#include "efm32g280f64.h"
|
||||
|
||||
#elif defined(EFM32G290F128)
|
||||
#include "efm32g290f128.h"
|
||||
|
||||
#elif defined(EFM32G290F32)
|
||||
#include "efm32g290f32.h"
|
||||
|
||||
#elif defined(EFM32G290F64)
|
||||
#include "efm32g290f64.h"
|
||||
|
||||
#elif defined(EFM32G840F128)
|
||||
#include "efm32g840f128.h"
|
||||
|
||||
#elif defined(EFM32G840F32)
|
||||
#include "efm32g840f32.h"
|
||||
|
||||
#elif defined(EFM32G840F64)
|
||||
#include "efm32g840f64.h"
|
||||
|
||||
#elif defined(EFM32G842F128)
|
||||
#include "efm32g842f128.h"
|
||||
|
||||
#elif defined(EFM32G842F32)
|
||||
#include "efm32g842f32.h"
|
||||
|
||||
#elif defined(EFM32G842F64)
|
||||
#include "efm32g842f64.h"
|
||||
|
||||
#elif defined(EFM32G880F128)
|
||||
#include "efm32g880f128.h"
|
||||
|
||||
#elif defined(EFM32G880F32)
|
||||
#include "efm32g880f32.h"
|
||||
|
||||
#elif defined(EFM32G880F64)
|
||||
#include "efm32g880f64.h"
|
||||
|
||||
#elif defined(EFM32G890F128)
|
||||
#include "efm32g890f128.h"
|
||||
|
||||
#elif defined(EFM32G890F32)
|
||||
#include "efm32g890f32.h"
|
||||
|
||||
#elif defined(EFM32G890F64)
|
||||
#include "efm32g890f64.h"
|
||||
|
||||
#elif defined(EFM32GG230F1024)
|
||||
#include "efm32gg230f1024.h"
|
||||
|
||||
#elif defined(EFM32GG230F512)
|
||||
#include "efm32gg230f512.h"
|
||||
|
||||
#elif defined(EFM32GG232F1024)
|
||||
#include "efm32gg232f1024.h"
|
||||
|
||||
#elif defined(EFM32GG232F512)
|
||||
#include "efm32gg232f512.h"
|
||||
|
||||
#elif defined(EFM32GG280F1024)
|
||||
#include "efm32gg280f1024.h"
|
||||
|
||||
#elif defined(EFM32GG280F512)
|
||||
#include "efm32gg280f512.h"
|
||||
|
||||
#elif defined(EFM32GG290F1024)
|
||||
#include "efm32gg290f1024.h"
|
||||
|
||||
#elif defined(EFM32GG290F512)
|
||||
#include "efm32gg290f512.h"
|
||||
|
||||
#elif defined(EFM32GG295F1024)
|
||||
#include "efm32gg295f1024.h"
|
||||
|
||||
#elif defined(EFM32GG295F512)
|
||||
#include "efm32gg295f512.h"
|
||||
|
||||
#elif defined(EFM32GG330F1024)
|
||||
#include "efm32gg330f1024.h"
|
||||
|
||||
#elif defined(EFM32GG330F512)
|
||||
#include "efm32gg330f512.h"
|
||||
|
||||
#elif defined(EFM32GG332F1024)
|
||||
#include "efm32gg332f1024.h"
|
||||
|
||||
#elif defined(EFM32GG332F512)
|
||||
#include "efm32gg332f512.h"
|
||||
|
||||
#elif defined(EFM32GG380F1024)
|
||||
#include "efm32gg380f1024.h"
|
||||
|
||||
#elif defined(EFM32GG380F512)
|
||||
#include "efm32gg380f512.h"
|
||||
|
||||
#elif defined(EFM32GG390F1024)
|
||||
#include "efm32gg390f1024.h"
|
||||
|
||||
#elif defined(EFM32GG390F512)
|
||||
#include "efm32gg390f512.h"
|
||||
|
||||
#elif defined(EFM32GG395F1024)
|
||||
#include "efm32gg395f1024.h"
|
||||
|
||||
#elif defined(EFM32GG395F512)
|
||||
#include "efm32gg395f512.h"
|
||||
|
||||
#elif defined(EFM32GG840F1024)
|
||||
#include "efm32gg840f1024.h"
|
||||
|
||||
#elif defined(EFM32GG840F512)
|
||||
#include "efm32gg840f512.h"
|
||||
|
||||
#elif defined(EFM32GG842F1024)
|
||||
#include "efm32gg842f1024.h"
|
||||
|
||||
#elif defined(EFM32GG842F512)
|
||||
#include "efm32gg842f512.h"
|
||||
|
||||
#elif defined(EFM32GG880F1024)
|
||||
#include "efm32gg880f1024.h"
|
||||
|
||||
#elif defined(EFM32GG880F512)
|
||||
#include "efm32gg880f512.h"
|
||||
|
||||
#elif defined(EFM32GG890F1024)
|
||||
#include "efm32gg890f1024.h"
|
||||
|
||||
#elif defined(EFM32GG890F512)
|
||||
#include "efm32gg890f512.h"
|
||||
|
||||
#elif defined(EFM32GG895F1024)
|
||||
#include "efm32gg895f1024.h"
|
||||
|
||||
#elif defined(EFM32GG895F512)
|
||||
#include "efm32gg895f512.h"
|
||||
|
||||
#elif defined(EFM32GG940F1024)
|
||||
#include "efm32gg940f1024.h"
|
||||
|
||||
#elif defined(EFM32GG940F512)
|
||||
#include "efm32gg940f512.h"
|
||||
|
||||
#elif defined(EFM32GG942F1024)
|
||||
#include "efm32gg942f1024.h"
|
||||
|
||||
#elif defined(EFM32GG942F512)
|
||||
#include "efm32gg942f512.h"
|
||||
|
||||
#elif defined(EFM32GG980F1024)
|
||||
#include "efm32gg980f1024.h"
|
||||
|
||||
#elif defined(EFM32GG980F512)
|
||||
#include "efm32gg980f512.h"
|
||||
|
||||
#elif defined(EFM32GG990F1024)
|
||||
#include "efm32gg990f1024.h"
|
||||
|
||||
#elif defined(EFM32GG990F512)
|
||||
#include "efm32gg990f512.h"
|
||||
|
||||
#elif defined(EFM32GG995F1024)
|
||||
#include "efm32gg995f1024.h"
|
||||
|
||||
#elif defined(EFM32GG995F512)
|
||||
#include "efm32gg995f512.h"
|
||||
|
||||
#elif defined(EFM32LG230F128)
|
||||
#include "efm32lg230f128.h"
|
||||
|
||||
#elif defined(EFM32LG230F256)
|
||||
#include "efm32lg230f256.h"
|
||||
|
||||
#elif defined(EFM32LG230F64)
|
||||
#include "efm32lg230f64.h"
|
||||
|
||||
#elif defined(EFM32LG232F128)
|
||||
#include "efm32lg232f128.h"
|
||||
|
||||
#elif defined(EFM32LG232F256)
|
||||
#include "efm32lg232f256.h"
|
||||
|
||||
#elif defined(EFM32LG232F64)
|
||||
#include "efm32lg232f64.h"
|
||||
|
||||
#elif defined(EFM32LG280F128)
|
||||
#include "efm32lg280f128.h"
|
||||
|
||||
#elif defined(EFM32LG280F256)
|
||||
#include "efm32lg280f256.h"
|
||||
|
||||
#elif defined(EFM32LG280F64)
|
||||
#include "efm32lg280f64.h"
|
||||
|
||||
#elif defined(EFM32LG290F128)
|
||||
#include "efm32lg290f128.h"
|
||||
|
||||
#elif defined(EFM32LG290F256)
|
||||
#include "efm32lg290f256.h"
|
||||
|
||||
#elif defined(EFM32LG290F64)
|
||||
#include "efm32lg290f64.h"
|
||||
|
||||
#elif defined(EFM32LG295F128)
|
||||
#include "efm32lg295f128.h"
|
||||
|
||||
#elif defined(EFM32LG295F256)
|
||||
#include "efm32lg295f256.h"
|
||||
|
||||
#elif defined(EFM32LG295F64)
|
||||
#include "efm32lg295f64.h"
|
||||
|
||||
#elif defined(EFM32LG330F128)
|
||||
#include "efm32lg330f128.h"
|
||||
|
||||
#elif defined(EFM32LG330F256)
|
||||
#include "efm32lg330f256.h"
|
||||
|
||||
#elif defined(EFM32LG330F64)
|
||||
#include "efm32lg330f64.h"
|
||||
|
||||
#elif defined(EFM32LG332F128)
|
||||
#include "efm32lg332f128.h"
|
||||
|
||||
#elif defined(EFM32LG332F256)
|
||||
#include "efm32lg332f256.h"
|
||||
|
||||
#elif defined(EFM32LG332F64)
|
||||
#include "efm32lg332f64.h"
|
||||
|
||||
#elif defined(EFM32LG380F128)
|
||||
#include "efm32lg380f128.h"
|
||||
|
||||
#elif defined(EFM32LG380F256)
|
||||
#include "efm32lg380f256.h"
|
||||
|
||||
#elif defined(EFM32LG380F64)
|
||||
#include "efm32lg380f64.h"
|
||||
|
||||
#elif defined(EFM32LG390F128)
|
||||
#include "efm32lg390f128.h"
|
||||
|
||||
#elif defined(EFM32LG390F256)
|
||||
#include "efm32lg390f256.h"
|
||||
|
||||
#elif defined(EFM32LG390F64)
|
||||
#include "efm32lg390f64.h"
|
||||
|
||||
#elif defined(EFM32LG395F128)
|
||||
#include "efm32lg395f128.h"
|
||||
|
||||
#elif defined(EFM32LG395F256)
|
||||
#include "efm32lg395f256.h"
|
||||
|
||||
#elif defined(EFM32LG395F64)
|
||||
#include "efm32lg395f64.h"
|
||||
|
||||
#elif defined(EFM32LG840F128)
|
||||
#include "efm32lg840f128.h"
|
||||
|
||||
#elif defined(EFM32LG840F256)
|
||||
#include "efm32lg840f256.h"
|
||||
|
||||
#elif defined(EFM32LG840F64)
|
||||
#include "efm32lg840f64.h"
|
||||
|
||||
#elif defined(EFM32LG842F128)
|
||||
#include "efm32lg842f128.h"
|
||||
|
||||
#elif defined(EFM32LG842F256)
|
||||
#include "efm32lg842f256.h"
|
||||
|
||||
#elif defined(EFM32LG842F64)
|
||||
#include "efm32lg842f64.h"
|
||||
|
||||
#elif defined(EFM32LG880F128)
|
||||
#include "efm32lg880f128.h"
|
||||
|
||||
#elif defined(EFM32LG880F256)
|
||||
#include "efm32lg880f256.h"
|
||||
|
||||
#elif defined(EFM32LG880F64)
|
||||
#include "efm32lg880f64.h"
|
||||
|
||||
#elif defined(EFM32LG890F128)
|
||||
#include "efm32lg890f128.h"
|
||||
|
||||
#elif defined(EFM32LG890F256)
|
||||
#include "efm32lg890f256.h"
|
||||
|
||||
#elif defined(EFM32LG890F64)
|
||||
#include "efm32lg890f64.h"
|
||||
|
||||
#elif defined(EFM32LG895F128)
|
||||
#include "efm32lg895f128.h"
|
||||
|
||||
#elif defined(EFM32LG895F256)
|
||||
#include "efm32lg895f256.h"
|
||||
|
||||
#elif defined(EFM32LG895F64)
|
||||
#include "efm32lg895f64.h"
|
||||
|
||||
#elif defined(EFM32LG940F128)
|
||||
#include "efm32lg940f128.h"
|
||||
|
||||
#elif defined(EFM32LG940F256)
|
||||
#include "efm32lg940f256.h"
|
||||
|
||||
#elif defined(EFM32LG940F64)
|
||||
#include "efm32lg940f64.h"
|
||||
|
||||
#elif defined(EFM32LG942F128)
|
||||
#include "efm32lg942f128.h"
|
||||
|
||||
#elif defined(EFM32LG942F256)
|
||||
#include "efm32lg942f256.h"
|
||||
|
||||
#elif defined(EFM32LG942F64)
|
||||
#include "efm32lg942f64.h"
|
||||
|
||||
#elif defined(EFM32LG980F128)
|
||||
#include "efm32lg980f128.h"
|
||||
|
||||
#elif defined(EFM32LG980F256)
|
||||
#include "efm32lg980f256.h"
|
||||
|
||||
#elif defined(EFM32LG980F64)
|
||||
#include "efm32lg980f64.h"
|
||||
|
||||
#elif defined(EFM32LG990F128)
|
||||
#include "efm32lg990f128.h"
|
||||
|
||||
#elif defined(EFM32LG990F256)
|
||||
#include "efm32lg990f256.h"
|
||||
|
||||
#elif defined(EFM32LG990F64)
|
||||
#include "efm32lg990f64.h"
|
||||
|
||||
#elif defined(EFM32LG995F128)
|
||||
#include "efm32lg995f128.h"
|
||||
|
||||
#elif defined(EFM32LG995F256)
|
||||
#include "efm32lg995f256.h"
|
||||
|
||||
#elif defined(EFM32LG995F64)
|
||||
#include "efm32lg995f64.h"
|
||||
|
||||
#elif defined(EFM32TG108F16)
|
||||
#include "efm32tg108f16.h"
|
||||
|
||||
#elif defined(EFM32TG108F32)
|
||||
#include "efm32tg108f32.h"
|
||||
|
||||
#elif defined(EFM32TG108F4)
|
||||
#include "efm32tg108f4.h"
|
||||
|
||||
#elif defined(EFM32TG108F8)
|
||||
#include "efm32tg108f8.h"
|
||||
|
||||
#elif defined(EFM32TG110F16)
|
||||
#include "efm32tg110f16.h"
|
||||
|
||||
#elif defined(EFM32TG110F32)
|
||||
#include "efm32tg110f32.h"
|
||||
|
||||
#elif defined(EFM32TG110F4)
|
||||
#include "efm32tg110f4.h"
|
||||
|
||||
#elif defined(EFM32TG110F8)
|
||||
#include "efm32tg110f8.h"
|
||||
|
||||
#elif defined(EFM32TG210F16)
|
||||
#include "efm32tg210f16.h"
|
||||
|
||||
#elif defined(EFM32TG210F32)
|
||||
#include "efm32tg210f32.h"
|
||||
|
||||
#elif defined(EFM32TG210F8)
|
||||
#include "efm32tg210f8.h"
|
||||
|
||||
#elif defined(EFM32TG222F16)
|
||||
#include "efm32tg222f16.h"
|
||||
|
||||
#elif defined(EFM32TG222F32)
|
||||
#include "efm32tg222f32.h"
|
||||
|
||||
#elif defined(EFM32TG222F8)
|
||||
#include "efm32tg222f8.h"
|
||||
|
||||
#elif defined(EFM32TG230F16)
|
||||
#include "efm32tg230f16.h"
|
||||
|
||||
#elif defined(EFM32TG230F32)
|
||||
#include "efm32tg230f32.h"
|
||||
|
||||
#elif defined(EFM32TG230F8)
|
||||
#include "efm32tg230f8.h"
|
||||
|
||||
#elif defined(EFM32TG232F16)
|
||||
#include "efm32tg232f16.h"
|
||||
|
||||
#elif defined(EFM32TG232F32)
|
||||
#include "efm32tg232f32.h"
|
||||
|
||||
#elif defined(EFM32TG232F8)
|
||||
#include "efm32tg232f8.h"
|
||||
|
||||
#elif defined(EFM32TG822F16)
|
||||
#include "efm32tg822f16.h"
|
||||
|
||||
#elif defined(EFM32TG822F32)
|
||||
#include "efm32tg822f32.h"
|
||||
|
||||
#elif defined(EFM32TG822F8)
|
||||
#include "efm32tg822f8.h"
|
||||
|
||||
#elif defined(EFM32TG840F16)
|
||||
#include "efm32tg840f16.h"
|
||||
|
||||
#elif defined(EFM32TG840F32)
|
||||
#include "efm32tg840f32.h"
|
||||
|
||||
#elif defined(EFM32TG840F8)
|
||||
#include "efm32tg840f8.h"
|
||||
|
||||
#elif defined(EFM32TG842F16)
|
||||
#include "efm32tg842f16.h"
|
||||
|
||||
#elif defined(EFM32TG842F32)
|
||||
#include "efm32tg842f32.h"
|
||||
|
||||
#elif defined(EFM32TG842F8)
|
||||
#include "efm32tg842f8.h"
|
||||
|
||||
|
||||
#else
|
||||
#error "efm32.h: PART NUMBER undefined"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,369 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief CMSIS Cortex-M3 Peripheral Access Layer for EFM32 devices.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "efm32.h"
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** LFRCO frequency, tuned to below frequency during manufacturing. */
|
||||
#define EFM32_LFRCO_FREQ (32768UL)
|
||||
#define EFM32_ULFRCO_FREQ (1000UL)
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/* System oscillator frequencies. These frequencies are normally constant */
|
||||
/* for a target, but they are made configurable in order to allow run-time */
|
||||
/* handling of different boards. The crystal oscillator clocks can be set */
|
||||
/* compile time to a non-default value by defining respective EFM32_nFXO_FREQ */
|
||||
/* values according to board design. By defining the EFM32_nFXO_FREQ to 0, */
|
||||
/* one indicates that the oscillator is not present, in order to save some */
|
||||
/* SW footprint. */
|
||||
|
||||
#ifndef EFM32_HFXO_FREQ
|
||||
#ifdef _EFM32_GIANT_FAMILY
|
||||
#define EFM32_HFXO_FREQ (48000000UL)
|
||||
#else
|
||||
#define EFM32_HFXO_FREQ (32000000UL)
|
||||
#endif
|
||||
#endif
|
||||
/* Do not define variable if HF crystal oscillator not present */
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
/** System HFXO clock. */
|
||||
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
|
||||
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
|
||||
#endif
|
||||
|
||||
#ifndef EFM32_LFXO_FREQ
|
||||
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
|
||||
#endif
|
||||
/* Do not define variable if LF crystal oscillator not present */
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
/** System LFXO clock. */
|
||||
static uint32_t SystemLFXOClock = EFM32_LFXO_FREQ;
|
||||
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL VARIABLES *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* System System Clock Frequency (Core Clock).
|
||||
*
|
||||
* @details
|
||||
* Required CMSIS global variable that must be kept up-to-date.
|
||||
*/
|
||||
uint32_t SystemCoreClock;
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the current core clock frequency.
|
||||
*
|
||||
* @details
|
||||
* Calculate and get the current core clock frequency based on the current
|
||||
* configuration. Assuming that the SystemCoreClock global variable is
|
||||
* maintained, the core clock frequency is stored in that variable as well.
|
||||
* This function will however calculate the core clock based on actual HW
|
||||
* configuration. It will also update the SystemCoreClock global variable.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* The current core clock frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t SystemCoreClockGet(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
ret = SystemHFClockGet();
|
||||
#if defined (_EFM32_GIANT_FAMILY)
|
||||
/* Leopard/Giant Gecko has an additional divider */
|
||||
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)>>_CMU_CTRL_HFCLKDIV_SHIFT));
|
||||
#endif
|
||||
ret >>= (CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
|
||||
_CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT;
|
||||
|
||||
/* Keep CMSIS variable up-to-date just in case */
|
||||
SystemCoreClock = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the current HFCLK frequency.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* The current HFCLK frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t SystemHFClockGet(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL |
|
||||
CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL))
|
||||
{
|
||||
case CMU_STATUS_LFXOSEL:
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
ret = SystemLFXOClock;
|
||||
#else
|
||||
/* We should not get here, since core should not be clocked. May */
|
||||
/* be caused by a misconfiguration though. */
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CMU_STATUS_LFRCOSEL:
|
||||
ret = EFM32_LFRCO_FREQ;
|
||||
break;
|
||||
|
||||
case CMU_STATUS_HFXOSEL:
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
ret = SystemHFXOClock;
|
||||
#else
|
||||
/* We should not get here, since core should not be clocked. May */
|
||||
/* be caused by a misconfiguration though. */
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default: /* CMU_STATUS_HFRCOSEL */
|
||||
switch (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)
|
||||
{
|
||||
case CMU_HFRCOCTRL_BAND_28MHZ:
|
||||
ret = 28000000;
|
||||
break;
|
||||
|
||||
case CMU_HFRCOCTRL_BAND_21MHZ:
|
||||
ret = 21000000;
|
||||
break;
|
||||
|
||||
case CMU_HFRCOCTRL_BAND_14MHZ:
|
||||
ret = 14000000;
|
||||
break;
|
||||
|
||||
case CMU_HFRCOCTRL_BAND_11MHZ:
|
||||
ret = 11000000;
|
||||
break;
|
||||
|
||||
case CMU_HFRCOCTRL_BAND_7MHZ:
|
||||
ret = 7000000;
|
||||
break;
|
||||
|
||||
case CMU_HFRCOCTRL_BAND_1MHZ:
|
||||
ret = 1000000;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get high frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* HFXO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemHFXOClockGet(void)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
return SystemHFXOClock;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set high frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This function is mainly provided for being able to handle target systems
|
||||
* with different HF crystal oscillator frequencies run-time. If used, it
|
||||
* should probably only be used once during system startup.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @param[in] freq
|
||||
* HFXO frequency in Hz used for target.
|
||||
*****************************************************************************/
|
||||
void SystemHFXOClockSet(uint32_t freq)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
SystemHFXOClock = freq;
|
||||
|
||||
/* Update core clock frequency if HFXO is used to clock core */
|
||||
if (CMU->STATUS & CMU_STATUS_HFXOSEL)
|
||||
{
|
||||
/* The function will update the global variable */
|
||||
SystemCoreClockGet();
|
||||
}
|
||||
#else
|
||||
(void)freq; /* Unused parameter */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the system.
|
||||
*
|
||||
* @details
|
||||
* Do required generic HW system init.
|
||||
*
|
||||
* @note
|
||||
* This function is invoked during system init, before the main() routine
|
||||
* and any data has been initialized. For this reason, it cannot do any
|
||||
* initialization of variables etc.
|
||||
*****************************************************************************/
|
||||
void SystemInit(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get low frequency RC oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* LFRCO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemLFRCOClockGet(void)
|
||||
{
|
||||
/* Currently we assume that this frequency is properly tuned during */
|
||||
/* manufacturing and is not changed after reset. If future requirements */
|
||||
/* for re-tuning by user, we can add support for that. */
|
||||
return EFM32_LFRCO_FREQ;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get ultra low frequency RC oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* ULFRCO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemULFRCOClockGet(void)
|
||||
{
|
||||
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
|
||||
return EFM32_ULFRCO_FREQ;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get low frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* LFXO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemLFXOClockGet(void)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
return SystemLFXOClock;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set low frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This function is mainly provided for being able to handle target systems
|
||||
* with different HF crystal oscillator frequencies run-time. If used, it
|
||||
* should probably only be used once during system startup.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @param[in] freq
|
||||
* LFXO frequency in Hz used for target.
|
||||
*****************************************************************************/
|
||||
void SystemLFXOClockSet(uint32_t freq)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
SystemLFXOClock = freq;
|
||||
|
||||
/* Update core clock frequency if LFXO is used to clock core */
|
||||
if (CMU->STATUS & CMU_STATUS_LFXOSEL)
|
||||
{
|
||||
/* The function will update the global variable */
|
||||
SystemCoreClockGet();
|
||||
}
|
||||
#else
|
||||
(void)freq; /* Unused parameter */
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief CMSIS Cortex-M3 Peripheral Access Layer for EFM32 devices.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __SYSTEM_EFM32_H
|
||||
#define __SYSTEM_EFM32_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL VARIABLES *******************************
|
||||
******************************************************************************/
|
||||
|
||||
extern uint32_t SystemCoreClock; /**< System Clock Frequency (Core Clock) */
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/* Interrupt routines - prototypes */
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
void Reset_Handler(void);
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void MemManage_Handler(void);
|
||||
void BusFault_Handler(void);
|
||||
void UsageFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void DMA_IRQHandler(void);
|
||||
void GPIO_EVEN_IRQHandler(void);
|
||||
void TIMER0_IRQHandler(void);
|
||||
void USART0_RX_IRQHandler(void);
|
||||
void USART0_TX_IRQHandler(void);
|
||||
void ACMP0_IRQHandler(void);
|
||||
void ADC0_IRQHandler(void);
|
||||
void DAC0_IRQHandler(void);
|
||||
void I2C0_IRQHandler(void);
|
||||
void GPIO_ODD_IRQHandler(void);
|
||||
void TIMER1_IRQHandler(void);
|
||||
void TIMER2_IRQHandler(void);
|
||||
void USART1_RX_IRQHandler(void);
|
||||
void USART1_TX_IRQHandler(void);
|
||||
void USART2_RX_IRQHandler(void);
|
||||
void USART2_TX_IRQHandler(void);
|
||||
void UART0_RX_IRQHandler(void);
|
||||
void UART0_TX_IRQHandler(void);
|
||||
void LEUART0_IRQHandler(void);
|
||||
void LEUART1_IRQHandler(void);
|
||||
void LETIMER0_IRQHandler(void);
|
||||
void PCNT0_IRQHandler(void);
|
||||
void PCNT1_IRQHandler(void);
|
||||
void PCNT2_IRQHandler(void);
|
||||
void RTC_IRQHandler(void);
|
||||
void CMU_IRQHandler(void);
|
||||
void VCMP_IRQHandler(void);
|
||||
void LCD_IRQHandler(void);
|
||||
void MSC_IRQHandler(void);
|
||||
void AES_IRQHandler(void);
|
||||
#endif
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY)
|
||||
void Reset_Handler(void);
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void MemManage_Handler(void);
|
||||
void BusFault_Handler(void);
|
||||
void UsageFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void DMA_IRQHandler(void);
|
||||
void GPIO_EVEN_IRQHandler(void);
|
||||
void TIMER0_IRQHandler(void);
|
||||
void USART0_RX_IRQHandler(void);
|
||||
void USART0_TX_IRQHandler(void);
|
||||
void ACMP0_IRQHandler(void);
|
||||
void ADC0_IRQHandler(void);
|
||||
void DAC0_IRQHandler(void);
|
||||
void I2C0_IRQHandler(void);
|
||||
void GPIO_ODD_IRQHandler(void);
|
||||
void TIMER1_IRQHandler(void);
|
||||
void USART1_RX_IRQHandler(void);
|
||||
void USART1_TX_IRQHandler(void);
|
||||
void LESENSE_IRQHandler(void);
|
||||
void LEUART0_IRQHandler(void);
|
||||
void LETIMER0_IRQHandler(void);
|
||||
void PCNT0_IRQHandler(void);
|
||||
void RTC_IRQHandler(void);
|
||||
void CMU_IRQHandler(void);
|
||||
void VCMP_IRQHandler(void);
|
||||
void LCD_IRQHandler(void);
|
||||
void MSC_IRQHandler(void);
|
||||
void AES_IRQHandler(void);
|
||||
#endif
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
void Reset_Handler(void);
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void MemManage_Handler(void);
|
||||
void BusFault_Handler(void);
|
||||
void UsageFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void DMA_IRQHandler(void);
|
||||
void GPIO_EVEN_IRQHandler(void);
|
||||
void TIMER0_IRQHandler(void);
|
||||
void USART0_RX_IRQHandler(void);
|
||||
void USART0_TX_IRQHandler(void);
|
||||
void USB_IRQHandler(void);
|
||||
void ACMP0_IRQHandler(void);
|
||||
void ADC0_IRQHandler(void);
|
||||
void DAC0_IRQHandler(void);
|
||||
void I2C0_IRQHandler(void);
|
||||
void I2C1_IRQHandler(void);
|
||||
void GPIO_ODD_IRQHandler(void);
|
||||
void TIMER1_IRQHandler(void);
|
||||
void TIMER2_IRQHandler(void);
|
||||
void TIMER3_IRQHandler(void);
|
||||
void USART1_RX_IRQHandler(void);
|
||||
void USART1_TX_IRQHandler(void);
|
||||
void LESENSE_IRQHandler(void);
|
||||
void USART2_RX_IRQHandler(void);
|
||||
void USART2_TX_IRQHandler(void);
|
||||
void UART0_RX_IRQHandler(void);
|
||||
void UART0_TX_IRQHandler(void);
|
||||
void UART1_RX_IRQHandler(void);
|
||||
void UART1_TX_IRQHandler(void);
|
||||
void LEUART0_IRQHandler(void);
|
||||
void LEUART1_IRQHandler(void);
|
||||
void LETIMER0_IRQHandler(void);
|
||||
void PCNT0_IRQHandler(void);
|
||||
void PCNT1_IRQHandler(void);
|
||||
void PCNT2_IRQHandler(void);
|
||||
void RTC_IRQHandler(void);
|
||||
void BURTC_IRQHandler(void);
|
||||
void CMU_IRQHandler(void);
|
||||
void VCMP_IRQHandler(void);
|
||||
void LCD_IRQHandler(void);
|
||||
void MSC_IRQHandler(void);
|
||||
void AES_IRQHandler(void);
|
||||
void EBI_IRQHandler(void);
|
||||
void EMU_IRQHandler(void);
|
||||
#endif
|
||||
|
||||
uint32_t SystemCoreClockGet(void);
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Update CMSIS SystemCoreClock variable.
|
||||
*
|
||||
* @details
|
||||
* CMSIS defines a global variable SystemCoreClock that shall hold the
|
||||
* core frequency in Hz. If the core frequency is dynamically changed, the
|
||||
* variable must be kept updated in order to be CMSIS compliant.
|
||||
*
|
||||
* Notice that if only changing core clock frequency through the EFM32 CMU
|
||||
* API, this variable will be kept updated. This function is only provided
|
||||
* for CMSIS compliance and if a user modifies the the core clock outside
|
||||
* the CMU API.
|
||||
*****************************************************************************/
|
||||
static __INLINE void SystemCoreClockUpdate(void)
|
||||
{
|
||||
SystemCoreClockGet();
|
||||
}
|
||||
|
||||
void SystemInit(void);
|
||||
|
||||
uint32_t SystemHFClockGet(void);
|
||||
uint32_t SystemHFXOClockGet(void);
|
||||
void SystemHFXOClockSet(uint32_t freq);
|
||||
uint32_t SystemLFRCOClockGet(void);
|
||||
uint32_t SystemULFRCOClockGet(void);
|
||||
uint32_t SystemLFXOClockGet(void);
|
||||
void SystemLFXOClockSet(uint32_t freq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_EFM32_H */
|
Binary file not shown.
|
@ -0,0 +1,154 @@
|
|||
================ Revision history ============================================
|
||||
2.3.2:
|
||||
- Fixed IAR startup files, corrected alignment of interrupt vector table
|
||||
- Updated efm32usb library with fixes
|
||||
- Updated efm32lib with new Tiny Gecko and Giant Gecko features
|
||||
|
||||
2.3.0:
|
||||
- Added DEVICE_FAMILY defines to identify Gecko/Tiny/Leopard/Giant parts
|
||||
- Fixed missing EMU_IRQ definitions in Leopard Gecko startup files
|
||||
- Added USART location to Tiny Gecko parts
|
||||
- Added LEUART locations to Tiny Gecko parts
|
||||
- Updated efm32lib with new Giant Gecko features (see separate readme)
|
||||
- Updated efm32usb with USB Host stack support (see separate readme)
|
||||
|
||||
2.2.2:
|
||||
- Removed huge AF_PORT, AF_PIN macros from header files, only peripheral
|
||||
specific alternate function defines are included
|
||||
- Updated efm32usb library with fixes
|
||||
- Updated efm32lib library with fixes
|
||||
|
||||
2.2.1:
|
||||
- Added interleave to all Giant Gecko parts
|
||||
- Updated efm32lib with more Giant Gecko features
|
||||
- Added efm32usb, USB Device stack for Giant Gecko USB parts
|
||||
- Added LOCATION defines for all I2C alternate locations on Tiny Gecko
|
||||
|
||||
2.1.1:
|
||||
- Added header files for Giant Gecko and Leopard Gecko devices
|
||||
- Minor fix for Gecko devices, EMU_CTRL_MASK was wrong
|
||||
- Fix for linker issue alignment of .data section in codesourcery .ld files
|
||||
|
||||
2.0.1:
|
||||
- DAC_OPAnMUX_POSSEL_OPAnIN changed to DAC_OPAnMUX_POSSEL_OPAnINP for Tiny
|
||||
Gecko
|
||||
- Added CMU_ROUTE_LOCATION, LOC2 for Tiny Gecko
|
||||
- PRS #define fixes, remove extra IRDA fields only available on USART0
|
||||
|
||||
2.0.0:
|
||||
- This release based on CMSIS_2_00, includes DSP_Lib (for Keil MDKARM, IAR has
|
||||
a port included with EWARM)
|
||||
- Removed "shadow" example that used to be in CMSIS directory earlier, use
|
||||
"blink" from board examples as starting point instead
|
||||
- Restructured header files to comply with CMSIS_2_00
|
||||
- CMU_CALCTRL_REFSEL is renamed to CMU_CALCTRL_UPSEL to match reference
|
||||
manual and clearify new DOWNSEL calibrartion features for Tiny Gecko
|
||||
- Added header files for new package types for Gecko devices
|
||||
- Added header files for Tiny Gecko devices
|
||||
|
||||
1.3.0:
|
||||
- DMA register WAITSTATUS changed to CHWAITSTATUS for consistency
|
||||
DMA test req/sreq registers added, CHSREQSTATUS and CHREQSTATUS
|
||||
- IFS and IFC interrupt registers are now marked as readable for several
|
||||
peripherals
|
||||
- TIMER, CCC renamed to CDTI
|
||||
- TIMER, QEM has been renamed to QDM
|
||||
- AF_DBG_SWV/TCLK/TDIO renamed to more commonly used AF_DBG_SWD/SWDIO/SWDCLK
|
||||
- AF_EBI_ADDRDAT renamed to AF_EBI_AD
|
||||
- Removed bit fields for extra LCD segment registers for Gecko parts
|
||||
- Fixed LCD_SEGEN_MASK, bit width was too narrow in version 1.2.x
|
||||
- Fixed LCD_SYNCBUSY bit fields
|
||||
- CMU_PCNTCTRL reset values corrected
|
||||
- PCNT_TOP and PCNT_TOPB reset values corrected
|
||||
- ADC_LPFMODE_RCFILT and LPFMOD_DECAP definitions corrected (they were
|
||||
reversed)
|
||||
- USART_RXDATAFULLRIGHT and USART_RXDATAVRIGHT removed for Gecko parts
|
||||
- GPIO, renamed INSENSE_PRSSENSE to INSENSE_PRS, similar for INT
|
||||
to be consistent with updated documentation (Reference Manual)
|
||||
|
||||
1.2.1:
|
||||
- Fixed DEVINFO calibration shift and mask value for temperature sensor
|
||||
fixed in rev.C Gecko devices
|
||||
|
||||
1.2.0:
|
||||
- Added new subgroup "Parts" for all part definitions in doxygen format
|
||||
- Removed unused _PARAM_ type definitions, less clutter in header files
|
||||
- _CMU_PCNTCTRL_RESETVALUE corrected
|
||||
- Added C startup file for IAR, can be used as replacement for assembly file
|
||||
- Use #defines instead of "numeric values reentered" in bit field definitions
|
||||
- TIMER_PARAM_CCNUM(i) changed to TIMER_PARAM_CC_NUM(i)
|
||||
- DPI_CHAN_COUNT changed to PRS_CHAN_COUNT
|
||||
|
||||
1.1.4:
|
||||
- TIMER_INIT_DEFAULT fix to efm32lib
|
||||
|
||||
1.1.3:
|
||||
- Removed ADC ROUTE register
|
||||
- Renamed DEVINFO DACCAL -> DAC0CAL for all 3 calibration registers and bit
|
||||
fields
|
||||
- Updated efm32lib with new peripherals
|
||||
|
||||
1.1.2:
|
||||
- Added support for CodeSourcery Sourcery G++ compiler and startup files
|
||||
- Device Information page (DEVINFO_TypeDef) - fixed several issues with
|
||||
endianness, and other changes to support test revision 4 and above parts.
|
||||
This has led to a small incompatibilty with test rev <= 4 and rev A parts,
|
||||
in that the flash and sram size bit fields has changed location.
|
||||
- DMA_CONTROL_TypeDef changed name to DMA_DESCRIPTOR_TypeDef to be better
|
||||
aligned with PL230 manual and code
|
||||
- DMA bit fields not supported on EFM32 was removed for the PL230 controller
|
||||
- DMA CTRL bit fields renamed to be more consistent with PL230 TRM manual
|
||||
- Added additional volatile statements to pointers in DMA Control structure
|
||||
- Fixed several registers that were readable, and was marked as __O (output
|
||||
only)
|
||||
|
||||
1.1.1:
|
||||
- Fixed startup code, CMSIS SystemInit cannot update global variable
|
||||
|
||||
1.1.0:
|
||||
- Note - some register bit field updates in this release are _not_ backward
|
||||
compatible
|
||||
- Updated register bit fields to comply with documentation updates, i.e.
|
||||
reference manual version > 0.83
|
||||
- Apply patch to CMSIS core for GCC issues
|
||||
- Added DMA_CONTROL_TypeDef control block for PrimeCell PL230 DMA controller
|
||||
- Added ROMTABLE PID / CHIP revision table and masks
|
||||
- Revised and updated Device Information page structure "DEVINFO page"
|
||||
This structure is ONLY valid for rev.B production devices
|
||||
- GPIO EXTIPSEL bit field marked "16" changed to 15 (bug correction)
|
||||
- Added more bit fields to TIMER_ROUTE registers
|
||||
- Cosmetic updates in doxygen comments and copyright statements
|
||||
|
||||
1.0.4:
|
||||
- ACMP INPUTSEL bit fields changed from ohm rating to res-n,
|
||||
- Added bit-band base addresses for peripherals and sram
|
||||
|
||||
1.0.3:
|
||||
- ADC SCANMODE and SCANCTRL bit field updates and corrections
|
||||
- Moved Readme.txt and Changes.txt to CMSIS/Readme-EFM32.txt and
|
||||
CMSIS/Changes-EFM32.txt
|
||||
- CCPEN and CDTIPEN splitted in TIMER_ROUTE
|
||||
- EMVREG in EMU_CTRL enumeration changed
|
||||
- LCD DISPCTRL volatage levels are part specific, changed settings changed to
|
||||
reflect this
|
||||
- Added "UL" (unsigned long) to some bit fields giving warnings due to sign
|
||||
conversion
|
||||
|
||||
1.0.2:
|
||||
- Corrected revision numbers in file headers
|
||||
- Removed example code that was moved into BSP/DVK installer package
|
||||
|
||||
1.0.1:
|
||||
- Updated to use official CMSIS1V30 release
|
||||
- Corrected IRQ vector table in assembly startup files, IMEM to MSC,
|
||||
UDMA to DMA
|
||||
- DMA peripheral/signal names corrected
|
||||
- Example Blinky application updated to work on all EFM32 MCU-Modules on DVK
|
||||
- Added "simple" board support package to example
|
||||
- Added "UL" (unsigned long) tag to several fields
|
||||
|
||||
1.0.0:
|
||||
- Initial release
|
||||
- Includes CMSIS1V30 2nd PreRelease
|
||||
- Now requires two include paths, CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32 and
|
||||
CMSIS/CM3/CoreSupport
|
|
@ -0,0 +1,39 @@
|
|||
* -------------------------------------------------------------------
|
||||
* Copyright (C) 2010 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Date: 30 November 2010
|
||||
* Revision: V2.00
|
||||
*
|
||||
* Project: Cortex Microcontroller Software Interface Standard (CMSIS)
|
||||
* Title: Release Note for CMSIS
|
||||
*
|
||||
* -------------------------------------------------------------------
|
||||
|
||||
|
||||
NOTE - Open the index.html file to access CMSIS documentation
|
||||
|
||||
|
||||
The Cortex Microcontroller Software Interface Standard (CMSIS) provides a single standard across all
|
||||
Cortex-Mx processor series vendors. It enables code re-use and code sharing across software projects
|
||||
and reduces time-to-market for new embedded applications.
|
||||
|
||||
CMSIS is released under the terms of the end user license agreement ("CMSIS END USER LICENCE AGREEMENT.pdf").
|
||||
Any user of the software package is bound to the terms and conditions of the end user license agreement.
|
||||
|
||||
|
||||
You will find the following sub-directories:
|
||||
|
||||
CM0 - CMSIS Core Support and Device Support package for Cortex-M0.
|
||||
|
||||
CM3 - CMSIS Core Support and Device Support package for Cortex-M3.
|
||||
|
||||
CM4 - CMSIS Core Support and Device Support package for Cortex-M4.
|
||||
|
||||
Documentation - Contains CMSIS documentation.
|
||||
|
||||
DSP_Lib - MDK project files, Examples and source files etc.. to build the
|
||||
CMSIS DSP Software Library for Cortex-M3 and Cortex-M4 processors.
|
||||
|
||||
Template_DeviceSupport - Template files for CMSIS Device Support package.
|
||||
|
||||
---
|
|
@ -0,0 +1,85 @@
|
|||
================ EFM32 Device Support Library (DSL) ==========================
|
||||
|
||||
This directory ,"CMSIS", contains the Energy Micro Support Library for the
|
||||
EFM32 series of microcontrollers.
|
||||
|
||||
================ About CMSIS =================================================
|
||||
|
||||
The library is based on CMSIS, the Cortex Microcontroller Software Interface
|
||||
Standard, as defined by ARM Inc.
|
||||
|
||||
For more information about CMSIS see
|
||||
http://www.onarm.com
|
||||
http://www.arm.com/products/CPUs/CMSIS.html
|
||||
|
||||
In short, CMSIS tries to provide a common interface for programming devices
|
||||
having one of the Cortex-M core architectures, making code sharing and reuse
|
||||
easier.
|
||||
|
||||
================ Development Environments ====================================
|
||||
|
||||
You will need a development environment which supports the Energy Micro EFM32
|
||||
devices. Currently this is either
|
||||
|
||||
IAR Embedded Workbench for ARM 5.40.6 or later, http://www.iar.com
|
||||
Keil uVision "MDK-ARM" 4.01 or later, http://www.keil.com
|
||||
Rowley CodeSourcery for ARM v2.0.5 or later, see http://www.rowley.co.uk
|
||||
Codesourcery Sourcery G++, see http://www.codesourcery.com
|
||||
|
||||
It is possible to develop with other tools, but for now these are the well
|
||||
supported development environment for Energy Micro example code.
|
||||
|
||||
This library uses C99-types, requires the presence of <stdint.h> and can use
|
||||
other functionality standardized in C99. If your compiler has a C99 compliance
|
||||
toggle, you should enable it for your projects.
|
||||
|
||||
================ File structure ==============================================
|
||||
|
||||
Short getting started guide:
|
||||
|
||||
The quickest way to start is to base your work on one of the simple example
|
||||
projects for the Energy Micro Development or Stareter Kits. These should be
|
||||
easy to port and change to adopt to your needs.
|
||||
|
||||
The board support packages for the various Energy Micro kits comes with a
|
||||
"blink" example, that serves as a good starting point for new projects.
|
||||
|
||||
Please note that you _will_ need to change the "Debugger" and "Flash/Download"
|
||||
configuration settings to fit your environment. See your IDE's manual for
|
||||
details.
|
||||
|
||||
Support for the EFM32 device family is located in the directory
|
||||
CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32
|
||||
|
||||
The most convenient way to start a project, is to define the device target
|
||||
in your compiler options, e.g. add a -DEFM32G890F128 to your compile options
|
||||
if you are targetting an EFM32G890F128 part.
|
||||
|
||||
When this is done, you should include the file "efm32.h" wherever you need
|
||||
register and bit field definitions for the EFM32 peripherals.
|
||||
|
||||
The peripheral registers follow the CMSIS convention of defining a structure
|
||||
which holds the "volatile" registers. Again, take a look at the examples for
|
||||
usage.
|
||||
|
||||
================ Licenses ====================================================
|
||||
|
||||
See the top of each file for SW license. Basically you are free to use the
|
||||
Energy Micro code for any project using EFM32 devices. Part of the CMSIS
|
||||
library is copyrighted by ARM Inc. See "License.doc" for ARM's CMSIS license.
|
||||
|
||||
================ Software updates ============================================
|
||||
|
||||
Energy Micro continually works to provide updated and improved DSL, example
|
||||
code and other software of use for EFM32 customers. Please check the download
|
||||
section of
|
||||
|
||||
http://www.energymicro.com/downloads
|
||||
|
||||
for the latest releases, news and updates.
|
||||
|
||||
(C) Copyright Energy Micro AS, 2011
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
================ Revision history ============================================
|
||||
2.3.2:
|
||||
- Added Tiny Gecko and Giant Gecko support in RMU for new reset causes
|
||||
- CMU_ClockFreqGet will now report correct clock rates if HFLE is set (/4)
|
||||
- Added Giant Gecko specific MSC_MassErase(), erase entire flash
|
||||
- Added Giant Gecko specific MSC_BusStrategy (inline) function
|
||||
- MSC_Init() will now configure TIMEBASE correctly according to AUXHFRCO clock
|
||||
rate for Tiny Gecko and Giant Gecko
|
||||
|
||||
2.3.0:
|
||||
- USART - Added USART_InitPrsTrigger to initialize USART PRS triggered
|
||||
transmissions.
|
||||
- CMU - numerous updates, now supports full clock tree of Giant/Tiny Gecko
|
||||
- CMU_ClockDivSet/Get will now use real dividend and not logarithmic values
|
||||
as earlier. Prior enumerated values have been kept for backward compatibility.
|
||||
- Added support for CMU HFLE and DIV4 factor for core clock for LE
|
||||
peripherals
|
||||
- Added support for alternate LCD segment animation range for Giant Gecko
|
||||
- Fixed bug: Don't enable VCMP low power reference until after warm up,
|
||||
allow biasprog value of 0 in VCMP_Init()
|
||||
- Added support for ALTMAP (256MB address map) in EBI_BankAddress()
|
||||
- TIMER_Init() will now reset CNT value
|
||||
|
||||
2.2.2:
|
||||
- Added DAC0 channel 0 and 1 to ACMP for Tiny and Giant devices
|
||||
- Fixed bug in CMU for MSC WAITSTATE configuration, leading to too high wait
|
||||
states depending on clock rate
|
||||
- Fixed bug in CMU for UART1 clock enable
|
||||
|
||||
2.2.1:
|
||||
- UART_Reset() and LEUART_Reset() will now reset ROUTE register as well, this
|
||||
will mean GPIO pins will not be driven after this call. Take care to ensure
|
||||
that GPIO ROUTE register is configured after calls to *UART_Init*Sync
|
||||
- Fixed problems with EFM_ASSERT when using UART in USART API
|
||||
- Added Giant Gecko support for EBI (new modes and TFT direct drive)
|
||||
- Added Giant Gecko support for CMU 2 WAIT STATES, and I2C1
|
||||
- Added Giant Gecko support for UART1 in CMU
|
||||
- Added Giant Gecko support for DMA LOOP and 2D Copy operations
|
||||
|
||||
2.1.0:
|
||||
- EMU_Restore will now disable HFRCO if it was not enabled when entering
|
||||
an Energy Mode
|
||||
- Run time changes only applies to Gecko devices, filter out Tiny and Giant
|
||||
for CHIP_Init();
|
||||
- Added const specificers to various initialization structures, to ensure
|
||||
they can reside in flash instead of SRAM
|
||||
- Bugfix in efm32_i2c.c, keep returning i2cTransferInProgress until done
|
||||
|
||||
2.0.1:
|
||||
- Changed enum OPAMP_PosSel_TypeDef. Enum value opaPosSelOpaIn changed from
|
||||
DAC_OPA0MUX_POSSEL_OPA1IN to DAC_OPA0MUX_POSSEL_OPA0INP.
|
||||
- Bugfix in efm32_lesense.h, LESENSE_ChClk_TypeDef now contains unshifted
|
||||
values, fixed the implementation in efm32_lesense.c where the bug prevented
|
||||
the sampleClk to be set to AUXHFRCO.
|
||||
|
||||
2.0.0:
|
||||
- USART_Init-functions now calls USART_Reset() which will also disable/reset
|
||||
interrupt
|
||||
- USART_BaudrateSyncSet() now asserts on invalid oversample configuration
|
||||
- Added initialization of parity bit in LEUART_Init()
|
||||
- Added Tiny Gecko support for CMU, ULFRCO, LESENSE clocks and continuous
|
||||
calibration
|
||||
- Added Tiny Gecko support for GPIO, EM4 pin retention and wake up support
|
||||
- Added Tiny Gecko support for I2S, SPI auto TX mode on USART
|
||||
- Added Tiny Gecko support for CACHE mesasurements for MSC module
|
||||
- Added Tiny Gecko support for LCD module (with no HIGH segment registers)
|
||||
- Added Tiny Gecko support for TIMER, PWM 2x, (DT lock not supported)
|
||||
- Added Tiny Gecko support for LESENSE module
|
||||
- Added Tiny Gecko support for PRS input in PCNT
|
||||
- Added Tiny Gecko support for async signals in PRS, PRS_SourceAsyncSignalSet()
|
||||
- Initial support for some Giant Gecko features, where overlapping with Tiny
|
||||
- Removed LPFEN / LPFREQ support from DAC
|
||||
- Fixed comments around interrupt functions, making it clear it is bitwise
|
||||
logical or interrupt flags
|
||||
- Fixed PCNT initialization for external clock configurations, making sure
|
||||
config is synchronized at startup to 3 clocks. Note fix only works for
|
||||
>revC EFM32G devices.
|
||||
- Fixed efm32_cmu.c, EFM_ASSERT statement for LEUART clock div logic was
|
||||
inverted
|
||||
- Fixed ADC_InitScan, PRSSEL shift value corrected
|
||||
- Fixed CMU_ClockFreqGet for devices that do not have I2C
|
||||
- Fixed I2C_TransferInit for devices with more than one I2C-bus (Giant Gecko)
|
||||
- Changed ACMP_Disable() implementation, now only disables the ACMP instance
|
||||
by clearing the EN bit in the CTRL register
|
||||
- Removed ACMP_DisableNoReset() function
|
||||
- Fixed ACMP_Init(), removed automatic enabling, added new structure member
|
||||
"enaReq" for ACMP_Init_TypeDef to control, fixed the EFM_ASSERT of the
|
||||
biasprog parameter
|
||||
- Added default configuration macro ACMP_INIT_DEFAULT for ACMP_Init_TypeDef
|
||||
- Fixed ACMP_CapsenseInit(), removed automatic enabling, added new structure member
|
||||
"enaReq" for ACMP_CapsenseInit_TypeDef to control, fixed the EFM_ASSERT of
|
||||
the biasprog parameter
|
||||
- Changed the name of the default configuration macro for
|
||||
ACMP_CapsenseInit_TypeDef to ACMP_CAPSENSE_INIT_DEFAULT
|
||||
- Added RTC_Reset and RTC_CounterReset functions for RTC
|
||||
|
||||
1.3.0:
|
||||
- MSC is automatically enabled/disabled when using the MSC API. This saves
|
||||
power, and reduces errors due to not calling MSC_Init().
|
||||
- Added API for controlling Cortex-M3 MPU (memory protection unit)
|
||||
- Adjusted bit fields to comply with latest CMSIS release, see EFM_CMSIS
|
||||
changes file for details
|
||||
- Fixed issue with bit mask clearing in ACMP
|
||||
- Functions ACMP_Enable and ACMP_DisableNoReset added
|
||||
- Added comment about rev.C chips in PCNT, CMD_LTOPBIM not neccessary any more
|
||||
- Added missing instance validity asserts to peripherals (ACMP, LEUART, USART)
|
||||
- Fixed UART0 check in CMU_ClockFreqGet()
|
||||
- Fixed command sync for PCNT before setting TOPB value during init
|
||||
- Fixed instance validity check macro in PCNT
|
||||
- Fixed TIMER_Reset() removed write to unimplemented timer channel registers
|
||||
- Fixed EFM_ASSERT statements in ACMP, VCMP
|
||||
- General code style update: added missing curly braces, default cases, etc.
|
||||
|
||||
1.2.1:
|
||||
- Feature complete efm32lib, now also includes peripheral API for modules
|
||||
AES,PCNT,MSC,ACMP,VCMP,LCD,EBI
|
||||
- Fixed _TIMER_CC_CTRL_ICEDGE flags for correct timer configuration
|
||||
- Fixed ADC calibration of Single and Scan mode of operation
|
||||
- Added PCNT (ChipRev A/B PCNT0 errata NOT supported) and AES support
|
||||
- Fixed conditional inclusion in efm32_emu.h
|
||||
- Fixed code for LEUART0 for devices with multiple LEUARTs.
|
||||
- Fixed incorrect setting of DOUT for GPIO configuration
|
||||
|
||||
1.1.4
|
||||
- Fix for TIMER_INIT_DEFAULT
|
||||
|
||||
1.1.3:
|
||||
- Added ADC, DAC, LETIMER, PRS, TIMER (except DTI) support
|
||||
- Added utility for fetching chip revision (efm32_system.c/h)
|
||||
- Removed RTC instance ref in API, only one RTC will be supported
|
||||
(Affects also define in efm32_cmu.h)
|
||||
- Added default init struct macros for LEUART, USART
|
||||
- Added msbf parameter in USART synchronous init struct, USART_InitSync_TypeDef.
|
||||
- Updated reset for I2C, USART, LEUART to also reset IEN register.
|
||||
- Corrected fault in GPIO_PortOutSet()
|
||||
|
||||
1.1.2:
|
||||
- Corrected minor issues in EMU, EM3 mode when restoring clocks
|
||||
- Corrected RMU reset cause checking
|
||||
- Changed GPIO enumerator symbols to start with gpio (from GPIO_)
|
||||
- Changed CMU and WDOG enum typedefs to start with CMU_/WDOG_ (from cmu/wdog)
|
||||
- Added USART/UART, LEUART, DMA, I2C support
|
||||
|
||||
1.1.1:
|
||||
- First version including support for CMU, DBG, EMU, GPIO, RTC, WDOG
|
|
@ -0,0 +1,75 @@
|
|||
================ EFM32 Peripheral Library ===================================
|
||||
|
||||
This directory, "efm32lib", contains the Energy Micro Peripheral Support
|
||||
library for the EFM32 series of microcontrollers.
|
||||
|
||||
The "efm32lib" SW is designed to support EFM32 Gecko rev B and later versions.
|
||||
The following known caveats exists for rev A devices:
|
||||
|
||||
- CMU: HFRCO band tuning values are not correctly set for rev A.
|
||||
- EMU: Errata "Peripheral clocks not gated in EM2/EM3 with debug session
|
||||
active" has not been implemented with SW workaround for rev A.
|
||||
|
||||
Some design guidelines for this library:
|
||||
|
||||
* Follow the guidelines established by ARM's and Energy Micro's adaptation
|
||||
of the CMSIS (see below) standard
|
||||
|
||||
* Be usable as a starting point for developing richer, more target specific
|
||||
functionality (i.e. copy and modify further)
|
||||
|
||||
* Ability to be used as a standalone software component, used by other drivers
|
||||
that should cover "the most common cases"
|
||||
|
||||
* Readability of the code and usability preferred before optimization for speed
|
||||
and size or covering a particular "narrow" purpose
|
||||
|
||||
* As little "cross-dependency" between modules as possible, to enable users to
|
||||
pick and choose what they want
|
||||
|
||||
================ About CMSIS ================================================
|
||||
|
||||
These APIs are based on EFM32_CMSIS, the Cortex Microcontroller Software
|
||||
Interface Standard support headers, as supplied by Energy Micro AS.
|
||||
|
||||
As a result of this, the library requires basic C99-support. You might have
|
||||
to enable C99 support in your compiler. Comments are in doxygen compatible
|
||||
format.
|
||||
|
||||
The EFM32_CMSIS library contains all peripheral module registers and bit field
|
||||
descriptors.
|
||||
|
||||
To download EFM32_CMSIS, go to
|
||||
http://www.energymicro.com/downloads
|
||||
|
||||
For more information about CMSIS see
|
||||
http://www.onarm.com
|
||||
http://www.arm.com/products/CPUs/CMSIS.html
|
||||
|
||||
The requirements for using CMSIS also apply to this package.
|
||||
|
||||
================ File structure ==============================================
|
||||
|
||||
inc/ - header files
|
||||
src/ - source files
|
||||
|
||||
================ Licenses ====================================================
|
||||
|
||||
See the top of each file for SW license. Basically you are free to use the
|
||||
Energy Micro code for any project using EFM32 devices. Parts of the CMSIS
|
||||
library is copyrighted by ARM Inc. See "License.doc" for ARM's CMSIS license.
|
||||
|
||||
================ Software updates ============================================
|
||||
|
||||
Energy Micro continually works to provide updated and improved efm32lib,
|
||||
example code and other software of use for EFM32 customers. Please check the
|
||||
download section of Energy Micro's web site at
|
||||
|
||||
http://www.energymicro.com/downloads
|
||||
|
||||
for the latest releases, news and updates. If you download and install the
|
||||
Simplicity Studio application, you will be notified about updates when
|
||||
available.
|
||||
|
||||
|
||||
(C) Copyright Energy Micro AS, 2011
|
|
@ -0,0 +1,395 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Analog Comparator (ACMP) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_ACMP_H
|
||||
#define __EFM32_ACMP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup ACMP
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Resistor values used for capacative sense. See the datasheet for your
|
||||
* device for details on each resistor value. */
|
||||
typedef enum
|
||||
{
|
||||
/** resistor value 0 */
|
||||
acmpResistor0 = _ACMP_INPUTSEL_CSRESSEL_RES0,
|
||||
/** resistor value 1 */
|
||||
acmpResistor1 = _ACMP_INPUTSEL_CSRESSEL_RES1,
|
||||
/** resistor value 2 */
|
||||
acmpResistor2 = _ACMP_INPUTSEL_CSRESSEL_RES2,
|
||||
/** resistor value 3 */
|
||||
acmpResistor3 = _ACMP_INPUTSEL_CSRESSEL_RES3
|
||||
} ACMP_CapsenseResistor_TypeDef;
|
||||
|
||||
/** Hysteresis level. See datasheet for your device for details on each
|
||||
* level. */
|
||||
typedef enum
|
||||
{
|
||||
acmpHysteresisLevel0 = _ACMP_CTRL_HYSTSEL_HYST0, /**< Hysteresis level 0 */
|
||||
acmpHysteresisLevel1 = _ACMP_CTRL_HYSTSEL_HYST1, /**< Hysteresis level 1 */
|
||||
acmpHysteresisLevel2 = _ACMP_CTRL_HYSTSEL_HYST2, /**< Hysteresis level 2 */
|
||||
acmpHysteresisLevel3 = _ACMP_CTRL_HYSTSEL_HYST3, /**< Hysteresis level 3 */
|
||||
acmpHysteresisLevel4 = _ACMP_CTRL_HYSTSEL_HYST4, /**< Hysteresis level 4 */
|
||||
acmpHysteresisLevel5 = _ACMP_CTRL_HYSTSEL_HYST5, /**< Hysteresis level 5 */
|
||||
acmpHysteresisLevel6 = _ACMP_CTRL_HYSTSEL_HYST6, /**< Hysteresis level 6 */
|
||||
acmpHysteresisLevel7 = _ACMP_CTRL_HYSTSEL_HYST7 /**< Hysteresis level 7 */
|
||||
} ACMP_HysteresisLevel_TypeDef;
|
||||
|
||||
/** ACMP warmup time. The delay is measured in HFPERCLK cycles and should
|
||||
* be at least 10 us. */
|
||||
typedef enum
|
||||
{
|
||||
/** 4 HFPERCLK cycles warmup */
|
||||
acmpWarmTime4 = _ACMP_CTRL_WARMTIME_4CYCLES,
|
||||
/** 8 HFPERCLK cycles warmup */
|
||||
acmpWarmTime8 = _ACMP_CTRL_WARMTIME_8CYCLES,
|
||||
/** 16 HFPERCLK cycles warmup */
|
||||
acmpWarmTime16 = _ACMP_CTRL_WARMTIME_16CYCLES,
|
||||
/** 32 HFPERCLK cycles warmup */
|
||||
acmpWarmTime32 = _ACMP_CTRL_WARMTIME_32CYCLES,
|
||||
/** 64 HFPERCLK cycles warmup */
|
||||
acmpWarmTime64 = _ACMP_CTRL_WARMTIME_64CYCLES,
|
||||
/** 128 HFPERCLK cycles warmup */
|
||||
acmpWarmTime128 = _ACMP_CTRL_WARMTIME_128CYCLES,
|
||||
/** 256 HFPERCLK cycles warmup */
|
||||
acmpWarmTime256 = _ACMP_CTRL_WARMTIME_256CYCLES,
|
||||
/** 512 HFPERCLK cycles warmup */
|
||||
acmpWarmTime512 = _ACMP_CTRL_WARMTIME_512CYCLES
|
||||
} ACMP_WarmTime_TypeDef;
|
||||
|
||||
/** ACMP inputs. Note that scaled VDD and bandgap references can only be used
|
||||
* as negative inputs. */
|
||||
typedef enum
|
||||
{
|
||||
/** Channel 0 */
|
||||
acmpChannel0 = _ACMP_INPUTSEL_NEGSEL_CH0,
|
||||
/** Channel 1 */
|
||||
acmpChannel1 = _ACMP_INPUTSEL_NEGSEL_CH1,
|
||||
/** Channel 2 */
|
||||
acmpChannel2 = _ACMP_INPUTSEL_NEGSEL_CH2,
|
||||
/** Channel 3 */
|
||||
acmpChannel3 = _ACMP_INPUTSEL_NEGSEL_CH3,
|
||||
/** Channel 4 */
|
||||
acmpChannel4 = _ACMP_INPUTSEL_NEGSEL_CH4,
|
||||
/** Channel 5 */
|
||||
acmpChannel5 = _ACMP_INPUTSEL_NEGSEL_CH5,
|
||||
/** Channel 6 */
|
||||
acmpChannel6 = _ACMP_INPUTSEL_NEGSEL_CH6,
|
||||
/** Channel 7 */
|
||||
acmpChannel7 = _ACMP_INPUTSEL_NEGSEL_CH7,
|
||||
/** 1.25V internal reference */
|
||||
acmpChannel1V25 = _ACMP_INPUTSEL_NEGSEL_1V25,
|
||||
/** 2.5V internal reference */
|
||||
acmpChannel2V5 = _ACMP_INPUTSEL_NEGSEL_2V5,
|
||||
/** Scaled VDD reference */
|
||||
acmpChannelVDD = _ACMP_INPUTSEL_NEGSEL_VDD,
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
/** DAC0 channel 0 */
|
||||
acmpChannelDAC0Ch0 = _ACMP_INPUTSEL_NEGSEL_DAC0CH0,
|
||||
/** DAC0 channel 1 */
|
||||
acmpChannelDAC0Ch1 = _ACMP_INPUTSEL_NEGSEL_DAC0CH1,
|
||||
#endif
|
||||
} ACMP_Channel_TypeDef;
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** STRUCTS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Capsense initialization structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Full bias current. See the ACMP chapter about bias and response time in
|
||||
* the reference manual for details. */
|
||||
bool fullBias;
|
||||
|
||||
/** Half bias current. See the ACMP chapter about bias and response time in
|
||||
* the reference manual for details. */
|
||||
bool halfBias;
|
||||
|
||||
/** Bias current. See the ACMP chapter about bias and response time in the
|
||||
* reference manual for details. Valid values are in the range 0-7. */
|
||||
uint32_t biasProg;
|
||||
|
||||
/** Warmup time. This is measured in HFPERCLK cycles and should be
|
||||
* about 10us in wall clock time. */
|
||||
ACMP_WarmTime_TypeDef warmTime;
|
||||
|
||||
/** Hysteresis level */
|
||||
ACMP_HysteresisLevel_TypeDef hysteresisLevel;
|
||||
|
||||
/** Resistor used in the capacative sensing circuit. For values see
|
||||
* your device datasheet. */
|
||||
ACMP_CapsenseResistor_TypeDef resistor;
|
||||
|
||||
/** Low power reference enabled. This setting, if enabled, reduces the
|
||||
* power used by the VDD and bandgap references. */
|
||||
bool lowPowerReferenceEnabled;
|
||||
|
||||
/** Vdd reference value. VDD_SCALED = VDD × VDDLEVEL × 50mV/3.8V.
|
||||
* Valid values are in the range 0-63. */
|
||||
uint32_t vddLevel;
|
||||
|
||||
/** If true, ACMP is being enabled after configuration. */
|
||||
bool enable;
|
||||
} ACMP_CapsenseInit_TypeDef;
|
||||
|
||||
/** Default config for capacitive sense mode initialization. */
|
||||
#define ACMP_CAPSENSE_INIT_DEFAULT \
|
||||
{ false, /* fullBias */ \
|
||||
false, /* halfBias */ \
|
||||
0x7, /* biasProg */ \
|
||||
acmpWarmTime512, /* 512 cycle warmup to be safe */ \
|
||||
acmpHysteresisLevel5, \
|
||||
acmpResistor3, \
|
||||
false, /* low power reference */ \
|
||||
0x3D, /* VDD level */ \
|
||||
true /* Enable after init. */ \
|
||||
}
|
||||
|
||||
/** ACMP initialization structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Full bias current. See the ACMP chapter about bias and response time in
|
||||
* the reference manual for details. */
|
||||
bool fullBias;
|
||||
|
||||
/** Half bias current. See the ACMP chapter about bias and response time in
|
||||
* the reference manual for details. */
|
||||
bool halfBias;
|
||||
|
||||
/** Bias current. See the ACMP chapter about bias and response time in the
|
||||
* reference manual for details. Valid values are in the range 0-7. */
|
||||
uint32_t biasProg;
|
||||
|
||||
/** Enable setting the interrupt flag on falling edge */
|
||||
bool interruptOnFallingEdge;
|
||||
|
||||
/** Enable setting the interrupt flag on rising edge */
|
||||
bool interruptOnRisingEdge;
|
||||
|
||||
/** Warmup time. This is measured in HFPERCLK cycles and should be
|
||||
* about 10us in wall clock time. */
|
||||
ACMP_WarmTime_TypeDef warmTime;
|
||||
|
||||
/** Hysteresis level */
|
||||
ACMP_HysteresisLevel_TypeDef hysteresisLevel;
|
||||
|
||||
/** Inactive value emitted by the ACMP during warmup */
|
||||
bool inactiveValue;
|
||||
|
||||
/** Low power reference enabled. This setting, if enabled, reduces the
|
||||
* power used by the VDD and bandgap references. */
|
||||
bool lowPowerReferenceEnabled;
|
||||
|
||||
/** Vdd reference value. VDD_SCALED = VDD × VDDLEVEL × 50mV/3.8V.
|
||||
* Valid values are in the range 0-63. */
|
||||
uint32_t vddLevel;
|
||||
|
||||
/** If true, ACMP is being enabled after configuration. */
|
||||
bool enable;
|
||||
} ACMP_Init_TypeDef;
|
||||
|
||||
/** Default config for ACMP regular initialization. */
|
||||
#define ACMP_INIT_DEFAULT \
|
||||
{ false, /* fullBias */ \
|
||||
false, /* halfBias */ \
|
||||
0x7, /* biasProg */ \
|
||||
false, /* No interrupt on falling edge. */ \
|
||||
false, /* No interrupt on rising edge. */ \
|
||||
acmpWarmTime512, /* 512 cycle warmup to be safe */ \
|
||||
acmpHysteresisLevel5, \
|
||||
false, /* Disabled emitting inactive value during warmup. */ \
|
||||
false, /* low power reference */ \
|
||||
0x3D, /* VDD level */ \
|
||||
true /* Enable after init. */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init);
|
||||
void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel);
|
||||
void ACMP_ChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef negSel, ACMP_Channel_TypeDef posSel);
|
||||
void ACMP_Disable(ACMP_TypeDef *acmp);
|
||||
void ACMP_Enable(ACMP_TypeDef *acmp);
|
||||
void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert);
|
||||
void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init);
|
||||
void ACMP_Reset(ACMP_TypeDef *acmp);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending ACMP interrupts.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending ACMP interrupt source to clear. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the ACMP module (ACMP_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void ACMP_IntClear(ACMP_TypeDef *acmp, uint32_t flags)
|
||||
{
|
||||
acmp->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more ACMP interrupts.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* ACMP interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the ACMP module (ACMP_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void ACMP_IntDisable(ACMP_TypeDef *acmp, uint32_t flags)
|
||||
{
|
||||
acmp->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more ACMP interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using ACMP_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* ACMP interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the ACMP module (ACMP_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void ACMP_IntEnable(ACMP_TypeDef *acmp, uint32_t flags)
|
||||
{
|
||||
acmp->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending ACMP interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* ACMP interrupt sources pending. A bitwise logic OR combination of valid
|
||||
* interrupt flags for the ACMP module (ACMP_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t ACMP_IntGet(ACMP_TypeDef *acmp)
|
||||
{
|
||||
return(acmp->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get enabled and pending ACMP interrupt flags.
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @param[in] usart
|
||||
* Pointer to ACMP peripheral register block.
|
||||
*
|
||||
* @note
|
||||
* Interrupt flags are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* Pending and enabled ACMP interrupt sources.
|
||||
* The return value is the bitwise AND combination of
|
||||
* - the OR combination of enabled interrupt sources in ACMPx_IEN_nnn
|
||||
* register (ACMPx_IEN_nnn) and
|
||||
* - the OR combination of valid interrupt flags of the ACMP module
|
||||
* (ACMPx_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t ACMP_IntGetEnabled(ACMP_TypeDef *acmp)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Store ACMPx->IEN in temporary variable in order to define explicit order
|
||||
* of volatile accesses. */
|
||||
tmp = acmp->IEN;
|
||||
|
||||
/* Bitwise AND of pending and enabled interrupts */
|
||||
return acmp->IF & tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending ACMP interrupts from SW.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* ACMP interrupt sources to set to pending. Use a bitwise logic OR
|
||||
* combination of valid interrupt flags for the ACMP module (ACMP_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void ACMP_IntSet(ACMP_TypeDef *acmp, uint32_t flags)
|
||||
{
|
||||
acmp->IFS = flags;
|
||||
}
|
||||
|
||||
/** @} (end addtogroup ACMP) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_ACMP_H */
|
|
@ -0,0 +1,557 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Analog to Digital Converter (ADC) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_ADC_H
|
||||
#define __EFM32_ADC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Acquisition time (in ADC clock cycles). */
|
||||
typedef enum
|
||||
{
|
||||
adcAcqTime1 = _ADC_SINGLECTRL_AT_1CYCLE, /**< 1 clock cycle. */
|
||||
adcAcqTime2 = _ADC_SINGLECTRL_AT_2CYCLES, /**< 2 clock cycles. */
|
||||
adcAcqTime4 = _ADC_SINGLECTRL_AT_4CYCLES, /**< 4 clock cycles. */
|
||||
adcAcqTime8 = _ADC_SINGLECTRL_AT_8CYCLES, /**< 8 clock cycles. */
|
||||
adcAcqTime16 = _ADC_SINGLECTRL_AT_16CYCLES, /**< 16 clock cycles. */
|
||||
adcAcqTime32 = _ADC_SINGLECTRL_AT_32CYCLES, /**< 32 clock cycles. */
|
||||
adcAcqTime64 = _ADC_SINGLECTRL_AT_64CYCLES, /**< 64 clock cycles. */
|
||||
adcAcqTime128 = _ADC_SINGLECTRL_AT_128CYCLES, /**< 128 clock cycles. */
|
||||
adcAcqTime256 = _ADC_SINGLECTRL_AT_256CYCLES /**< 256 clock cycles. */
|
||||
} ADC_AcqTime_TypeDef;
|
||||
|
||||
|
||||
/** Lowpass filter mode. */
|
||||
typedef enum
|
||||
{
|
||||
/** No filter or decoupling capacitor. */
|
||||
adcLPFilterBypass = _ADC_CTRL_LPFMODE_BYPASS,
|
||||
|
||||
/** On-chip RC filter. */
|
||||
adcLPFilterRC = _ADC_CTRL_LPFMODE_RCFILT,
|
||||
|
||||
/** On-chip decoupling capacitor. */
|
||||
adcLPFilterDeCap = _ADC_CTRL_LPFMODE_DECAP
|
||||
} ADC_LPFilter_TypeDef;
|
||||
|
||||
|
||||
/** Oversample rate select. */
|
||||
typedef enum
|
||||
{
|
||||
/** 2 samples per conversion result. */
|
||||
adcOvsRateSel2 = _ADC_CTRL_OVSRSEL_X2,
|
||||
|
||||
/** 4 samples per conversion result. */
|
||||
adcOvsRateSel4 = _ADC_CTRL_OVSRSEL_X4,
|
||||
|
||||
/** 8 samples per conversion result. */
|
||||
adcOvsRateSel8 = _ADC_CTRL_OVSRSEL_X8,
|
||||
|
||||
/** 16 samples per conversion result. */
|
||||
adcOvsRateSel16 = _ADC_CTRL_OVSRSEL_X16,
|
||||
|
||||
/** 32 samples per conversion result. */
|
||||
adcOvsRateSel32 = _ADC_CTRL_OVSRSEL_X32,
|
||||
|
||||
/** 64 samples per conversion result. */
|
||||
adcOvsRateSel64 = _ADC_CTRL_OVSRSEL_X64,
|
||||
|
||||
/** 128 samples per conversion result. */
|
||||
adcOvsRateSel128 = _ADC_CTRL_OVSRSEL_X128,
|
||||
|
||||
/** 256 samples per conversion result. */
|
||||
adcOvsRateSel256 = _ADC_CTRL_OVSRSEL_X256,
|
||||
|
||||
/** 512 samples per conversion result. */
|
||||
adcOvsRateSel512 = _ADC_CTRL_OVSRSEL_X512,
|
||||
|
||||
/** 1024 samples per conversion result. */
|
||||
adcOvsRateSel1024 = _ADC_CTRL_OVSRSEL_X1024,
|
||||
|
||||
/** 2048 samples per conversion result. */
|
||||
adcOvsRateSel2048 = _ADC_CTRL_OVSRSEL_X2048,
|
||||
|
||||
/** 4096 samples per conversion result. */
|
||||
adcOvsRateSel4096 = _ADC_CTRL_OVSRSEL_X4096
|
||||
} ADC_OvsRateSel_TypeDef;
|
||||
|
||||
|
||||
/** Peripheral Reflex System signal used to trigger single sample. */
|
||||
typedef enum
|
||||
{
|
||||
adcPRSSELCh0 = _ADC_SINGLECTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
|
||||
adcPRSSELCh1 = _ADC_SINGLECTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
|
||||
adcPRSSELCh2 = _ADC_SINGLECTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
|
||||
adcPRSSELCh3 = _ADC_SINGLECTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
|
||||
adcPRSSELCh4 = _ADC_SINGLECTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
|
||||
adcPRSSELCh5 = _ADC_SINGLECTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
|
||||
adcPRSSELCh6 = _ADC_SINGLECTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
|
||||
adcPRSSELCh7 = _ADC_SINGLECTRL_PRSSEL_PRSCH7 /**< PRS channel 7. */
|
||||
} ADC_PRSSEL_TypeDef;
|
||||
|
||||
|
||||
/** Reference to ADC sample. */
|
||||
typedef enum
|
||||
{
|
||||
/** Internal 1.25V reference. */
|
||||
adcRef1V25 = _ADC_SINGLECTRL_REF_1V25,
|
||||
|
||||
/** Internal 2.5V reference. */
|
||||
adcRef2V5 = _ADC_SINGLECTRL_REF_2V5,
|
||||
|
||||
/** Buffered VDD. */
|
||||
adcRefVDD = _ADC_SINGLECTRL_REF_VDD,
|
||||
|
||||
/** Internal differential 5V reference. */
|
||||
adcRef5VDIFF = _ADC_SINGLECTRL_REF_5VDIFF,
|
||||
|
||||
/** Single ended ext. ref. from pin 6. */
|
||||
adcRefExtSingle = _ADC_SINGLECTRL_REF_EXTSINGLE,
|
||||
|
||||
/** Differential ext. ref. from pin 6 and 7. */
|
||||
adcRef2xExtDiff = _ADC_SINGLECTRL_REF_2XEXTDIFF,
|
||||
|
||||
/** Unbuffered 2xVDD. */
|
||||
adcRef2xVDD = _ADC_SINGLECTRL_REF_2XVDD
|
||||
} ADC_Ref_TypeDef;
|
||||
|
||||
|
||||
/** Sample resolution. */
|
||||
typedef enum
|
||||
{
|
||||
adcRes12Bit = _ADC_SINGLECTRL_RES_12BIT, /**< 12 bit sampling. */
|
||||
adcRes8Bit = _ADC_SINGLECTRL_RES_8BIT, /**< 8 bit sampling. */
|
||||
adcRes6Bit = _ADC_SINGLECTRL_RES_6BIT, /**< 6 bit sampling. */
|
||||
adcResOVS = _ADC_SINGLECTRL_RES_OVS /**< Oversampling. */
|
||||
} ADC_Res_TypeDef;
|
||||
|
||||
|
||||
/** Single sample input selection. */
|
||||
typedef enum
|
||||
{
|
||||
/* Differential mode disabled */
|
||||
adcSingleInpCh0 = _ADC_SINGLECTRL_INPUTSEL_CH0, /**< Channel 0. */
|
||||
adcSingleInpCh1 = _ADC_SINGLECTRL_INPUTSEL_CH1, /**< Channel 1. */
|
||||
adcSingleInpCh2 = _ADC_SINGLECTRL_INPUTSEL_CH2, /**< Channel 2. */
|
||||
adcSingleInpCh3 = _ADC_SINGLECTRL_INPUTSEL_CH3, /**< Channel 3. */
|
||||
adcSingleInpCh4 = _ADC_SINGLECTRL_INPUTSEL_CH4, /**< Channel 4. */
|
||||
adcSingleInpCh5 = _ADC_SINGLECTRL_INPUTSEL_CH5, /**< Channel 5. */
|
||||
adcSingleInpCh6 = _ADC_SINGLECTRL_INPUTSEL_CH6, /**< Channel 6. */
|
||||
adcSingleInpCh7 = _ADC_SINGLECTRL_INPUTSEL_CH7, /**< Channel 7. */
|
||||
adcSingleInpTemp = _ADC_SINGLECTRL_INPUTSEL_TEMP, /**< Temperature reference. */
|
||||
adcSingleInpVDDDiv3 = _ADC_SINGLECTRL_INPUTSEL_VDDDIV3, /**< VDD divided by 3. */
|
||||
adcSingleInpVDD = _ADC_SINGLECTRL_INPUTSEL_VDD, /**< VDD. */
|
||||
adcSingleInpVSS = _ADC_SINGLECTRL_INPUTSEL_VSS, /**< VSS. */
|
||||
adcSingleInpVrefDiv2 = _ADC_SINGLECTRL_INPUTSEL_VREFDIV2, /**< Vref divided by 2. */
|
||||
adcSingleInpDACOut0 = _ADC_SINGLECTRL_INPUTSEL_DAC0OUT0, /**< DAC output 0. */
|
||||
adcSingleInpDACOut1 = _ADC_SINGLECTRL_INPUTSEL_DAC0OUT1, /**< DAC output 1. */
|
||||
/* TBD: Use define when available */
|
||||
adcSingleInpATEST = 15, /**< ATEST. */
|
||||
|
||||
/* Differential mode enabled */
|
||||
adcSingleInpCh0Ch1 = _ADC_SINGLECTRL_INPUTSEL_CH0CH1, /**< Positive Ch0, negative Ch1. */
|
||||
adcSingleInpCh2Ch3 = _ADC_SINGLECTRL_INPUTSEL_CH2CH3, /**< Positive Ch2, negative Ch3. */
|
||||
adcSingleInpCh4Ch5 = _ADC_SINGLECTRL_INPUTSEL_CH4CH5, /**< Positive Ch4, negative Ch5. */
|
||||
adcSingleInpCh6Ch7 = _ADC_SINGLECTRL_INPUTSEL_CH6CH7, /**< Positive Ch6, negative Ch7. */
|
||||
/* TBD: Use define when available */
|
||||
adcSingleInpDiff0 = 4 /**< Differential 0. */
|
||||
} ADC_SingleInput_TypeDef;
|
||||
|
||||
|
||||
/** Acquisition time (in ADC clock cycles). */
|
||||
typedef enum
|
||||
{
|
||||
/** Start single conversion. */
|
||||
adcStartSingle = ADC_CMD_SINGLESTART,
|
||||
|
||||
/** Start scan sequence. */
|
||||
adcStartScan = ADC_CMD_SCANSTART,
|
||||
|
||||
/**
|
||||
* Start scan sequence and single conversion, typically used when tailgating
|
||||
* single conversion after scan sequence.
|
||||
*/
|
||||
adcStartScanAndSingle = ADC_CMD_SCANSTART | ADC_CMD_SINGLESTART
|
||||
} ADC_Start_TypeDef;
|
||||
|
||||
|
||||
/** Warm-up mode. */
|
||||
typedef enum
|
||||
{
|
||||
/** ADC shutdown after each conversion. */
|
||||
adcWarmupNormal = _ADC_CTRL_WARMUPMODE_NORMAL,
|
||||
|
||||
/** Do not warm-up bandgap references. */
|
||||
adcWarmupFastBG = _ADC_CTRL_WARMUPMODE_FASTBG,
|
||||
|
||||
/** Reference selected for scan mode kept warm.*/
|
||||
adcWarmupKeepScanRefWarm = _ADC_CTRL_WARMUPMODE_KEEPSCANREFWARM,
|
||||
|
||||
/** ADC and reference selected for scan mode kept warm.*/
|
||||
adcWarmupKeepADCWarm = _ADC_CTRL_WARMUPMODE_KEEPADCWARM
|
||||
} ADC_Warmup_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** ADC init structure, common for single conversion and scan sequence. */
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Oversampling rate select. In order to have any effect, oversampling must
|
||||
* be enabled for single/scan mode.
|
||||
*/
|
||||
ADC_OvsRateSel_TypeDef ovsRateSel;
|
||||
|
||||
/** Lowpass or decoupling capacitor filter to use. */
|
||||
ADC_LPFilter_TypeDef lpfMode;
|
||||
|
||||
/** Warm-up mode to use for ADC. */
|
||||
ADC_Warmup_TypeDef warmUpMode;
|
||||
|
||||
/**
|
||||
* Timebase used for ADC warm up. Select N to give (N+1)HFPERCLK cycles.
|
||||
* (Additional delay is added for bandgap references, please refer to the
|
||||
* reference manual.) Normally, N should be selected so that the timebase
|
||||
* is at least 1 us. See ADC_TimebaseCalcDefault() for a way to obtain
|
||||
* a suggested timebase of at least 1 us.
|
||||
*/
|
||||
uint8_t timebase;
|
||||
|
||||
/** Clock division factor N, ADC clock = HFPERCLK / (N + 1). */
|
||||
uint8_t prescale;
|
||||
|
||||
/** Enable/disable conversion tailgating. */
|
||||
bool tailgate;
|
||||
} ADC_Init_TypeDef;
|
||||
|
||||
/** Default config for ADC init structure. */
|
||||
#define ADC_INIT_DEFAULT \
|
||||
{ adcOvsRateSel2, /* 2x oversampling (if enabled). */ \
|
||||
adcLPFilterBypass, /* No input filter selected. */ \
|
||||
adcWarmupNormal, /* ADC shutdown after each conversion. */ \
|
||||
_ADC_CTRL_TIMEBASE_DEFAULT, /* Use HW default value. */ \
|
||||
_ADC_CTRL_PRESC_DEFAULT, /* Use HW default value. */ \
|
||||
false /* Do not use tailgate. */ \
|
||||
}
|
||||
|
||||
|
||||
/** Scan sequence init structure. */
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Peripheral reflex system trigger selection. Only applicable if @p prsEnable
|
||||
* is enabled.
|
||||
*/
|
||||
ADC_PRSSEL_TypeDef prsSel;
|
||||
|
||||
/** Acquisition time (in ADC clock cycles). */
|
||||
ADC_AcqTime_TypeDef acqTime;
|
||||
|
||||
/**
|
||||
* Sample reference selection. Notice that for external references, the
|
||||
* ADC calibration register must be set explicitly.
|
||||
*/
|
||||
ADC_Ref_TypeDef reference;
|
||||
|
||||
/** Sample resolution. */
|
||||
ADC_Res_TypeDef resolution;
|
||||
|
||||
/**
|
||||
* Input scan selection. If single ended (@p diff is false), use logical
|
||||
* combination of ADC_SCANCTRL_INPUTMASK_CHx defines. If differential input
|
||||
* (@p diff is true), use logical combination of ADC_SCANCTRL_INPUTMASK_CHxCHy
|
||||
* defines. (Notice underscore prefix for defines used.)
|
||||
*/
|
||||
uint32_t input;
|
||||
|
||||
/** Select if single ended or differential input. */
|
||||
bool diff;
|
||||
|
||||
/** Peripheral reflex system trigger enable. */
|
||||
bool prsEnable;
|
||||
|
||||
/** Select if left adjustment should be done. */
|
||||
bool leftAdjust;
|
||||
|
||||
/** Select if continuous conversion until explicit stop. */
|
||||
bool rep;
|
||||
} ADC_InitScan_TypeDef;
|
||||
|
||||
/** Default config for ADC scan init structure. */
|
||||
#define ADC_INITSCAN_DEFAULT \
|
||||
{ adcPRSSELCh0, /* PRS ch0 (if enabled). */ \
|
||||
adcAcqTime1, /* 1 ADC_CLK cycle acquisition time. */ \
|
||||
adcRef1V25, /* 1.25V internal reference. */ \
|
||||
adcRes12Bit, /* 12 bit resolution. */ \
|
||||
0, /* No input selected. */ \
|
||||
false, /* Single ended input. */ \
|
||||
false, /* PRS disabled. */ \
|
||||
false, /* Right adjust. */ \
|
||||
false /* Deactivate conversion after one scan sequence. */ \
|
||||
}
|
||||
|
||||
|
||||
/** Single conversion init structure. */
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Peripheral reflex system trigger selection. Only applicable if @p prsEnable
|
||||
* is enabled.
|
||||
*/
|
||||
ADC_PRSSEL_TypeDef prsSel;
|
||||
|
||||
/** Acquisition time (in ADC clock cycles). */
|
||||
ADC_AcqTime_TypeDef acqTime;
|
||||
|
||||
/**
|
||||
* Sample reference selection. Notice that for external references, the
|
||||
* ADC calibration register must be set explicitly.
|
||||
*/
|
||||
ADC_Ref_TypeDef reference;
|
||||
|
||||
/** Sample resolution. */
|
||||
ADC_Res_TypeDef resolution;
|
||||
|
||||
/**
|
||||
* Sample input selection, use single ended or differential input according
|
||||
* to setting of @p diff.
|
||||
*/
|
||||
ADC_SingleInput_TypeDef input;
|
||||
|
||||
/** Select if single ended or differential input. */
|
||||
bool diff;
|
||||
|
||||
/** Peripheral reflex system trigger enable. */
|
||||
bool prsEnable;
|
||||
|
||||
/** Select if left adjustment should be done. */
|
||||
bool leftAdjust;
|
||||
|
||||
/** Select if continuous conversion until explicit stop. */
|
||||
bool rep;
|
||||
} ADC_InitSingle_TypeDef;
|
||||
|
||||
/** Default config for ADC single conversion init structure. */
|
||||
#define ADC_INITSINGLE_DEFAULT \
|
||||
{ adcPRSSELCh0, /* PRS ch0 (if enabled). */ \
|
||||
adcAcqTime1, /* 1 ADC_CLK cycle acquisition time. */ \
|
||||
adcRef1V25, /* 1.25V internal reference. */ \
|
||||
adcRes12Bit, /* 12 bit resolution. */ \
|
||||
adcSingleInpCh0, /* CH0 input selected. */ \
|
||||
false, /* Single ended input. */ \
|
||||
false, /* PRS disabled. */ \
|
||||
false, /* Right adjust. */ \
|
||||
false /* Deactivate conversion after one scan sequence. */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get single conversion result.
|
||||
*
|
||||
* @note
|
||||
* Do only use if single conversion data valid.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t ADC_DataSingleGet(ADC_TypeDef *adc)
|
||||
{
|
||||
return(adc->SINGLEDATA);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get scan result.
|
||||
*
|
||||
* @note
|
||||
* Do only use if scan data valid.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t ADC_DataScanGet(ADC_TypeDef *adc)
|
||||
{
|
||||
return(adc->SCANDATA);
|
||||
}
|
||||
|
||||
|
||||
void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init);
|
||||
void ADC_InitScan(ADC_TypeDef *adc, const ADC_InitScan_TypeDef *init);
|
||||
void ADC_InitSingle(ADC_TypeDef *adc, const ADC_InitSingle_TypeDef *init);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending ADC interrupts.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending ADC interrupt source to clear. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the ADC module (ADC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void ADC_IntClear(ADC_TypeDef *adc, uint32_t flags)
|
||||
{
|
||||
adc->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more ADC interrupts.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* ADC interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the ADC module (ADC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void ADC_IntDisable(ADC_TypeDef *adc, uint32_t flags)
|
||||
{
|
||||
adc->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more ADC interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using ADC_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* ADC interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the ADC module (ADC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void ADC_IntEnable(ADC_TypeDef *adc, uint32_t flags)
|
||||
{
|
||||
adc->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending ADC interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* ADC interrupt sources pending. A bitwise logic OR combination of valid
|
||||
* interrupt flags for the ADC module (ADC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t ADC_IntGet(ADC_TypeDef *adc)
|
||||
{
|
||||
return(adc->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending ADC interrupts from SW.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* ADC interrupt sources to set to pending. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the ADC module (ADC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void ADC_IntSet(ADC_TypeDef *adc, uint32_t flags)
|
||||
{
|
||||
adc->IFS = flags;
|
||||
}
|
||||
|
||||
uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Start scan sequence and/or single conversion.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] cmd
|
||||
* Command indicating which type of sampling to start.
|
||||
******************************************************************************/
|
||||
static __INLINE void ADC_Start(ADC_TypeDef *adc, ADC_Start_TypeDef cmd)
|
||||
{
|
||||
adc->CMD = (uint32_t)cmd;
|
||||
}
|
||||
|
||||
void ADC_Reset(ADC_TypeDef *adc);
|
||||
uint8_t ADC_TimebaseCalc(uint32_t hfperFreq);
|
||||
|
||||
/** @} (end addtogroup ADC) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_ADC_H */
|
|
@ -0,0 +1,228 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Advanced encryption standard (AES) accelerator peripheral API for
|
||||
* EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_AES_H
|
||||
#define __EFM32_AES_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#if defined(AES_COUNT) && (AES_COUNT > 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup AES
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** TYPEDEFS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* AES counter modification function pointer.
|
||||
* @details
|
||||
* Parameters:
|
||||
* @li ctr - Ptr to byte array (16 bytes) holding counter to be modified.
|
||||
*/
|
||||
typedef void (*AES_CtrFuncPtr_TypeDef)(uint8_t *ctr);
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void AES_CBC128(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
const uint8_t *iv,
|
||||
bool encrypt);
|
||||
|
||||
void AES_CBC256(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
const uint8_t *iv,
|
||||
bool encrypt);
|
||||
|
||||
void AES_CFB128(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
const uint8_t *iv,
|
||||
bool encrypt);
|
||||
|
||||
void AES_CFB256(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
const uint8_t *iv,
|
||||
bool encrypt);
|
||||
|
||||
void AES_CTR128(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
uint8_t *ctr,
|
||||
AES_CtrFuncPtr_TypeDef ctrFunc);
|
||||
|
||||
void AES_CTR256(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
uint8_t *ctr,
|
||||
AES_CtrFuncPtr_TypeDef ctrFunc);
|
||||
|
||||
void AES_CTRUpdate32Bit(uint8_t *ctr);
|
||||
|
||||
void AES_DecryptKey128(uint8_t *out, const uint8_t *in);
|
||||
|
||||
void AES_DecryptKey256(uint8_t *out, const uint8_t *in);
|
||||
|
||||
void AES_ECB128(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
bool encrypt);
|
||||
|
||||
void AES_ECB256(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
bool encrypt);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending AES interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending AES interrupt source to clear. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the AES module (AES_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void AES_IntClear(uint32_t flags)
|
||||
{
|
||||
AES->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more AES interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* AES interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the AES module (AES_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void AES_IntDisable(uint32_t flags)
|
||||
{
|
||||
AES->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more AES interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using AES_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] flags
|
||||
* AES interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the AES module (AES_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void AES_IntEnable(uint32_t flags)
|
||||
{
|
||||
AES->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending AES interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* AES interrupt sources pending. A bitwise logic OR combination of valid
|
||||
* interrupt flags for the AES module (AES_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t AES_IntGet(void)
|
||||
{
|
||||
return(AES->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending AES interrupts from SW.
|
||||
*
|
||||
* @param[in] flags
|
||||
* AES interrupt sources to set to pending. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the AES module (AES_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void AES_IntSet(uint32_t flags)
|
||||
{
|
||||
AES->IFS = flags;
|
||||
}
|
||||
|
||||
|
||||
void AES_OFB128(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
const uint8_t *iv);
|
||||
|
||||
void AES_OFB256(uint8_t *out,
|
||||
const uint8_t *in,
|
||||
unsigned int len,
|
||||
const uint8_t *key,
|
||||
const uint8_t *iv);
|
||||
|
||||
|
||||
/** @} (end addtogroup AES) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_AES_H */
|
||||
|
||||
#endif /* defined(AES_COUNT) && (AES_COUNT > 0) */
|
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief EFM32 peripheral API "assert" implementation.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*
|
||||
* @details
|
||||
* By default, EFM32 library assert usage is not included in order to reduce
|
||||
* footprint and processing overhead. Further, EFM32 assert usage is decoupled
|
||||
* from ISO C assert handling (NDEBUG usage), to allow a user to use ISO C
|
||||
* assert without including EFM32 assert statements.
|
||||
*
|
||||
* Below are available defines for controlling EFM32 assert inclusion. The defines
|
||||
* are typically defined for a project to be used by the preprocessor.
|
||||
*
|
||||
* @li If DEBUG_EFM is defined, the internal EFM32 library assert handling will
|
||||
* be used, which may be a quite rudimentary implementation.
|
||||
*
|
||||
* @li If DEBUG_EFM_USER is defined instead, the user must provide its own EFM32
|
||||
* assert handling routine (assertEFM()).
|
||||
*
|
||||
* As indicated above, if none of the above defines are used, EFM32 assert
|
||||
* statements are not compiled.
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_ASSERT_H
|
||||
#define __EFM32_ASSERT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#if defined(DEBUG_EFM) || defined(DEBUG_EFM_USER)
|
||||
|
||||
/* Due to footprint considerations, we only pass file name and line number, */
|
||||
/* not the assert expression (nor function name (C99)) */
|
||||
void assertEFM(const char *file, int line);
|
||||
#define EFM_ASSERT(expr) ((expr) ? ((void)0) : assertEFM(__FILE__, __LINE__))
|
||||
|
||||
#else
|
||||
|
||||
#define EFM_ASSERT(expr) ((void)0)
|
||||
|
||||
#endif /* defined(DEBUG_EFM) || defined(DEBUG_EFM_USER) */
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_ASSERT_H */
|
|
@ -0,0 +1,103 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Bitband Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_BITBAND_H
|
||||
#define __EFM32_BITBAND_H
|
||||
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup BITBAND
|
||||
* @brief BITBAND Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Perform bit-band operation on peripheral memory location.
|
||||
*
|
||||
* @details
|
||||
* Bit-banding provides atomic read-modify-write cycle for single bit
|
||||
* modification. Please refer to the reference manual for further details
|
||||
* about bit-banding.
|
||||
*
|
||||
* @param[in,out] addr Peripheral address location to modify bit in.
|
||||
*
|
||||
* @param[in] bit Bit position to modify, 0-31.
|
||||
*
|
||||
* @param[in] val Value to set bit to, 0 or 1.
|
||||
******************************************************************************/
|
||||
static __INLINE void BITBAND_Peripheral(volatile uint32_t *addr,
|
||||
uint32_t bit,
|
||||
uint32_t val)
|
||||
{
|
||||
uint32_t tmp = BITBAND_PER_BASE + (((uint32_t)addr - PER_MEM_BASE) * 32) + (bit * 4);
|
||||
|
||||
*((volatile uint32_t *)tmp) = (uint32_t)val;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Perform bit-band operation on SRAM memory location.
|
||||
*
|
||||
* @details
|
||||
* Bit-banding provides atomic read-modify-write cycle for single bit
|
||||
* modification. Please refer to the reference manual for further details
|
||||
* about bit-banding.
|
||||
*
|
||||
* @param[in,out] addr SRAM address location to modify bit in.
|
||||
*
|
||||
* @param[in] bit Bit position to modify, 0-31.
|
||||
*
|
||||
* @param[in] val Value to set bit to, 0 or 1.
|
||||
******************************************************************************/
|
||||
static __INLINE void BITBAND_SRAM(uint32_t *addr, uint32_t bit, uint32_t val)
|
||||
{
|
||||
uint32_t tmp = BITBAND_RAM_BASE + (((uint32_t)addr - RAM_MEM_BASE) * 32) + (bit * 4);
|
||||
|
||||
*((volatile uint32_t *)tmp) = (uint32_t)val;
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup BITBAND) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_BITBAND_H */
|
|
@ -0,0 +1,160 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Chip Initialization API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_CHIP_H
|
||||
#define __EFM32_CHIP_H
|
||||
|
||||
#include "efm32.h"
|
||||
#include "efm32_system.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup CHIP
|
||||
* @brief Chip Initialization API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Chip initialization routine for revision errata workarounds
|
||||
*
|
||||
* This init function will configure the EFM32 device to a state where it is
|
||||
* as similar as later revisions as possible, to improve software compatibility
|
||||
* with newer parts. See the device specific errata for details.
|
||||
*****************************************************************************/
|
||||
static __INLINE void CHIP_Init(void)
|
||||
{
|
||||
/* Currently only run time changes for Gecko devices */
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
uint32_t rev;
|
||||
SYSTEM_ChipRevision_TypeDef chipRev;
|
||||
volatile uint32_t *reg;
|
||||
|
||||
rev = *(volatile uint32_t *)(0x0FE081FC);
|
||||
/* Engineering Sample calibration setup */
|
||||
if ((rev >> 24) == 0)
|
||||
{
|
||||
reg = (volatile uint32_t *)0x400CA00C;
|
||||
*reg &= ~(0x70UL);
|
||||
/* DREG */
|
||||
reg = (volatile uint32_t *)0x400C6020;
|
||||
*reg &= ~(0xE0000000UL);
|
||||
*reg |= ~(7UL << 25);
|
||||
}
|
||||
if ((rev >> 24) <= 3)
|
||||
{
|
||||
/* DREG */
|
||||
reg = (volatile uint32_t *)0x400C6020;
|
||||
*reg &= ~(0x00001F80UL);
|
||||
/* Update CMU reset values */
|
||||
reg = (volatile uint32_t *)0x400C8040;
|
||||
*reg = 0;
|
||||
reg = (volatile uint32_t *)0x400C8044;
|
||||
*reg = 0;
|
||||
reg = (volatile uint32_t *)0x400C8058;
|
||||
*reg = 0;
|
||||
reg = (volatile uint32_t *)0x400C8060;
|
||||
*reg = 0;
|
||||
reg = (volatile uint32_t *)0x400C8078;
|
||||
*reg = 0;
|
||||
}
|
||||
|
||||
SYSTEM_ChipRevisionGet(&chipRev);
|
||||
if (chipRev.major == 0x01)
|
||||
{
|
||||
/* Rev A errata handling for EM2/3. Must enable DMA clock in order for EM2/3 */
|
||||
/* to work. This will be fixed in later chip revisions, so only do for rev A. */
|
||||
if (chipRev.minor == 00)
|
||||
{
|
||||
reg = (volatile uint32_t *)0x400C8040;
|
||||
*reg |= 0x2;
|
||||
}
|
||||
|
||||
/* Rev A+B errata handling for I2C when using EM2/3. USART0 clock must be enabled */
|
||||
/* after waking up from EM2/EM3 in order for I2C to work. This will be fixed in */
|
||||
/* later chip revisions, so only do for rev A+B. */
|
||||
if (chipRev.minor <= 0x01)
|
||||
{
|
||||
reg = (volatile uint32_t *)0x400C8044;
|
||||
*reg |= 0x1;
|
||||
}
|
||||
}
|
||||
/* Ensure correct ADC/DAC calibration value */
|
||||
rev = *(volatile uint32_t *)0x0FE081F0;
|
||||
if (rev < 0x4C8ABA00)
|
||||
{
|
||||
uint32_t cal;
|
||||
|
||||
/* Enable ADC/DAC clocks */
|
||||
reg = (volatile uint32_t *)0x400C8044UL;
|
||||
*reg |= (1 << 14 | 1 << 11);
|
||||
|
||||
/* Retrive calibration values */
|
||||
cal = ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL) >>
|
||||
8) << 24;
|
||||
|
||||
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL) >>
|
||||
0) << 16;
|
||||
|
||||
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL) >>
|
||||
8) << 8;
|
||||
|
||||
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL) >>
|
||||
0) << 0;
|
||||
|
||||
/* ADC0->CAL = 1.25 reference */
|
||||
reg = (volatile uint32_t *)0x40002034UL;
|
||||
*reg = cal;
|
||||
|
||||
/* DAC0->CAL = 1.25 reference */
|
||||
reg = (volatile uint32_t *)(0x4000402CUL);
|
||||
cal = *(volatile uint32_t *)0x0FE081C8UL;
|
||||
*reg = cal;
|
||||
|
||||
/* Turn off ADC/DAC clocks */
|
||||
reg = (volatile uint32_t *)0x400C8044UL;
|
||||
*reg &= ~(1 << 14 | 1 << 11);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} (end addtogroup SYSTEM) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_CHIP_H */
|
|
@ -0,0 +1,819 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock management unit (CMU) API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_CMU_H
|
||||
#define __EFM32_CMU_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup CMU
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/* Select register ids, for internal use */
|
||||
#define CMU_NOSEL_REG 0
|
||||
#define CMU_HFCLKSEL_REG 1
|
||||
#define CMU_LFACLKSEL_REG 2
|
||||
#define CMU_LFBCLKSEL_REG 3
|
||||
#define CMU_DBGCLKSEL_REG 4
|
||||
#if defined (_EFM32_GIANT_FAMILY)
|
||||
#define CMU_USBCCLKSEL_REG 5
|
||||
#endif
|
||||
|
||||
#define CMU_SEL_REG_POS 0
|
||||
#define CMU_SEL_REG_MASK 0xf
|
||||
|
||||
/* Divisor register ids, for internal use */
|
||||
#define CMU_NODIV_REG 0
|
||||
#define CMU_HFPERCLKDIV_REG 1
|
||||
#define CMU_HFCORECLKDIV_REG 2
|
||||
#define CMU_LFAPRESC0_REG 3
|
||||
#define CMU_LFBPRESC0_REG 4
|
||||
#if defined (_EFM32_GIANT_FAMILY)
|
||||
#define CMU_HFCLKDIV_REG 5
|
||||
#endif
|
||||
#define CMU_DIV_REG_POS 4
|
||||
#define CMU_DIV_REG_MASK 0xf
|
||||
|
||||
/* Enable register ids, for internal use */
|
||||
#define CMU_NO_EN_REG 0
|
||||
#define CMU_HFPERCLKDIV_EN_REG 1
|
||||
#define CMU_HFPERCLKEN0_EN_REG 2
|
||||
#define CMU_HFCORECLKEN0_EN_REG 3
|
||||
#define CMU_LFACLKEN0_EN_REG 4
|
||||
#define CMU_LFBCLKEN0_EN_REG 5
|
||||
#define CMU_PCNT_EN_REG 6
|
||||
|
||||
#define CMU_EN_REG_POS 8
|
||||
#define CMU_EN_REG_MASK 0xf
|
||||
|
||||
/* Enable register bit position, for internal use */
|
||||
#define CMU_EN_BIT_POS 12
|
||||
#define CMU_EN_BIT_MASK 0x1f
|
||||
|
||||
/* Clock branch bitfield position, for internal use */
|
||||
#define CMU_HF_CLK_BRANCH 0
|
||||
#define CMU_HFPER_CLK_BRANCH 1
|
||||
#define CMU_HFCORE_CLK_BRANCH 2
|
||||
#define CMU_LFA_CLK_BRANCH 3
|
||||
#define CMU_RTC_CLK_BRANCH 4
|
||||
#define CMU_LETIMER_CLK_BRANCH 5
|
||||
#define CMU_LCDPRE_CLK_BRANCH 6
|
||||
#define CMU_LCD_CLK_BRANCH 7
|
||||
#define CMU_LESENSE_CLK_BRANCH 8
|
||||
#define CMU_LFB_CLK_BRANCH 9
|
||||
#define CMU_LEUART0_CLK_BRANCH 10
|
||||
#define CMU_LEUART1_CLK_BRANCH 11
|
||||
#define CMU_DBG_CLK_BRANCH 12
|
||||
#define CMU_AUX_CLK_BRANCH 13
|
||||
#define CMU_USBC_CLK_BRANCH 14
|
||||
|
||||
#define CMU_CLK_BRANCH_POS 17
|
||||
#define CMU_CLK_BRANCH_MASK 0x1f
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Clock divisors. These values are valid for prescalers. */
|
||||
#define cmuClkDiv_1 1 /**< Divide clock by 1. */
|
||||
#define cmuClkDiv_2 2 /**< Divide clock by 2. */
|
||||
#define cmuClkDiv_4 4 /**< Divide clock by 4. */
|
||||
#define cmuClkDiv_8 8 /**< Divide clock by 8. */
|
||||
#define cmuClkDiv_16 16 /**< Divide clock by 16. */
|
||||
#define cmuClkDiv_32 32 /**< Divide clock by 32. */
|
||||
#define cmuClkDiv_64 64 /**< Divide clock by 64. */
|
||||
#define cmuClkDiv_128 128 /**< Divide clock by 128. */
|
||||
#define cmuClkDiv_256 256 /**< Divide clock by 256. */
|
||||
#define cmuClkDiv_512 512 /**< Divide clock by 512. */
|
||||
#define cmuClkDiv_1024 1024 /**< Divide clock by 1024. */
|
||||
#define cmuClkDiv_2048 2048 /**< Divide clock by 2048. */
|
||||
#define cmuClkDiv_4096 4096 /**< Divide clock by 4096. */
|
||||
#define cmuClkDiv_8192 8192 /**< Divide clock by 8192. */
|
||||
#define cmuClkDiv_16384 16384 /**< Divide clock by 16384. */
|
||||
#define cmuClkDiv_32768 32768 /**< Divide clock by 32768. */
|
||||
|
||||
/** Clock divider configuration */
|
||||
typedef uint32_t CMU_ClkDiv_TypeDef;
|
||||
|
||||
/** High frequency RC bands. */
|
||||
typedef enum
|
||||
{
|
||||
/** 1MHz RC band. */
|
||||
cmuHFRCOBand_1MHz = _CMU_HFRCOCTRL_BAND_1MHZ,
|
||||
/** 7MHz RC band. */
|
||||
cmuHFRCOBand_7MHz = _CMU_HFRCOCTRL_BAND_7MHZ,
|
||||
/** 11MHz RC band. */
|
||||
cmuHFRCOBand_11MHz = _CMU_HFRCOCTRL_BAND_11MHZ,
|
||||
/** 14MHz RC band. */
|
||||
cmuHFRCOBand_14MHz = _CMU_HFRCOCTRL_BAND_14MHZ,
|
||||
/** 21MHz RC band. */
|
||||
cmuHFRCOBand_21MHz = _CMU_HFRCOCTRL_BAND_21MHZ,
|
||||
/** 28MHz RC band. */
|
||||
cmuHFRCOBand_28MHz = _CMU_HFRCOCTRL_BAND_28MHZ
|
||||
} CMU_HFRCOBand_TypeDef;
|
||||
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/** AUX High frequency RC bands. */
|
||||
typedef enum
|
||||
{
|
||||
/** 1MHz RC band. */
|
||||
cmuAUXHFRCOBand_1MHz = _CMU_AUXHFRCOCTRL_BAND_1MHZ,
|
||||
/** 7MHz RC band. */
|
||||
cmuAUXHFRCOBand_7MHz = _CMU_AUXHFRCOCTRL_BAND_7MHZ,
|
||||
/** 11MHz RC band. */
|
||||
cmuAUXHFRCOBand_11MHz = _CMU_AUXHFRCOCTRL_BAND_11MHZ,
|
||||
/** 14MHz RC band. */
|
||||
cmuAUXHFRCOBand_14MHz = _CMU_AUXHFRCOCTRL_BAND_14MHZ,
|
||||
/** 21MHz RC band. */
|
||||
cmuAUXHFRCOBand_21MHz = _CMU_AUXHFRCOCTRL_BAND_21MHZ,
|
||||
/** 28MHz RC band. */
|
||||
cmuAUXHFRCOBand_28MHz = _CMU_AUXHFRCOCTRL_BAND_28MHZ
|
||||
} CMU_AUXHFRCOBand_TypeDef;
|
||||
#endif
|
||||
|
||||
/** Clock points in CMU. Please refer to CMU overview in reference manual. */
|
||||
typedef enum
|
||||
{
|
||||
/*******************/
|
||||
/* HF clock branch */
|
||||
/*******************/
|
||||
|
||||
/** High frequency clock */
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
cmuClock_HF = (CMU_HFCLKDIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_HFCLKSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
|
||||
(0 << CMU_EN_BIT_POS) |
|
||||
(CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#else
|
||||
cmuClock_HF = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_HFCLKSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
|
||||
(0 << CMU_EN_BIT_POS) |
|
||||
(CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Debug clock */
|
||||
cmuClock_DBG = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_DBGCLKSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
|
||||
(0 << CMU_EN_BIT_POS) |
|
||||
(CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
/** AUX clock */
|
||||
cmuClock_AUX = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
|
||||
(0 << CMU_EN_BIT_POS) |
|
||||
(CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
/**********************************/
|
||||
/* HF peripheral clock sub-branch */
|
||||
/**********************************/
|
||||
|
||||
/** High frequency peripheral clock */
|
||||
cmuClock_HFPER = (CMU_HFPERCLKDIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKDIV_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKDIV_HFPERCLKEN_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
/** Universal sync/async receiver/transmitter 0 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_USART0_MASK)
|
||||
cmuClock_USART0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_USART0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Universal sync/async receiver/transmitter 1 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_USART1_MASK)
|
||||
cmuClock_USART1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_USART1_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Universal sync/async receiver/transmitter 2 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_USART2_MASK)
|
||||
cmuClock_USART2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_USART2_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Universal async receiver/transmitter 0 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_UART0_MASK)
|
||||
cmuClock_UART0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_UART0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Universal async receiver/transmitter 1 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_UART1_MASK)
|
||||
cmuClock_UART1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_UART1_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Timer 0 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_TIMER0_MASK)
|
||||
cmuClock_TIMER0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_TIMER0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Timer 1 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_TIMER1_MASK)
|
||||
cmuClock_TIMER1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_TIMER1_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Timer 2 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_TIMER2_MASK)
|
||||
cmuClock_TIMER2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_TIMER2_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Analog comparator 0 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_ACMP0_MASK)
|
||||
cmuClock_ACMP0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_ACMP0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Analog comparator 1 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_ACMP1_MASK)
|
||||
cmuClock_ACMP1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_ACMP1_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Peripheral reflex system clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_PRS_MASK)
|
||||
cmuClock_PRS = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_PRS_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Digital to analog converter 0 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_DAC0_MASK)
|
||||
cmuClock_DAC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_DAC0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** General purpose input/output clock. */
|
||||
#if defined(GPIO_PRESENT)
|
||||
cmuClock_GPIO = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_GPIO_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Voltage comparator clock. */
|
||||
#if defined(VCMP_PRESENT)
|
||||
cmuClock_VCMP = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_VCMP_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Analog to digital converter 0 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_ADC0_MASK)
|
||||
cmuClock_ADC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_ADC0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** I2C 0 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_I2C0_MASK)
|
||||
cmuClock_I2C0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_I2C0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** I2C 1 clock. */
|
||||
#if defined(_CMU_HFPERCLKEN0_I2C1_MASK)
|
||||
cmuClock_I2C1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFPERCLKEN0_I2C1_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/**********************/
|
||||
/* HF core sub-branch */
|
||||
/**********************/
|
||||
|
||||
/** Core clock */
|
||||
cmuClock_CORE = (CMU_HFCORECLKDIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
|
||||
(0 << CMU_EN_BIT_POS) |
|
||||
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
/** Advanced encryption standard accelerator clock. */
|
||||
#if defined(AES_PRESENT)
|
||||
cmuClock_AES = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFCORECLKEN0_AES_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Direct memory access controller clock. */
|
||||
#if defined(DMA_PRESENT)
|
||||
cmuClock_DMA = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFCORECLKEN0_DMA_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
/** Low energy clocking module clock. */
|
||||
cmuClock_CORELE = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFCORECLKEN0_LE_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
/** External bus interface clock. */
|
||||
#if defined(EBI_PRESENT)
|
||||
cmuClock_EBI = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFCORECLKEN0_EBI_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
#if defined(USB_PRESENT)
|
||||
cmuClock_USBC = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_USBCCLKSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFCORECLKEN0_USBC_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
cmuClock_USB = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_HFCORECLKEN0_USB_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/***************/
|
||||
/* LF A branch */
|
||||
/***************/
|
||||
|
||||
/** Low frequency A clock */
|
||||
cmuClock_LFA = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_LFACLKSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
|
||||
(0 << CMU_EN_BIT_POS) |
|
||||
(CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
/** Real time counter clock. */
|
||||
#if defined(RTC_PRESENT)
|
||||
cmuClock_RTC = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_LFACLKEN0_RTC_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Low energy timer 0 clock. */
|
||||
#if defined(_CMU_LFACLKEN0_LETIMER0_MASK)
|
||||
cmuClock_LETIMER0 = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_LFACLKEN0_LETIMER0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Liquid crystal display, pre FDIV clock. */
|
||||
#if defined(_CMU_LFACLKEN0_LCD_MASK)
|
||||
cmuClock_LCDpre = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
|
||||
(0 << CMU_EN_BIT_POS) |
|
||||
(CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
/** Liquid crystal display clock. Please notice that FDIV prescaler
|
||||
* must be set by special API. */
|
||||
cmuClock_LCD = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_LFACLKEN0_LCD_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Pulse counter 0 clock. */
|
||||
#if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK)
|
||||
cmuClock_PCNT0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_PCNTCTRL_PCNT0CLKEN_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Pulse counter 1 clock. */
|
||||
#if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK)
|
||||
cmuClock_PCNT1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_PCNTCTRL_PCNT1CLKEN_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Pulse counter 2 clock. */
|
||||
#if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK)
|
||||
cmuClock_PCNT2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_PCNTCTRL_PCNT2CLKEN_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
/** LESENSE clock. */
|
||||
#if defined(_CMU_LFACLKEN0_LESENSE_MASK)
|
||||
cmuClock_LESENSE = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_LFACLKEN0_LESENSE_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/***************/
|
||||
/* LF B branch */
|
||||
/***************/
|
||||
|
||||
/** Low frequency B clock */
|
||||
cmuClock_LFB = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_LFBCLKSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
|
||||
(0 << CMU_EN_BIT_POS) |
|
||||
(CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
|
||||
/** Low energy universal asynchronous receiver/transmitter 0 clock. */
|
||||
#if defined(_CMU_LFBCLKEN0_LEUART0_MASK)
|
||||
cmuClock_LEUART0 = (CMU_LFBPRESC0_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_LFBCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_LFBCLKEN0_LEUART0_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
|
||||
/** Low energy universal asynchronous receiver/transmitter 1 clock. */
|
||||
#if defined(_CMU_LFBCLKEN0_LEUART1_MASK)
|
||||
cmuClock_LEUART1 = (CMU_LFBPRESC0_REG << CMU_DIV_REG_POS) |
|
||||
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
|
||||
(CMU_LFBCLKEN0_EN_REG << CMU_EN_REG_POS) |
|
||||
(_CMU_LFBCLKEN0_LEUART1_SHIFT << CMU_EN_BIT_POS) |
|
||||
(CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS),
|
||||
#endif
|
||||
} CMU_Clock_TypeDef;
|
||||
|
||||
|
||||
/** Oscillator types. */
|
||||
typedef enum
|
||||
{
|
||||
cmuOsc_LFXO, /**< Low frequency crystal oscillator. */
|
||||
cmuOsc_LFRCO, /**< Low frequency RC oscillator. */
|
||||
cmuOsc_HFXO, /**< High frequency crystal oscillator. */
|
||||
cmuOsc_HFRCO, /**< High frequency RC oscillator. */
|
||||
cmuOsc_AUXHFRCO, /**< Auxiliary high frequency RC oscillator. */
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
cmuOsc_ULFRCO /**< Ultra low frequency RC oscillator. */
|
||||
#endif
|
||||
} CMU_Osc_TypeDef;
|
||||
|
||||
|
||||
/** Selectable clock sources. */
|
||||
typedef enum
|
||||
{
|
||||
cmuSelect_Error, /**< Usage error. */
|
||||
cmuSelect_Disabled, /**< Clock selector disabled. */
|
||||
cmuSelect_LFXO, /**< Low frequency crystal oscillator. */
|
||||
cmuSelect_LFRCO, /**< Low frequency RC oscillator. */
|
||||
cmuSelect_HFXO, /**< High frequency crystal oscillator. */
|
||||
cmuSelect_HFRCO, /**< High frequency RC oscillator. */
|
||||
cmuSelect_CORELEDIV2, /**< Core low energy clock divided by 2. */
|
||||
cmuSelect_AUXHFRCO, /**< Auxilliary clock source can be used for debug clock */
|
||||
cmuSelect_HFCLK, /**< Divided HFCLK on Giant for debug clock, undivided on Tiny Gecko and for USBC (not used on Gecko) */
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
cmuSelect_ULFRCO, /**< Ultra low frequency RC oscillator. */
|
||||
#endif
|
||||
} CMU_Select_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable);
|
||||
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock);
|
||||
CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock);
|
||||
CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock);
|
||||
void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div);
|
||||
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref);
|
||||
|
||||
CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void);
|
||||
void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band);
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void);
|
||||
void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band);
|
||||
#endif
|
||||
void CMU_HFRCOStartupDelaySet(uint32_t delay);
|
||||
uint32_t CMU_HFRCOStartupDelayGet(void);
|
||||
|
||||
void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait);
|
||||
uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc);
|
||||
void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val);
|
||||
|
||||
bool CMU_PCNTClockExternalGet(unsigned int inst);
|
||||
void CMU_PCNTClockExternalSet(unsigned int inst, bool external);
|
||||
|
||||
uint32_t CMU_LCDClkFDIVGet(void);
|
||||
void CMU_LCDClkFDIVSet(uint32_t div);
|
||||
|
||||
void CMU_FreezeEnable(bool enable);
|
||||
uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef reference);
|
||||
void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
|
||||
CMU_Osc_TypeDef upSel);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending CMU interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* CMU interrupt sources to clear.
|
||||
******************************************************************************/
|
||||
static __INLINE void CMU_IntClear(uint32_t flags)
|
||||
{
|
||||
CMU->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more CMU interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* CMU interrupt sources to disable.
|
||||
******************************************************************************/
|
||||
static __INLINE void CMU_IntDisable(uint32_t flags)
|
||||
{
|
||||
CMU->IEN &= ~flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more CMU interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using CMU_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] flags
|
||||
* CMU interrupt sources to enable.
|
||||
******************************************************************************/
|
||||
static __INLINE void CMU_IntEnable(uint32_t flags)
|
||||
{
|
||||
CMU->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending CMU interrupts.
|
||||
*
|
||||
* @return
|
||||
* CMU interrupt sources pending.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t CMU_IntGet(void)
|
||||
{
|
||||
return CMU->IF;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get enabled and pending CMU interrupt flags.
|
||||
*
|
||||
* @details
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* Pending and enabled CMU interrupt sources.
|
||||
* The return value is the bitwise AND combination of
|
||||
* - the OR combination of enabled interrupt sources in CMU_IEN_nnn
|
||||
* register (CMU_IEN_nnn) and
|
||||
* - the OR combination of valid interrupt flags of the CMU module
|
||||
* (CMU_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t CMU_IntGetEnabled(void)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
|
||||
/* Store LESENSE->IEN in temporary variable in order to define explicit order
|
||||
* of volatile accesses. */
|
||||
tmp = CMU->IEN;
|
||||
|
||||
/* Bitwise AND of pending and enabled interrupts */
|
||||
return CMU->IF & tmp;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending CMU interrupts from SW.
|
||||
*
|
||||
* @param[in] flags
|
||||
* CMU interrupt sources to set to pending.
|
||||
*****************************************************************************/
|
||||
static __INLINE void CMU_IntSet(uint32_t flags)
|
||||
{
|
||||
CMU->IFS = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Lock the CMU in order to protect some of its registers against unintended
|
||||
* modification.
|
||||
*
|
||||
* @details
|
||||
* Please refer to the reference manual for CMU registers that will be
|
||||
* locked.
|
||||
*
|
||||
* @note
|
||||
* If locking the CMU registers, they must be unlocked prior to using any
|
||||
* CMU API functions modifying CMU registers protected by the lock.
|
||||
******************************************************************************/
|
||||
static __INLINE void CMU_Lock(void)
|
||||
{
|
||||
CMU->LOCK = CMU_LOCK_LOCKKEY_LOCK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unlock the CMU so that writing to locked registers again is possible.
|
||||
******************************************************************************/
|
||||
static __INLINE void CMU_Unlock(void)
|
||||
{
|
||||
CMU->LOCK = CMU_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get calibration count register
|
||||
* @note
|
||||
* If continuous calibrartion mode is active, calibration busy will allmost
|
||||
* always be on, and we just need to read the value, where the normal case
|
||||
* would be that this function call has been triggered by the CALRDY
|
||||
* interrupt flag.
|
||||
* @return
|
||||
* Calibration count, the number of UPSEL clocks (see CMU_CalibrateConfig)
|
||||
* in the period of DOWNSEL oscillator clock cycles configured by a previous
|
||||
* write operation to CMU->CALCNT
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t CMU_CalibrateCountGet(void)
|
||||
{
|
||||
/* Wait until calibration completes, UNLESS continuous calibration mode is */
|
||||
/* active */
|
||||
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
if (!(CMU->CALCTRL & CMU_CALCTRL_CONT))
|
||||
{
|
||||
while (CMU->STATUS & CMU_STATUS_CALBSY)
|
||||
;
|
||||
}
|
||||
#else
|
||||
while (CMU->STATUS & CMU_STATUS_CALBSY)
|
||||
;
|
||||
#endif
|
||||
return CMU->CALCNT;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Starts calibration
|
||||
* @note
|
||||
* This call is usually invoked after CMU_CalibrateConfig() and possibly
|
||||
* CMU_CalibrateCont()
|
||||
******************************************************************************/
|
||||
static __INLINE void CMU_CalibrateStart(void)
|
||||
{
|
||||
CMU->CMD = CMU_CMD_CALSTART;
|
||||
}
|
||||
|
||||
|
||||
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Stop the calibration counters
|
||||
******************************************************************************/
|
||||
static __INLINE void CMU_CalibrateStop(void)
|
||||
{
|
||||
CMU->CMD = CMU_CMD_CALSTOP;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configures continuous calibration mode
|
||||
* @param[in] enable
|
||||
* If true, enables continuous calibration, if false disables continuous
|
||||
* calibrartion
|
||||
******************************************************************************/
|
||||
static __INLINE void CMU_CalibrateCont(bool enable)
|
||||
{
|
||||
BITBAND_Peripheral(&(CMU->CALCTRL), _CMU_CALCTRL_CONT_SHIFT, enable);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup CMU) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_CMU_H */
|
|
@ -0,0 +1,109 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief EFM32 general purpose utilities.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_COMMON_H
|
||||
#define __EFM32_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup COMMON
|
||||
* @brief EFM32 general purpose utilities.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
|
||||
/** Macro for getting minimum value. */
|
||||
#define EFM32_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
/** Macro for getting maximum value. */
|
||||
#define EFM32_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
/** Macros for handling packed structs. */
|
||||
#define STRINGIZE(X) #X
|
||||
#define EFM32_PACK_START(X) _Pragma( STRINGIZE( pack( ##X## ) ) )
|
||||
#define EFM32_PACK_END() _Pragma( "pack()" )
|
||||
#define __attribute__(...)
|
||||
|
||||
/** Macros for handling aligned structs. */
|
||||
#ifdef __CC_ARM
|
||||
#define EFM32_ALIGN(X) __align(X)
|
||||
#endif
|
||||
#ifdef __ICCARM__
|
||||
#define EFM32_ALIGN(X) _Pragma( STRINGIZE( data_alignment=##X## ) )
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/** Macro for getting minimum value. No sideeffects, a and b are evaluated once only. */
|
||||
#define EFM32_MIN(a, b) ({ __typeof__(a) _a = (a); __typeof__(b) _b = (b); _a < _b ? _a : _b; })
|
||||
/** Macro for getting maximum value. No sideeffects, a and b are evaluated once only. */
|
||||
#define EFM32_MAX(a, b) ({ __typeof__(a) _a = (a); __typeof__(b) _b = (b); _a > _b ? _a : _b; })
|
||||
|
||||
/** Macro for handling packed structs.
|
||||
* @n Use this macro before the struct definition.
|
||||
* @n X denotes the maximum alignment of struct members. X is not supported on
|
||||
* gcc, gcc always use 1 byte maximum alignment.
|
||||
*/
|
||||
#define EFM32_PACK_START( x )
|
||||
|
||||
/** Macro for handling packed structs.
|
||||
* @n Use this macro after the struct definition.
|
||||
* @n On gcc add __attribute__ ((packed)) after the closing } of the struct
|
||||
* definition.
|
||||
*/
|
||||
#define EFM32_PACK_END()
|
||||
|
||||
/** Macro for aligning a variable.
|
||||
* @n Use this macro before the variable definition.
|
||||
* @n X denotes the storage alignment value in bytes.
|
||||
* @n On gcc use __attribute__ ((aligned(X))) before the ; on normal variables.
|
||||
* Use __attribute__ ((aligned(X))) before the opening { on struct variables.
|
||||
*/
|
||||
#define EFM32_ALIGN(X)
|
||||
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup COMMON) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_COMMON_H */
|
|
@ -0,0 +1,312 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Digital to Analog Converter (DAC) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_DAC_H
|
||||
#define __EFM32_DAC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup DAC
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of DAC register block pointer reference for assert statements. */
|
||||
#define DAC_REF_VALID(ref) ((ref) == DAC0)
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Conversion mode. */
|
||||
typedef enum
|
||||
{
|
||||
dacConvModeContinuous = _DAC_CTRL_CONVMODE_CONTINUOUS, /**< Continuous mode. */
|
||||
dacConvModeSampleHold = _DAC_CTRL_CONVMODE_SAMPLEHOLD, /**< Sample/hold mode. */
|
||||
dacConvModeSampleOff = _DAC_CTRL_CONVMODE_SAMPLEOFF /**< Sample/shut off mode. */
|
||||
} DAC_ConvMode_TypeDef;
|
||||
|
||||
/** Output mode. */
|
||||
typedef enum
|
||||
{
|
||||
dacOutputDisable = _DAC_CTRL_OUTMODE_DISABLE, /**< Output to pin and ADC disabled. */
|
||||
dacOutputPin = _DAC_CTRL_OUTMODE_PIN, /**< Output to pin only. */
|
||||
dacOutputADC = _DAC_CTRL_OUTMODE_ADC, /**< Output to ADC only */
|
||||
dacOutputPinADC = _DAC_CTRL_OUTMODE_PINADC /**< Output to pin and ADC. */
|
||||
} DAC_Output_TypeDef;
|
||||
|
||||
|
||||
/** Peripheral Reflex System signal used to trigger single sample. */
|
||||
typedef enum
|
||||
{
|
||||
dacPRSSELCh0 = _DAC_CH0CTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
|
||||
dacPRSSELCh1 = _DAC_CH0CTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
|
||||
dacPRSSELCh2 = _DAC_CH0CTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
|
||||
dacPRSSELCh3 = _DAC_CH0CTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
|
||||
dacPRSSELCh4 = _DAC_CH0CTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
|
||||
dacPRSSELCh5 = _DAC_CH0CTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
|
||||
dacPRSSELCh6 = _DAC_CH0CTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
|
||||
dacPRSSELCh7 = _DAC_CH0CTRL_PRSSEL_PRSCH7 /**< PRS channel 7. */
|
||||
} DAC_PRSSEL_TypeDef;
|
||||
|
||||
|
||||
/** Reference voltage for DAC. */
|
||||
typedef enum
|
||||
{
|
||||
dacRef1V25 = _DAC_CTRL_REFSEL_1V25, /**< Internal 1.25V bandgap reference. */
|
||||
dacRef2V5 = _DAC_CTRL_REFSEL_2V5, /**< Internal 2.5V bandgap reference. */
|
||||
dacRefVDD = _DAC_CTRL_REFSEL_VDD /**< VDD reference. */
|
||||
} DAC_Ref_TypeDef;
|
||||
|
||||
|
||||
/** Refresh interval. */
|
||||
typedef enum
|
||||
{
|
||||
dacRefresh8 = _DAC_CTRL_REFRSEL_8CYCLES, /**< Refresh every 8 prescaled cycles. */
|
||||
dacRefresh16 = _DAC_CTRL_REFRSEL_16CYCLES, /**< Refresh every 16 prescaled cycles. */
|
||||
dacRefresh32 = _DAC_CTRL_REFRSEL_32CYCLES, /**< Refresh every 32 prescaled cycles. */
|
||||
dacRefresh64 = _DAC_CTRL_REFRSEL_64CYCLES /**< Refresh every 64 prescaled cycles. */
|
||||
} DAC_Refresh_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** DAC init structure, common for both channels. */
|
||||
typedef struct
|
||||
{
|
||||
/** Refresh interval. Only used if REFREN bit set for a DAC channel. */
|
||||
DAC_Refresh_TypeDef refresh;
|
||||
|
||||
/** Reference voltage to use. */
|
||||
DAC_Ref_TypeDef reference;
|
||||
|
||||
/** Output mode */
|
||||
DAC_Output_TypeDef outMode;
|
||||
|
||||
/** Conversion mode. */
|
||||
DAC_ConvMode_TypeDef convMode;
|
||||
|
||||
/**
|
||||
* Prescaler used to get DAC clock. Derived as follows:
|
||||
* DACclk=HFPERclk/(2^prescale). The DAC clock should be <= 1MHz.
|
||||
*/
|
||||
uint8_t prescale;
|
||||
|
||||
/** Enable/disable use of low pass filter on output. */
|
||||
bool lpEnable;
|
||||
|
||||
/** Enable/disable reset of prescaler on ch0 start. */
|
||||
bool ch0ResetPre;
|
||||
|
||||
/** Enable/disable output enable control by CH1 PRS signal. */
|
||||
bool outEnablePRS;
|
||||
|
||||
/** Enable/disable sine mode. */
|
||||
bool sineEnable;
|
||||
|
||||
/** Select if single ended or differential mode. */
|
||||
bool diff;
|
||||
} DAC_Init_TypeDef;
|
||||
|
||||
/** Default config for DAC init structure. */
|
||||
#define DAC_INIT_DEFAULT \
|
||||
{ dacRefresh8, /* Refresh every 8 prescaled cycles. */ \
|
||||
dacRef1V25, /* 1.25V internal reference. */ \
|
||||
dacOutputPin, /* Output to pin only. */ \
|
||||
dacConvModeContinuous, /* Continuous mode. */ \
|
||||
0, /* No prescaling. */ \
|
||||
false, /* Do not enable low pass filter. */ \
|
||||
false, /* Do not reset prescaler on ch0 start. */ \
|
||||
false, /* DAC output enable always on. */ \
|
||||
false, /* Disable sine mode. */ \
|
||||
false /* Single ended mode. */ \
|
||||
}
|
||||
|
||||
|
||||
/** DAC channel init structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Enable channel. */
|
||||
bool enable;
|
||||
|
||||
/**
|
||||
* Peripheral reflex system trigger enable. If false, channel is triggered
|
||||
* by writing to CHnDATA.
|
||||
*/
|
||||
bool prsEnable;
|
||||
|
||||
/**
|
||||
* Enable/disable automatic refresh of channel. Refresh interval must be
|
||||
* defined in common control init, please see DAC_Init().
|
||||
*/
|
||||
bool refreshEnable;
|
||||
|
||||
/**
|
||||
* Peripheral reflex system trigger selection. Only applicable if @p prsEnable
|
||||
* is enabled.
|
||||
*/
|
||||
DAC_PRSSEL_TypeDef prsSel;
|
||||
} DAC_InitChannel_TypeDef;
|
||||
|
||||
/** Default config for DAC channel init structure. */
|
||||
#define DAC_INITCHANNEL_DEFAULT \
|
||||
{ false, /* Leave channel disabled when init done. */ \
|
||||
false, /* Disable PRS triggering. */ \
|
||||
false, /* Channel not refreshed automatically. */ \
|
||||
dacPRSSELCh0 /* Select PRS ch0 (if PRS triggering enabled). */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void DAC_Enable(DAC_TypeDef *dac, unsigned int ch, bool enable);
|
||||
void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init);
|
||||
void DAC_InitChannel(DAC_TypeDef *dac,
|
||||
const DAC_InitChannel_TypeDef *init,
|
||||
unsigned int ch);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending DAC interrupts.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending DAC interrupt source to clear. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the DAC module (DAC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void DAC_IntClear(DAC_TypeDef *dac, uint32_t flags)
|
||||
{
|
||||
dac->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more DAC interrupts.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* DAC interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the DAC module (DAC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void DAC_IntDisable(DAC_TypeDef *dac, uint32_t flags)
|
||||
{
|
||||
dac->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more DAC interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using DAC_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* DAC interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the DAC module (DAC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void DAC_IntEnable(DAC_TypeDef *dac, uint32_t flags)
|
||||
{
|
||||
dac->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending DAC interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* DAC interrupt sources pending. A bitwise logic OR combination of valid
|
||||
* interrupt flags for the DAC module (DAC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t DAC_IntGet(DAC_TypeDef *dac)
|
||||
{
|
||||
return(dac->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending DAC interrupts from SW.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* DAC interrupt sources to set to pending. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the DAC module (DAC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void DAC_IntSet(DAC_TypeDef *dac, uint32_t flags)
|
||||
{
|
||||
dac->IFS = flags;
|
||||
}
|
||||
|
||||
uint8_t DAC_PrescaleCalc(uint32_t dacFreq, uint32_t hfperFreq);
|
||||
void DAC_Reset(DAC_TypeDef *dac);
|
||||
|
||||
/** @} (end addtogroup DAC) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_DAC_H */
|
|
@ -0,0 +1,84 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Debug (DBG) API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_DBG_H
|
||||
#define __EFM32_DBG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup DBG
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check if a debugger is connected (and debug session activated)
|
||||
*
|
||||
* @details
|
||||
* Used to make run-time decisions depending on whether a debug session
|
||||
* has been active since last reset, ie using a debug probe or similar. In
|
||||
* some cases special handling is required in that scenario.
|
||||
*
|
||||
* @return
|
||||
* true if a debug session is active since last reset, otherwise false.
|
||||
******************************************************************************/
|
||||
static __INLINE bool DBG_Connected(void)
|
||||
{
|
||||
if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void DBG_SWOEnable(unsigned int location);
|
||||
|
||||
/** @} (end addtogroup DBG) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_DBG_H */
|
|
@ -0,0 +1,457 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Direct memory access (DMA) API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __EFM32_DMA_H
|
||||
#define __EFM32_DMA_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup DMA
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Amount source/destination address should be incremented for each data
|
||||
* transfer.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
dmaDataInc1 = _DMA_CTRL_SRC_INC_BYTE, /**< Increment address 1 byte. */
|
||||
dmaDataInc2 = _DMA_CTRL_SRC_INC_HALFWORD, /**< Increment address 2 bytes. */
|
||||
dmaDataInc4 = _DMA_CTRL_SRC_INC_WORD, /**< Increment address 4 bytes. */
|
||||
dmaDataIncNone = _DMA_CTRL_SRC_INC_NONE /**< Do not increment address. */
|
||||
} DMA_DataInc_TypeDef;
|
||||
|
||||
|
||||
/** Data sizes (in number of bytes) to be read/written by DMA transfer. */
|
||||
typedef enum
|
||||
{
|
||||
dmaDataSize1 = _DMA_CTRL_SRC_SIZE_BYTE, /**< 1 byte DMA transfer size. */
|
||||
dmaDataSize2 = _DMA_CTRL_SRC_SIZE_HALFWORD, /**< 2 byte DMA transfer size. */
|
||||
dmaDataSize4 = _DMA_CTRL_SRC_SIZE_WORD /**< 4 byte DMA transfer size. */
|
||||
} DMA_DataSize_TypeDef;
|
||||
|
||||
|
||||
/** Type of DMA transfer. */
|
||||
typedef enum
|
||||
{
|
||||
/** Basic DMA cycle. */
|
||||
dmaCycleCtrlBasic = _DMA_CTRL_CYCLE_CTRL_BASIC,
|
||||
/** Auto-request DMA cycle. */
|
||||
dmaCycleCtrlAuto = _DMA_CTRL_CYCLE_CTRL_AUTO,
|
||||
/** Ping-pong DMA cycle. */
|
||||
dmaCycleCtrlPingPong = _DMA_CTRL_CYCLE_CTRL_PINGPONG,
|
||||
/** Memory scatter-gather DMA cycle. */
|
||||
dmaCycleCtrlMemScatterGather = _DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER,
|
||||
/** Peripheral scatter-gather DMA cycle. */
|
||||
dmaCycleCtrlPerScatterGather = _DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER
|
||||
} DMA_CycleCtrl_TypeDef;
|
||||
|
||||
|
||||
/** Number of transfers before controller does new arbitration. */
|
||||
typedef enum
|
||||
{
|
||||
dmaArbitrate1 = _DMA_CTRL_R_POWER_1, /**< Arbitrate after 1 DMA transfer. */
|
||||
dmaArbitrate2 = _DMA_CTRL_R_POWER_2, /**< Arbitrate after 2 DMA transfers. */
|
||||
dmaArbitrate4 = _DMA_CTRL_R_POWER_4, /**< Arbitrate after 4 DMA transfers. */
|
||||
dmaArbitrate8 = _DMA_CTRL_R_POWER_8, /**< Arbitrate after 8 DMA transfers. */
|
||||
dmaArbitrate16 = _DMA_CTRL_R_POWER_16, /**< Arbitrate after 16 DMA transfers. */
|
||||
dmaArbitrate32 = _DMA_CTRL_R_POWER_32, /**< Arbitrate after 32 DMA transfers. */
|
||||
dmaArbitrate64 = _DMA_CTRL_R_POWER_64, /**< Arbitrate after 64 DMA transfers. */
|
||||
dmaArbitrate128 = _DMA_CTRL_R_POWER_128, /**< Arbitrate after 128 DMA transfers. */
|
||||
dmaArbitrate256 = _DMA_CTRL_R_POWER_256, /**< Arbitrate after 256 DMA transfers. */
|
||||
dmaArbitrate512 = _DMA_CTRL_R_POWER_512, /**< Arbitrate after 512 DMA transfers. */
|
||||
dmaArbitrate1024 = _DMA_CTRL_R_POWER_1024 /**< Arbitrate after 1024 DMA transfers. */
|
||||
} DMA_ArbiterConfig_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* DMA interrupt callback function pointer.
|
||||
* @details
|
||||
* Parameters:
|
||||
* @li channel - The DMA channel the callback function is invoked for.
|
||||
* @li primary - Indicates if callback is invoked for completion of primary
|
||||
* (true) or alternate (false) descriptor. This is mainly useful for
|
||||
* ping-pong DMA cycles, in order to know which descriptor to refresh.
|
||||
* @li user - User definable reference that may be used to pass information
|
||||
* to be used by the callback handler. If used, the referenced data must be
|
||||
* valid at the point when the interrupt handler invokes the callback.
|
||||
* If callback changes any data in the provided user structure, remember
|
||||
* that those changes are done in interrupt context, and proper protection
|
||||
* of data may be required.
|
||||
*/
|
||||
typedef void (*DMA_FuncPtr_TypeDef)(unsigned int channel, bool primary, void *user);
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Callback structure that can be used to define DMA complete actions.
|
||||
* @details
|
||||
* A reference to this structure is only stored in the primary descriptor
|
||||
* for a channel (if callback feature is used). If callback is required
|
||||
* for both primary and alternate descriptor completion, this must be
|
||||
* handled by one common callback, using the provided 'primary' parameter
|
||||
* with the callback function.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Pointer to callback function to invoke when DMA transfer cycle done.
|
||||
* Notice that this function is invoked in interrupt context, and therefore
|
||||
* should be short and non-blocking.
|
||||
*/
|
||||
DMA_FuncPtr_TypeDef cbFunc;
|
||||
|
||||
/** User defined pointer to provide with callback function. */
|
||||
void *userPtr;
|
||||
|
||||
/**
|
||||
* For internal use only: Indicates if next callback applies to primary
|
||||
* or alternate descriptor completion. Mainly useful for ping-pong DMA
|
||||
* cycles. Set this value to 0 prior to configuring callback handling.
|
||||
*/
|
||||
uint8_t primary;
|
||||
} DMA_CB_TypeDef;
|
||||
|
||||
|
||||
/** Configuration structure for a channel. */
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Select if channel priority is in the high or default priority group
|
||||
* with respect to arbitration. Within a priority group, lower numbered
|
||||
* channels have higher priority than higher numbered channels.
|
||||
*/
|
||||
bool highPri;
|
||||
|
||||
/**
|
||||
* Select if interrupt shall be enabled for channel (triggering interrupt
|
||||
* handler when dma_done signal is asserted). It should normally be
|
||||
* enabled if using the callback feature for a channel, and disabled if
|
||||
* not using the callback feature.
|
||||
*/
|
||||
bool enableInt;
|
||||
|
||||
/**
|
||||
* Channel control specifying the source of DMA signals. If accessing
|
||||
* peripherals, use one of the DMAREQ_nnn defines available for the
|
||||
* peripheral. Set it to 0 for memory-to-memory DMA cycles.
|
||||
*/
|
||||
uint32_t select;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* User definable callback handling configuration.
|
||||
* @details
|
||||
* Please refer to structure definition for details. The callback
|
||||
* is invoked when the specified DMA cycle is complete (when dma_done
|
||||
* signal asserted). The callback is invoked in interrupt context,
|
||||
* and should be efficient and non-blocking. Set to NULL to not
|
||||
* use the callback feature.
|
||||
* @note
|
||||
* The referenced structure is used by the interrupt handler, and must
|
||||
* be available until no longer used. Thus, in most cases it should
|
||||
* not be located on the stack.
|
||||
*/
|
||||
DMA_CB_TypeDef *cb;
|
||||
} DMA_CfgChannel_TypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* Configuration structure for primary or alternate descriptor
|
||||
* (not used for scatter-gather DMA cycles).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Destination increment size for each DMA transfer */
|
||||
DMA_DataInc_TypeDef dstInc;
|
||||
|
||||
/** Source increment size for each DMA transfer */
|
||||
DMA_DataInc_TypeDef srcInc;
|
||||
|
||||
/** DMA transfer unit size. */
|
||||
DMA_DataSize_TypeDef size;
|
||||
|
||||
/**
|
||||
* Arbitration rate, ie number of DMA transfers done before rearbitration
|
||||
* takes place.
|
||||
*/
|
||||
DMA_ArbiterConfig_TypeDef arbRate;
|
||||
|
||||
/**
|
||||
* HPROT signal state, please refer to reference manual, DMA chapter for
|
||||
* further details. Normally set to 0 if protection is not an issue.
|
||||
* The following bits are available:
|
||||
* @li bit 0 - HPROT[1] control for source read accesses,
|
||||
* privileged/non-privileged access
|
||||
* @li bit 3 - HPROT[1] control for destination write accesses,
|
||||
* privileged/non-privileged access
|
||||
*/
|
||||
uint8_t hprot;
|
||||
} DMA_CfgDescr_TypeDef;
|
||||
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/**
|
||||
* Configuration structure for loop mode
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Enable repeated loop */
|
||||
bool enable;
|
||||
/** Width of transfer, reload value for nMinus1 */
|
||||
uint16_t nMinus1;
|
||||
} DMA_CfgLoop_TypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* Configuration structure for rectangular copy
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** DMA channel destination stride (width of destination image, distance between lines) */
|
||||
uint16_t dstStride;
|
||||
/** DMA channel source stride (width of source image, distance between lines) */
|
||||
uint16_t srcStride;
|
||||
/** 2D copy height */
|
||||
uint16_t height;
|
||||
} DMA_CfgRect_TypeDef;
|
||||
#endif
|
||||
|
||||
|
||||
/** Configuration structure for alternate scatter-gather descriptor. */
|
||||
typedef struct
|
||||
{
|
||||
/** Pointer to location to transfer data from. */
|
||||
void *src;
|
||||
|
||||
/** Pointer to location to transfer data to. */
|
||||
void *dst;
|
||||
|
||||
/** Destination increment size for each DMA transfer */
|
||||
DMA_DataInc_TypeDef dstInc;
|
||||
|
||||
/** Source increment size for each DMA transfer */
|
||||
DMA_DataInc_TypeDef srcInc;
|
||||
|
||||
/** DMA transfer unit size. */
|
||||
DMA_DataSize_TypeDef size;
|
||||
|
||||
/**
|
||||
* Arbitration rate, ie number of DMA transfers done before rearbitration
|
||||
* takes place.
|
||||
*/
|
||||
DMA_ArbiterConfig_TypeDef arbRate;
|
||||
|
||||
/** Number of DMA transfers minus 1 to do. Must be <= 1023. */
|
||||
uint16_t nMinus1;
|
||||
|
||||
/**
|
||||
* HPROT signal state, please refer to reference manual, DMA chapter for
|
||||
* further details. Normally set to 0 if protection is not an issue.
|
||||
* The following bits are available:
|
||||
* @li bit 0 - HPROT[1] control for source read accesses,
|
||||
* privileged/non-privileged access
|
||||
* @li bit 3 - HPROT[1] control for destination write accesses,
|
||||
* privileged/non-privileged access
|
||||
*/
|
||||
uint8_t hprot;
|
||||
|
||||
/** Specify if a memory or peripheral scatter-gather DMA cycle. Notice
|
||||
* that this parameter should be the same for all alternate
|
||||
* descriptors.
|
||||
* @li true - this is a peripheral scatter-gather cycle
|
||||
* @li false - this is a memory scatter-gather cycle
|
||||
*/
|
||||
bool peripheral;
|
||||
} DMA_CfgDescrSGAlt_TypeDef;
|
||||
|
||||
|
||||
/** DMA init structure */
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* HPROT signal state when accessing the primary/alternate
|
||||
* descriptors. Normally set to 0 if protection is not an issue.
|
||||
* The following bits are available:
|
||||
* @li bit 0 - HPROT[1] control for descriptor accesses (ie when
|
||||
* the DMA controller accesses the channel control block itself),
|
||||
* privileged/non-privileged access
|
||||
*/
|
||||
uint8_t hprot;
|
||||
|
||||
/**
|
||||
* Pointer to the controlblock in memory holding descriptors (channel
|
||||
* control data structures). This memory must be properly aligned
|
||||
* according to requirements.
|
||||
*
|
||||
* Alignment requirements are
|
||||
* a) 5 bits base requirement, bits [4:0]
|
||||
* b) Add the number of bits needed to represent the wanted number
|
||||
* of channels
|
||||
* c) Align structure with this number of bits set to zero
|
||||
*
|
||||
* Examples: 4 channels, 5 + 2 (channels 0 to 3) = 7 bits
|
||||
* 7 bit alignment, 64 byte address alignment
|
||||
* 8 channels, 5 + 3 (channels 0 to 7) = 8 bits
|
||||
* 8 bit alignment, 256 byte address alignment
|
||||
* 12 channels, 5 + 4 (channels 0 to 11) = 9 bits
|
||||
* 9 bit alignment, 512 byte address alignment
|
||||
*
|
||||
* Please refer to the reference manual, DMA chapter for more details.
|
||||
*
|
||||
* It is possible to provide a smaller memory block, only covering
|
||||
* those channels actually used, if not all available channels are used.
|
||||
* Ie, if only using 4 channels (0-3), both primary and alternate
|
||||
* structures, then only 16*2*4 = 128 bytes must be provided. This
|
||||
* implementation has however no check if later exceeding such a limit
|
||||
* by configuring for instance channel 4, in which case memory overwrite
|
||||
* of some other data will occur.
|
||||
*/
|
||||
DMA_DESCRIPTOR_TypeDef *controlBlock;
|
||||
} DMA_Init_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void DMA_ActivateAuto(unsigned int channel,
|
||||
bool primary,
|
||||
void *dst,
|
||||
void *src,
|
||||
unsigned int nMinus1);
|
||||
void DMA_ActivateBasic(unsigned int channel,
|
||||
bool primary,
|
||||
bool useBurst,
|
||||
void *dst,
|
||||
void *src,
|
||||
unsigned int nMinus1);
|
||||
void DMA_ActivatePingPong(unsigned int channel,
|
||||
bool useBurst,
|
||||
void *primDst,
|
||||
void *primSrc,
|
||||
unsigned int primNMinus1,
|
||||
void *altDst,
|
||||
void *altSrc,
|
||||
unsigned int altNMinus1);
|
||||
void DMA_ActivateScatterGather(unsigned int channel,
|
||||
bool useBurst,
|
||||
DMA_DESCRIPTOR_TypeDef *altDescr,
|
||||
unsigned int count);
|
||||
void DMA_CfgChannel(unsigned int channel, DMA_CfgChannel_TypeDef *cfg);
|
||||
void DMA_CfgDescr(unsigned int channel,
|
||||
bool primary,
|
||||
DMA_CfgDescr_TypeDef *cfg);
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
void DMA_CfgLoop(unsigned int channel, DMA_CfgLoop_TypeDef *cfg);
|
||||
void DMA_CfgRect(unsigned int channel, DMA_CfgRect_TypeDef *cfg);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear Loop configuration for channel
|
||||
*
|
||||
* @param[in] channel
|
||||
* Channel to reset loop configuration for
|
||||
******************************************************************************/
|
||||
static __INLINE void DMA_ResetLoop(unsigned int channel)
|
||||
{
|
||||
/* Clean loop copy operation */
|
||||
switch(channel)
|
||||
{
|
||||
case 0:
|
||||
DMA->LOOP0 = _DMA_LOOP0_RESETVALUE;
|
||||
break;
|
||||
case 1:
|
||||
DMA->LOOP1 = _DMA_LOOP1_RESETVALUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear Rect/2D DMA configuration for channel
|
||||
*
|
||||
* @param[in] channel
|
||||
* Channel to reset loop configuration for
|
||||
******************************************************************************/
|
||||
static __INLINE void DMA_ResetRect(unsigned int channel)
|
||||
{
|
||||
(void) channel;
|
||||
|
||||
/* Clear rect copy operation */
|
||||
DMA->RECT0 = _DMA_RECT0_RESETVALUE;
|
||||
}
|
||||
#endif
|
||||
void DMA_CfgDescrScatterGather(DMA_DESCRIPTOR_TypeDef *descr,
|
||||
unsigned int indx,
|
||||
DMA_CfgDescrSGAlt_TypeDef *cfg);
|
||||
bool DMA_ChannelEnabled(unsigned int channel);
|
||||
void DMA_Init(DMA_Init_TypeDef *init);
|
||||
void DMA_IRQHandler(void);
|
||||
void DMA_RefreshPingPong(unsigned int channel,
|
||||
bool primary,
|
||||
bool useBurst,
|
||||
void *dst,
|
||||
void *src,
|
||||
unsigned int nMinus1,
|
||||
bool last);
|
||||
void DMA_Reset(void);
|
||||
|
||||
/** @} (end addtogroup DMA) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_DMA_H */
|
|
@ -0,0 +1,789 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief External Bus Iterface (EBI) peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_EBI_H
|
||||
#define __EFM32_EBI_H
|
||||
|
||||
#include "efm32.h"
|
||||
|
||||
#if defined(EBI_COUNT) && (EBI_COUNT > 0)
|
||||
#include "efm32_assert.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EBI
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @verbatim
|
||||
*
|
||||
* --------- ---------
|
||||
* | EBI | /| |\ | Ext. |
|
||||
* | | / --------- \ | Async |
|
||||
* |(EFM32)| \ --------- / | Device|
|
||||
* | | \| |/ | |
|
||||
* --------- ---------
|
||||
* Parallel interface
|
||||
*
|
||||
* @endverbatim
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
#define EBI_BANK0 (uint32_t)(1 << 1) /**< EBI address bank 0 */
|
||||
#define EBI_BANK1 (uint32_t)(1 << 2) /**< EBI address bank 1 */
|
||||
#define EBI_BANK2 (uint32_t)(1 << 3) /**< EBI address bank 2 */
|
||||
#define EBI_BANK3 (uint32_t)(1 << 4) /**< EBI address bank 3 */
|
||||
|
||||
#define EBI_CS0 (uint32_t)(1 << 1) /**< EBI chip select line 0 */
|
||||
#define EBI_CS1 (uint32_t)(1 << 2) /**< EBI chip select line 1 */
|
||||
#define EBI_CS2 (uint32_t)(1 << 3) /**< EBI chip select line 2 */
|
||||
#define EBI_CS3 (uint32_t)(1 << 4) /**< EBI chip select line 3 */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** EBI Mode of operation */
|
||||
typedef enum
|
||||
{
|
||||
/** 8 data bits, 8 address bits */
|
||||
ebiModeD8A8 = EBI_CTRL_MODE_D8A8,
|
||||
/** 16 data bits, 16 address bits, using address latch enable */
|
||||
ebiModeD16A16ALE = EBI_CTRL_MODE_D16A16ALE,
|
||||
/** 8 data bits, 24 address bits, using address latch enable */
|
||||
ebiModeD8A24ALE = EBI_CTRL_MODE_D8A24ALE,
|
||||
/** Mode D16 */
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
ebiModeD16 = EBI_CTRL_MODE_D16,
|
||||
#endif
|
||||
} EBI_Mode_TypeDef;
|
||||
|
||||
/** EBI Polarity configuration */
|
||||
typedef enum
|
||||
{
|
||||
/** Active Low */
|
||||
ebiActiveLow = 0,
|
||||
/** Active High */
|
||||
ebiActiveHigh = 1
|
||||
} EBI_Polarity_TypeDef;
|
||||
|
||||
/** EBI Pin Line types */
|
||||
typedef enum
|
||||
{
|
||||
/** Address Ready line */
|
||||
ebiLineARDY,
|
||||
/** Address Latch Enable line */
|
||||
ebiLineALE,
|
||||
/** Write Enable line */
|
||||
ebiLineWE,
|
||||
/** Read Enable line */
|
||||
ebiLineRE,
|
||||
/** Chip Select line */
|
||||
ebiLineCS,
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** BL line */
|
||||
ebiLineBL,
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** TFT VSYNC line */
|
||||
ebiLineTFTVSync,
|
||||
/** TFT HSYNC line */
|
||||
ebiLineTFTHSync,
|
||||
/** TFT Data enable line */
|
||||
ebiLineTFTDataEn,
|
||||
/** TFT DCLK line */
|
||||
ebiLineTFTDClk,
|
||||
/** TFT Chip select line */
|
||||
ebiLineTFTCS,
|
||||
#endif
|
||||
} EBI_Line_TypeDef;
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** Address Pin Enable, lower limit - lower range of pins to enable */
|
||||
typedef enum
|
||||
{
|
||||
/** Adress lines EBI_A[0] and upwards are enabled by APEN */
|
||||
ebiALowA0 = EBI_ROUTE_ALB_A0,
|
||||
/** Adress lines EBI_A[8] and upwards are enabled by APEN */
|
||||
ebiALowA8 = EBI_ROUTE_ALB_A8,
|
||||
/** Adress lines EBI_A[16] and upwards are enabled by APEN */
|
||||
ebiALowA16 = EBI_ROUTE_ALB_A16,
|
||||
/** Adress lines EBI_A[24] and upwards are enabled by APEN */
|
||||
ebiALowA24 = EBI_ROUTE_ALB_A24,
|
||||
} EBI_ALow_TypeDef;
|
||||
|
||||
/** Adress Pin Enable, high limit - higher limit of pins to enable */
|
||||
typedef enum
|
||||
{
|
||||
/** All EBI_A pins are disabled */
|
||||
ebiAHighA0 = EBI_ROUTE_APEN_A0,
|
||||
/** All EBI_A[4:ALow] are enabled */
|
||||
ebiAHighA5 = EBI_ROUTE_APEN_A5,
|
||||
/** All EBI_A[5:ALow] are enabled */
|
||||
ebiAHighA6 = EBI_ROUTE_APEN_A6,
|
||||
/** All EBI_A[6:ALow] are enabled */
|
||||
ebiAHighA7 = EBI_ROUTE_APEN_A7,
|
||||
/** All EBI_A[7:ALow] are enabled */
|
||||
ebiAHighA8 = EBI_ROUTE_APEN_A8,
|
||||
/** All EBI_A[8:ALow] are enabled */
|
||||
ebiAHighA9 = EBI_ROUTE_APEN_A9,
|
||||
/** All EBI_A[9:ALow] are enabled */
|
||||
ebiAHighA10 = EBI_ROUTE_APEN_A10,
|
||||
/** All EBI_A[10:ALow] are enabled */
|
||||
ebiAHighA11 = EBI_ROUTE_APEN_A11,
|
||||
/** All EBI_A[11:ALow] are enabled */
|
||||
ebiAHighA12 = EBI_ROUTE_APEN_A12,
|
||||
/** All EBI_A[12:ALow] are enabled */
|
||||
ebiAHighA13 = EBI_ROUTE_APEN_A13,
|
||||
/** All EBI_A[13:ALow] are enabled */
|
||||
ebiAHighA14 = EBI_ROUTE_APEN_A14,
|
||||
/** All EBI_A[14:ALow] are enabled */
|
||||
ebiAHighA15 = EBI_ROUTE_APEN_A15,
|
||||
/** All EBI_A[15:ALow] are enabled */
|
||||
ebiAHighA16 = EBI_ROUTE_APEN_A16,
|
||||
/** All EBI_A[16:ALow] are enabled */
|
||||
ebiAHighA17 = EBI_ROUTE_APEN_A17,
|
||||
/** All EBI_A[17:ALow] are enabled */
|
||||
ebiAHighA18 = EBI_ROUTE_APEN_A18,
|
||||
/** All EBI_A[18:ALow] are enabled */
|
||||
ebiAHighA19 = EBI_ROUTE_APEN_A19,
|
||||
/** All EBI_A[19:ALow] are enabled */
|
||||
ebiAHighA20 = EBI_ROUTE_APEN_A20,
|
||||
/** All EBI_A[20:ALow] are enabled */
|
||||
ebiAHighA21 = EBI_ROUTE_APEN_A21,
|
||||
/** All EBI_A[21:ALow] are enabled */
|
||||
ebiAHighA22 = EBI_ROUTE_APEN_A22,
|
||||
/** All EBI_A[22:ALow] are enabled */
|
||||
ebiAHighA23 = EBI_ROUTE_APEN_A23,
|
||||
/** All EBI_A[23:ALow] are enabled */
|
||||
ebiAHighA24 = EBI_ROUTE_APEN_A24,
|
||||
/** All EBI_A[24:ALow] are enabled */
|
||||
ebiAHighA25 = EBI_ROUTE_APEN_A25,
|
||||
/** All EBI_A[25:ALow] are enabled */
|
||||
ebiAHighA26 = EBI_ROUTE_APEN_A26,
|
||||
/** All EBI_A[26:ALow] are enabled */
|
||||
ebiAHighA27 = EBI_ROUTE_APEN_A27,
|
||||
/** All EBI_A[27:ALow] are enabled */
|
||||
ebiAHighA28 = EBI_ROUTE_APEN_A28,
|
||||
} EBI_AHigh_TypeDef;
|
||||
|
||||
/** EBI I/O Alternate Pin Location */
|
||||
typedef enum {
|
||||
/** EBI PIN I/O Location 0 */
|
||||
ebiLocation0 = EBI_ROUTE_LOCATION_LOC0,
|
||||
/** EBI PIN I/O Location 1 */
|
||||
ebiLocation1 = EBI_ROUTE_LOCATION_LOC1,
|
||||
/** EBI PIN I/O Location 2 */
|
||||
ebiLocation2 = EBI_ROUTE_LOCATION_LOC2,
|
||||
/** EBI PIN I/O Location 3 */
|
||||
// ebiLocation3 = EBI_ROUTE_LOCATION_LOC3,
|
||||
} EBI_Location_TypeDef;
|
||||
#endif
|
||||
|
||||
/* TFT support */
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** EBI TFT Graphics Bank Select */
|
||||
typedef enum
|
||||
{
|
||||
/** Memory BANK0 contains frame buffer */
|
||||
ebiTFTBank0 = EBI_TFTCTRL_BANKSEL_BANK0,
|
||||
/** Memory BANK1 contains frame buffer */
|
||||
ebiTFTBank1 = EBI_TFTCTRL_BANKSEL_BANK1,
|
||||
/** Memory BANK2 contains frame buffer */
|
||||
ebiTFTBank2 = EBI_TFTCTRL_BANKSEL_BANK2,
|
||||
/** Memory BANK3 contains frame buffer */
|
||||
ebiTFTBank3 = EBI_TFTCTRL_BANKSEL_BANK3
|
||||
} EBI_TFTBank_TypeDef;
|
||||
|
||||
/** Masking and Alpha blending source color*/
|
||||
typedef enum
|
||||
{
|
||||
/** Use memory as source color for masking/alpha blending */
|
||||
ebiTFTColorSrcMem = EBI_TFTCTRL_COLOR1SRC_MEM,
|
||||
/** Use PIXEL1 register as source color for masking/alpha blending */
|
||||
ebiTFTColorSrcPixel1 = EBI_TFTCTRL_COLOR1SRC_PIXEL1,
|
||||
} EBI_TFTColorSrc_TypeDef;
|
||||
|
||||
/** Bus Data Interleave Mode */
|
||||
typedef enum
|
||||
{
|
||||
/** Unlimited interleaved accesses per EBI_DCLK period. Can cause jitter */
|
||||
ebiTFTInterleaveUnlimited = EBI_TFTCTRL_INTERLEAVE_UNLIMITED,
|
||||
/** Allow 1 interleaved access per EBI_DCLK period */
|
||||
ebiTFTInterleaveOnePerDClk = EBI_TFTCTRL_INTERLEAVE_ONEPERDCLK,
|
||||
/** Only allow accesses during porch periods */
|
||||
ebiTFTInterleavePorch = EBI_TFTCTRL_INTERLEAVE_PORCH,
|
||||
} EBI_TFTInterleave_TypeDef;
|
||||
|
||||
/** Control frame base pointer copy */
|
||||
typedef enum
|
||||
{
|
||||
/** Trigger update of frame buffer pointer on vertical sync */
|
||||
ebiTFTFrameBufTriggerVSync = EBI_TFTCTRL_FBCTRIG_VSYNC,
|
||||
/** Trigger update of frame buffer pointer on horizontal sync */
|
||||
ebiTFTFrameBufTriggerHSync = EBI_TFTCTRL_FBCTRIG_HSYNC,
|
||||
} EBI_TFTFrameBufTrigger_TypeDef;
|
||||
|
||||
/** Control of mask and alpha blending mode */
|
||||
typedef enum
|
||||
{
|
||||
/** Masking and blending are disabled */
|
||||
ebiTFTMBDisabled = EBI_TFTCTRL_MASKBLEND_DISABLED,
|
||||
/** Internal masking */
|
||||
ebiTFTMBIMask = EBI_TFTCTRL_MASKBLEND_IMASK,
|
||||
/** Internal alpha blending */
|
||||
ebiTFTMBIAlpha = EBI_TFTCTRL_MASKBLEND_IALPHA,
|
||||
/** Internal masking and alpha blending are enabled */
|
||||
ebiTFTMBIMaskAlpha = EBI_TFTCTRL_MASKBLEND_IMASKIALPHA,
|
||||
/** External masking */
|
||||
ebiTFTMBEMask = EBI_TFTCTRL_MASKBLEND_EMASK,
|
||||
/** External alpha blending */
|
||||
ebiTFTMBEAlpha = EBI_TFTCTRL_MASKBLEND_EALPHA,
|
||||
/** External masking and alpha blending */
|
||||
ebiTFTMBEMaskAlpha = EBI_TFTCTRL_MASKBLEND_EMASKEALPHA,
|
||||
} EBI_TFTMaskBlend_TypeDef;
|
||||
|
||||
/** TFT Direct Drive mode */
|
||||
typedef enum
|
||||
{
|
||||
/** Disabled */
|
||||
ebiTFTDDModeDisabled = EBI_TFTCTRL_DD_DISABLED,
|
||||
/** Direct Drive from internal memory */
|
||||
ebiTFTDDModeInternal = EBI_TFTCTRL_DD_INTERNAL,
|
||||
/** Direct Drive from external memory */
|
||||
ebiTFTDDModeExternal = EBI_TFTCTRL_DD_EXTERNAL,
|
||||
} EBI_TFTDDMode_TypeDef;
|
||||
|
||||
/** TFT Data Increment Width */
|
||||
typedef enum
|
||||
{
|
||||
/** Pixel increments are 1 byte at a time */
|
||||
ebiTFTWidthByte = EBI_TFTCTRL_WIDTH_BYTE,
|
||||
/** Pixel increments are 2 bytes (half word) */
|
||||
ebiTFTWidthHalfWord = EBI_TFTCTRL_WIDTH_HALFWORD,
|
||||
} EBI_TFTWidth_TypeDef;
|
||||
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** EBI Initialization structure */
|
||||
typedef struct
|
||||
{
|
||||
/** EBI operation mode, data and address limits */
|
||||
EBI_Mode_TypeDef mode;
|
||||
/** Address Ready pin polarity, active high or low */
|
||||
EBI_Polarity_TypeDef ardyPolarity;
|
||||
/** Address Latch Enable pin polarity, active high or low */
|
||||
EBI_Polarity_TypeDef alePolarity;
|
||||
/** Write Enable pin polarity, active high or low */
|
||||
EBI_Polarity_TypeDef wePolarity;
|
||||
/** Read Enable pin polarity, active high or low */
|
||||
EBI_Polarity_TypeDef rePolarity;
|
||||
/** Chip Select pin polarity, active high or low */
|
||||
EBI_Polarity_TypeDef csPolarity;
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** Byte Lane pin polaritym, active high or low */
|
||||
EBI_Polarity_TypeDef blPolarity;
|
||||
/** Flag to enable or disable Byte Lane support */
|
||||
bool blEnable;
|
||||
/** Flag to enable or disable idle state insertion between transfers */
|
||||
bool noIdle;
|
||||
#endif
|
||||
/** Flag to enable or disable Address Ready support */
|
||||
bool ardyEnable;
|
||||
/** Set to turn off 32 cycle timeout ability */
|
||||
bool ardyDisableTimeout;
|
||||
/** Mask of flags which selects address banks to configure EBI_BANK<0-3> */
|
||||
uint32_t banks;
|
||||
/** Mask of flags which selects chip select lines to configure EBI_CS<0-3> */
|
||||
uint32_t csLines;
|
||||
/** Number of cycles address is held after Adress Latch Enable is asserted */
|
||||
int addrSetupCycles;
|
||||
/** Number of cycles address is driven onto the ADDRDAT bus before ALE is asserted */
|
||||
int addrHoldCycles;
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** Enable or disables half cycle duration of the ALE strobe in the last address setup cycle */
|
||||
bool addrHalfALE;
|
||||
#endif
|
||||
/** Number of cycles for address setup before REn is asserted */
|
||||
int readSetupCycles;
|
||||
/** Number of cycles REn is held active */
|
||||
int readStrobeCycles;
|
||||
/** Number of cycles CSn is held active after REn is deasserted */
|
||||
int readHoldCycles;
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** Enable or disable page mode reads */
|
||||
bool readPageMode;
|
||||
/** Enables or disable prefetching from sequential addresses */
|
||||
bool readPrefetch;
|
||||
/** Enabled or disables half cycle duration of the REn signal in the last strobe cycle */
|
||||
bool readHalfRE;
|
||||
#endif
|
||||
/** Number of cycles for address setup before WEn is asserted */
|
||||
int writeSetupCycles;
|
||||
/** Number of cycles WEn is held active */
|
||||
int writeStrobeCycles;
|
||||
/** Number of cycles CSn is held active after WEn is deasserted */
|
||||
int writeHoldCycles;
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** Enable or disable the write buffer */
|
||||
bool writeBufferDisable;
|
||||
/** Enables or disables half cycle duration of the WEn signal in the last strobe cycle */
|
||||
bool writeHalfWE;
|
||||
/** Lower address pin limit to enable */
|
||||
EBI_ALow_TypeDef aLow;
|
||||
/** High address pin limit to enable */
|
||||
EBI_AHigh_TypeDef aHigh;
|
||||
/** Pin Location */
|
||||
EBI_Location_TypeDef location;
|
||||
#endif
|
||||
/** Flag, if EBI should be enabled after configuration */
|
||||
bool enable;
|
||||
} EBI_Init_TypeDef;
|
||||
|
||||
/** Default config for EBI init structures */
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
#define EBI_INIT_DEFAULT \
|
||||
{ ebiModeD8A8, /* 8 bit address, 8 bit data */ \
|
||||
ebiActiveLow, /* ARDY polarity */ \
|
||||
ebiActiveLow, /* ALE polarity */ \
|
||||
ebiActiveLow, /* WE polarity */ \
|
||||
ebiActiveLow, /* RE polarity */ \
|
||||
ebiActiveLow, /* CS polarity */ \
|
||||
ebiActiveLow, /* BL polarity */ \
|
||||
false, /* enable BL */ \
|
||||
false, /* enable NOIDLE */ \
|
||||
false, /* enable ARDY */ \
|
||||
false, /* don't disable ARDY timeout */ \
|
||||
EBI_BANK0, /* enable bank 0 */ \
|
||||
EBI_CS0, /* enable chip select 0 */ \
|
||||
0, /* addr setup cycles */ \
|
||||
1, /* addr hold cycles */ \
|
||||
false, /* do not enable half cycle ALE strobe */ \
|
||||
0, /* read setup cycles */ \
|
||||
0, /* read strobe cycles */ \
|
||||
0, /* read hold cycles */ \
|
||||
false, /* disable page mode */ \
|
||||
false, /* disable prefetch */ \
|
||||
false, /* do not enable half cycle REn strobe */ \
|
||||
0, /* write setup cycles */ \
|
||||
0, /* write strobe cycles */ \
|
||||
1, /* write hold cycles */ \
|
||||
false, /* do not disable the write buffer */ \
|
||||
false, /* do not enable halc cycle WEn strobe */ \
|
||||
ebiALowA0, /* ALB - Low bound, address lines */ \
|
||||
ebiAHighA0, /* APEN - High bound, address lines */ \
|
||||
ebiLocation0, /* Use Location 0 */ \
|
||||
true, /* enable EBI */ \
|
||||
}
|
||||
#else
|
||||
#define EBI_INIT_DEFAULT \
|
||||
{ ebiModeD8A8, /* 8 bit address, 8 bit data */ \
|
||||
ebiActiveLow, /* ARDY polarity */ \
|
||||
ebiActiveLow, /* ALE polarity */ \
|
||||
ebiActiveLow, /* WE polarity */ \
|
||||
ebiActiveLow, /* RE polarity */ \
|
||||
ebiActiveLow, /* CS polarity */ \
|
||||
false, /* enable ARDY */ \
|
||||
false, /* don't disable ARDY timeout */ \
|
||||
EBI_BANK0, /* enable bank 0 */ \
|
||||
EBI_CS0, /* enable chip select 0 */ \
|
||||
0, /* addr setup cycles */ \
|
||||
1, /* addr hold cycles */ \
|
||||
0, /* read setup cycles */ \
|
||||
0, /* read strobe cycles */ \
|
||||
0, /* read hold cycles */ \
|
||||
0, /* write setup cycles */ \
|
||||
0, /* write strobe cycles */ \
|
||||
1, /* write hold cycles */ \
|
||||
true, /* enable EBI */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
|
||||
/** TFT Initialization structure */
|
||||
typedef struct
|
||||
{
|
||||
/** External memory bank for driving display */
|
||||
EBI_TFTBank_TypeDef bank;
|
||||
/** Width */
|
||||
EBI_TFTWidth_TypeDef width;
|
||||
/** Color source for masking and alpha blending */
|
||||
EBI_TFTColorSrc_TypeDef colSrc;
|
||||
/** Bus Interleave mode */
|
||||
EBI_TFTInterleave_TypeDef interleave;
|
||||
/** Trigger for updating frame buffer pointer */
|
||||
EBI_TFTFrameBufTrigger_TypeDef fbTrigger;
|
||||
/** Drive DCLK from negative clock edge of internal clock */
|
||||
bool shiftDClk;
|
||||
/** Masking and alpha blending mode */
|
||||
EBI_TFTMaskBlend_TypeDef maskBlend;
|
||||
/** TFT Direct Drive mode */
|
||||
EBI_TFTDDMode_TypeDef driveMode;
|
||||
/** TFT Polarity for Chip Select (CS) Line */
|
||||
EBI_Polarity_TypeDef csPolarity;
|
||||
/** TFT Polarity for Data Clock (DCLK) Line */
|
||||
EBI_Polarity_TypeDef dclkPolarity;
|
||||
/** TFT Polarity for Data Enable (DATAEN) Line */
|
||||
EBI_Polarity_TypeDef dataenPolarity;
|
||||
/** TFT Polarity for Horizontal Sync (HSYNC) Line */
|
||||
EBI_Polarity_TypeDef hsyncPolarity;
|
||||
/** TFT Polarity for Vertical Sync (VSYNC) Line */
|
||||
EBI_Polarity_TypeDef vsyncPolarity;
|
||||
/** Horizontal size in pixels */
|
||||
int hsize;
|
||||
/** Horizontal Front Porch Size */
|
||||
int hPorchFront;
|
||||
/** Horizontal Back Porch Size */
|
||||
int hPorchBack;
|
||||
/** Horizontal Synchronization Pulse Width */
|
||||
int hPulseWidth;
|
||||
/** Vertical size in pixels */
|
||||
int vsize;
|
||||
/** Vertical Front Porch Size */
|
||||
int vPorchFront;
|
||||
/** Vertical Back Porch Size */
|
||||
int vPorchBack;
|
||||
/** Vertical Synchronization Pulse Width */
|
||||
int vPulseWidth;
|
||||
/** TFT Frame Buffer address, offset to EBI bank base address */
|
||||
uint32_t addressOffset;
|
||||
/** TFT DCLK period in internal cycles */
|
||||
int dclkPeriod;
|
||||
/** Starting position of External Direct Drive relative to DCLK inactive edge */
|
||||
int startPosition;
|
||||
/** Number of cycles RGB data is driven before active edge of DCLK */
|
||||
int setupCycles;
|
||||
/** Number of cycles RGB data is held after active edge of DCLK */
|
||||
int holdCycles;
|
||||
} EBI_TFTInit_TypeDef;
|
||||
|
||||
#define EBI_TFTINIT_DEFAULT \
|
||||
{ ebiTFTBank0, /* Select EBI Bank 0 */ \
|
||||
ebiTFTWidthHalfWord, /* Select 2-byte increments */ \
|
||||
ebiTFTColorSrcMem, /* Use memory as source for mask/blending */ \
|
||||
ebiTFTInterleaveUnlimited, /* Unlimited interleaved accesses */ \
|
||||
ebiTFTFrameBufTriggerVSync, /* VSYNC as frame buffer update trigger */ \
|
||||
false, /* Drive DCLK from negative edge of internal clock */ \
|
||||
ebiTFTMBDisabled, /* No masking and alpha blending enabled */ \
|
||||
ebiTFTDDModeExternal, /* Drive from external memory */ \
|
||||
ebiActiveLow, /* CS Active Low polarity */ \
|
||||
ebiActiveLow, /* DCLK Active Low polarity */ \
|
||||
ebiActiveLow, /* DATAEN Active Low polarity */ \
|
||||
ebiActiveLow, /* HSYNC Active Low polarity */ \
|
||||
ebiActiveLow, /* VSYNC Active Low polarity */ \
|
||||
320, /* Horizontal size in pixels */ \
|
||||
1, /* Horizontal Front Porch */ \
|
||||
29, /* Horizontal Back Porch */ \
|
||||
2, /* Horizontal Synchronization Pulse Width */ \
|
||||
240, /* Vertical size in pixels */ \
|
||||
1, /* Vertical Front Porch */ \
|
||||
4, /* Vertical Back Porch */ \
|
||||
2, /* Vertical Synchronization Pulse Width */ \
|
||||
0x0000, /* Address offset to EBI memory base */ \
|
||||
5, /* DCLK Period */ \
|
||||
2, /* DCLK Start */ \
|
||||
1, /* DCLK Setup cycles */ \
|
||||
1, /* DCLK Hold cycles */ \
|
||||
}
|
||||
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void EBI_Init(const EBI_Init_TypeDef *ebiInit);
|
||||
void EBI_Disable(void);
|
||||
uint32_t EBI_BankAddress(uint32_t bank);
|
||||
void EBI_BankEnable(uint32_t banks, bool enable);
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
void EBI_TFTInit(const EBI_TFTInit_TypeDef *ebiTFTInit);
|
||||
void EBI_TFTSizeSet(uint32_t horizontal, uint32_t vertical);
|
||||
void EBI_TFTHPorchSet(int front, int back, int pulseWidth);
|
||||
void EBI_TFTVPorchSet(int front, int back, int pulseWidth);
|
||||
void EBI_TFTTimingSet(int dclkPeriod, int start, int setup, int hold);
|
||||
#endif
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/* This functionality is only available on devices with independent timing support */
|
||||
void EBI_BankReadTimingSet(uint32_t bank, int setupCycles, int strobeCycles, int holdCycles);
|
||||
void EBI_BankReadTimingConfig(uint32_t bank, bool pageMode, bool prefetch, bool halfRE);
|
||||
|
||||
void EBI_BankWriteTimingSet(uint32_t bank, int setupCycles, int strobeCycles, int holdCycles);
|
||||
void EBI_BankWriteTimingConfig(uint32_t bank, bool writeBufDisable, bool halfWE);
|
||||
|
||||
void EBI_BankAddressTimingSet(uint32_t bank, int setupCycles, int holdCycles);
|
||||
void EBI_BankAddressTimingConfig(uint32_t bank, bool halfALE);
|
||||
|
||||
void EBI_BankPolaritySet(uint32_t bank, EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity);
|
||||
void EBI_BankByteLaneEnable(uint32_t bank, bool enable);
|
||||
void EBI_BankPage(uint32_t bank, bool enable);
|
||||
void EBI_AltMapEnable(bool enable);
|
||||
|
||||
/* TBD: NAND support */
|
||||
/* TBD: ECC support */
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable or disable TFT Direct Drive
|
||||
*
|
||||
* @param[in] mode
|
||||
* Drive from Internal or External memory, or Disable Direct Drive
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_TFTEnable(EBI_TFTDDMode_TypeDef mode)
|
||||
{
|
||||
EBI->TFTCTRL = (EBI->TFTCTRL & ~(_EBI_TFTCTRL_DD_MASK)) | (uint32_t) mode;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure frame buffer pointer
|
||||
*
|
||||
* @param[in] address
|
||||
* Frame pointer address, as offset by EBI base address
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_TFTFrameBaseSet(uint32_t address)
|
||||
{
|
||||
EBI->TFTFRAMEBASE = (uint32_t) address;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Set TFT Pixel Color 0 or 1
|
||||
*
|
||||
* @param[in] pixel
|
||||
* Which pixel instance to set
|
||||
* @param[in] color
|
||||
* Color of pixel, 16-bit value
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_TFTPixelSet(int pixel, uint32_t color)
|
||||
{
|
||||
EFM_ASSERT(pixel == 0 || pixel == 1);
|
||||
|
||||
if (pixel == 0)
|
||||
{
|
||||
EBI->TFTPIXEL0 = color;
|
||||
}
|
||||
if (pixel == 1)
|
||||
{
|
||||
EBI->TFTPIXEL1 = color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Masking and Blending Mode Set
|
||||
*
|
||||
* @param[in] alpha
|
||||
* 8-bit value indicating blending factor
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_TFTMaskBlendMode(EBI_TFTMaskBlend_TypeDef maskBlend)
|
||||
{
|
||||
EBI->TFTCTRL = (EBI->TFTCTRL & (~_EBI_TFTCTRL_MASKBLEND_MASK))|maskBlend;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Set TFT Alpha Blending Factor
|
||||
*
|
||||
* @param[in] alpha
|
||||
* 8-bit value indicating blending factor
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_TFTAlphaBlendSet(uint8_t alpha)
|
||||
{
|
||||
EBI->TFTALPHA = alpha;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Set TFT mask value
|
||||
* Data accesses that matches this value are suppressed
|
||||
* @param[in] mask
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_TFTMaskSet(uint32_t mask)
|
||||
{
|
||||
EBI->TFTMASK = mask;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get current vertical position counter
|
||||
* @return
|
||||
* Returns the current line position for the visible part of a frame
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t EBI_TFTVCount(void)
|
||||
{
|
||||
return((EBI->TFTSTATUS & _EBI_TFTSTATUS_VCNT_MASK) >> _EBI_TFTSTATUS_VCNT_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get current horizontal position counter
|
||||
* @return
|
||||
* Returns the current horizontal pixel position within a visible line
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t EBI_TFTHCount(void)
|
||||
{
|
||||
return((EBI->TFTSTATUS & _EBI_TFTSTATUS_HCNT_MASK) >> _EBI_TFTSTATUS_HCNT_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Set Frame Buffer Trigger
|
||||
* Frame buffer pointer will be updated either on each horizontal line (hsync)
|
||||
* or vertical update (vsync)(
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_TFTFBTriggerSet(EBI_TFTFrameBufTrigger_TypeDef sync)
|
||||
{
|
||||
EBI->TFTCTRL = ((EBI->TFTCTRL & ~_EBI_TFTCTRL_FBCTRIG_MASK)|sync);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Set horizontal TFT stride value in number of bytes
|
||||
*
|
||||
* @param[in] nbytes
|
||||
* Number of bytes to add to frame buffer pointer after each horizontal line
|
||||
* update
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_TFTHStrideSet(uint32_t nbytes)
|
||||
{
|
||||
EFM_ASSERT(nbytes < 0x1000);
|
||||
|
||||
EBI->TFTSTRIDE = (EBI->TFTSTRIDE & ~(_EBI_TFTSTRIDE_HSTRIDE_MASK))|
|
||||
(nbytes<<_EBI_TFTSTRIDE_HSTRIDE_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending EBI interrupts.
|
||||
* @param[in] flags
|
||||
* Pending EBI interrupt source to clear. Use a logical OR combination
|
||||
* of valid interrupt flags for the EBI module (EBI_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_IntClear(uint32_t flags)
|
||||
{
|
||||
EBI->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending EBI interrupts from SW.
|
||||
*
|
||||
* @param[in] flags
|
||||
* EBI interrupt sources to set to pending. Use a logical OR combination of
|
||||
* valid interrupt flags for the EBI module (EBI_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_IntSet(uint32_t flags)
|
||||
{
|
||||
EBI->IFS = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more EBI interrupts
|
||||
*
|
||||
* @param[in] flags
|
||||
* EBI interrupt sources to disable. Use logical OR combination of valid
|
||||
* interrupt flags for the EBI module (EBI_IF_nnn)
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_IntDisable(uint32_t flags)
|
||||
{
|
||||
EBI->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more EBI interrupts
|
||||
*
|
||||
* @param[in] flags
|
||||
* EBI interrupt sources to enable. Use logical OR combination of valid
|
||||
* interrupt flags for the EBI module (EBI_IF_nnn)
|
||||
******************************************************************************/
|
||||
static __INLINE void EBI_IntEnable(uint32_t flags)
|
||||
{
|
||||
EBI->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending EBI interrupt flags
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function
|
||||
*
|
||||
* @return
|
||||
* EBI interrupt sources pending, a logical combination of valid EBI
|
||||
* interrupt flags, EBI_IF_nnn
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t EBI_IntGet(void)
|
||||
{
|
||||
return(EBI->IF);
|
||||
}
|
||||
#endif
|
||||
|
||||
void EBI_ChipSelectEnable(uint32_t banks, bool enable);
|
||||
void EBI_ReadTimingSet(int setupCycles, int strobeCycles, int holdCycles);
|
||||
void EBI_WriteTimingSet(int setupCycles, int strobeCycles, int holdCycles);
|
||||
void EBI_AddressTimingSet(int setupCycles, int holdCycles);
|
||||
void EBI_PolaritySet(EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity);
|
||||
|
||||
/** @} (end addtogroup EBI) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(EBI_COUNT) && (EBI_COUNT > 0) */
|
||||
|
||||
#endif /* __EFM32_EBI_H */
|
|
@ -0,0 +1,287 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Energy management unit (EMU) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_EMU_H
|
||||
#define __EFM32_EMU_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EMU
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** EM4 duty oscillator */
|
||||
typedef enum
|
||||
{
|
||||
/** Select ULFRCO as duty oscillator in EM4 */
|
||||
emuEM4Osc_ULFRCO = EMU_EM4CONF_OSC_ULFRCO,
|
||||
/** Select LFXO as duty oscillator in EM4 */
|
||||
emuEM4Osc_LFXO = EMU_EM4CONF_OSC_LFXO,
|
||||
/** Select LFRCO as duty oscillator in EM4 */
|
||||
emuEM4Osc_LFRCO = EMU_EM4CONF_OSC_LFRCO
|
||||
} EMU_EM4Osc_TypeDef;
|
||||
|
||||
/** Backup Power Voltage Probe types */
|
||||
typedef enum
|
||||
{
|
||||
/** Disable voltage probe */
|
||||
emuProbe_Disable = EMU_BUCTRL_PROBE_DISABLE,
|
||||
/** Connect probe to VDD_DREG */
|
||||
emuProbe_VDDDReg = EMU_BUCTRL_PROBE_VDDDREG,
|
||||
/** Connect probe to BU_IN */
|
||||
emuProbe_BUIN = EMU_BUCTRL_PROBE_BUIN,
|
||||
/** Connect probe to BU_OUT */
|
||||
emuProbe_BUOUT = EMU_BUCTRL_PROBE_BUOUT
|
||||
} EMU_Probe_TypeDef;
|
||||
|
||||
/** Backup Power Domain resistor selection */
|
||||
typedef enum
|
||||
{
|
||||
/** Main power and backup power connected with RES0 series resistance */
|
||||
emuRes_Res0 = EMU_PWRCONF_PWRRES_RES0,
|
||||
/** Main power and backup power connected with RES1 series resistance */
|
||||
emuRes_Res1 = EMU_PWRCONF_PWRRES_RES1,
|
||||
/** Main power and backup power connected with RES2 series resistance */
|
||||
emuRes_Res2 = EMU_PWRCONF_PWRRES_RES2,
|
||||
/** Main power and backup power connected with RES3 series resistance */
|
||||
emuRes_Res3 = EMU_PWRCONF_PWRRES_RES3,
|
||||
} EMU_Resistor_TypeDef;
|
||||
|
||||
/** Backup Power Domain power connection */
|
||||
typedef enum
|
||||
{
|
||||
/** No connection between main and backup power */
|
||||
emuPower_None = EMU_BUINACT_PWRCON_NONE,
|
||||
/** Main power and backup power connected through diode,
|
||||
allowing current from backup to main only */
|
||||
emuPower_BUMain = EMU_BUINACT_PWRCON_BUMAIN,
|
||||
/** Main power and backup power connected through diode,
|
||||
allowing current from main to backup only */
|
||||
emuPower_MainBU = EMU_BUINACT_PWRCON_MAINBU,
|
||||
/** Main power and backup power connected without diode */
|
||||
emuPower_NoDiode = EMU_BUINACT_PWRCON_NODIODE,
|
||||
} EMU_Power_TypeDef;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** Energy Mode 4 initialization structure */
|
||||
typedef struct
|
||||
{
|
||||
/** Lock configuration of regulator, BOD and oscillator */
|
||||
bool lockConfig;
|
||||
/** EM4 duty oscillator */
|
||||
EMU_EM4Osc_TypeDef osc;
|
||||
/** Wake up on EM4 BURTC interrupt */
|
||||
bool buRtcWakeup;
|
||||
/** Enable EM4 voltage regulator */
|
||||
bool vreg;
|
||||
} EMU_EM4Init_TypeDef;
|
||||
|
||||
/** Default initialization of EM4 configuration */
|
||||
#define EMU_EM4INIT_DEFAULT \
|
||||
{ false, /* Dont't lock configuration after it's been set */ \
|
||||
emuEM4Osc_ULFRCO, /* Use default ULFRCO oscillator */ \
|
||||
true, /* Wake up on EM4 BURTC interrupt */ \
|
||||
true, /* Enable VREG */ \
|
||||
}
|
||||
|
||||
/** Backup Power Domain Initialization structure */
|
||||
typedef struct
|
||||
{
|
||||
/* Backup Power Domain power configuration */
|
||||
|
||||
/** Voltage probe select, selects ADC voltage */
|
||||
EMU_Probe_TypeDef probe;
|
||||
/** Enable BOD calibration mode */
|
||||
bool bodCal;
|
||||
/** Enable BU_STAT status pin for active BU mode */
|
||||
bool statusPinEnable;
|
||||
|
||||
/* Backup Power Domain connection configuration */
|
||||
/** Power domain resistor */
|
||||
EMU_Resistor_TypeDef resistor;
|
||||
/** BU_VOUT strong enable */
|
||||
bool voutStrong;
|
||||
/** BU_VOUT medium enable */
|
||||
bool voutMed;
|
||||
/** BU_VOUT weak enable */
|
||||
bool voutWeak;
|
||||
|
||||
/* Backup Power Domain inactive configuration */
|
||||
/** Power connection, when not in Backup Mode */
|
||||
EMU_Power_TypeDef inactivePower;
|
||||
/** Threshold range for backup BOD sensing on VDD_DREG, when not in Backup Mode */
|
||||
uint32_t inactiveThresRange;
|
||||
/** Threshold for backup BOD sesning on VDD_DREG, when not in Backup Mode */
|
||||
uint32_t inactiveThreshold;
|
||||
|
||||
/* Backup Power Domain active configuration */
|
||||
/** Power connection, when in Backup Mode */
|
||||
EMU_Power_TypeDef activePower;
|
||||
/** Threshold range for backup BOD sensing when in Backup Mode */
|
||||
uint32_t activeThresRange;
|
||||
/** Threshold for backup BOD sesning on VDD_DREG, when in Backup Mode */
|
||||
uint32_t activeThreshold;
|
||||
|
||||
/** Enable backup power domain, and release reset, enable BU_VIN pin */
|
||||
bool enable;
|
||||
} EMU_BUPDInit_TypeDef;
|
||||
|
||||
/** Default */
|
||||
#define EMU_BUPDINIT_DEFAULT \
|
||||
{ emuProbe_Disable, /* Do not enable voltage probe */ \
|
||||
false, /* Disable BOD calibration mode */ \
|
||||
false, /* Disable BU_STAT pin for backup mode indication */ \
|
||||
\
|
||||
emuRes_Res0, /* RES0 series resistance between main and backup power */ \
|
||||
false, /* Don't enable strong switch */ \
|
||||
false, /* Don't enable medium switch */ \
|
||||
false, /* Don't enable weak switch */ \
|
||||
\
|
||||
emuPower_None, /* No connection between main and backup power (inactive mode) */ \
|
||||
0, /* Default threshold range for backup BOD sense (inactive mode) */ \
|
||||
0, /* Default threshold for backup BOD snese (inactive mode) */ \
|
||||
\
|
||||
emuPower_None, /* No connection between main and backup power (active mode) */ \
|
||||
0, /* Default threshold range for backup BOD sense (active mode) */ \
|
||||
0, /* Default threshold for backup BOD snese (active mode) */ \
|
||||
\
|
||||
true /* Enable BUPD enter on BOD, enable BU_VIN pin, release BU reset */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enter energy mode 1 (EM1).
|
||||
******************************************************************************/
|
||||
static __INLINE void EMU_EnterEM1(void)
|
||||
{
|
||||
/* Just enter Cortex-M3 sleep mode */
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
__WFI();
|
||||
}
|
||||
|
||||
|
||||
void EMU_EnterEM2(bool restore);
|
||||
void EMU_EnterEM3(bool restore);
|
||||
void EMU_EnterEM4(void);
|
||||
void EMU_MemPwrDown(uint32_t blocks);
|
||||
void EMU_UpdateOscConfig(void);
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
void EMU_EM4Init(EMU_EM4Init_TypeDef *em4init);
|
||||
void EMU_BUPDInit(EMU_BUPDInit_TypeDef *budpdInit);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable BU_VIN support
|
||||
* @param[in] enable
|
||||
* If true, enables BU_VIN input pin support, if false disables it
|
||||
******************************************************************************/
|
||||
static __INLINE void EMU_BUPinEnable(bool enable)
|
||||
{
|
||||
BITBAND_Peripheral(&(EMU->ROUTE), _EMU_ROUTE_BUVINPEN_SHIFT, enable);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Lock the EMU in order to protect all its registers against unintended
|
||||
* modification.
|
||||
*
|
||||
* @note
|
||||
* If locking the EMU registers, they must be unlocked prior to using any
|
||||
* EMU API functions modifying EMU registers. An exception to this is the
|
||||
* energy mode entering API (EMU_EnterEMn()), which can be used when the
|
||||
* EMU registers are locked.
|
||||
******************************************************************************/
|
||||
static __INLINE void EMU_Lock(void)
|
||||
{
|
||||
EMU->LOCK = EMU_LOCK_LOCKKEY_LOCK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unlock the EMU so that writing to locked registers again is possible.
|
||||
******************************************************************************/
|
||||
static __INLINE void EMU_Unlock(void)
|
||||
{
|
||||
EMU->LOCK = EMU_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Block entering EM2 or higher number energy modes.
|
||||
******************************************************************************/
|
||||
static __INLINE void EMU_EM2Block(void)
|
||||
{
|
||||
BITBAND_Peripheral(&(EMU->CTRL), _EMU_CTRL_EM2BLOCK_SHIFT, 1U);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unblock entering EM2 or higher number energy modes.
|
||||
******************************************************************************/
|
||||
static __INLINE void EMU_EM2UnBlock(void)
|
||||
{
|
||||
BITBAND_Peripheral(&(EMU->CTRL), _EMU_CTRL_EM2BLOCK_SHIFT, 0U);
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup EMU) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_EMU_H */
|
|
@ -0,0 +1,439 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief General Purpose IO (GPIO) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_GPIO_H
|
||||
#define __EFM32_GPIO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
#include "efm32_bitband.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup GPIO
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** GPIO ports identificator. */
|
||||
typedef enum
|
||||
{
|
||||
gpioPortA = 0, /**< Port A */
|
||||
gpioPortB = 1, /**< Port B */
|
||||
gpioPortC = 2, /**< Port C */
|
||||
gpioPortD = 3, /**< Port D */
|
||||
gpioPortE = 4, /**< Port E */
|
||||
gpioPortF = 5 /**< Port F */
|
||||
} GPIO_Port_TypeDef;
|
||||
|
||||
/** GPIO drive mode. */
|
||||
typedef enum
|
||||
{
|
||||
/** Default 6mA */
|
||||
gpioDriveModeStandard = GPIO_P_CTRL_DRIVEMODE_STANDARD,
|
||||
/** 0.5 mA */
|
||||
gpioDriveModeLowest = GPIO_P_CTRL_DRIVEMODE_LOWEST,
|
||||
/** 20 mA */
|
||||
gpioDriveModeHigh = GPIO_P_CTRL_DRIVEMODE_HIGH,
|
||||
/** 2 mA */
|
||||
gpioDriveModeLow = GPIO_P_CTRL_DRIVEMODE_LOW
|
||||
} GPIO_DriveMode_TypeDef;
|
||||
|
||||
/** Pin mode. For more details on each mode, please refer to the EFM32
|
||||
* reference manual. */
|
||||
typedef enum
|
||||
{
|
||||
/** Input disabled. Pullup if DOUT is set. */
|
||||
gpioModeDisabled = _GPIO_P_MODEL_MODE0_DISABLED,
|
||||
/** Input enabled. Filter if DOUT is set */
|
||||
gpioModeInput = _GPIO_P_MODEL_MODE0_INPUT,
|
||||
/** Input enabled. DOUT determines pull direction */
|
||||
gpioModeInputPull = _GPIO_P_MODEL_MODE0_INPUTPULL,
|
||||
/** Input enabled with filter. DOUT determines pull direction */
|
||||
gpioModeInputPullFilter = _GPIO_P_MODEL_MODE0_INPUTPULLFILTER,
|
||||
/** Push-pull output */
|
||||
gpioModePushPull = _GPIO_P_MODEL_MODE0_PUSHPULL,
|
||||
/** Push-pull output with drive-strength set by DRIVEMODE */
|
||||
gpioModePushPullDrive = _GPIO_P_MODEL_MODE0_PUSHPULLDRIVE,
|
||||
/** Wired-or output */
|
||||
gpioModeWiredOr = _GPIO_P_MODEL_MODE0_WIREDOR,
|
||||
/** Wired-or output with pull-down */
|
||||
gpioModeWiredOrPullDown = _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN,
|
||||
/** Open-drain output */
|
||||
gpioModeWiredAnd = _GPIO_P_MODEL_MODE0_WIREDAND,
|
||||
/** Open-drain output with filter */
|
||||
gpioModeWiredAndFilter = _GPIO_P_MODEL_MODE0_WIREDANDFILTER,
|
||||
/** Open-drain output with pullup */
|
||||
gpioModeWiredAndPullUp = _GPIO_P_MODEL_MODE0_WIREDANDPULLUP,
|
||||
/** Open-drain output with filter and pullup */
|
||||
gpioModeWiredAndPullUpFilter = _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER,
|
||||
/** Open-drain output with drive-strength set by DRIVEMODE */
|
||||
gpioModeWiredAndDrive = _GPIO_P_MODEL_MODE0_WIREDANDDRIVE,
|
||||
/** Open-drain output with filter and drive-strength set by DRIVEMODE */
|
||||
gpioModeWiredAndDriveFilter = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEFILTER,
|
||||
/** Open-drain output with pullup and drive-strength set by DRIVEMODE */
|
||||
gpioModeWiredAndDrivePullUp = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUP,
|
||||
/** Open-drain output with filter, pullup and drive-strength set by DRIVEMODE */
|
||||
gpioModeWiredAndDrivePullUpFilter = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUPFILTER
|
||||
} GPIO_Mode_TypeDef;
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void GPIO_DbgLocationSet(unsigned int location);
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
static __INLINE void GPIO_EM4SetPinRetention(bool enable);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable serial wire clock pin.
|
||||
*
|
||||
* @note
|
||||
* Disabling SWDClk will disable the debug interface, which may result in
|
||||
* a lockout if done early in startup (before debugger is able to halt core).
|
||||
*
|
||||
* @param[in] enable
|
||||
* @li false - disable serial wire clock.
|
||||
* @li true - enable serial wire clock (default after reset).
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_DbgSWDClkEnable(bool enable)
|
||||
{
|
||||
BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWCLKPEN_SHIFT, (unsigned int)enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable serial wire data pin.
|
||||
*
|
||||
* @note
|
||||
* Disabling SWDClk will disable the debug interface, which may result in
|
||||
* a lockout if done early in startup (before debugger is able to halt core).
|
||||
*
|
||||
* @param[in] enable
|
||||
* @li false - disable serial wire data pin.
|
||||
* @li true - enable serial wire data pin (default after reset).
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_DbgSWDIOEnable(bool enable)
|
||||
{
|
||||
BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWDIOPEN_SHIFT, (unsigned int)enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/Disable serial wire output pin.
|
||||
*
|
||||
* @note
|
||||
* Enabling this pin is not sufficient to fully enable serial wire output
|
||||
* which is also dependent on issues outside the GPIO module. Please refer to
|
||||
* DBG_SWOEnable().
|
||||
*
|
||||
* @param[in] enable
|
||||
* @li false - disable serial wire viewer pin (default after reset).
|
||||
* @li true - enable serial wire viewer pin.
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_DbgSWOEnable(bool enable)
|
||||
{
|
||||
BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWOPEN_SHIFT, (unsigned int)enable);
|
||||
}
|
||||
|
||||
|
||||
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode);
|
||||
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Disable GPIO pin wake-up from EM4.
|
||||
*
|
||||
* @param[in] pinmask
|
||||
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to disable.
|
||||
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
|
||||
*****************************************************************************/
|
||||
static __INLINE void GPIO_EM4DisablePinWakeup(uint32_t pinmask)
|
||||
{
|
||||
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
|
||||
|
||||
GPIO->EM4WUEN &= ~pinmask;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Enable GPIO pin wake-up from EM4. When the function exits,
|
||||
* EM4 mode can be safely entered.
|
||||
*
|
||||
* @note
|
||||
* It is assumed that the GPIO pin modes are set correctly.
|
||||
* Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.
|
||||
*
|
||||
* @param[in] pinmask
|
||||
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
|
||||
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
|
||||
* @param[in] polaritymask
|
||||
* Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
|
||||
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
|
||||
*****************************************************************************/
|
||||
static __INLINE void GPIO_EM4EnablePinWakeup(uint32_t pinmask,
|
||||
uint32_t polaritymask)
|
||||
{
|
||||
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
|
||||
EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
|
||||
|
||||
GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */
|
||||
GPIO->EM4WUPOL |= pinmask & polaritymask;
|
||||
GPIO->EM4WUEN |= pinmask; /* Enable wakeup */
|
||||
|
||||
GPIO_EM4SetPinRetention(true); /* Enable pin retention */
|
||||
|
||||
GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Check which GPIO pin(s) that caused a wake-up from EM4.
|
||||
*
|
||||
* @return
|
||||
* Bitmask containing the bitwise logic OR of which GPIO pin(s) caused the
|
||||
* wake-up. Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
|
||||
*****************************************************************************/
|
||||
static __INLINE uint32_t GPIO_EM4GetPinWakeupCause(void)
|
||||
{
|
||||
return GPIO->EM4WUCAUSE & _GPIO_EM4WUCAUSE_MASK;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Enable GPIO pin retention of output enable, output value, pull enable and
|
||||
* pull direction in EM4.
|
||||
*
|
||||
* @param[in] enable
|
||||
* @li true - enable EM4 pin retention.
|
||||
* @li false - disable EM4 pin retention.
|
||||
*****************************************************************************/
|
||||
static __INLINE void GPIO_EM4SetPinRetention(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
GPIO->CTRL |= GPIO_CTRL_EM4RET;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO->CTRL &= ~GPIO_CTRL_EM4RET;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable input sensing.
|
||||
*
|
||||
* @details
|
||||
* Disabling input sensing if not used, can save some energy consumption.
|
||||
*
|
||||
* @param[in] val
|
||||
* Bitwise logic OR of one or more of:
|
||||
* @li GPIO_INSENSE_INTSENSE - interrupt input sensing.
|
||||
* @li GPIO_INSENSE_PRSSENSE - peripheral reflex system input sensing.
|
||||
*
|
||||
* @param[in] mask
|
||||
* Mask containing bitwise logic OR of bits similar as for @p val used to indicate
|
||||
* which input sense options to disable/enable.
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_InputSenseSet(uint32_t val, uint32_t mask)
|
||||
{
|
||||
GPIO->INSENSE = (GPIO->INSENSE & ~mask) | (val & mask);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending GPIO interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Bitwise logic OR of GPIO interrupt sources to clear.
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_IntClear(uint32_t flags)
|
||||
{
|
||||
GPIO->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
void GPIO_IntConfig(GPIO_Port_TypeDef port,
|
||||
unsigned int pin,
|
||||
bool risingEdge,
|
||||
bool fallingEdge,
|
||||
bool enable);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more GPIO interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* GPIO interrupt sources to disable.
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_IntDisable(uint32_t flags)
|
||||
{
|
||||
GPIO->IEN &= ~flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more GPIO interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using GPIO_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] flags
|
||||
* GPIO interrupt sources to enable.
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_IntEnable(uint32_t flags)
|
||||
{
|
||||
GPIO->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending GPIO interrupts.
|
||||
*
|
||||
* @return
|
||||
* GPIO interrupt sources pending.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t GPIO_IntGet(void)
|
||||
{
|
||||
return(GPIO->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get enabled and pending GPIO interrupt flags.
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @note
|
||||
* Interrupt flags are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* Pending and enabled GPIO interrupt sources.
|
||||
* The return value is the bitwise AND combination of
|
||||
* - the OR combination of enabled interrupt sources in GPIO_IEN register
|
||||
* and
|
||||
* - the OR combination of valid interrupt flags in GPIO_IF register.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t GPIO_IntGetEnabled(void)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Store GPIO->IEN in temporary variable in order to define explicit order
|
||||
* of volatile accesses. */
|
||||
tmp = GPIO->IEN;
|
||||
|
||||
/* Bitwise AND of pending and enabled interrupts */
|
||||
return GPIO->IF & tmp;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending GPIO interrupts from SW.
|
||||
*
|
||||
* @param[in] flags
|
||||
* GPIO interrupt sources to set to pending.
|
||||
*****************************************************************************/
|
||||
static __INLINE void GPIO_IntSet(uint32_t flags)
|
||||
{
|
||||
GPIO->IFS = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Locks the GPIO configuration.
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_Lock(void)
|
||||
{
|
||||
GPIO->LOCK = GPIO_LOCK_LOCKKEY_LOCK;
|
||||
}
|
||||
|
||||
|
||||
unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin);
|
||||
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
|
||||
unsigned int pin,
|
||||
GPIO_Mode_TypeDef mode,
|
||||
unsigned int out);
|
||||
void GPIO_PinOutClear(GPIO_Port_TypeDef port, unsigned int pin);
|
||||
unsigned int GPIO_PinOutGet(GPIO_Port_TypeDef port, unsigned int pin);
|
||||
void GPIO_PinOutSet(GPIO_Port_TypeDef port, unsigned int pin);
|
||||
void GPIO_PinOutToggle(GPIO_Port_TypeDef port, unsigned int pin);
|
||||
|
||||
uint32_t GPIO_PortInGet(GPIO_Port_TypeDef port);
|
||||
void GPIO_PortOutClear(GPIO_Port_TypeDef port, uint32_t pins);
|
||||
uint32_t GPIO_PortOutGet(GPIO_Port_TypeDef port);
|
||||
void GPIO_PortOutSet(GPIO_Port_TypeDef port, uint32_t pins);
|
||||
void GPIO_PortOutSetVal(GPIO_Port_TypeDef port, uint32_t val, uint32_t mask);
|
||||
void GPIO_PortOutToggle(GPIO_Port_TypeDef port, uint32_t pins);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unlocks the GPIO configuration.
|
||||
******************************************************************************/
|
||||
static __INLINE void GPIO_Unlock(void)
|
||||
{
|
||||
GPIO->LOCK = GPIO_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup GPIO) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_GPIO_H */
|
|
@ -0,0 +1,483 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Inter-intergrated circuit (I2C) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_I2C_H
|
||||
#define __EFM32_I2C_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup I2C
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Standard mode max frequency assuming using 4:4 ratio for Nlow:Nhigh.
|
||||
* @details
|
||||
* From I2C specification: Min Tlow = 4.7us, min Thigh = 4.0us,
|
||||
* max Trise=1.0us, max Tfall=0.3us. Since ratio is 4:4, have to use
|
||||
* worst case value of Tlow or Thigh as base.
|
||||
*
|
||||
* 1/(Tlow + Thigh + 1us + 0.3us) = 1/(4.7 + 4.7 + 1.3)us = 93458Hz
|
||||
*/
|
||||
#define I2C_FREQ_STANDARD_MAX 93500
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Fast mode max frequency assuming using 6:3 ratio for Nlow:Nhigh.
|
||||
* @details
|
||||
* From I2C specification: Min Tlow = 1.3us, min Thigh = 0.6us,
|
||||
* max Trise=0.3us, max Tfall=0.3us. Since ratio is 6:3, have to use
|
||||
* worst case value of Tlow or 2xThigh as base.
|
||||
*
|
||||
* 1/(Tlow + Thigh + 0.3us + 0.3us) = 1/(1.3 + 0.65 + 0.6)us = 392157Hz
|
||||
*/
|
||||
#define I2C_FREQ_FAST_MAX 392500
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Fast mode+ max frequency assuming using 11:6 ratio for Nlow:Nhigh.
|
||||
* @details
|
||||
* From I2C specification: Min Tlow = 0.5us, min Thigh = 0.26us,
|
||||
* max Trise=0.012us, max Tfall=0.12us. Since ratio is 11:6, have to use
|
||||
* worst case value of Tlow or (11/6)xThigh as base.
|
||||
*
|
||||
* 1/(Tlow + Thigh + 0.12us + 0.12us) = 1/(0.5 + 0.273 + 0.24)us = 987167Hz
|
||||
*/
|
||||
#define I2C_FREQ_FASTPLUS_MAX 987500
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Indicate plain write sequence: S+ADDR(W)+DATA0+P.
|
||||
* @details
|
||||
* @li S - Start
|
||||
* @li ADDR(W) - address with W/R bit cleared
|
||||
* @li DATA0 - Data taken from buffer with index 0
|
||||
* @li P - Stop
|
||||
*/
|
||||
#define I2C_FLAG_WRITE 0x0001
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Indicate plain read sequence: S+ADDR(R)+DATA0+P.
|
||||
* @details
|
||||
* @li S - Start
|
||||
* @li ADDR(R) - address with W/R bit set
|
||||
* @li DATA0 - Data read into buffer with index 0
|
||||
* @li P - Stop
|
||||
*/
|
||||
#define I2C_FLAG_READ 0x0002
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Indicate combined write/read sequence: S+ADDR(W)+DATA0+Sr+ADDR(R)+DATA1+P.
|
||||
* @details
|
||||
* @li S - Start
|
||||
* @li Sr - Repeated start
|
||||
* @li ADDR(W) - address with W/R bit cleared
|
||||
* @li ADDR(R) - address with W/R bit set
|
||||
* @li DATAn - Data written from/read into buffer with index n
|
||||
* @li P - Stop
|
||||
*/
|
||||
#define I2C_FLAG_WRITE_READ 0x0004
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Indicate write sequence using two buffers: S+ADDR(W)+DATA0+DATA1+P.
|
||||
* @details
|
||||
* @li S - Start
|
||||
* @li ADDR(W) - address with W/R bit cleared
|
||||
* @li DATAn - Data written from buffer with index n
|
||||
* @li P - Stop
|
||||
*/
|
||||
#define I2C_FLAG_WRITE_WRITE 0x0008
|
||||
|
||||
/** Use 10 bit address. */
|
||||
#define I2C_FLAG_10BIT_ADDR 0x0010
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Clock low to high ratio settings. */
|
||||
typedef enum
|
||||
{
|
||||
i2cClockHLRStandard = _I2C_CTRL_CLHR_STANDARD, /**< Ratio is 4:4 */
|
||||
i2cClockHLRAsymetric = _I2C_CTRL_CLHR_ASYMMETRIC, /**< Ratio is 6:3 */
|
||||
i2cClockHLRFast = _I2C_CTRL_CLHR_FAST /**< Ratio is 11:3 */
|
||||
} I2C_ClockHLR_TypeDef;
|
||||
|
||||
|
||||
/** Return codes for single master mode transfer function. */
|
||||
typedef enum
|
||||
{
|
||||
/* In progress code (>0) */
|
||||
i2cTransferInProgress = 1, /**< Transfer in progress. */
|
||||
|
||||
/* Complete code (=0) */
|
||||
i2cTransferDone = 0, /**< Transfer completed successfully. */
|
||||
|
||||
/* Transfer error codes (<0) */
|
||||
i2cTransferNack = -1, /**< NACK received during transfer. */
|
||||
i2cTransferBusErr = -2, /**< Bus error during transfer (misplaced START/STOP). */
|
||||
i2cTransferArbLost = -3, /**< Arbitration lost during transfer. */
|
||||
i2cTransferUsageFault = -4, /**< Usage fault. */
|
||||
i2cTransferSwFault = -5 /**< SW fault. */
|
||||
} I2C_TransferReturn_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** I2C initialization structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Enable I2C peripheral when init completed. */
|
||||
bool enable;
|
||||
|
||||
/** Set to master (true) or slave (false) mode */
|
||||
bool master;
|
||||
|
||||
/**
|
||||
* I2C reference clock assumed when configuring bus frequency setup.
|
||||
* Set it to 0 if currently configurated reference clock shall be used
|
||||
* This parameter is only applicable if operating in master mode.
|
||||
*/
|
||||
uint32_t refFreq;
|
||||
|
||||
/**
|
||||
* (Max) I2C bus frequency to use. This parameter is only applicable
|
||||
* if operating in master mode.
|
||||
*/
|
||||
uint32_t freq;
|
||||
|
||||
/** Clock low/high ratio control. */
|
||||
I2C_ClockHLR_TypeDef clhr;
|
||||
} I2C_Init_TypeDef;
|
||||
|
||||
/** Suggested default config for I2C init structure. */
|
||||
#define I2C_INIT_DEFAULT \
|
||||
{ true, /* Enable when init done */ \
|
||||
true, /* Set to master mode */ \
|
||||
0, /* Use currently configured reference clock */ \
|
||||
I2C_FREQ_STANDARD_MAX, /* Set to standard rate assuring being */ \
|
||||
/* within I2C spec */ \
|
||||
i2cClockHLRStandard /* Set to use 4:4 low/high duty cycle */ \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Master mode transfer message structure used to define a complete
|
||||
* I2C transfer sequence (from start to stop).
|
||||
* @details
|
||||
* The structure allows for defining the following types of sequences,
|
||||
* please refer to defines for sequence details.
|
||||
* @li #I2C_FLAG_READ - data read into buf[0].data
|
||||
* @li #I2C_FLAG_WRITE - data written from buf[0].data
|
||||
* @li #I2C_FLAG_WRITE_READ - data written from buf[0].data and read
|
||||
* into buf[1].data
|
||||
* @li #I2C_FLAG_WRITE_WRITE - data written from buf[0].data and
|
||||
* buf[1].data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* @brief
|
||||
* Address to use after (repeated) start.
|
||||
* @details
|
||||
* Layout details, A = address bit, X = don't care bit (set to 0):
|
||||
* @li 7 bit address - use format AAAA AAAX.
|
||||
* @li 10 bit address - use format XXXX XAAX AAAA AAAA
|
||||
*/
|
||||
uint16_t addr;
|
||||
|
||||
/** Flags defining sequence type and details, see I2C_FLAG_... defines. */
|
||||
uint16_t flags;
|
||||
|
||||
/**
|
||||
* Buffers used to hold data to send from or receive into depending
|
||||
* on sequence type.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/** Buffer used for data to transmit/receive, must be @p len long. */
|
||||
uint8_t *data;
|
||||
|
||||
/**
|
||||
* Number of bytes in @p data to send or receive. Notice that when
|
||||
* receiving data to this buffer, at least 1 byte must be received.
|
||||
* Setting @p len to 0 in the receive case is considered a usage fault.
|
||||
* Transmitting 0 bytes is legal, in which case only the address
|
||||
* is transmitted after the start condition.
|
||||
*/
|
||||
uint16_t len;
|
||||
} buf[2];
|
||||
} I2C_TransferSeq_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c);
|
||||
void I2C_BusFreqSet(I2C_TypeDef *i2c,
|
||||
uint32_t refFreq,
|
||||
uint32_t freq,
|
||||
I2C_ClockHLR_TypeDef type);
|
||||
void I2C_Enable(I2C_TypeDef *i2c, bool enable);
|
||||
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending I2C interrupts.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending I2C interrupt source to clear. Use a bitwse logic OR combination of
|
||||
* valid interrupt flags for the I2C module (I2C_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void I2C_IntClear(I2C_TypeDef *i2c, uint32_t flags)
|
||||
{
|
||||
i2c->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more I2C interrupts.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* I2C interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the I2C module (I2C_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void I2C_IntDisable(I2C_TypeDef *i2c, uint32_t flags)
|
||||
{
|
||||
i2c->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more I2C interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using I2C_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* I2C interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the I2C module (I2C_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void I2C_IntEnable(I2C_TypeDef *i2c, uint32_t flags)
|
||||
{
|
||||
i2c->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending I2C interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* I2C interrupt sources pending. A bitwise logic OR combination of valid
|
||||
* interrupt flags for the I2C module (I2C_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t I2C_IntGet(I2C_TypeDef *i2c)
|
||||
{
|
||||
return(i2c->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending I2C interrupts from SW.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* I2C interrupt sources to set to pending. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the I2C module (I2C_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void I2C_IntSet(I2C_TypeDef *i2c, uint32_t flags)
|
||||
{
|
||||
i2c->IFS = flags;
|
||||
}
|
||||
|
||||
void I2C_Reset(I2C_TypeDef *i2c);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get slave address used for I2C peripheral (when operating in slave mode).
|
||||
*
|
||||
* @details
|
||||
* For 10 bit addressing mode, the address is split in two bytes, and only
|
||||
* the first byte setting is fetched, effectively only controlling the 2 most
|
||||
* significant bits of the 10 bit address. Full handling of 10 bit addressing
|
||||
* in slave mode requires additional SW handling.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* I2C slave address in use. The 7 most significant bits define the actual
|
||||
* address, the least significant bit is reserved and always returned as 0.
|
||||
******************************************************************************/
|
||||
static __INLINE uint8_t I2C_SlaveAddressGet(I2C_TypeDef *i2c)
|
||||
{
|
||||
return((uint8_t)(i2c->SADDR));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set slave address to use for I2C peripheral (when operating in slave mode).
|
||||
*
|
||||
* @details
|
||||
* For 10 bit addressing mode, the address is split in two bytes, and only
|
||||
* the first byte is set, effectively only controlling the 2 most significant
|
||||
* bits of the 10 bit address. Full handling of 10 bit addressing in slave
|
||||
* mode requires additional SW handling.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] addr
|
||||
* I2C slave address to use. The 7 most significant bits define the actual
|
||||
* address, the least significant bit is reserved and always set to 0.
|
||||
******************************************************************************/
|
||||
static __INLINE void I2C_SlaveAddressSet(I2C_TypeDef *i2c, uint8_t addr)
|
||||
{
|
||||
i2c->SADDR = (uint32_t)addr & 0xfe;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get slave address mask used for I2C peripheral (when operating in slave
|
||||
* mode).
|
||||
*
|
||||
* @details
|
||||
* The address mask defines how the comparator works. A bit position with
|
||||
* value 0 means that the corresponding slave address bit is ignored during
|
||||
* comparison (don't care). A bit position with value 1 means that the
|
||||
* corresponding slave address bit must match.
|
||||
*
|
||||
* For 10 bit addressing mode, the address is split in two bytes, and only
|
||||
* the mask for the first address byte is fetched, effectively only
|
||||
* controlling the 2 most significant bits of the 10 bit address.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* I2C slave address mask in use. The 7 most significant bits define the
|
||||
* actual address mask, the least significant bit is reserved and always
|
||||
* returned as 0.
|
||||
******************************************************************************/
|
||||
static __INLINE uint8_t I2C_SlaveAddressMaskGet(I2C_TypeDef *i2c)
|
||||
{
|
||||
return((uint8_t)(i2c->SADDRMASK));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set slave address mask used for I2C peripheral (when operating in slave
|
||||
* mode).
|
||||
*
|
||||
* @details
|
||||
* The address mask defines how the comparator works. A bit position with
|
||||
* value 0 means that the corresponding slave address bit is ignored during
|
||||
* comparison (don't care). A bit position with value 1 means that the
|
||||
* corresponding slave address bit must match.
|
||||
*
|
||||
* For 10 bit addressing mode, the address is split in two bytes, and only
|
||||
* the mask for the first address byte is set, effectively only controlling
|
||||
* the 2 most significant bits of the 10 bit address.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] mask
|
||||
* I2C slave address mask to use. The 7 most significant bits define the
|
||||
* actual address mask, the least significant bit is reserved and should
|
||||
* be 0.
|
||||
******************************************************************************/
|
||||
static __INLINE void I2C_SlaveAddressMaskSet(I2C_TypeDef *i2c, uint8_t mask)
|
||||
{
|
||||
i2c->SADDRMASK = (uint32_t)mask & 0xfe;
|
||||
}
|
||||
|
||||
|
||||
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c);
|
||||
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
|
||||
I2C_TransferSeq_TypeDef *seq);
|
||||
|
||||
/** @} (end addtogroup I2C) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_I2C_H */
|
|
@ -0,0 +1,110 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Interrupt enable/disable unit API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_INT_H
|
||||
#define __EFM32_INT_H
|
||||
|
||||
#include "efm32.h"
|
||||
|
||||
extern uint32_t INT_LockCnt;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup INT
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable interrupts.
|
||||
*
|
||||
* @return
|
||||
* The resulting interrupt nesting level.
|
||||
*
|
||||
* @details
|
||||
* Disable interrupts and increment lock level counter.
|
||||
*
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t INT_Disable(void)
|
||||
{
|
||||
__disable_irq();
|
||||
if (INT_LockCnt < UINT32_MAX)
|
||||
{
|
||||
INT_LockCnt++;
|
||||
}
|
||||
|
||||
return INT_LockCnt;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable interrupts.
|
||||
*
|
||||
* @return
|
||||
* The resulting interrupt nesting level.
|
||||
*
|
||||
* @details
|
||||
* Decrement interrupt lock level counter and enable interrupts if counter
|
||||
* reached zero.
|
||||
*
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t INT_Enable(void)
|
||||
{
|
||||
uint32_t retVal;
|
||||
|
||||
if (INT_LockCnt > 0)
|
||||
{
|
||||
INT_LockCnt--;
|
||||
retVal = INT_LockCnt;
|
||||
if (retVal == 0)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} (end addtogroup INT) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_INT_H */
|
|
@ -0,0 +1,627 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Liquid Crystal Display (LCD) peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_LCD_H
|
||||
#define __EFM32_LCD_H
|
||||
|
||||
#include "efm32.h"
|
||||
|
||||
#if defined(LCD_COUNT) && (LCD_COUNT > 0)
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup LCD
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** MUX setting */
|
||||
typedef enum
|
||||
{
|
||||
/** Static (segments can be multiplexed with LCD_COM[0]) */
|
||||
lcdMuxStatic = LCD_DISPCTRL_MUX_STATIC,
|
||||
/** Duplex / 1/2 Duty cycle (segments can be multiplexed with LCD_COM[0:1]) */
|
||||
lcdMuxDuplex = LCD_DISPCTRL_MUX_DUPLEX,
|
||||
/** Triplex / 1/3 Duty cycle (segments can be multiplexed with LCD_COM[0:2]) */
|
||||
lcdMuxTriplex = LCD_DISPCTRL_MUX_TRIPLEX,
|
||||
/** Quadruplex / 1/4 Duty cycle (segments can be multiplexed with LCD_COM[0:3]) */
|
||||
lcdMuxQuadruplex = LCD_DISPCTRL_MUX_QUADRUPLEX,
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/** Sextaplex / 1/6 Duty cycle (segments can be multiplexed with LCD_COM[0:5]) */
|
||||
lcdMuxSextaplex = LCD_DISPCTRL_MUXE_MUXE | LCD_DISPCTRL_MUX_DUPLEX,
|
||||
/** Octaplex / 1/6 Duty cycle (segments can be multiplexed with LCD_COM[0:5]) */
|
||||
lcdMuxOctaplex = LCD_DISPCTRL_MUXE_MUXE | LCD_DISPCTRL_MUX_QUADRUPLEX
|
||||
#endif
|
||||
} LCD_Mux_TypeDef;
|
||||
|
||||
/** Bias setting */
|
||||
typedef enum
|
||||
{
|
||||
/** Static (2 levels) */
|
||||
lcdBiasStatic = LCD_DISPCTRL_BIAS_STATIC,
|
||||
/** 1/2 Bias (3 levels) */
|
||||
lcdBiasOneHalf = LCD_DISPCTRL_BIAS_ONEHALF,
|
||||
/** 1/3 Bias (4 levels) */
|
||||
lcdBiasOneThird = LCD_DISPCTRL_BIAS_ONETHIRD,
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/** 1/4 Bias (5 levels) */
|
||||
lcdBiasOneFourth = LCD_DISPCTRL_BIAS_ONEFOURTH,
|
||||
#endif
|
||||
} LCD_Bias_TypeDef;
|
||||
|
||||
/** Wave type */
|
||||
typedef enum
|
||||
{
|
||||
/** Low power optimized waveform output */
|
||||
lcdWaveLowPower = LCD_DISPCTRL_WAVE_LOWPOWER,
|
||||
/** Regular waveform output */
|
||||
lcdWaveNormal = LCD_DISPCTRL_WAVE_NORMAL
|
||||
} LCD_Wave_TypeDef;
|
||||
|
||||
/** VLCD Voltage Source */
|
||||
typedef enum
|
||||
{
|
||||
/** VLCD Powered by VDD */
|
||||
lcdVLCDSelVDD = LCD_DISPCTRL_VLCDSEL_VDD,
|
||||
/** VLCD Powered by external VDD / Voltage Boost */
|
||||
lcdVLCDSelVExtBoost = LCD_DISPCTRL_VLCDSEL_VEXTBOOST
|
||||
} LCD_VLCDSel_TypeDef;
|
||||
|
||||
/** Contrast Configuration */
|
||||
typedef enum
|
||||
{
|
||||
/** Contrast is adjusted relative to VDD (VLCD) */
|
||||
lcdConConfVLCD = LCD_DISPCTRL_CONCONF_VLCD,
|
||||
/** Contrast is adjusted relative to Ground */
|
||||
lcdConConfGND = LCD_DISPCTRL_CONCONF_GND
|
||||
} LCD_ConConf_TypeDef;
|
||||
|
||||
/** Voltage Boost Level - Datasheets document setting for each part number */
|
||||
typedef enum
|
||||
{
|
||||
lcdVBoostLevel0 = LCD_DISPCTRL_VBLEV_LEVEL0, /**< Voltage boost LEVEL0 */
|
||||
lcdVBoostLevel1 = LCD_DISPCTRL_VBLEV_LEVEL1, /**< Voltage boost LEVEL1 */
|
||||
lcdVBoostLevel2 = LCD_DISPCTRL_VBLEV_LEVEL2, /**< Voltage boost LEVEL2 */
|
||||
lcdVBoostLevel3 = LCD_DISPCTRL_VBLEV_LEVEL3, /**< Voltage boost LEVEL3 */
|
||||
lcdVBoostLevel4 = LCD_DISPCTRL_VBLEV_LEVEL4, /**< Voltage boost LEVEL4 */
|
||||
lcdVBoostLevel5 = LCD_DISPCTRL_VBLEV_LEVEL5, /**< Voltage boost LEVEL5 */
|
||||
lcdVBoostLevel6 = LCD_DISPCTRL_VBLEV_LEVEL6, /**< Voltage boost LEVEL6 */
|
||||
lcdVBoostLevel7 = LCD_DISPCTRL_VBLEV_LEVEL7 /**< Voltage boost LEVEL7 */
|
||||
} LCD_VBoostLevel_TypeDef;
|
||||
|
||||
/** Frame Counter Clock Prescaler, FC-CLK = FrameRate (Hz) / this factor */
|
||||
typedef enum
|
||||
{
|
||||
/** Prescale Div 1 */
|
||||
lcdFCPrescDiv1 = LCD_BACTRL_FCPRESC_DIV1,
|
||||
/** Prescale Div 2 */
|
||||
lcdFCPrescDiv2 = LCD_BACTRL_FCPRESC_DIV2,
|
||||
/** Prescale Div 4 */
|
||||
lcdFCPrescDiv4 = LCD_BACTRL_FCPRESC_DIV4,
|
||||
/** Prescale Div 8 */
|
||||
lcdFCPrescDiv8 = LCD_BACTRL_FCPRESC_DIV8
|
||||
} LCD_FCPreScale_TypeDef;
|
||||
|
||||
/** Segment selection */
|
||||
typedef enum
|
||||
{
|
||||
/** Select segment lines 0 to 3 */
|
||||
lcdSegment0_3 = (1 << 0),
|
||||
/** Select segment lines 4 to 7 */
|
||||
lcdSegment4_7 = (1 << 1),
|
||||
/** Select segment lines 8 to 11 */
|
||||
lcdSegment8_11 = (1 << 2),
|
||||
/** Select segment lines 12 to 15 */
|
||||
lcdSegment12_15 = (1 << 3),
|
||||
/** Select segment lines 16 to 19 */
|
||||
lcdSegment16_19 = (1 << 4),
|
||||
/** Select segment lines 20 to 23 */
|
||||
lcdSegment20_23 = (1 << 5),
|
||||
#if defined(_EFM32_TINY_FAMILY)
|
||||
/** Select all segment lines */
|
||||
lcdSegmentAll = (0x003f)
|
||||
#endif
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/** Select segment lines 24 to 27 */
|
||||
lcdSegment24_27 = (1 << 6),
|
||||
/** Select segment lines 28 to 31 */
|
||||
lcdSegment28_31 = (1 << 7),
|
||||
/** Select segment lines 32 to 35 */
|
||||
lcdSegment32_35 = (1 << 8),
|
||||
/** Select segment lines 36 to 39 */
|
||||
lcdSegment36_39 = (1 << 9),
|
||||
/** Select all segment lines */
|
||||
lcdSegmentAll = (0x03ff)
|
||||
#endif
|
||||
} LCD_SegmentRange_TypeDef;
|
||||
|
||||
/** Update Data Control */
|
||||
typedef enum
|
||||
{
|
||||
/** Regular update, data transfer done immediately */
|
||||
lcdUpdateCtrlRegular = LCD_CTRL_UDCTRL_REGULAR,
|
||||
/** Data transfer done at Frame Counter event */
|
||||
lcdUpdateCtrlFCEvent = LCD_CTRL_UDCTRL_FCEVENT,
|
||||
/** Data transfer done at Frame Start */
|
||||
lcdUpdateCtrlFrameStart = LCD_CTRL_UDCTRL_FRAMESTART
|
||||
} LCD_UpdateCtrl_TypeDef;
|
||||
|
||||
/** Animation Shift operation; none, left or right */
|
||||
typedef enum
|
||||
{
|
||||
/** No shift */
|
||||
lcdAnimShiftNone = _LCD_BACTRL_AREGASC_NOSHIFT,
|
||||
/** Shift segment bits left */
|
||||
lcdAnimShiftLeft = _LCD_BACTRL_AREGASC_SHIFTLEFT,
|
||||
/** Shift segment bits right */
|
||||
lcdAnimShiftRight = _LCD_BACTRL_AREGASC_SHIFTRIGHT
|
||||
} LCD_AnimShift_TypeDef;
|
||||
|
||||
/** Animation Logic Control, how AReg and BReg should be combined */
|
||||
typedef enum
|
||||
{
|
||||
/** Use bitwise logic AND to mix animation register A (AREGA) and B (AREGB) */
|
||||
lcdAnimLogicAnd = LCD_BACTRL_ALOGSEL_AND,
|
||||
/** Use bitwise logic OR to mix animation register A (AREGA) and B (AREGB) */
|
||||
lcdAnimLogicOr = LCD_BACTRL_ALOGSEL_OR
|
||||
} LCD_AnimLogic_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** LCD Animation Configuration */
|
||||
typedef struct
|
||||
{
|
||||
/** Enable Animation at end of initialization */
|
||||
bool enable;
|
||||
/** Initial Animation Register A Value */
|
||||
uint32_t AReg;
|
||||
/** Shift operation of Animation Register A */
|
||||
LCD_AnimShift_TypeDef AShift;
|
||||
/** Initial Animation Register B Value */
|
||||
uint32_t BReg;
|
||||
/** Shift operation of Animation Register B */
|
||||
LCD_AnimShift_TypeDef BShift;
|
||||
/** A and B Logical Operation to use for mixing and outputting resulting segments */
|
||||
LCD_AnimLogic_TypeDef animLogic;
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** Number of first segment to animate. Options are 0 or 8 for Giant/Leopard. End is startSeg+7 */
|
||||
int startSeg;
|
||||
#endif
|
||||
} LCD_AnimInit_TypeDef;
|
||||
|
||||
/** LCD Frame Control Initialization */
|
||||
typedef struct
|
||||
{
|
||||
/** Enable at end */
|
||||
bool enable;
|
||||
/** Frame Counter top value */
|
||||
uint32_t top;
|
||||
/** Frame Counter clock prescaler */
|
||||
LCD_FCPreScale_TypeDef prescale;
|
||||
} LCD_FrameCountInit_TypeDef;
|
||||
|
||||
/** LCD Controller Initialization structure */
|
||||
typedef struct
|
||||
{
|
||||
/** Enable controller at end of initialization */
|
||||
bool enable;
|
||||
/** Mux configuration */
|
||||
LCD_Mux_TypeDef mux;
|
||||
/** Bias configuration */
|
||||
LCD_Bias_TypeDef bias;
|
||||
/** Wave configuration */
|
||||
LCD_Wave_TypeDef wave;
|
||||
/** VLCD Select */
|
||||
LCD_VLCDSel_TypeDef vlcd;
|
||||
/** Contrast Configuration */
|
||||
LCD_ConConf_TypeDef contrast;
|
||||
} LCD_Init_TypeDef;
|
||||
|
||||
/** Default config for LCD init structure, enables 160 segments */
|
||||
#define LCD_INIT_DEFAULT \
|
||||
{ true, \
|
||||
lcdMuxQuadruplex, \
|
||||
lcdBiasOneThird, \
|
||||
lcdWaveLowPower, \
|
||||
lcdVLCDSelVDD, \
|
||||
lcdConConfVLCD \
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void LCD_Init(const LCD_Init_TypeDef *lcdInit);
|
||||
void LCD_VLCDSelect(LCD_VLCDSel_TypeDef vlcd);
|
||||
void LCD_UpdateCtrl(LCD_UpdateCtrl_TypeDef ud);
|
||||
void LCD_FrameCountInit(const LCD_FrameCountInit_TypeDef *fcInit);
|
||||
void LCD_AnimInit(const LCD_AnimInit_TypeDef *animInit);
|
||||
|
||||
void LCD_SegmentRangeEnable(LCD_SegmentRange_TypeDef segment, bool enable);
|
||||
void LCD_SegmentSet(int com, int bit, bool enable);
|
||||
void LCD_SegmentSetLow(int com, uint32_t mask, uint32_t bits);
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
void LCD_SegmentSetHigh(int com, uint32_t mask, uint32_t bits);
|
||||
#endif
|
||||
void LCD_ContrastSet(int level);
|
||||
void LCD_VBoostSet(LCD_VBoostLevel_TypeDef vboost);
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
void LCD_BiasSegmentSet(int segment, int biasLevel);
|
||||
void LCD_BiasComSet(int com, int biasLevel);
|
||||
#endif
|
||||
|
||||
static __INLINE void LCD_Enable(bool enable);
|
||||
static __INLINE void LCD_AnimEnable(bool enable);
|
||||
static __INLINE void LCD_BlinkEnable(bool enable);
|
||||
static __INLINE void LCD_BlankEnable(bool enable);
|
||||
static __INLINE void LCD_FrameCountEnable(bool enable);
|
||||
static __INLINE int LCD_AnimState(void);
|
||||
static __INLINE int LCD_BlinkState(void);
|
||||
static __INLINE void LCD_FreezeEnable(bool enable);
|
||||
static __INLINE uint32_t LCD_SyncBusyGet(void);
|
||||
static __INLINE void LCD_SyncBusyDelay(uint32_t flags);
|
||||
static __INLINE uint32_t LCD_IntGet(void);
|
||||
static __INLINE uint32_t LCD_IntGetEnabled(void);
|
||||
static __INLINE void LCD_IntSet(uint32_t flags);
|
||||
static __INLINE void LCD_IntEnable(uint32_t flags);
|
||||
static __INLINE void LCD_IntDisable(uint32_t flags);
|
||||
static __INLINE void LCD_IntClear(uint32_t flags);
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
static __INLINE void LCD_DSCEnable(bool enable);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable or disable LCD controller
|
||||
*
|
||||
* @param[in] enable
|
||||
* If true, enables LCD controller with current configuration, if false
|
||||
* disables LCD controller. CMU clock for LCD must be enabled for correct
|
||||
* operation.
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_Enable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
LCD->CTRL |= LCD_CTRL_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD->CTRL &= ~(LCD_CTRL_EN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables or disables LCD Animation feature
|
||||
*
|
||||
* @param[in] enable
|
||||
* Boolean true enables animation, false disables animation
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_AnimEnable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
LCD->BACTRL |= LCD_BACTRL_AEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD->BACTRL &= ~(LCD_BACTRL_AEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables or disables LCD blink
|
||||
*
|
||||
* @param[in] enable
|
||||
* Boolean true enables blink, false disables blink
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_BlinkEnable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
LCD->BACTRL |= LCD_BACTRL_BLINKEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD->BACTRL &= ~(LCD_BACTRL_BLINKEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disables all segments, while keeping segment state
|
||||
*
|
||||
* @param[in] enable
|
||||
* Boolean true clears all segments, boolean false restores all segment lines
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_BlankEnable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
LCD->BACTRL |= LCD_BACTRL_BLANK;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD->BACTRL &= ~(LCD_BACTRL_BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables or disables LCD Frame Control
|
||||
*
|
||||
* @param[in] enable
|
||||
* Boolean true enables frame counter, false disables frame counter
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_FrameCountEnable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
LCD->BACTRL |= LCD_BACTRL_FCEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD->BACTRL &= ~(LCD_BACTRL_FCEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns current animation state
|
||||
*
|
||||
* @return
|
||||
* Animation state, in range 0-15
|
||||
******************************************************************************/
|
||||
static __INLINE int LCD_AnimState(void)
|
||||
{
|
||||
return (int)(LCD->STATUS & _LCD_STATUS_ASTATE_MASK) >> _LCD_STATUS_ASTATE_SHIFT;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns current blink state
|
||||
*
|
||||
* @return
|
||||
* Return value is 1 if segments are enabled, 0 if disabled
|
||||
******************************************************************************/
|
||||
static __INLINE int LCD_BlinkState(void)
|
||||
{
|
||||
return (int)(LCD->STATUS & _LCD_STATUS_BLINK_MASK) >> _LCD_STATUS_BLINK_SHIFT;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* When set, LCD registers will not be updated until cleared,
|
||||
*
|
||||
* @param[in] enable
|
||||
* When enable is true, update is stopped, when false all registers are
|
||||
* updated
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_FreezeEnable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
LCD->FREEZE = LCD_FREEZE_REGFREEZE_FREEZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD->FREEZE = LCD_FREEZE_REGFREEZE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns SYNCBUSY bits, indicating which registers have pending updates
|
||||
*
|
||||
* @return
|
||||
* Bit fields for LCD registers which have pending updates
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t LCD_SyncBusyGet(void)
|
||||
{
|
||||
return(LCD->SYNCBUSY);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Polls LCD SYNCBUSY flags, until flag has been cleared
|
||||
*
|
||||
* @param[in] flags
|
||||
* Bit fields for LCD registers that shall be updated before we continue
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_SyncBusyDelay(uint32_t flags)
|
||||
{
|
||||
while (LCD->SYNCBUSY & flags)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending LCD interrupt flags
|
||||
*
|
||||
* @return
|
||||
* Pending LCD interrupt sources. Returns a set of interrupt flags OR-ed
|
||||
* together for multiple interrupt sources in the LCD module (LCD_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t LCD_IntGet(void)
|
||||
{
|
||||
return(LCD->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get enabled and pending LCD interrupt flags.
|
||||
*
|
||||
* @details
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* Pending and enabled LCD interrupt sources.
|
||||
* The return value is the bitwise AND combination of
|
||||
* - the OR combination of enabled interrupt sources in LCD_IEN_nnn
|
||||
* register (LCD_IEN_nnn) and
|
||||
* - the bitwise OR combination of valid interrupt flags of the LCD module
|
||||
* (LCD_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t LCD_IntGetEnabled(void)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
/* Store LCD->IEN in temporary variable in order to define explicit order
|
||||
* of volatile accesses. */
|
||||
tmp = LCD->IEN;
|
||||
|
||||
/* Bitwise AND of pending and enabled interrupts */
|
||||
return LCD->IF & tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending LCD interrupts from SW.
|
||||
*
|
||||
* @param[in] flags
|
||||
* LCD interrupt sources to set to pending. Use a set of interrupt flags
|
||||
* OR-ed together to set multiple interrupt sources for the LCD module
|
||||
* (LCD_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_IntSet(uint32_t flags)
|
||||
{
|
||||
LCD->IFS = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable LCD interrupts
|
||||
*
|
||||
* @param[in] flags
|
||||
* LCD interrupt sources to enable. Use a set of interrupt flags OR-ed
|
||||
* together to set multiple interrupt sources for the LCD module
|
||||
* (LCD_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_IntEnable(uint32_t flags)
|
||||
{
|
||||
LCD->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable LCD interrupts
|
||||
*
|
||||
* @param[in] flags
|
||||
* LCD interrupt sources to disable. Use a set of interrupt flags OR-ed
|
||||
* together to disable multiple interrupt sources for the LCD module
|
||||
* (LCD_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_IntDisable(uint32_t flags)
|
||||
{
|
||||
LCD->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more interrupt flags
|
||||
*
|
||||
* @param[in] flags
|
||||
* LCD interrupt sources to clear. Use a set of interrupt flags OR-ed
|
||||
* together to clear multiple interrupt sources for the LCD module
|
||||
* (LCD_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_IntClear(uint32_t flags)
|
||||
{
|
||||
LCD->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable or disable LCD Direct Segment Control
|
||||
*
|
||||
* @param[in] enable
|
||||
* If true, enables LCD controller Direct Segment Control
|
||||
* Segment and COM line bias levels needs to be set explicitly with the
|
||||
* LCD_BiasSegmentSet() and LCD_BiasComSet() function calls.
|
||||
******************************************************************************/
|
||||
static __INLINE void LCD_DSCEnable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
LCD->CTRL |= LCD_CTRL_DSC;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD->CTRL &= ~(LCD_CTRL_DSC);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup LCD) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(LCD_COUNT) && (LCD_COUNT > 0) */
|
||||
|
||||
#endif /* __EFM32_LCD_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,259 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Low Energy Timer (LETIMER) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_LETIMER_H
|
||||
#define __EFM32_LETIMER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup LETIMER
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Repeat mode. */
|
||||
typedef enum
|
||||
{
|
||||
/** Count until stopped by SW. */
|
||||
letimerRepeatFree = _LETIMER_CTRL_REPMODE_FREE,
|
||||
/** Count REP0 times. */
|
||||
letimerRepeatOneshot = _LETIMER_CTRL_REPMODE_ONESHOT,
|
||||
/**
|
||||
* Count REP0 times, if REP1 has been written to, it is loaded into
|
||||
* REP0 when REP0 is about to be decremented to 0.
|
||||
*/
|
||||
letimerRepeatBuffered = _LETIMER_CTRL_REPMODE_BUFFERED,
|
||||
/**
|
||||
* Run as long as both REP0 and REP1 are not 0. Both REP0 and REP1
|
||||
* are decremented when counter underflows.
|
||||
*/
|
||||
letimerRepeatDouble = _LETIMER_CTRL_REPMODE_DOUBLE
|
||||
} LETIMER_RepeatMode_TypeDef;
|
||||
|
||||
|
||||
/** Underflow action on output. */
|
||||
typedef enum
|
||||
{
|
||||
/** No output action. */
|
||||
letimerUFOANone = _LETIMER_CTRL_UFOA0_NONE,
|
||||
/** Toggle output when counter underflows. */
|
||||
letimerUFOAToggle = _LETIMER_CTRL_UFOA0_TOGGLE,
|
||||
/** Hold output one LETIMER clock cycle when counter underflows. */
|
||||
letimerUFOAPulse = _LETIMER_CTRL_UFOA0_PULSE,
|
||||
/** Set output idle when counter underflows, and active when matching COMP1. */
|
||||
letimerUFOAPwm = _LETIMER_CTRL_UFOA0_PWM
|
||||
} LETIMER_UFOA_TypeDef;
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** LETIMER initialization structure. */
|
||||
typedef struct
|
||||
{
|
||||
bool enable; /**< Start counting when init completed. */
|
||||
bool debugRun; /**< Counter shall keep running during debug halt. */
|
||||
bool rtcComp0Enable; /**< Start counting on RTC COMP0 match. */
|
||||
bool rtcComp1Enable; /**< Start counting on RTC COMP1 match. */
|
||||
bool comp0Top; /**< Load COMP0 register into CNT when counter underflows. */
|
||||
bool bufTop; /**< Load COMP1 into COMP0 when REP0 reaches 0. */
|
||||
uint8_t out0Pol; /**< Idle value for output 0. */
|
||||
uint8_t out1Pol; /**< Idle value for output 1. */
|
||||
LETIMER_UFOA_TypeDef ufoa0; /**< Underflow output 0 action. */
|
||||
LETIMER_UFOA_TypeDef ufoa1; /**< Underflow output 1 action. */
|
||||
LETIMER_RepeatMode_TypeDef repMode; /**< Repeat mode. */
|
||||
} LETIMER_Init_TypeDef;
|
||||
|
||||
/** Default config for LETIMER init structure. */
|
||||
#define LETIMER_INIT_DEFAULT \
|
||||
{ true, /* Enable timer when init complete. */ \
|
||||
false, /* Stop counter during debug halt. */ \
|
||||
false, /* Do not start counting on RTC COMP0 match. */ \
|
||||
false, /* Do not start counting on RTC COMP1 match. */ \
|
||||
false, /* Do not load COMP0 into CNT on underflow. */ \
|
||||
false, /* Do not load COMP1 into COMP0 when REP0 reaches 0. */ \
|
||||
0, /* Idle value 0 for output 0. */ \
|
||||
0, /* Idle value 0 for output 1. */ \
|
||||
letimerUFOANone, /* No action on underflow on output 0. */ \
|
||||
letimerUFOANone, /* No action on underflow on output 1. */ \
|
||||
letimerRepeatFree /* Count until stopped by SW. */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp);
|
||||
void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
|
||||
unsigned int comp,
|
||||
uint32_t value);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get LETIMER counter value.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current LETIMER counter value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t LETIMER_CounterGet(LETIMER_TypeDef *letimer)
|
||||
{
|
||||
return(letimer->CNT);
|
||||
}
|
||||
|
||||
|
||||
void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable);
|
||||
void LETIMER_FreezeEnable(LETIMER_TypeDef *letimer, bool enable);
|
||||
void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending LETIMER interrupts.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending LETIMER interrupt source to clear. Use a bitwise logic OR
|
||||
* combination of valid interrupt flags for the LETIMER module
|
||||
* (LETIMER_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LETIMER_IntClear(LETIMER_TypeDef *letimer, uint32_t flags)
|
||||
{
|
||||
letimer->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more LETIMER interrupts.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* LETIMER interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LETIMER_IntDisable(LETIMER_TypeDef *letimer, uint32_t flags)
|
||||
{
|
||||
letimer->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more LETIMER interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using LETIMER_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* LETIMER interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LETIMER_IntEnable(LETIMER_TypeDef *letimer, uint32_t flags)
|
||||
{
|
||||
letimer->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending LETIMER interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* LETIMER interrupt sources pending. A bitwise logic OR combination of
|
||||
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t LETIMER_IntGet(LETIMER_TypeDef *letimer)
|
||||
{
|
||||
return(letimer->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending LETIMER interrupts from SW.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* LETIMER interrupt sources to set to pending. Use a bitwise logic OR
|
||||
* combination of valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LETIMER_IntSet(LETIMER_TypeDef *letimer, uint32_t flags)
|
||||
{
|
||||
letimer->IFS = flags;
|
||||
}
|
||||
|
||||
uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep);
|
||||
void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
|
||||
unsigned int rep,
|
||||
uint32_t value);
|
||||
void LETIMER_Reset(LETIMER_TypeDef *letimer);
|
||||
|
||||
|
||||
/** @} (end addtogroup LETIMER) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_LETIMER_H */
|
|
@ -0,0 +1,255 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Low Energy Universal Asynchronous Receiver/Transmitter (LEUART)
|
||||
* peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_LEUART_H
|
||||
#define __EFM32_LEUART_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup LEUART
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Databit selection. */
|
||||
typedef enum
|
||||
{
|
||||
leuartDatabits8 = LEUART_CTRL_DATABITS_EIGHT, /**< 8 databits. */
|
||||
leuartDatabits9 = LEUART_CTRL_DATABITS_NINE /**< 9 databits. */
|
||||
} LEUART_Databits_TypeDef;
|
||||
|
||||
|
||||
/** Enable selection. */
|
||||
typedef enum
|
||||
{
|
||||
/** Disable both receiver and transmitter. */
|
||||
leuartDisable = 0x0,
|
||||
|
||||
/** Enable receiver only, transmitter disabled. */
|
||||
leuartEnableRx = LEUART_CMD_RXEN,
|
||||
|
||||
/** Enable transmitter only, receiver disabled. */
|
||||
leuartEnableTx = LEUART_CMD_TXEN,
|
||||
|
||||
/** Enable both receiver and transmitter. */
|
||||
leuartEnable = (LEUART_CMD_RXEN | LEUART_CMD_TXEN)
|
||||
} LEUART_Enable_TypeDef;
|
||||
|
||||
|
||||
/** Parity selection. */
|
||||
typedef enum
|
||||
{
|
||||
leuartNoParity = LEUART_CTRL_PARITY_NONE, /**< No parity. */
|
||||
leuartEvenParity = LEUART_CTRL_PARITY_EVEN, /**< Even parity. */
|
||||
leuartOddParity = LEUART_CTRL_PARITY_ODD /**< Odd parity. */
|
||||
} LEUART_Parity_TypeDef;
|
||||
|
||||
|
||||
/** Stopbits selection. */
|
||||
typedef enum
|
||||
{
|
||||
leuartStopbits1 = LEUART_CTRL_STOPBITS_ONE, /**< 1 stopbits. */
|
||||
leuartStopbits2 = LEUART_CTRL_STOPBITS_TWO /**< 2 stopbits. */
|
||||
} LEUART_Stopbits_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Init structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Specifies whether TX and/or RX shall be enabled when init completed. */
|
||||
LEUART_Enable_TypeDef enable;
|
||||
|
||||
/**
|
||||
* LEUART reference clock assumed when configuring baudrate setup. Set
|
||||
* it to 0 if currently configurated reference clock shall be used.
|
||||
*/
|
||||
uint32_t refFreq;
|
||||
|
||||
/** Desired baudrate. */
|
||||
uint32_t baudrate;
|
||||
|
||||
/** Number of databits in frame. */
|
||||
LEUART_Databits_TypeDef databits;
|
||||
|
||||
/** Parity mode to use. */
|
||||
LEUART_Parity_TypeDef parity;
|
||||
|
||||
/** Number of stopbits to use. */
|
||||
LEUART_Stopbits_TypeDef stopbits;
|
||||
} LEUART_Init_TypeDef;
|
||||
|
||||
/** Default config for LEUART init structure. */
|
||||
#define LEUART_INIT_DEFAULT \
|
||||
{ leuartEnable, /* Enable RX/TX when init completed. */ \
|
||||
0, /* Use current configured reference clock for configuring baudrate. */ \
|
||||
9600, /* 9600 bits/s. */ \
|
||||
leuartDatabits8, /* 8 databits. */ \
|
||||
leuartNoParity, /* No parity. */ \
|
||||
leuartStopbits1 /* 1 stopbit. */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
uint32_t LEUART_BaudrateCalc(uint32_t refFreq, uint32_t clkdiv);
|
||||
uint32_t LEUART_BaudrateGet(LEUART_TypeDef *leuart);
|
||||
void LEUART_BaudrateSet(LEUART_TypeDef *leuart,
|
||||
uint32_t refFreq,
|
||||
uint32_t baudrate);
|
||||
void LEUART_Enable(LEUART_TypeDef *leuart, LEUART_Enable_TypeDef enable);
|
||||
void LEUART_FreezeEnable(LEUART_TypeDef *leuart, bool enable);
|
||||
void LEUART_Init(LEUART_TypeDef *leuart, LEUART_Init_TypeDef *init);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending LEUART interrupts.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending LEUART interrupt source to clear. Use a bitwise logic OR
|
||||
* combination of valid interrupt flags for the LEUART module (LEUART_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LEUART_IntClear(LEUART_TypeDef *leuart, uint32_t flags)
|
||||
{
|
||||
leuart->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more LEUART interrupts.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* LEUART interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the LEUART module (LEUART_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LEUART_IntDisable(LEUART_TypeDef *leuart, uint32_t flags)
|
||||
{
|
||||
leuart->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more LEUART interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using LEUART_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* LEUART interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the LEUART module (LEUART_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LEUART_IntEnable(LEUART_TypeDef *leuart, uint32_t flags)
|
||||
{
|
||||
leuart->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending LEUART interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* LEUART interrupt sources pending. A bitwise logic OR combination of valid
|
||||
* interrupt flags for the LEUART module (LEUART_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t LEUART_IntGet(LEUART_TypeDef *leuart)
|
||||
{
|
||||
return(leuart->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending LEUART interrupts from SW.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* LEUART interrupt sources to set to pending. Use a bitwise logic OR
|
||||
* combination of valid interrupt flags for the LEUART module (LEUART_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void LEUART_IntSet(LEUART_TypeDef *leuart, uint32_t flags)
|
||||
{
|
||||
leuart->IFS = flags;
|
||||
}
|
||||
|
||||
void LEUART_Reset(LEUART_TypeDef *leuart);
|
||||
uint8_t LEUART_Rx(LEUART_TypeDef *leuart);
|
||||
uint16_t LEUART_RxExt(LEUART_TypeDef *leuart);
|
||||
void LEUART_Tx(LEUART_TypeDef *leuart, uint8_t data);
|
||||
void LEUART_TxExt(LEUART_TypeDef *leuart, uint16_t data);
|
||||
|
||||
|
||||
/** @} (end addtogroup LEUART) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_LEUART_H */
|
|
@ -0,0 +1,236 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Memory protection unit (MPU) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_MPU_H
|
||||
#define __EFM32_MPU_H
|
||||
|
||||
#include "efm32.h"
|
||||
|
||||
#if defined(__MPU_PRESENT) && (__MPU_PRESENT == 1)
|
||||
#include "efm32_assert.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup MPU
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/** @anchor MPU_CTRL_PRIVDEFENA
|
||||
* Argument to MPU_enable(). Enables priviledged
|
||||
* access to default memory map. */
|
||||
#define MPU_CTRL_PRIVDEFENA MPU_CTRL_PRIVDEFENA_Msk
|
||||
|
||||
/** @anchor MPU_CTRL_HFNMIENA
|
||||
* Argument to MPU_enable(). Enables MPU during hard fault,
|
||||
* NMI, and FAULTMASK handlers. */
|
||||
#define MPU_CTRL_HFNMIENA MPU_CTRL_HFNMIENA_Msk
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Size of an MPU region.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
mpuRegionSize32b = 4, /**< 32 byte region size. */
|
||||
mpuRegionSize64b = 5, /**< 64 byte region size. */
|
||||
mpuRegionSize128b = 6, /**< 128 byte region size. */
|
||||
mpuRegionSize256b = 7, /**< 256 byte region size. */
|
||||
mpuRegionSize512b = 8, /**< 512 byte region size. */
|
||||
mpuRegionSize1Kb = 9, /**< 1K byte region size. */
|
||||
mpuRegionSize2Kb = 10, /**< 2K byte region size. */
|
||||
mpuRegionSize4Kb = 11, /**< 4K byte region size. */
|
||||
mpuRegionSize8Kb = 12, /**< 8K byte region size. */
|
||||
mpuRegionSize16Kb = 13, /**< 16K byte region size. */
|
||||
mpuRegionSize32Kb = 14, /**< 32K byte region size. */
|
||||
mpuRegionSize64Kb = 15, /**< 64K byte region size. */
|
||||
mpuRegionSize128Kb = 16, /**< 128K byte region size. */
|
||||
mpuRegionSize256Kb = 17, /**< 256K byte region size. */
|
||||
mpuRegionSize512Kb = 18, /**< 512K byte region size. */
|
||||
mpuRegionSize1Mb = 19, /**< 1M byte region size. */
|
||||
mpuRegionSize2Mb = 20, /**< 2M byte region size. */
|
||||
mpuRegionSize4Mb = 21, /**< 4M byte region size. */
|
||||
mpuRegionSize8Mb = 22, /**< 8M byte region size. */
|
||||
mpuRegionSize16Mb = 23, /**< 16M byte region size. */
|
||||
mpuRegionSize32Mb = 24, /**< 32M byte region size. */
|
||||
mpuRegionSize64Mb = 25, /**< 64M byte region size. */
|
||||
mpuRegionSize128Mb = 26, /**< 128M byte region size. */
|
||||
mpuRegionSize256Mb = 27, /**< 256M byte region size. */
|
||||
mpuRegionSize512Mb = 28, /**< 512M byte region size. */
|
||||
mpuRegionSize1Gb = 29, /**< 1G byte region size. */
|
||||
mpuRegionSize2Gb = 30, /**< 2G byte region size. */
|
||||
mpuRegionSize4Gb = 31 /**< 4G byte region size. */
|
||||
} MPU_RegionSize_TypeDef;
|
||||
|
||||
/**
|
||||
* MPU region access permission attributes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
mpuRegionNoAccess = 0, /**< No access what so ever. */
|
||||
mpuRegionApPRw = 1, /**< Priviledged state R/W only. */
|
||||
mpuRegionApPRwURo = 2, /**< Priviledged state R/W, User state R only. */
|
||||
mpuRegionApFullAccess = 3, /**< R/W in Priviledged and User state. */
|
||||
mpuRegionApPRo = 5, /**< Priviledged R only. */
|
||||
mpuRegionApPRo_URo = 6 /**< R only in Priviledged and User state. */
|
||||
} MPU_RegionAp_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** MPU Region init structure. */
|
||||
typedef struct
|
||||
{
|
||||
bool regionEnable; /**< MPU region enable. */
|
||||
uint8_t regionNo; /**< MPU region number. */
|
||||
uint32_t baseAddress; /**< Region baseaddress. */
|
||||
MPU_RegionSize_TypeDef size; /**< Memory region size. */
|
||||
MPU_RegionAp_TypeDef accessPermission; /**< Memory access permissions. */
|
||||
bool disableExec; /**< Disable execution. */
|
||||
bool shareable; /**< Memory shareable attribute. */
|
||||
bool cacheable; /**< Memory cacheable attribute. */
|
||||
bool bufferable; /**< Memory bufferable attribute. */
|
||||
uint8_t srd; /**< Memory subregion disable bits. */
|
||||
uint8_t tex; /**< Memory type extension attributes. */
|
||||
} MPU_RegionInit_TypeDef;
|
||||
|
||||
/** Default configuration of MPU region init structure for flash memory. */
|
||||
#define MPU_INIT_FLASH_DEFAULT \
|
||||
{ \
|
||||
true, /* Enable MPU region. */ \
|
||||
0, /* MPU Region number. */ \
|
||||
FLASH_MEM_BASE, /* Flash base address. */ \
|
||||
mpuRegionSize1Mb, /* Size - Set to max. for EFM32. */ \
|
||||
mpuRegionApFullAccess, /* Access permissions. */ \
|
||||
false, /* Execution allowed. */ \
|
||||
false, /* Not shareable. */ \
|
||||
true, /* Cacheable. */ \
|
||||
false, /* Not bufferable. */ \
|
||||
0, /* No subregions. */ \
|
||||
0 /* No TEX attributes. */ \
|
||||
}
|
||||
|
||||
|
||||
/** Default configuration of MPU region init structure for sram memory. */
|
||||
#define MPU_INIT_SRAM_DEFAULT \
|
||||
{ \
|
||||
true, /* Enable MPU region. */ \
|
||||
1, /* MPU Region number. */ \
|
||||
RAM_MEM_BASE, /* SRAM base address. */ \
|
||||
mpuRegionSize128Kb, /* Size - Set to max. for EFM32. */ \
|
||||
mpuRegionApFullAccess, /* Access permissions. */ \
|
||||
false, /* Execution allowed. */ \
|
||||
true, /* Shareable. */ \
|
||||
true, /* Cacheable. */ \
|
||||
false, /* Not bufferable. */ \
|
||||
0, /* No subregions. */ \
|
||||
0 /* No TEX attributes. */ \
|
||||
}
|
||||
|
||||
|
||||
/** Default configuration of MPU region init structure for onchip peripherals.*/
|
||||
#define MPU_INIT_PERIPHERAL_DEFAULT \
|
||||
{ \
|
||||
true, /* Enable MPU region. */ \
|
||||
0, /* MPU Region number. */ \
|
||||
0, /* Region base address. */ \
|
||||
mpuRegionSize32b, /* Size - Set to minimum */ \
|
||||
mpuRegionApFullAccess, /* Access permissions. */ \
|
||||
true, /* Execution not allowed. */ \
|
||||
true, /* Shareable. */ \
|
||||
false, /* Not cacheable. */ \
|
||||
true, /* Bufferable. */ \
|
||||
0, /* No subregions. */ \
|
||||
0 /* No TEX attributes. */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
void MPU_ConfigureRegion(const MPU_RegionInit_TypeDef *init);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable the MPU
|
||||
* @details
|
||||
* Disable MPU and MPU fault exceptions.
|
||||
******************************************************************************/
|
||||
static __INLINE void MPU_Disable(void)
|
||||
{
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; /* Disable fault exceptions */
|
||||
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; /* Disable the MPU */
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable the MPU
|
||||
* @details
|
||||
* Enable MPU and MPU fault exceptions.
|
||||
* @param[in] flags
|
||||
* Use a logical OR of @ref MPU_CTRL_PRIVDEFENA and
|
||||
* @ref MPU_CTRL_HFNMIENA as needed.
|
||||
******************************************************************************/
|
||||
static __INLINE void MPU_Enable(uint32_t flags)
|
||||
{
|
||||
EFM_ASSERT(!(flags & ~(MPU_CTRL_PRIVDEFENA_Msk |
|
||||
MPU_CTRL_HFNMIENA_Msk |
|
||||
MPU_CTRL_ENABLE_Msk)));
|
||||
|
||||
MPU->CTRL = flags | MPU_CTRL_ENABLE_Msk; /* Enable the MPU */
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; /* Enable fault exceptions */
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup MPU) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(__MPU_PRESENT) && (EBI_COUNT == 1) */
|
||||
|
||||
#endif /* __EFM32_MPU_H */
|
|
@ -0,0 +1,367 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Flash controller module (MSC) peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_MSC_H
|
||||
#define __EFM32_MSC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "efm32.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup MSC
|
||||
* @brief Flash controller (MSC) peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************* DEFINES *****************************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* The timeout used while waiting for the flash to become ready after
|
||||
* a write. This number indicates the number of iterations to perform before
|
||||
* issuing a timeout.
|
||||
* @note
|
||||
* This timeout is set very large (in the order of 100x longer than
|
||||
* necessary). This is to avoid any corner cases.
|
||||
*
|
||||
*/
|
||||
#define MSC_PROGRAM_TIMEOUT 10000000ul
|
||||
|
||||
/*******************************************************************************
|
||||
************************* TYPEDEFS ****************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Return codes for writing/erasing the flash */
|
||||
typedef enum
|
||||
{
|
||||
mscReturnOk = 0, /**< Flash write/erase successful. */
|
||||
mscReturnInvalidAddr = -1, /**< Invalid address. Write to an address that is not flash. */
|
||||
mscReturnLocked = -2, /**< Flash address is locked. */
|
||||
mscReturnTimeOut = -3, /**< Timeout while writing to flash. */
|
||||
mscReturnUnaligned = -4 /**< Unaligned access to flash. */
|
||||
} msc_Return_TypeDef;
|
||||
|
||||
|
||||
#if defined (_EFM32_GIANT_FAMILY)
|
||||
/** Strategy for prioritized bus access */
|
||||
typedef enum {
|
||||
mscBusStrategyCPU = MSC_READCTRL_BUSSTRATEGY_CPU, /**< Prioritize CPU bus accesses */
|
||||
mscBusStrategyDMA = MSC_READCTRL_BUSSTRATEGY_DMA, /**< Prioritize DMA bus accesses */
|
||||
mscBusStrategyDMAEM2 = MSC_READCTRL_BUSSTRATEGY_DMAEM2, /**< Prioritize DMAEM2 for bus accesses */
|
||||
mscBusStrategyNone = MSC_READCTRL_BUSSTRATEGY_NONE /**< No unit has bus priority */
|
||||
} mscBusStrategy_Typedef;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
************************* PROTOTYPES **************************************
|
||||
******************************************************************************/
|
||||
|
||||
void MSC_Deinit(void);
|
||||
void MSC_Init(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending MSC interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending MSC intterupt source to clear. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the MSC module (MSC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_IntClear(uint32_t flags)
|
||||
{
|
||||
MSC->IFC = flags;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more MSC interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* MSC interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the MSC module (MSC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_IntDisable(uint32_t flags)
|
||||
{
|
||||
MSC->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more MSC interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using MSC_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] flags
|
||||
* MSC interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the MSC module (MSC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_IntEnable(uint32_t flags)
|
||||
{
|
||||
MSC->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending MSV interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* MSC interrupt sources pending. A bitwise logic OR combination of valid
|
||||
* interrupt flags for the MSC module (MSC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t MSC_IntGet(void)
|
||||
{
|
||||
return(MSC->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending MSC interrupts from SW.
|
||||
*
|
||||
* @param[in] flags
|
||||
* MSC interrupt sources to set to pending. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the MSC module (MSC_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_IntSet(uint32_t flags)
|
||||
{
|
||||
MSC->IFS = flags;
|
||||
}
|
||||
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Starts measuring cache hit ratio.
|
||||
* @details
|
||||
* This function starts the performance counters. It is defined inline to
|
||||
* minimize the impact of this code on the measurement itself.
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_StartCacheMeasurement(void)
|
||||
{
|
||||
/* Clear CMOF and CHOF to catch these later */
|
||||
MSC->IFC = MSC_IF_CHOF | MSC_IF_CMOF;
|
||||
|
||||
/* Start performance counters */
|
||||
MSC->CMD = MSC_CMD_STARTPC;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Stops measuring the hit rate.
|
||||
* @note
|
||||
* This function is defined inline to minimize the impact of this
|
||||
* code on the measurement itself.
|
||||
* This code only works for relatively short sections of code. If you wish
|
||||
* to measure longer sections of code you need to implement a IRQ Handler for
|
||||
* The CHOF and CMOF overflow interrupts. Theses overflows needs to be
|
||||
* counted and included in the total.
|
||||
* The functions can then be implemented as follows:
|
||||
* @verbatim
|
||||
* volatile uint32_t hitOverflows
|
||||
* volatile uint32_t missOverflows
|
||||
*
|
||||
* void MSC_IRQHandler(void)
|
||||
* {
|
||||
* uint32_t flags;
|
||||
* flags = MSC->IF;
|
||||
* if (flags & MSC_IF_CHOF)
|
||||
* {
|
||||
* MSC->IFC = MSC_IF_CHOF;
|
||||
* hitOverflows++;
|
||||
* }
|
||||
* if (flags & MSC_IF_CMOF)
|
||||
* {
|
||||
* MSC->IFC = MSC_IF_CMOF;
|
||||
* missOverflows++;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* void startPerformanceCounters(void)
|
||||
* {
|
||||
* hitOverflows = 0;
|
||||
* missOverflows = 0;
|
||||
*
|
||||
* MSC_IntEnable(MSC_IF_CHOF | MSC_IF_CMOF);
|
||||
* NVIC_EnableIRQ(MSC_IRQn);
|
||||
*
|
||||
* MSC_StartCacheMeasurement();
|
||||
* }
|
||||
* @endverbatim
|
||||
* @return
|
||||
* Returns -1 if there has been no cache accesses.
|
||||
* Returns -2 if there has been an overflow in the performance counters.
|
||||
* If not, it will return the percentage of hits versus misses.
|
||||
******************************************************************************/
|
||||
static __INLINE int32_t MSC_GetCacheMeasurement(void)
|
||||
{
|
||||
int32_t total;
|
||||
/* Stop the counter before computing the hit-rate */
|
||||
MSC->CMD = MSC_CMD_STOPPC;
|
||||
|
||||
/* Check for overflows in performance counters */
|
||||
if (MSC->IF & (MSC_IF_CHOF | MSC_IF_CMOF))
|
||||
return -2;
|
||||
|
||||
/* Because the hits and misses are volatile, we need to split this up into
|
||||
* two statements to avoid a compiler warning regarding the order of volatile
|
||||
* accesses. */
|
||||
total = MSC->CACHEHITS;
|
||||
total += MSC->CACHEMISSES;
|
||||
|
||||
/* To avoid a division by zero. */
|
||||
if (total == 0)
|
||||
return -1;
|
||||
|
||||
return (MSC->CACHEHITS * 100) / total;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Flush the contents of the instruction cache.
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_FlushCache(void)
|
||||
{
|
||||
MSC->CMD = MSC_CMD_INVCACHE;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable or disable instruction cache functionality
|
||||
* @param[in] enable
|
||||
* Enable instruction cache. Default is on.
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_EnableCache(bool enable)
|
||||
{
|
||||
BITBAND_Peripheral(&(MSC->READCTRL), _MSC_READCTRL_IFCDIS_SHIFT, ~enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable or disable instruction cache functionality in IRQs
|
||||
* @param[in] enable
|
||||
* Enable instruction cache. Default is on.
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_EnableCacheIRQs(bool enable)
|
||||
{
|
||||
BITBAND_Peripheral(&(MSC->READCTRL), _MSC_READCTRL_ICCDIS_SHIFT, ~enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable or disable instruction cache flushing when writing to flash
|
||||
* @param[in] enable
|
||||
* Enable automatic cache flushing. Default is on.
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_EnableAutoCacheFlush(bool enable)
|
||||
{
|
||||
BITBAND_Peripheral(&(MSC->READCTRL), _MSC_READCTRL_AIDIS_SHIFT, ~enable);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure which unit should get priority on system bus.
|
||||
* @param[in] mode
|
||||
* Unit to prioritize bus accesses for.
|
||||
******************************************************************************/
|
||||
static __INLINE void MSC_BusStrategy(mscBusStrategy_Typedef mode)
|
||||
{
|
||||
MSC->READCTRL = (MSC->READCTRL & ~(_MSC_READCTRL_BUSSTRATEGY_MASK))|mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __CC_ARM /* MDK-ARM compiler */
|
||||
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes);
|
||||
msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress);
|
||||
#if defined (_EFM32_GIANT_FAMILY)
|
||||
msc_Return_TypeDef MSC_MassErase(void);
|
||||
#endif
|
||||
#endif /* __CC_ARM */
|
||||
|
||||
#ifdef __ICCARM__ /* IAR compiler */
|
||||
__ramfunc msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes);
|
||||
__ramfunc msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress);
|
||||
#if defined (_EFM32_GIANT_FAMILY)
|
||||
__ramfunc msc_Return_TypeDef MSC_MassErase(void);
|
||||
#endif
|
||||
#endif /* __ICCARM__ */
|
||||
|
||||
#ifdef __GNUC__ /* GCC based compilers */
|
||||
#ifdef __CROSSWORKS_ARM /* Rowley Crossworks */
|
||||
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes) __attribute__ ((section(".fast")));
|
||||
msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress) __attribute__ ((section(".fast")));
|
||||
#if defined (_EFM32_GIANT_FAMILY)
|
||||
msc_Return_TypeDef MSC_MassErase(void) __attribute__ ((section(".fast")));
|
||||
#endif
|
||||
#else /* Sourcery G++ */
|
||||
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes) __attribute__ ((section(".ram")));
|
||||
msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress) __attribute__ ((section(".ram")));
|
||||
#if defined (_EFM32_GIANT_FAMILY)
|
||||
msc_Return_TypeDef MSC_MassErase(void) __attribute__ ((section(".ram")));
|
||||
#endif
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
#endif /* __CROSSWORKS_ARM */
|
||||
|
||||
/** @} (end addtogroup MSC) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_MSC_H */
|
|
@ -0,0 +1,538 @@
|
|||
/**************************************************************************//**
|
||||
* @file
|
||||
* @brief Operational Amplifier (OPAMP) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __EFM32_OPAMP_H
|
||||
#define __EFM32_OPAMP_H
|
||||
|
||||
#include "efm32.h"
|
||||
#if defined(OPAMP_PRESENT) && (OPAMP_COUNT == 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "efm32_dac.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup OPAMP
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of DAC OPA number for assert statements. */
|
||||
#define DAC_OPA_VALID(opa) ((opa) <= OPA2)
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** OPAMP selector values. */
|
||||
typedef enum
|
||||
{
|
||||
OPA0 = 0, /**< Select OPA0. */
|
||||
OPA1 = 1, /**< Select OPA1. */
|
||||
OPA2 = 2 /**< Select OPA2. */
|
||||
} OPAMP_TypeDef;
|
||||
|
||||
/** OPAMP negative terminal input selection values. */
|
||||
typedef enum
|
||||
{
|
||||
opaNegSelDisable = DAC_OPA0MUX_NEGSEL_DISABLE, /**< Input disabled. */
|
||||
opaNegSelUnityGain = DAC_OPA0MUX_NEGSEL_UG, /**< Unity gain feedback path. */
|
||||
opaNegSelResTap = DAC_OPA0MUX_NEGSEL_OPATAP, /**< Feedback resistor ladder tap. */
|
||||
opaNegSelNegPad = DAC_OPA0MUX_NEGSEL_NEGPAD /**< Negative pad as input. */
|
||||
} OPAMP_NegSel_TypeDef;
|
||||
|
||||
/** OPAMP positive terminal input selection values. */
|
||||
typedef enum
|
||||
{
|
||||
opaPosSelDisable = DAC_OPA0MUX_POSSEL_DISABLE, /**< Input disabled. */
|
||||
opaPosSelDac = DAC_OPA0MUX_POSSEL_DAC, /**< DAC as input (not OPA2). */
|
||||
opaPosSelPosPad = DAC_OPA0MUX_POSSEL_POSPAD, /**< Positive pad as input. */
|
||||
opaPosSelOpaIn = DAC_OPA0MUX_POSSEL_OPA0INP, /**< Input from OPAx. */
|
||||
opaPosSelResTapOpa0 = DAC_OPA0MUX_POSSEL_OPATAP /**< Feedback resistor ladder tap from OPA0. */
|
||||
} OPAMP_PosSel_TypeDef;
|
||||
|
||||
/** OPAMP output terminal selection values. */
|
||||
typedef enum
|
||||
{
|
||||
opaOutModeDisable = DAC_OPA0MUX_OUTMODE_DISABLE, /**< OPA output disabled. */
|
||||
opaOutModeMain = DAC_OPA0MUX_OUTMODE_MAIN, /**< Main output to pin enabled. */
|
||||
opaOutModeAlt = DAC_OPA0MUX_OUTMODE_ALT, /**< Alternate output(s) enabled (not OPA2). */
|
||||
opaOutModeAll = DAC_OPA0MUX_OUTMODE_ALL /**< Both main and alternate enabled (not OPA2). */
|
||||
} OPAMP_OutMode_TypeDef;
|
||||
|
||||
/** OPAMP gain values. */
|
||||
typedef enum
|
||||
{
|
||||
opaResSelDefault = DAC_OPA0MUX_RESSEL_DEFAULT, /**< Default value when resistor ladder is unused. */
|
||||
opaResSelR2eq0_33R1 = DAC_OPA0MUX_RESSEL_RES0, /**< R2 = 0.33 * R1 */
|
||||
opaResSelR2eqR1 = DAC_OPA0MUX_RESSEL_RES1, /**< R2 = R1 */
|
||||
opaResSelR1eq1_67R1 = DAC_OPA0MUX_RESSEL_RES2, /**< R2 = 1.67 R1 */
|
||||
opaResSelR2eq2R1 = DAC_OPA0MUX_RESSEL_RES3, /**< R2 = 2 * R1 */
|
||||
opaResSelR2eq3R1 = DAC_OPA0MUX_RESSEL_RES4, /**< R2 = 3 * R1 */
|
||||
opaResSelR2eq4_33R1 = DAC_OPA0MUX_RESSEL_RES5, /**< R2 = 4.33 * R1 */
|
||||
opaResSelR2eq7R1 = DAC_OPA0MUX_RESSEL_RES6, /**< R2 = 7 * R1 */
|
||||
opaResSelR2eq15R1 = DAC_OPA0MUX_RESSEL_RES7 /**< R2 = 15 * R1 */
|
||||
} OPAMP_ResSel_TypeDef;
|
||||
|
||||
/** OPAMP resistor ladder input selector values. */
|
||||
typedef enum
|
||||
{
|
||||
opaResInMuxDisable = DAC_OPA0MUX_RESINMUX_DISABLE, /**< Resistor ladder disabled. */
|
||||
opaResInMuxOpaIn = DAC_OPA0MUX_RESINMUX_OPA0INP, /**< Input from OPAx. */
|
||||
opaResInMuxNegPad = DAC_OPA0MUX_RESINMUX_NEGPAD, /**< Input from negative pad. */
|
||||
opaResInMuxPosPad = DAC_OPA0MUX_RESINMUX_POSPAD, /**< Input from positive pad. */
|
||||
opaResInMuxVss = DAC_OPA0MUX_RESINMUX_VSS /**< Input connected to Vss. */
|
||||
} OPAMP_ResInMux_TypeDef;
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** OPAMP init structure. */
|
||||
typedef struct
|
||||
{
|
||||
OPAMP_NegSel_TypeDef negSel; /**< Select input source for negative terminal. */
|
||||
OPAMP_PosSel_TypeDef posSel; /**< Select input source for positive terminal. */
|
||||
OPAMP_OutMode_TypeDef outMode; /**< Output terminal connection. */
|
||||
OPAMP_ResSel_TypeDef resSel; /**< Select R2/R1 resistor ratio. */
|
||||
OPAMP_ResInMux_TypeDef resInMux; /**< Select input source for resistor ladder. */
|
||||
uint32_t outPen; /**< Select alternate output terminal connections. */
|
||||
uint32_t bias; /**< Set OPAMP bias current. */
|
||||
bool halfBias; /**< Divide OPAMP bias current by 2. */
|
||||
bool lpfPosPadDisable; /**< Disable low pass filter on positive pad. */
|
||||
bool lpfNegPadDisable; /**< Disable low pass filter on negative pad. */
|
||||
bool nextOut; /**< Enable NEXTOUT signal source. */
|
||||
bool npEn; /**< Enable positive pad. */
|
||||
bool ppEn; /**< Enable negative pad. */
|
||||
bool shortInputs; /**< Short OPAMP input terminals. */
|
||||
bool hcmDisable; /**< Disable input rail-to-rail capability. */
|
||||
bool defaultOffset; /**< Use factory calibrated opamp offset value. */
|
||||
uint32_t offset; /**< Opamp offset value when @ref defaultOffset is false.*/
|
||||
} OPAMP_Init_TypeDef;
|
||||
|
||||
/** Configuration of OPA0/1 in unity gain voltage follower mode. */
|
||||
#define OPA_INIT_UNITY_GAIN \
|
||||
{ \
|
||||
opaNegSelUnityGain, /* Unity gain. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelDefault, /* Resistor ladder is not used. */ \
|
||||
opaResInMuxDisable, /* Resistor ladder disabled. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
false, /* Neg pad disabled. */ \
|
||||
true, /* Pos pad enabled, used as signal input. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA2 in unity gain voltage follower mode. */
|
||||
#define OPA_INIT_UNITY_GAIN_OPA2 \
|
||||
{ \
|
||||
opaNegSelUnityGain, /* Unity gain. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelDefault, /* Resistor ladder is not used. */ \
|
||||
opaResInMuxDisable, /* Resistor ladder disabled. */ \
|
||||
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
false, /* Neg pad disabled. */ \
|
||||
true, /* Pos pad enabled, used as signal input. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA0/1 in non-inverting amplifier mode. */
|
||||
#define OPA_INIT_NON_INVERTING \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
true, /* Neg pad enabled, used as signal ground. */ \
|
||||
true, /* Pos pad enabled, used as signal input. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA2 in non-inverting amplifier mode. */
|
||||
#define OPA_INIT_NON_INVERTING_OPA2 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
true, /* Neg pad enabled, used as signal ground. */ \
|
||||
true, /* Pos pad enabled, used as signal input. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA0/1 in inverting amplifier mode. */
|
||||
#define OPA_INIT_INVERTING \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelR2eqR1, /* R2 = R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
true, /* Neg pad enabled, used as signal input. */ \
|
||||
true, /* Pos pad enabled, used as signal ground. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA2 in inverting amplifier mode. */
|
||||
#define OPA_INIT_INVERTING_OPA2 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelR2eqR1, /* R2 = R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
true, /* Neg pad enabled, used as signal input. */ \
|
||||
true, /* Pos pad enabled, used as signal ground. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA0 in cascaded non-inverting amplifier mode. */
|
||||
#define OPA_INIT_CASCADED_NON_INVERTING_OPA0 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeAll, /* Both main and alternate outputs. */ \
|
||||
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
true, /* Pass output to next stage (OPA1). */ \
|
||||
true, /* Neg pad enabled, used as signal ground. */ \
|
||||
true, /* Pos pad enabled, used as signal input. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA1 in cascaded non-inverting amplifier mode. */
|
||||
#define OPA_INIT_CASCADED_NON_INVERTING_OPA1 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelOpaIn, /* Pos input from OPA0 output. */ \
|
||||
opaOutModeAll, /* Both main and alternate outputs. */ \
|
||||
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
true, /* Pass output to next stage (OPA2). */ \
|
||||
true, /* Neg pad enabled, used as signal ground. */ \
|
||||
false, /* Pos pad disabled. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA2 in cascaded non-inverting amplifier mode. */
|
||||
#define OPA_INIT_CASCADED_NON_INVERTING_OPA2 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelOpaIn, /* Pos input from OPA1 output. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
true, /* Neg pad enabled, used as signal ground. */ \
|
||||
false, /* Pos pad disabled. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA0 in cascaded inverting amplifier mode. */
|
||||
#define OPA_INIT_CASCADED_INVERTING_OPA0 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeAll, /* Both main and alternate outputs. */ \
|
||||
opaResSelR2eqR1, /* R2 = R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
true, /* Pass output to next stage (OPA1). */ \
|
||||
true, /* Neg pad enabled, used as signal input. */ \
|
||||
true, /* Pos pad enabled, used as signal ground. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA1 in cascaded inverting amplifier mode. */
|
||||
#define OPA_INIT_CASCADED_INVERTING_OPA1 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeAll, /* Both main and alternate outputs. */ \
|
||||
opaResSelR2eqR1, /* R2 = R1 */ \
|
||||
opaResInMuxOpaIn, /* Resistor ladder input from OPA0. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
true, /* Pass output to next stage (OPA2). */ \
|
||||
false, /* Neg pad disabled. */ \
|
||||
true, /* Pos pad enabled, used as signal ground. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA2 in cascaded inverting amplifier mode. */
|
||||
#define OPA_INIT_CASCADED_INVERTING_OPA2 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelR2eqR1, /* R2 = R1 */ \
|
||||
opaResInMuxOpaIn, /* Resistor ladder input from OPA1. */ \
|
||||
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
false, /* Neg pad disabled. */ \
|
||||
true, /* Pos pad enabled, used as signal ground. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA0 in two-opamp differential driver mode. */
|
||||
#define OPA_INIT_DIFF_DRIVER_OPA0 \
|
||||
{ \
|
||||
opaNegSelUnityGain, /* Unity gain. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeAll, /* Both main and alternate outputs. */ \
|
||||
opaResSelDefault, /* Resistor ladder is not used. */ \
|
||||
opaResInMuxDisable, /* Resistor ladder disabled. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
true, /* Pass output to next stage (OPA1). */ \
|
||||
false, /* Neg pad disabled. */ \
|
||||
true, /* Pos pad enabled, used as signal input. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA1 in two-opamp differential driver mode. */
|
||||
#define OPA_INIT_DIFF_DRIVER_OPA1 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelR2eqR1, /* R2 = R1 */ \
|
||||
opaResInMuxOpaIn, /* Resistor ladder input from OPA0. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
false, /* Neg pad disabled. */ \
|
||||
true, /* Pos pad enabled, used as signal ground. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA0 in three-opamp differential receiver mode. */
|
||||
#define OPA_INIT_DIFF_RECEIVER_OPA0 \
|
||||
{ \
|
||||
opaNegSelUnityGain, /* Unity gain. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeAll, /* Both main and alternate outputs. */ \
|
||||
opaResSelR2eqR1, /* R2 = R1 */ \
|
||||
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
true, /* Pass output to next stage (OPA2). */ \
|
||||
true, /* Neg pad enabled, used as signal ground. */ \
|
||||
true, /* Pos pad enabled, used as signal input. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA1 in three-opamp differential receiver mode. */
|
||||
#define OPA_INIT_DIFF_RECEIVER_OPA1 \
|
||||
{ \
|
||||
opaNegSelUnityGain, /* Unity gain. */ \
|
||||
opaPosSelPosPad, /* Pos input from pad. */ \
|
||||
opaOutModeAll, /* Both main and alternate outputs. */ \
|
||||
opaResSelDefault, /* Resistor ladder is not used. */ \
|
||||
opaResInMuxDisable, /* Disable resistor ladder. */ \
|
||||
0, /* No alternate outputs enabled. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
true, /* Pass output to next stage (OPA2). */ \
|
||||
false, /* Neg pad disabled. */ \
|
||||
true, /* Pos pad enabled, used as signal input. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/** Configuration of OPA2 in three-opamp differential receiver mode. */
|
||||
#define OPA_INIT_DIFF_RECEIVER_OPA2 \
|
||||
{ \
|
||||
opaNegSelResTap, /* Input from resistor ladder tap. */ \
|
||||
opaPosSelResTapOpa0, /* Input from OPA0 resistor ladder tap. */ \
|
||||
opaOutModeMain, /* Main output enabled. */ \
|
||||
opaResSelR2eqR1, /* R2 = R1 */ \
|
||||
opaResInMuxOpaIn, /* Resistor ladder input from OPA1. */ \
|
||||
DAC_OPA0MUX_OUTPEN_OUT0, /* Enable alternate output 0. */ \
|
||||
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
|
||||
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
|
||||
false, /* No low pass filter on pos pad. */ \
|
||||
false, /* No low pass filter on neg pad. */ \
|
||||
false, /* No nextout output enabled. */ \
|
||||
false, /* Neg pad disabled. */ \
|
||||
false, /* Pos pad disabled. */ \
|
||||
false, /* No shorting of inputs. */ \
|
||||
false, /* Rail-to-rail input enabled. */ \
|
||||
true, /* Use factory calibrated opamp offset. */ \
|
||||
0 /* Opamp offset value (not used). */ \
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void OPAMP_Disable(DAC_TypeDef *dac, OPAMP_TypeDef opa);
|
||||
void OPAMP_Enable(DAC_TypeDef *dac, OPAMP_TypeDef opa, const OPAMP_Init_TypeDef *init);
|
||||
|
||||
/** @} (end addtogroup OPAMP) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined( OPAMP_PRESENT ) && ( OPAMP_COUNT == 1 ) */
|
||||
#endif /* __EFM32_DAC_H */
|
|
@ -0,0 +1,454 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Pulse Counter (PCNT) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_PCNT_H
|
||||
#define __EFM32_PCNT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup PCNT
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Mode selection. */
|
||||
typedef enum
|
||||
{
|
||||
/** Disable pulse counter. */
|
||||
pcntModeDisable = _PCNT_CTRL_MODE_DISABLE,
|
||||
|
||||
/** Single input LFACLK oversampling mode (available in EM0-EM2). */
|
||||
pcntModeOvsSingle = _PCNT_CTRL_MODE_OVSSINGLE,
|
||||
|
||||
/** Externally clocked single input counter mode (available in EM0-EM3). */
|
||||
pcntModeExtSingle = _PCNT_CTRL_MODE_EXTCLKSINGLE,
|
||||
|
||||
/** Externally clocked quadrature decoder mode (available in EM0-EM3). */
|
||||
pcntModeExtQuad = _PCNT_CTRL_MODE_EXTCLKQUAD
|
||||
} PCNT_Mode_TypeDef;
|
||||
|
||||
|
||||
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
|
||||
/** Counter event selection.
|
||||
* Note: unshifted values are being used for enumeration because multiple
|
||||
* configuration structure members use this type definition. */
|
||||
typedef enum
|
||||
{
|
||||
/** Counts up on up-count and down on down-count events. */
|
||||
pcntCntEventBoth = _PCNT_CTRL_CNTEV_BOTH,
|
||||
|
||||
/** Only counts up on up-count events. */
|
||||
pcntCntEventUp = _PCNT_CTRL_CNTEV_UP,
|
||||
|
||||
/** Only counts down on down-count events. */
|
||||
pcntCntEventDown = _PCNT_CTRL_CNTEV_DOWN,
|
||||
|
||||
/** Never counts. */
|
||||
pcntCntEventNone = _PCNT_CTRL_CNTEV_NONE
|
||||
} PCNT_CntEvent_TypeDef;
|
||||
|
||||
|
||||
/** PRS sources for @p s0PRS and @p s1PRS. */
|
||||
typedef enum
|
||||
{
|
||||
pcntPRSCh0 = 0, /**< PRS channel 0. */
|
||||
pcntPRSCh1 = 1, /**< PRS channel 1. */
|
||||
pcntPRSCh2 = 2, /**< PRS channel 2. */
|
||||
pcntPRSCh3 = 3, /**< PRS channel 3. */
|
||||
pcntPRSCh4 = 4, /**< PRS channel 4. */
|
||||
pcntPRSCh5 = 5, /**< PRS channel 5. */
|
||||
pcntPRSCh6 = 6, /**< PRS channel 6. */
|
||||
pcntPRSCh7 = 7 /**< PRS channel 7. */
|
||||
} PCNT_PRSSel_TypeDef;
|
||||
|
||||
|
||||
/** PRS inputs of PCNT. */
|
||||
typedef enum
|
||||
{
|
||||
pcntPRSInputS0 = 0, /** PRS input 0. */
|
||||
pcntPRSInputS1 = 1 /** PRS input 1. */
|
||||
} PCNT_PRSInput_TypeDef;
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Init structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Mode to operate in. */
|
||||
PCNT_Mode_TypeDef mode;
|
||||
|
||||
/** Initial counter value (refer to reference manual for max value allowed).
|
||||
* Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes.
|
||||
* If using #pcntModeExtSingle or #pcntModeExtQuad modes, the counter
|
||||
* value is reset to HW reset value. */
|
||||
uint32_t counter;
|
||||
|
||||
/** Initial top value (refer to reference manual for max value allowed).
|
||||
* Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes.
|
||||
* If using #pcntModeExtSingle or #pcntModeExtQuad modes, the top
|
||||
* value is reset to HW reset value. */
|
||||
uint32_t top;
|
||||
|
||||
/** Polarity of incoming edge.
|
||||
* @li #pcntModeExtSingle mode - if false, positive edges are counted,
|
||||
* otherwise negative edges.
|
||||
* @li #pcntModeExtQuad mode - if true, counting direction is inverted. */
|
||||
bool negEdge;
|
||||
|
||||
/** Counting direction, only applicable for #pcntModeOvsSingle and
|
||||
* #pcntModeExtSingle modes. */
|
||||
bool countDown;
|
||||
|
||||
/** Enable filter, only available in #pcntModeOvsSingle mode. */
|
||||
bool filter;
|
||||
|
||||
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
|
||||
/** Set to true to enable hysteresis. When its enabled, the PCNT will always
|
||||
* overflow and underflow to TOP/2. */
|
||||
bool hyst;
|
||||
|
||||
/** Set to true to enable S1 to determine the direction of counting in
|
||||
* OVSSINGLE or EXTCLKSINGLE modes.
|
||||
* When S1 is high, the count direction is given by CNTDIR, and when S1 is
|
||||
* low, the count direction is the opposite. */
|
||||
bool s1CntDir;
|
||||
|
||||
/** Selects whether the regular counter responds to up-count events,
|
||||
* down-count events, both or none. */
|
||||
PCNT_CntEvent_TypeDef cntEvent;
|
||||
|
||||
/** Selects whether the auxiliary counter responds to up-count events,
|
||||
* down-count events, both or none. */
|
||||
PCNT_CntEvent_TypeDef auxCntEvent;
|
||||
|
||||
/** Select PRS channel as input to S0IN in PCNTx_INPUT register. */
|
||||
PCNT_PRSSel_TypeDef s0PRS;
|
||||
|
||||
/** Select PRS channel as input to S1IN in PCNTx_INPUT register. */
|
||||
PCNT_PRSSel_TypeDef s1PRS;
|
||||
#endif
|
||||
} PCNT_Init_TypeDef;
|
||||
|
||||
/** Default config for PCNT init structure. */
|
||||
#if defined (_EFM32_GECKO_FAMILY)
|
||||
#define PCNT_INIT_DEFAULT \
|
||||
{ pcntModeDisable, /* Disabled by default. */ \
|
||||
_PCNT_CNT_RESETVALUE, /* Default counter HW reset value. */ \
|
||||
_PCNT_TOP_RESETVALUE, /* Default counter HW reset value. */ \
|
||||
false, /* Use positive edge. */ \
|
||||
false, /* Up-counting. */ \
|
||||
false /* Filter disabled. */ \
|
||||
}
|
||||
#elif (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
|
||||
#define PCNT_INIT_DEFAULT \
|
||||
{ pcntModeDisable, /* Disabled by default. */ \
|
||||
_PCNT_CNT_RESETVALUE, /* Default counter HW reset value. */ \
|
||||
_PCNT_TOP_RESETVALUE, /* Default counter HW reset value. */ \
|
||||
false, /* Use positive edge. */ \
|
||||
false, /* Up-counting. */ \
|
||||
false, /* Filter disabled. */ \
|
||||
false, /* Hysteresis disabled. */ \
|
||||
true, /* Counter direction is given by CNTDIR. */ \
|
||||
pcntCntEventUp, /* Regular counter counts up on upcount events. */ \
|
||||
pcntCntEventNone, /* Auxiliary counter doesn't respond to events. */ \
|
||||
pcntPRSCh0, /* PRS channel 0 selected as S0IN. */ \
|
||||
pcntPRSCh0 /* PRS channel 0 selected as S1IN. */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pulse counter value.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current pulse counter value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t PCNT_CounterGet(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
return pcnt->CNT;
|
||||
}
|
||||
|
||||
|
||||
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get auxiliary counter value.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current auxiliary counter value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t PCNT_AuxCounterGet(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
return pcnt->AUXCNT;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void PCNT_CounterReset(PCNT_TypeDef *pcnt);
|
||||
void PCNT_CounterTopSet(PCNT_TypeDef *pcnt, uint32_t count, uint32_t top);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set counter value.
|
||||
*
|
||||
* @details
|
||||
* The pulse counter is disabled while changing counter value, and reenabled
|
||||
* (if originally enabled) when counter value has been set.
|
||||
*
|
||||
* @note
|
||||
* This function will stall until synchronization to low frequency domain is
|
||||
* completed. For that reason, it should normally not be used when using
|
||||
* an external clock to clock the PCNT module, since stall time may be
|
||||
* undefined in that case. The counter should normally only be set when
|
||||
* operating in (or about to enable) #pcntModeOvsSingle mode.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] count
|
||||
* Value to set in counter register.
|
||||
******************************************************************************/
|
||||
static __INLINE void PCNT_CounterSet(PCNT_TypeDef *pcnt, uint32_t count)
|
||||
{
|
||||
PCNT_CounterTopSet(pcnt, count, pcnt->TOP);
|
||||
}
|
||||
|
||||
|
||||
void PCNT_Enable(PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode);
|
||||
void PCNT_FreezeEnable(PCNT_TypeDef *pcnt, bool enable);
|
||||
void PCNT_Init(PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init);
|
||||
|
||||
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
|
||||
void PCNT_PRSInputEnable(PCNT_TypeDef *pcnt,
|
||||
PCNT_PRSInput_TypeDef prsInput,
|
||||
bool enable);
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending PCNT interrupts.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending PCNT interrupt source to clear. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the PCNT module (PCNT_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void PCNT_IntClear(PCNT_TypeDef *pcnt, uint32_t flags)
|
||||
{
|
||||
pcnt->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more PCNT interrupts.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* PCNT interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the PCNT module (PCNT_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void PCNT_IntDisable(PCNT_TypeDef *pcnt, uint32_t flags)
|
||||
{
|
||||
pcnt->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more PCNT interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using PCNT_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* PCNT interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the PCNT module (PCNT_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void PCNT_IntEnable(PCNT_TypeDef *pcnt, uint32_t flags)
|
||||
{
|
||||
pcnt->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending PCNT interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* PCNT interrupt sources pending. A bitwise logic OR combination of valid
|
||||
* interrupt flags for the PCNT module (PCNT_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t PCNT_IntGet(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
return pcnt->IF;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get enabled and pending PCNT interrupt flags.
|
||||
*
|
||||
* @details
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Pending and enabled PCNT interrupt sources.
|
||||
* The return value is the bitwise AND combination of
|
||||
* - the OR combination of enabled interrupt sources in PCNT_IEN_nnn
|
||||
* register (PCNT_IEN_nnn) and
|
||||
* - the OR combination of valid interrupt flags of the PCNT module
|
||||
* (PCNT_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t PCNT_IntGetEnabled(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
|
||||
/* Store pcnt->IEN in temporary variable in order to define explicit order
|
||||
* of volatile accesses. */
|
||||
tmp = pcnt->IEN;
|
||||
|
||||
/* Bitwise AND of pending and enabled interrupts */
|
||||
return pcnt->IF & tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending PCNT interrupts from SW.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* PCNT interrupt sources to set to pending. Use a bitwise logic OR combination
|
||||
* of valid interrupt flags for the PCNT module (PCNT_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void PCNT_IntSet(PCNT_TypeDef *pcnt, uint32_t flags)
|
||||
{
|
||||
pcnt->IFS = flags;
|
||||
}
|
||||
|
||||
void PCNT_Reset(PCNT_TypeDef *pcnt);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pulse counter top buffer value.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current pulse counter top buffer value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t PCNT_TopBufferGet(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
return pcnt->TOPB;
|
||||
}
|
||||
|
||||
void PCNT_TopBufferSet(PCNT_TypeDef *pcnt, uint32_t val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pulse counter top value.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current pulse counter top value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t PCNT_TopGet(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
return pcnt->TOP;
|
||||
}
|
||||
|
||||
void PCNT_TopSet(PCNT_TypeDef *pcnt, uint32_t val);
|
||||
|
||||
|
||||
/** @} (end addtogroup PCNT) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_PCNT_H */
|
|
@ -0,0 +1,123 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Peripheral Reflex System (PRS) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_PRS_H
|
||||
#define __EFM32_PRS_H
|
||||
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup PRS
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Edge detection type. */
|
||||
typedef enum
|
||||
{
|
||||
prsEdgeOff = PRS_CH_CTRL_EDSEL_OFF, /**< Leave signal as is. */
|
||||
prsEdgePos = PRS_CH_CTRL_EDSEL_POSEDGE, /**< Generate pules on positive edge. */
|
||||
prsEdgeNeg = PRS_CH_CTRL_EDSEL_NEGEDGE, /**< Generate pules on negative edge. */
|
||||
prsEdgeBoth = PRS_CH_CTRL_EDSEL_BOTHEDGES /**< Generate pules on both edges. */
|
||||
} PRS_Edge_TypeDef;
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set level control bit for one or more channels.
|
||||
*
|
||||
* @details
|
||||
* The level value for a channel is XORed with both the pulse possible issued
|
||||
* by PRS_PulseTrigger() and the PRS input signal selected for the channel(s).
|
||||
*
|
||||
* @param[in] level
|
||||
* Level to use for channels indicated by @p mask. Use logical OR combination
|
||||
* of PRS_SWLEVEL_CHnLEVEL defines for channels to set high level, otherwise 0.
|
||||
*
|
||||
* @param[in] mask
|
||||
* Mask indicating which channels to set level for. Use logical OR combination
|
||||
* of PRS_SWLEVEL_CHnLEVEL defines.
|
||||
******************************************************************************/
|
||||
static __INLINE void PRS_LevelSet(uint32_t level, uint32_t mask)
|
||||
{
|
||||
PRS->SWLEVEL = (PRS->SWLEVEL & ~mask) | (level & mask);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Trigger a high pulse (one HFPERCLK) for one or more channels.
|
||||
*
|
||||
* @details
|
||||
* Setting a bit for a channel causes the bit in the register to remain high
|
||||
* for one HFPERCLK cycle. The pulse is XORed with both the corresponding bit
|
||||
* in PRS SWLEVEL register and the PRS input signal selected for the
|
||||
* channel(s).
|
||||
*
|
||||
* @param[in] channels
|
||||
* Logical ORed combination of channels to trigger a pulse for. Use
|
||||
* PRS_SWPULSE_CHnPULSE defines.
|
||||
******************************************************************************/
|
||||
static __INLINE void PRS_PulseTrigger(uint32_t channels)
|
||||
{
|
||||
PRS->SWPULSE = channels & _PRS_SWPULSE_MASK;
|
||||
}
|
||||
|
||||
void PRS_SourceSignalSet(unsigned int ch,
|
||||
uint32_t source,
|
||||
uint32_t signal,
|
||||
PRS_Edge_TypeDef edge);
|
||||
|
||||
#if ((defined _EFM32_TINY_FAMILY) || (defined _EFM32_GIANT_FAMILY))
|
||||
void PRS_SourceAsyncSignalSet(unsigned int ch,
|
||||
uint32_t source,
|
||||
uint32_t signal);
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup PRS) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_PRS_H */
|
|
@ -0,0 +1,63 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Reset Management Unit (RMU) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_RMU_H
|
||||
#define __EFM32_RMU_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup RMU
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void RMU_LockupResetDisable(bool disable);
|
||||
void RMU_ResetCauseClear(void);
|
||||
uint32_t RMU_ResetCauseGet(void);
|
||||
|
||||
/** @} (end addtogroup RMU) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_RMU_H */
|
|
@ -0,0 +1,182 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Real Time Counter (RTC) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_RTC_H
|
||||
#define __EFM32_RTC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup RTC
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** RTC initialization structure. */
|
||||
typedef struct
|
||||
{
|
||||
bool enable; /**< Start counting when init completed. */
|
||||
bool debugRun; /**< Counter shall keep running during debug halt. */
|
||||
bool comp0Top; /**< Use compare register 0 as max count value. */
|
||||
} RTC_Init_TypeDef;
|
||||
|
||||
/** Suggested default config for RTC init structure. */
|
||||
#define RTC_INIT_DEFAULT \
|
||||
{ true, /* Start counting when init done */ \
|
||||
false, /* Disable updating during debug halt */ \
|
||||
true /* Restart counting from 0 when reaching COMP0 */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
uint32_t RTC_CompareGet(unsigned int comp);
|
||||
void RTC_CompareSet(unsigned int comp, uint32_t value);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get RTC counter value.
|
||||
*
|
||||
* @return
|
||||
* Current RTC counter value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t RTC_CounterGet(void)
|
||||
{
|
||||
return(RTC->CNT);
|
||||
}
|
||||
|
||||
void RTC_CounterReset(void);
|
||||
void RTC_Enable(bool enable);
|
||||
void RTC_FreezeEnable(bool enable);
|
||||
void RTC_Init(const RTC_Init_TypeDef *init);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending RTC interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* RTC interrupt sources to clear. Use a set of interrupt flags OR-ed
|
||||
* together to clear multiple interrupt sources for the RTC module
|
||||
* (RTC_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void RTC_IntClear(uint32_t flags)
|
||||
{
|
||||
RTC->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more RTC interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* RTC interrupt sources to disable. Use a set of interrupt flags OR-ed
|
||||
* together to disable multiple interrupt sources for the RTC module
|
||||
* (RTC_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void RTC_IntDisable(uint32_t flags)
|
||||
{
|
||||
RTC->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more RTC interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using RTC_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] flags
|
||||
* RTC interrupt sources to enable. Use a set of interrupt flags OR-ed
|
||||
* together to set multiple interrupt sources for the RTC module
|
||||
* (RTC_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void RTC_IntEnable(uint32_t flags)
|
||||
{
|
||||
RTC->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending RTC interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* Pending RTC interrupt sources. Returns a set of interrupt flags OR-ed
|
||||
* together for multiple interrupt sources in the RTC module (RTC_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t RTC_IntGet(void)
|
||||
{
|
||||
return(RTC->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending RTC interrupts from SW.
|
||||
*
|
||||
* @param[in] flags
|
||||
* RTC interrupt sources to set to pending. Use a set of interrupt flags
|
||||
* OR-ed together to set multiple interrupt sources for the RTC module
|
||||
* (RTC_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void RTC_IntSet(uint32_t flags)
|
||||
{
|
||||
RTC->IFS = flags;
|
||||
}
|
||||
|
||||
void RTC_Reset(void);
|
||||
|
||||
/** @} (end addtogroup RTC) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_RTC_H */
|
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief System API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_SYSTEM_H
|
||||
#define __EFM32_SYSTEM_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup SYSTEM
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Chip revision details */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t major; /**< Major revision number */
|
||||
uint8_t minor; /**< Minor revision number */
|
||||
} SYSTEM_ChipRevision_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev);
|
||||
uint32_t SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress);
|
||||
|
||||
/** @} (end addtogroup SYSTEM) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_SYSTEM_H */
|
|
@ -0,0 +1,642 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Timer/counter (TIMER) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_TIMER_H
|
||||
#define __EFM32_TIMER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup TIMER
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Timer compare/capture mode. */
|
||||
typedef enum
|
||||
{
|
||||
timerCCModeOff = _TIMER_CC_CTRL_MODE_OFF, /**< Channel turned off. */
|
||||
timerCCModeCapture = _TIMER_CC_CTRL_MODE_INPUTCAPTURE, /**< Input capture. */
|
||||
timerCCModeCompare = _TIMER_CC_CTRL_MODE_OUTPUTCOMPARE, /**< Output compare. */
|
||||
timerCCModePWM = _TIMER_CC_CTRL_MODE_PWM /**< Pulse-Width modulation. */
|
||||
} TIMER_CCMode_TypeDef;
|
||||
|
||||
|
||||
/** Clock select. */
|
||||
typedef enum
|
||||
{
|
||||
/** Prescaled HFPER clock. */
|
||||
timerClkSelHFPerClk = _TIMER_CTRL_CLKSEL_PRESCHFPERCLK,
|
||||
|
||||
/** Prescaled HFPER clock. */
|
||||
timerClkSelCC1 = _TIMER_CTRL_CLKSEL_CC1,
|
||||
|
||||
/**
|
||||
* Cascaded, clocked by underflow (down-counting) or overflow (up-counting)
|
||||
* by lower numbered timer.
|
||||
*/
|
||||
timerClkSelCascade = _TIMER_CTRL_CLKSEL_TIMEROUF
|
||||
} TIMER_ClkSel_TypeDef;
|
||||
|
||||
|
||||
/** Input capture edge select. */
|
||||
typedef enum
|
||||
{
|
||||
/** Rising edges detected. */
|
||||
timerEdgeRising = _TIMER_CC_CTRL_ICEDGE_RISING,
|
||||
|
||||
/** Falling edges detected. */
|
||||
timerEdgeFalling = _TIMER_CC_CTRL_ICEDGE_FALLING,
|
||||
|
||||
/** Both edges detected. */
|
||||
timerEdgeBoth = _TIMER_CC_CTRL_ICEDGE_BOTH,
|
||||
|
||||
/** No edge detection, leave signal as is. */
|
||||
timerEdgeNone = _TIMER_CC_CTRL_ICEDGE_NONE
|
||||
} TIMER_Edge_TypeDef;
|
||||
|
||||
|
||||
/** Input capture event control. */
|
||||
typedef enum
|
||||
{
|
||||
/** PRS output pulse, interrupt flag and DMA request set on every capture. */
|
||||
timerEventEveryEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE,
|
||||
/** PRS output pulse, interrupt flag and DMA request set on every second capture. */
|
||||
timerEventEvery2ndEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE,
|
||||
/**
|
||||
* PRS output pulse, interrupt flag and DMA request set on rising edge (if
|
||||
* input capture edge = BOTH).
|
||||
*/
|
||||
timerEventRising = _TIMER_CC_CTRL_ICEVCTRL_RISING,
|
||||
/**
|
||||
* PRS output pulse, interrupt flag and DMA request set on falling edge (if
|
||||
* input capture edge = BOTH).
|
||||
*/
|
||||
timerEventFalling = _TIMER_CC_CTRL_ICEVCTRL_FALLING
|
||||
} TIMER_Event_TypeDef;
|
||||
|
||||
|
||||
/** Input edge action. */
|
||||
typedef enum
|
||||
{
|
||||
/** No action taken. */
|
||||
timerInputActionNone = _TIMER_CTRL_FALLA_NONE,
|
||||
|
||||
/** Start counter without reload. */
|
||||
timerInputActionStart = _TIMER_CTRL_FALLA_START,
|
||||
|
||||
/** Stop counter without reload. */
|
||||
timerInputActionStop = _TIMER_CTRL_FALLA_STOP,
|
||||
|
||||
/** Reload and start counter. */
|
||||
timerInputActionReloadStart = _TIMER_CTRL_FALLA_RELOADSTART
|
||||
} TIMER_InputAction_TypeDef;
|
||||
|
||||
|
||||
/** Timer mode. */
|
||||
typedef enum
|
||||
{
|
||||
timerModeUp = _TIMER_CTRL_MODE_UP, /**< Up-counting. */
|
||||
timerModeDown = _TIMER_CTRL_MODE_DOWN, /**< Down-counting. */
|
||||
timerModeUpDown = _TIMER_CTRL_MODE_UPDOWN, /**< Up/down-counting. */
|
||||
timerModeQDec = _TIMER_CTRL_MODE_QDEC /**< Quadrature decoder. */
|
||||
} TIMER_Mode_TypeDef;
|
||||
|
||||
|
||||
/** Compare/capture output action. */
|
||||
typedef enum
|
||||
{
|
||||
/** No action. */
|
||||
timerOutputActionNone = _TIMER_CC_CTRL_CUFOA_NONE,
|
||||
|
||||
/** Toggle on event. */
|
||||
timerOutputActionToggle = _TIMER_CC_CTRL_CUFOA_TOGGLE,
|
||||
|
||||
/** Clear on event. */
|
||||
timerOutputActionClear = _TIMER_CC_CTRL_CUFOA_CLEAR,
|
||||
|
||||
/** Set on event. */
|
||||
timerOutputActionSet = _TIMER_CC_CTRL_CUFOA_SET
|
||||
} TIMER_OutputAction_TypeDef;
|
||||
|
||||
|
||||
/** Prescaler. */
|
||||
typedef enum
|
||||
{
|
||||
timerPrescale1 = _TIMER_CTRL_PRESC_DIV1, /**< Divide by 1. */
|
||||
timerPrescale2 = _TIMER_CTRL_PRESC_DIV2, /**< Divide by 2. */
|
||||
timerPrescale4 = _TIMER_CTRL_PRESC_DIV4, /**< Divide by 4. */
|
||||
timerPrescale8 = _TIMER_CTRL_PRESC_DIV8, /**< Divide by 8. */
|
||||
timerPrescale16 = _TIMER_CTRL_PRESC_DIV16, /**< Divide by 16. */
|
||||
timerPrescale32 = _TIMER_CTRL_PRESC_DIV32, /**< Divide by 32. */
|
||||
timerPrescale64 = _TIMER_CTRL_PRESC_DIV64, /**< Divide by 64. */
|
||||
timerPrescale128 = _TIMER_CTRL_PRESC_DIV128, /**< Divide by 128. */
|
||||
timerPrescale256 = _TIMER_CTRL_PRESC_DIV256, /**< Divide by 256. */
|
||||
timerPrescale512 = _TIMER_CTRL_PRESC_DIV512, /**< Divide by 512. */
|
||||
timerPrescale1024 = _TIMER_CTRL_PRESC_DIV1024 /**< Divide by 1024. */
|
||||
} TIMER_Prescale_TypeDef;
|
||||
|
||||
|
||||
/** Peripheral Reflex System signal. */
|
||||
typedef enum
|
||||
{
|
||||
timerPRSSELCh0 = _ADC_SINGLECTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
|
||||
timerPRSSELCh1 = _ADC_SINGLECTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
|
||||
timerPRSSELCh2 = _ADC_SINGLECTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
|
||||
timerPRSSELCh3 = _ADC_SINGLECTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
|
||||
timerPRSSELCh4 = _ADC_SINGLECTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
|
||||
timerPRSSELCh5 = _ADC_SINGLECTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
|
||||
timerPRSSELCh6 = _ADC_SINGLECTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
|
||||
timerPRSSELCh7 = _ADC_SINGLECTRL_PRSSEL_PRSCH7 /**< PRS channel 7. */
|
||||
} TIMER_PRSSEL_TypeDef;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** TIMER initialization structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Start counting when init completed. */
|
||||
bool enable;
|
||||
|
||||
/** Counter shall keep running during debug halt. */
|
||||
bool debugRun;
|
||||
|
||||
/** Prescaling factor, if HFPER clock used. */
|
||||
TIMER_Prescale_TypeDef prescale;
|
||||
|
||||
/** Clock selection. */
|
||||
TIMER_ClkSel_TypeDef clkSel;
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
/** 2x Count mode, counter increments/decrements by 2, meant for PWN mode. */
|
||||
bool count2x;
|
||||
|
||||
/** ATI (Always Track Inputs) makes CCPOL always track
|
||||
* the polarity of the inputs. */
|
||||
bool ati;
|
||||
#endif
|
||||
|
||||
/** Action on falling input edge. */
|
||||
TIMER_InputAction_TypeDef fallAction;
|
||||
|
||||
/** Action on rising input edge. */
|
||||
TIMER_InputAction_TypeDef riseAction;
|
||||
|
||||
/** Counting mode. */
|
||||
TIMER_Mode_TypeDef mode;
|
||||
|
||||
/** DMA request clear on active. */
|
||||
bool dmaClrAct;
|
||||
|
||||
/** Select X2 or X4 quadrature decode mode (if used). */
|
||||
bool quadModeX4;
|
||||
|
||||
/** Determines if only counting up or down once. */
|
||||
bool oneShot;
|
||||
|
||||
/** Timer start/stop/reload by other timers. */
|
||||
bool sync;
|
||||
} TIMER_Init_TypeDef;
|
||||
|
||||
/** Default config for TIMER init structure. */
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
#define TIMER_INIT_DEFAULT \
|
||||
{ true, /* Enable timer when init complete. */ \
|
||||
false, /* Stop counter during debug halt. */ \
|
||||
timerPrescale1, /* No prescaling. */ \
|
||||
timerClkSelHFPerClk, /* Select HFPER clock. */ \
|
||||
false, /* Not 2x count mode. */ \
|
||||
false, /* No ATI. */ \
|
||||
timerInputActionNone, /* No action on falling input edge. */ \
|
||||
timerInputActionNone, /* No action on rising input edge. */ \
|
||||
timerModeUp, /* Up-counting. */ \
|
||||
false, /* Do not clear DMA requests when DMA channel is active. */ \
|
||||
false, /* Select X2 quadrature decode mode (if used). */ \
|
||||
false, /* Disable one shot. */ \
|
||||
false /* Not started/stopped/reloaded by other timers. */ \
|
||||
}
|
||||
#else
|
||||
#define TIMER_INIT_DEFAULT \
|
||||
{ true, /* Enable timer when init complete. */ \
|
||||
false, /* Stop counter during debug halt. */ \
|
||||
timerPrescale1, /* No prescaling. */ \
|
||||
timerClkSelHFPerClk, /* Select HFPER clock. */ \
|
||||
timerInputActionNone, /* No action on falling input edge. */ \
|
||||
timerInputActionNone, /* No action on rising input edge. */ \
|
||||
timerModeUp, /* Up-counting. */ \
|
||||
false, /* Do not clear DMA requests when DMA channel is active. */ \
|
||||
false, /* Select X2 quadrature decode mode (if used). */ \
|
||||
false, /* Disable one shot. */ \
|
||||
false /* Not started/stopped/reloaded by other timers. */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/** TIMER compare/capture initialization structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Input capture event control. */
|
||||
TIMER_Event_TypeDef eventCtrl;
|
||||
|
||||
/** Input capture edge select. */
|
||||
TIMER_Edge_TypeDef edge;
|
||||
|
||||
/**
|
||||
* Peripheral reflex system trigger selection. Only applicable if @p prsInput
|
||||
* is enabled.
|
||||
*/
|
||||
TIMER_PRSSEL_TypeDef prsSel;
|
||||
|
||||
/** Counter underflow output action. */
|
||||
TIMER_OutputAction_TypeDef cufoa;
|
||||
|
||||
/** Counter overflow output action. */
|
||||
TIMER_OutputAction_TypeDef cofoa;
|
||||
|
||||
/** Counter match output action. */
|
||||
TIMER_OutputAction_TypeDef cmoa;
|
||||
|
||||
/** Compare/capture channel mode. */
|
||||
TIMER_CCMode_TypeDef mode;
|
||||
|
||||
/** Enable digital filter. */
|
||||
bool filter;
|
||||
|
||||
/** Select TIMERnCCx (false) or PRS input (true). */
|
||||
bool prsInput;
|
||||
|
||||
/**
|
||||
* Compare output initial state. Only used in Output Compare and PWM mode.
|
||||
* When true, the compare/PWM output is set high when the counter is
|
||||
* disabled. When counting resumes, this value will represent the initial
|
||||
* value for the compare/PWM output. If the bit is cleared, the output
|
||||
* will be cleared when the counter is disabled.
|
||||
*/
|
||||
bool coist;
|
||||
|
||||
/** Invert output from compare/capture channel. */
|
||||
bool outInvert;
|
||||
} TIMER_InitCC_TypeDef;
|
||||
|
||||
/** Default config for TIMER compare/capture init structure. */
|
||||
#define TIMER_INITCC_DEFAULT \
|
||||
{ timerEventEveryEdge, /* Event on every capture. */ \
|
||||
timerEdgeRising, /* Input capture edge on rising edge. */ \
|
||||
timerPRSSELCh0, /* Not used by default, select PRS channel 0. */ \
|
||||
timerOutputActionNone, /* No action on underflow. */ \
|
||||
timerOutputActionNone, /* No action on overflow. */ \
|
||||
timerOutputActionNone, /* No action on match. */ \
|
||||
timerCCModeOff, /* Disable compare/capture channel. */ \
|
||||
false, /* Disable filter. */ \
|
||||
false, /* Select TIMERnCCx input. */ \
|
||||
false, /* Clear output when countre disabled. */ \
|
||||
false /* Do not invert output. */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get capture value for compare/capture channel when operating in capture
|
||||
* mode.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Compare/capture channel to access.
|
||||
*
|
||||
* @return
|
||||
* Current capture value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t TIMER_CaptureGet(TIMER_TypeDef *timer, unsigned int ch)
|
||||
{
|
||||
return(timer->CC[ch].CCV);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set compare value buffer for compare/capture channel when operating in
|
||||
* compare or PWM mode.
|
||||
*
|
||||
* @details
|
||||
* The compare value buffer holds the value which will be written to
|
||||
* TIMERn_CCx_CCV on an update event if the buffer has been updated since
|
||||
* the last event.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Compare/capture channel to access.
|
||||
*
|
||||
* @param[in] val
|
||||
* Value to set in compare value buffer register.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_CompareBufSet(TIMER_TypeDef *timer,
|
||||
unsigned int ch,
|
||||
uint32_t val)
|
||||
{
|
||||
timer->CC[ch].CCVB = val;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set compare value for compare/capture channel when operating in compare
|
||||
* or PWM mode.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Compare/capture channel to access.
|
||||
*
|
||||
* @param[in] val
|
||||
* Value to set in compare value register.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_CompareSet(TIMER_TypeDef *timer,
|
||||
unsigned int ch,
|
||||
uint32_t val)
|
||||
{
|
||||
timer->CC[ch].CCV = val;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get TIMER counter value.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current TIMER counter value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t TIMER_CounterGet(TIMER_TypeDef *timer)
|
||||
{
|
||||
return(timer->CNT);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set TIMER counter value.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] val
|
||||
* Value to set counter to.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_CounterSet(TIMER_TypeDef *timer, uint32_t val)
|
||||
{
|
||||
timer->CNT = val;
|
||||
}
|
||||
|
||||
|
||||
void TIMER_Enable(TIMER_TypeDef *rtc, bool enable);
|
||||
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init);
|
||||
void TIMER_InitCC(TIMER_TypeDef *timer,
|
||||
unsigned int ch,
|
||||
const TIMER_InitCC_TypeDef *init);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending TIMER interrupts.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending TIMER interrupt source(s) to clear. Use one or more valid
|
||||
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags)
|
||||
{
|
||||
timer->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more TIMER interrupts.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* TIMER interrupt source(s) to disable. Use one or more valid
|
||||
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_IntDisable(TIMER_TypeDef *timer, uint32_t flags)
|
||||
{
|
||||
timer->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more TIMER interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using TIMER_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* TIMER interrupt source(s) to enable. Use one or more valid
|
||||
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags)
|
||||
{
|
||||
timer->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending TIMER interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* TIMER interrupt source(s) pending. Returns one or more valid
|
||||
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t TIMER_IntGet(TIMER_TypeDef *timer)
|
||||
{
|
||||
return(timer->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get enabled and pending TIMER interrupt flags.
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @note
|
||||
* Interrupt flags are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* Pending and enabled TIMER interrupt sources.
|
||||
* The return value is the bitwise AND combination of
|
||||
* - the OR combination of enabled interrupt sources in TIMERx_IEN_nnn
|
||||
* register (TIMERx_IEN_nnn) and
|
||||
* - the OR combination of valid interrupt flags of the TIMER module
|
||||
* (TIMERx_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t TIMER_IntGetEnabled(TIMER_TypeDef *timer)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Store TIMER->IEN in temporary variable in order to define explicit order
|
||||
* of volatile accesses. */
|
||||
tmp = timer->IEN;
|
||||
|
||||
/* Bitwise AND of pending and enabled interrupts */
|
||||
return timer->IF & tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending TIMER interrupts from SW.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* TIMER interrupt source(s) to set to pending. Use one or more valid
|
||||
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_IntSet(TIMER_TypeDef *timer, uint32_t flags)
|
||||
{
|
||||
timer->IFS = flags;
|
||||
}
|
||||
|
||||
#ifdef TIMER_DTLOCK_LOCKKEY_LOCK
|
||||
void TIMER_Lock(TIMER_TypeDef *timer);
|
||||
#endif
|
||||
|
||||
void TIMER_Reset(TIMER_TypeDef *timer);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set top value buffer for timer.
|
||||
*
|
||||
* @details
|
||||
* When the top value buffer register is updated, the value is loaded into
|
||||
* the top value register at the next wrap around. This feature is useful
|
||||
* in order to update the top value safely when the timer is running.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] val
|
||||
* Value to set in top value buffer register.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_TopBufSet(TIMER_TypeDef *timer, uint32_t val)
|
||||
{
|
||||
timer->TOPB = val;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get top value setting for timer.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current top value.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t TIMER_TopGet(TIMER_TypeDef *timer)
|
||||
{
|
||||
return(timer->TOP);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set top value for timer.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] val
|
||||
* Value to set in top value register.
|
||||
******************************************************************************/
|
||||
static __INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val)
|
||||
{
|
||||
timer->TOP = val;
|
||||
}
|
||||
|
||||
#ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
|
||||
void TIMER_Unlock(TIMER_TypeDef *timer);
|
||||
#endif
|
||||
|
||||
|
||||
/** @} (end addtogroup TIMER) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_TIMER_H */
|
|
@ -0,0 +1,645 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Universal synchronous/asynchronous receiver/transmitter (USART/UART)
|
||||
* peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_USART_H
|
||||
#define __EFM32_USART_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup USART
|
||||
* @brief Universal Synchronous/Asynchronous Receiver/Transmitter (USART) peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Databit selection. */
|
||||
typedef enum
|
||||
{
|
||||
usartDatabits4 = USART_FRAME_DATABITS_FOUR, /**< 4 databits (not available for UART). */
|
||||
usartDatabits5 = USART_FRAME_DATABITS_FIVE, /**< 5 databits (not available for UART). */
|
||||
usartDatabits6 = USART_FRAME_DATABITS_SIX, /**< 6 databits (not available for UART). */
|
||||
usartDatabits7 = USART_FRAME_DATABITS_SEVEN, /**< 7 databits (not available for UART). */
|
||||
usartDatabits8 = USART_FRAME_DATABITS_EIGHT, /**< 8 databits. */
|
||||
usartDatabits9 = USART_FRAME_DATABITS_NINE, /**< 9 databits. */
|
||||
usartDatabits10 = USART_FRAME_DATABITS_TEN, /**< 10 databits (not available for UART). */
|
||||
usartDatabits11 = USART_FRAME_DATABITS_ELEVEN, /**< 11 databits (not available for UART). */
|
||||
usartDatabits12 = USART_FRAME_DATABITS_TWELVE, /**< 12 databits (not available for UART). */
|
||||
usartDatabits13 = USART_FRAME_DATABITS_THIRTEEN, /**< 13 databits (not available for UART). */
|
||||
usartDatabits14 = USART_FRAME_DATABITS_FOURTEEN, /**< 14 databits (not available for UART). */
|
||||
usartDatabits15 = USART_FRAME_DATABITS_FIFTEEN, /**< 15 databits (not available for UART). */
|
||||
usartDatabits16 = USART_FRAME_DATABITS_SIXTEEN /**< 16 databits (not available for UART). */
|
||||
} USART_Databits_TypeDef;
|
||||
|
||||
|
||||
/** Enable selection. */
|
||||
typedef enum
|
||||
{
|
||||
/** Disable both receiver and transmitter. */
|
||||
usartDisable = 0x0,
|
||||
|
||||
/** Enable receiver only, transmitter disabled. */
|
||||
usartEnableRx = USART_CMD_RXEN,
|
||||
|
||||
/** Enable transmitter only, receiver disabled. */
|
||||
usartEnableTx = USART_CMD_TXEN,
|
||||
|
||||
/** Enable both receiver and transmitter. */
|
||||
usartEnable = (USART_CMD_RXEN | USART_CMD_TXEN)
|
||||
} USART_Enable_TypeDef;
|
||||
|
||||
|
||||
/** Oversampling selection, used for asynchronous operation. */
|
||||
typedef enum
|
||||
{
|
||||
usartOVS16 = USART_CTRL_OVS_X16, /**< 16x oversampling (normal). */
|
||||
usartOVS8 = USART_CTRL_OVS_X8, /**< 8x oversampling. */
|
||||
usartOVS6 = USART_CTRL_OVS_X6, /**< 6x oversampling. */
|
||||
usartOVS4 = USART_CTRL_OVS_X4 /**< 4x oversampling. */
|
||||
} USART_OVS_TypeDef;
|
||||
|
||||
|
||||
/** Parity selection, mainly used for asynchronous operation. */
|
||||
typedef enum
|
||||
{
|
||||
usartNoParity = USART_FRAME_PARITY_NONE, /**< No parity. */
|
||||
usartEvenParity = USART_FRAME_PARITY_EVEN, /**< Even parity. */
|
||||
usartOddParity = USART_FRAME_PARITY_ODD /**< Odd parity. */
|
||||
} USART_Parity_TypeDef;
|
||||
|
||||
|
||||
/** Stopbits selection, used for asynchronous operation. */
|
||||
typedef enum
|
||||
{
|
||||
usartStopbits0p5 = USART_FRAME_STOPBITS_HALF, /**< 0.5 stopbits. */
|
||||
usartStopbits1 = USART_FRAME_STOPBITS_ONE, /**< 1 stopbits. */
|
||||
usartStopbits1p5 = USART_FRAME_STOPBITS_ONEANDAHALF, /**< 1.5 stopbits. */
|
||||
usartStopbits2 = USART_FRAME_STOPBITS_TWO /**< 2 stopbits. */
|
||||
} USART_Stopbits_TypeDef;
|
||||
|
||||
|
||||
/** Clock polarity/phase mode. */
|
||||
typedef enum
|
||||
{
|
||||
/** Clock idle low, sample on rising edge. */
|
||||
usartClockMode0 = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLELEADING,
|
||||
|
||||
/** Clock idle low, sample on falling edge. */
|
||||
usartClockMode1 = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLETRAILING,
|
||||
|
||||
/** Clock idle high, sample on falling edge. */
|
||||
usartClockMode2 = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLELEADING,
|
||||
|
||||
/** Clock idle high, sample on rising edge. */
|
||||
usartClockMode3 = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLETRAILING
|
||||
} USART_ClockMode_TypeDef;
|
||||
|
||||
|
||||
/** Pulse width selection for IrDA mode. */
|
||||
typedef enum
|
||||
{
|
||||
/** IrDA pulse width is 1/16 for OVS=0 and 1/8 for OVS=1 */
|
||||
usartIrDAPwONE = USART_IRCTRL_IRPW_ONE,
|
||||
|
||||
/** IrDA pulse width is 2/16 for OVS=0 and 2/8 for OVS=1 */
|
||||
usartIrDAPwTWO = USART_IRCTRL_IRPW_TWO,
|
||||
|
||||
/** IrDA pulse width is 3/16 for OVS=0 and 3/8 for OVS=1 */
|
||||
usartIrDAPwTHREE = USART_IRCTRL_IRPW_THREE,
|
||||
|
||||
/** IrDA pulse width is 4/16 for OVS=0 and 4/8 for OVS=1 */
|
||||
usartIrDAPwFOUR = USART_IRCTRL_IRPW_FOUR
|
||||
} USART_IrDAPw_Typedef;
|
||||
|
||||
|
||||
/** PRS channel selection for IrDA mode. */
|
||||
typedef enum
|
||||
{
|
||||
usartIrDAPrsCh0 = USART_IRCTRL_IRPRSSEL_PRSCH0, /**< PRS channel 0 */
|
||||
usartIrDAPrsCh1 = USART_IRCTRL_IRPRSSEL_PRSCH1, /**< PRS channel 1 */
|
||||
usartIrDAPrsCh2 = USART_IRCTRL_IRPRSSEL_PRSCH2, /**< PRS channel 2 */
|
||||
usartIrDAPrsCh3 = USART_IRCTRL_IRPRSSEL_PRSCH3, /**< PRS channel 3 */
|
||||
usartIrDAPrsCh4 = USART_IRCTRL_IRPRSSEL_PRSCH4, /**< PRS channel 4 */
|
||||
usartIrDAPrsCh5 = USART_IRCTRL_IRPRSSEL_PRSCH5, /**< PRS channel 5 */
|
||||
usartIrDAPrsCh6 = USART_IRCTRL_IRPRSSEL_PRSCH6, /**< PRS channel 6 */
|
||||
usartIrDAPrsCh7 = USART_IRCTRL_IRPRSSEL_PRSCH7 /**< PRS channel 7 */
|
||||
} USART_IrDAPrsSel_Typedef;
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
/** I2S format selection. */
|
||||
typedef enum
|
||||
{
|
||||
usartI2sFormatW32D32 = USART_I2SCTRL_FORMAT_W32D32, /**< 32-bit word, 32-bit data */
|
||||
usartI2sFormatW32D24M = USART_I2SCTRL_FORMAT_W32D24M, /**< 32-bit word, 32-bit data with 8 lsb masked */
|
||||
usartI2sFormatW32D24 = USART_I2SCTRL_FORMAT_W32D24, /**< 32-bit word, 24-bit data */
|
||||
usartI2sFormatW32D16 = USART_I2SCTRL_FORMAT_W32D16, /**< 32-bit word, 16-bit data */
|
||||
usartI2sFormatW32D8 = USART_I2SCTRL_FORMAT_W32D8, /**< 32-bit word, 8-bit data */
|
||||
usartI2sFormatW16D16 = USART_I2SCTRL_FORMAT_W16D16, /**< 16-bit word, 16-bit data */
|
||||
usartI2sFormatW16D8 = USART_I2SCTRL_FORMAT_W16D8, /**< 16-bit word, 8-bit data */
|
||||
usartI2sFormatW8D8 = USART_I2SCTRL_FORMAT_W8D8 /**< 8-bit word, 8-bit data */
|
||||
} USART_I2sFormat_TypeDef;
|
||||
|
||||
/** I2S frame data justify. */
|
||||
typedef enum
|
||||
{
|
||||
usartI2sJustifyLeft = USART_I2SCTRL_JUSTIFY_LEFT, /**< Data is left-justified within the frame */
|
||||
usartI2sJustifyRight = USART_I2SCTRL_JUSTIFY_RIGHT /**< Data is right-justified within the frame */
|
||||
} USART_I2sJustify_TypeDef;
|
||||
|
||||
/** USART Rx input PRS selection. */
|
||||
typedef enum
|
||||
{
|
||||
usartPrsRxCh0 = USART_INPUT_RXPRSSEL_PRSCH0, /**< PRSCH0 selected as USART_INPUT */
|
||||
usartPrsRxCh1 = USART_INPUT_RXPRSSEL_PRSCH1, /**< PRSCH1 selected as USART_INPUT */
|
||||
usartPrsRxCh2 = USART_INPUT_RXPRSSEL_PRSCH2, /**< PRSCH2 selected as USART_INPUT */
|
||||
usartPrsRxCh3 = USART_INPUT_RXPRSSEL_PRSCH3, /**< PRSCH3 selected as USART_INPUT */
|
||||
usartPrsRxCh4 = USART_INPUT_RXPRSSEL_PRSCH4, /**< PRSCH4 selected as USART_INPUT */
|
||||
usartPrsRxCh5 = USART_INPUT_RXPRSSEL_PRSCH5, /**< PRSCH5 selected as USART_INPUT */
|
||||
usartPrsRxCh6 = USART_INPUT_RXPRSSEL_PRSCH6, /**< PRSCH6 selected as USART_INPUT */
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY)
|
||||
usartPrsRxCh7 = USART_INPUT_RXPRSSEL_PRSCH7 /**< PRSCH7 selected as USART_INPUT */
|
||||
|
||||
#elif defined(_EFM32_GIANT_FAMILY)
|
||||
usartPrsRxCh7 = USART_INPUT_RXPRSSEL_PRSCH7, /**< PRSCH7 selected as USART_INPUT */
|
||||
usartPrsRxCh8 = USART_INPUT_RXPRSSEL_PRSCH8, /**< PRSCH8 selected as USART_INPUT */
|
||||
usartPrsRxCh9 = USART_INPUT_RXPRSSEL_PRSCH9, /**< PRSCH9 selected as USART_INPUT */
|
||||
usartPrsRxCh10 = USART_INPUT_RXPRSSEL_PRSCH10, /**< PRSCH10 selected as USART_INPUT */
|
||||
usartPrsRxCh11 = USART_INPUT_RXPRSSEL_PRSCH11 /**< PRSCH11 selected as USART_INPUT */
|
||||
#else
|
||||
#error Unknown EFM32 family.
|
||||
#endif
|
||||
} USART_PrsRxCh_TypeDef;
|
||||
#endif
|
||||
|
||||
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/** USART PRS Transmit Trigger Channels */
|
||||
typedef enum
|
||||
{
|
||||
usartPrsTriggerCh0 = USART_TRIGCTRL_TSEL_PRSCH0, /**< PRSCH0 selected as USART Trigger */
|
||||
usartPrsTriggerCh1 = USART_TRIGCTRL_TSEL_PRSCH1, /**< PRSCH0 selected as USART Trigger */
|
||||
usartPrsTriggerCh2 = USART_TRIGCTRL_TSEL_PRSCH2, /**< PRSCH0 selected as USART Trigger */
|
||||
usartPrsTriggerCh3 = USART_TRIGCTRL_TSEL_PRSCH3, /**< PRSCH0 selected as USART Trigger */
|
||||
usartPrsTriggerCh4 = USART_TRIGCTRL_TSEL_PRSCH4, /**< PRSCH0 selected as USART Trigger */
|
||||
usartPrsTriggerCh5 = USART_TRIGCTRL_TSEL_PRSCH5, /**< PRSCH0 selected as USART Trigger */
|
||||
usartPrsTriggerCh6 = USART_TRIGCTRL_TSEL_PRSCH6, /**< PRSCH0 selected as USART Trigger */
|
||||
usartPrsTriggerCh7 = USART_TRIGCTRL_TSEL_PRSCH7, /**< PRSCH0 selected as USART Trigger */
|
||||
} USART_PrsTriggerCh_TypeDef;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Asynchronous mode init structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Specifies whether TX and/or RX shall be enabled when init completed. */
|
||||
USART_Enable_TypeDef enable;
|
||||
|
||||
/**
|
||||
* USART/UART reference clock assumed when configuring baudrate setup. Set
|
||||
* it to 0 if currently configurated reference clock shall be used.
|
||||
*/
|
||||
uint32_t refFreq;
|
||||
|
||||
/** Desired baudrate. */
|
||||
uint32_t baudrate;
|
||||
|
||||
/** Oversampling used. */
|
||||
USART_OVS_TypeDef oversampling;
|
||||
|
||||
/** Number of databits in frame. Notice that UART modules only support 8 or
|
||||
* 9 databits. */
|
||||
USART_Databits_TypeDef databits;
|
||||
|
||||
/** Parity mode to use. */
|
||||
USART_Parity_TypeDef parity;
|
||||
|
||||
/** Number of stopbits to use. */
|
||||
USART_Stopbits_TypeDef stopbits;
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
/** Majority Vote Disable for 16x, 8x and 6x oversampling modes. */
|
||||
bool mvdis;
|
||||
|
||||
/** Enable USART Rx via PRS. */
|
||||
bool prsRxEnable;
|
||||
|
||||
/** Select PRS channel for USART Rx. (Only valid if prsRxEnable is true). */
|
||||
USART_PrsRxCh_TypeDef prsRxCh;
|
||||
#endif
|
||||
} USART_InitAsync_TypeDef;
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/** USART PRS trigger enable */
|
||||
typedef struct
|
||||
{
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/** Enable AUTOTX */
|
||||
bool autoTxTriggerEnable;
|
||||
#endif
|
||||
/** Trigger receive via PRS channel */
|
||||
bool rxTriggerEnable;
|
||||
/** Trigger transmit via PRS channel */
|
||||
bool txTriggerEnable;
|
||||
/** PRS channel to be used to trigger auto transmission */
|
||||
USART_PrsTriggerCh_TypeDef prsTriggerChannel;
|
||||
} USART_PrsTriggerInit_TypeDef;
|
||||
#endif
|
||||
|
||||
/** Default config for USART async init structure. */
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
#define USART_INITASYNC_DEFAULT \
|
||||
{ usartEnable, /* Enable RX/TX when init completed. */ \
|
||||
0, /* Use current configured reference clock for configuring baudrate. */ \
|
||||
115200, /* 115200 bits/s. */ \
|
||||
usartOVS16, /* 16x oversampling. */ \
|
||||
usartDatabits8, /* 8 databits. */ \
|
||||
usartNoParity, /* No parity. */ \
|
||||
usartStopbits1, /* 1 stopbit. */ \
|
||||
false, /* Do not disable majority vote. */ \
|
||||
false, /* Not USART PRS input mode. */ \
|
||||
usartPrsRxCh0 /* PRS channel 0. */ \
|
||||
}
|
||||
#else
|
||||
#define USART_INITASYNC_DEFAULT \
|
||||
{ usartEnable, /* Enable RX/TX when init completed. */ \
|
||||
0, /* Use current configured reference clock for configuring baudrate. */ \
|
||||
115200, /* 115200 bits/s. */ \
|
||||
usartOVS16, /* 16x oversampling. */ \
|
||||
usartDatabits8, /* 8 databits. */ \
|
||||
usartNoParity, /* No parity. */ \
|
||||
usartStopbits1 /* 1 stopbit. */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Synchronous mode init structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Specifies whether TX and/or RX shall be enabled when init completed. */
|
||||
USART_Enable_TypeDef enable;
|
||||
|
||||
/**
|
||||
* USART/UART reference clock assumed when configuring baudrate setup. Set
|
||||
* it to 0 if currently configurated reference clock shall be used.
|
||||
*/
|
||||
uint32_t refFreq;
|
||||
|
||||
/** Desired baudrate. */
|
||||
uint32_t baudrate;
|
||||
|
||||
/** Number of databits in frame. */
|
||||
USART_Databits_TypeDef databits;
|
||||
|
||||
/** Select if to operate in master or slave mode. */
|
||||
bool master;
|
||||
|
||||
/** Select if to send most or least significant bit first. */
|
||||
bool msbf;
|
||||
|
||||
/** Clock polarity/phase mode. */
|
||||
USART_ClockMode_TypeDef clockMode;
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
/** Enable USART Rx via PRS. */
|
||||
bool prsRxEnable;
|
||||
|
||||
/** Select PRS channel for USART Rx. (Only valid if prsRxEnable is true). */
|
||||
USART_PrsRxCh_TypeDef prsRxCh;
|
||||
|
||||
/** Enable AUTOTX mode. Transmits as long as RX is not full.
|
||||
* If TX is empty, underflows are generated. */
|
||||
bool autoTx;
|
||||
#endif
|
||||
} USART_InitSync_TypeDef;
|
||||
|
||||
/** Default config for USART sync init structure. */
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
#define USART_INITSYNC_DEFAULT \
|
||||
{ usartEnable, /* Enable RX/TX when init completed. */ \
|
||||
0, /* Use current configured reference clock for configuring baudrate. */ \
|
||||
1000000, /* 1 Mbits/s. */ \
|
||||
usartDatabits8, /* 8 databits. */ \
|
||||
true, /* Master mode. */ \
|
||||
false, /* Send least significant bit first. */ \
|
||||
usartClockMode0, /* Clock idle low, sample on rising edge. */ \
|
||||
false, /* Not USART PRS input mode. */ \
|
||||
usartPrsRxCh0, /* PRS channel 0. */ \
|
||||
false /* No AUTOTX mode. */ \
|
||||
}
|
||||
#else
|
||||
#define USART_INITSYNC_DEFAULT \
|
||||
{ usartEnable, /* Enable RX/TX when init completed. */ \
|
||||
0, /* Use current configured reference clock for configuring baudrate. */ \
|
||||
1000000, /* 1 Mbits/s. */ \
|
||||
usartDatabits8, /* 8 databits. */ \
|
||||
true, /* Master mode. */ \
|
||||
false, /* Send least significant bit first. */ \
|
||||
usartClockMode0 /* Clock idle low, sample on rising edge. */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** IrDA mode init structure. Inherited from asynchronous mode init structure */
|
||||
typedef struct
|
||||
{
|
||||
/** General Async initialization structure. */
|
||||
USART_InitAsync_TypeDef async;
|
||||
|
||||
/** Set to invert Rx signal before IrDA demodulator. */
|
||||
bool irRxInv;
|
||||
|
||||
/** Set to enable filter on IrDA demodulator. */
|
||||
bool irFilt;
|
||||
|
||||
/** Configure the pulse width generated by the IrDA modulator as a fraction
|
||||
* of the configured USART bit period. */
|
||||
USART_IrDAPw_Typedef irPw;
|
||||
|
||||
/** Enable the PRS channel selected by irPrsSel as input to IrDA module
|
||||
* instead of TX. */
|
||||
bool irPrsEn;
|
||||
|
||||
/** A PRS can be used as input to the pulse modulator instead of TX.
|
||||
* This value selects the channel to use. */
|
||||
USART_IrDAPrsSel_Typedef irPrsSel;
|
||||
} USART_InitIrDA_TypeDef;
|
||||
|
||||
|
||||
/** Default config for IrDA mode init structure. */
|
||||
#define USART_INITIRDA_DEFAULT \
|
||||
{ \
|
||||
{ usartEnable, /* Enable RX/TX when init completed. */ \
|
||||
0, /* Use current configured reference clock for configuring baudrate. */ \
|
||||
115200, /* 115200 bits/s. */ \
|
||||
usartOVS16, /* 16x oversampling. */ \
|
||||
usartDatabits8, /* 8 databits. */ \
|
||||
usartEvenParity, /* Even parity. */ \
|
||||
usartStopbits1 /* 1 stopbit. */ \
|
||||
}, \
|
||||
false, /* Rx invert disabled. */ \
|
||||
false, /* Filtering disabled. */ \
|
||||
usartIrDAPwTHREE, /* Pulse width is set to ONE. */ \
|
||||
false, /* Routing to PRS is disabled. */ \
|
||||
usartIrDAPrsCh0 /* PRS channel 0. */ \
|
||||
}
|
||||
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
/** I2S mode init structure. Inherited from synchronous mode init structure */
|
||||
typedef struct
|
||||
{
|
||||
/** General Sync initialization structure. */
|
||||
USART_InitSync_TypeDef sync;
|
||||
|
||||
/** I2S mode. */
|
||||
USART_I2sFormat_TypeDef format;
|
||||
|
||||
/** Delay on I2S data. Set to add a one-cycle delay between a transition
|
||||
* on the word-clock and the start of the I2S word.
|
||||
* Should be set for standard I2S format. */
|
||||
bool delay;
|
||||
|
||||
/** Separate DMA Request For Left/Right Data. */
|
||||
bool dmaSplit;
|
||||
|
||||
/** Justification of I2S data within the frame */
|
||||
USART_I2sJustify_TypeDef justify;
|
||||
|
||||
/** Stero or Mono, set to true for mono. */
|
||||
bool mono;
|
||||
} USART_InitI2s_TypeDef;
|
||||
|
||||
|
||||
/** Default config for I2S mode init structure. */
|
||||
#define USART_INITI2S_DEFAULT \
|
||||
{ \
|
||||
{ usartEnableTx, /* Enable TX when init completed. */ \
|
||||
0, /* Use current configured reference clock for configuring baudrate. */ \
|
||||
1000000, /* Baudrate 1M bits/s. */ \
|
||||
usartDatabits16, /* 16 databits. */ \
|
||||
true, /* Operate as I2S master. */ \
|
||||
true, /* Most significant bit first. */ \
|
||||
usartClockMode0, /* Clock idle low, sample on rising edge. */ \
|
||||
false, /* Don't enable USARTRx via PRS. */ \
|
||||
usartPrsRxCh0, /* PRS channel selection (dummy). */ \
|
||||
false /* Disable AUTOTX mode. */ \
|
||||
}, \
|
||||
usartI2sFormatW16D16, /* 16-bit word, 16-bit data */ \
|
||||
true, /* Delay on I2S data. */ \
|
||||
false, /* No DMA split. */ \
|
||||
usartI2sJustifyLeft, /* Data is left-justified within the frame */ \
|
||||
false /* Stereo mode. */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void USART_BaudrateAsyncSet(USART_TypeDef *usart,
|
||||
uint32_t refFreq,
|
||||
uint32_t baudrate,
|
||||
USART_OVS_TypeDef ovs);
|
||||
uint32_t USART_BaudrateCalc(uint32_t refFreq,
|
||||
uint32_t clkdiv,
|
||||
bool syncmode,
|
||||
USART_OVS_TypeDef ovs);
|
||||
uint32_t USART_BaudrateGet(USART_TypeDef *usart);
|
||||
void USART_BaudrateSyncSet(USART_TypeDef *usart,
|
||||
uint32_t refFreq,
|
||||
uint32_t baudrate);
|
||||
void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable);
|
||||
|
||||
void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init);
|
||||
void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init);
|
||||
void USART_InitIrDA(const USART_InitIrDA_TypeDef *init);
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
void USART_InitI2s(USART_TypeDef *usart, USART_InitI2s_TypeDef *init);
|
||||
void USART_InitPrsTrigger(USART_TypeDef *usart, const USART_PrsTriggerInit_TypeDef *init);
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending USART interrupts.
|
||||
*
|
||||
* @param[in] usart
|
||||
* Pointer to USART/UART peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pending USART/UART interrupt source(s) to clear. Use one or more valid
|
||||
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE void USART_IntClear(USART_TypeDef *usart, uint32_t flags)
|
||||
{
|
||||
usart->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more USART interrupts.
|
||||
*
|
||||
* @param[in] usart
|
||||
* Pointer to USART/UART peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* USART/UART interrupt source(s) to disable. Use one or more valid
|
||||
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE void USART_IntDisable(USART_TypeDef *usart, uint32_t flags)
|
||||
{
|
||||
usart->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more USART interrupts.
|
||||
*
|
||||
* @note
|
||||
* Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. Consider using USART_IntClear() prior to enabling
|
||||
* if such a pending interrupt should be ignored.
|
||||
*
|
||||
* @param[in] usart
|
||||
* Pointer to USART/UART peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* USART/UART interrupt source(s) to enable. Use one or more valid
|
||||
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE void USART_IntEnable(USART_TypeDef *usart, uint32_t flags)
|
||||
{
|
||||
usart->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending USART interrupt flags.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @param[in] usart
|
||||
* Pointer to USART/UART peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* USART/UART interrupt source(s) pending. Returns one or more valid
|
||||
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t USART_IntGet(USART_TypeDef *usart)
|
||||
{
|
||||
return usart->IF;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get enabled and pending USART interrupt flags.
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @param[in] usart
|
||||
* Pointer to USART/UART peripheral register block.
|
||||
*
|
||||
* @note
|
||||
* Interrupt flags are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* Pending and enabled USART interrupt sources.
|
||||
* The return value is the bitwise AND combination of
|
||||
* - the OR combination of enabled interrupt sources in USARTx_IEN_nnn
|
||||
* register (USARTx_IEN_nnn) and
|
||||
* - the OR combination of valid interrupt flags of the USART module
|
||||
* (USARTx_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t USART_IntGetEnabled(USART_TypeDef *usart)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Store USARTx->IEN in temporary variable in order to define explicit order
|
||||
* of volatile accesses. */
|
||||
tmp = usart->IEN;
|
||||
|
||||
/* Bitwise AND of pending and enabled interrupts */
|
||||
return usart->IF & tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending USART interrupts from SW.
|
||||
*
|
||||
* @param[in] usart
|
||||
* Pointer to USART/UART peripheral register block.
|
||||
*
|
||||
* @param[in] flags
|
||||
* USART/UART interrupt source(s) to set to pending. Use one or more valid
|
||||
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
|
||||
******************************************************************************/
|
||||
static __INLINE void USART_IntSet(USART_TypeDef *usart, uint32_t flags)
|
||||
{
|
||||
usart->IFS = flags;
|
||||
}
|
||||
|
||||
void USART_Reset(USART_TypeDef *usart);
|
||||
uint8_t USART_Rx(USART_TypeDef *usart);
|
||||
uint16_t USART_RxDouble(USART_TypeDef *usart);
|
||||
uint32_t USART_RxDoubleExt(USART_TypeDef *usart);
|
||||
uint16_t USART_RxExt(USART_TypeDef *usart);
|
||||
void USART_Tx(USART_TypeDef *usart, uint8_t data);
|
||||
void USART_TxDouble(USART_TypeDef *usart, uint16_t data);
|
||||
void USART_TxDoubleExt(USART_TypeDef *usart, uint32_t data);
|
||||
void USART_TxExt(USART_TypeDef *usart, uint16_t data);
|
||||
|
||||
|
||||
/** @} (end addtogroup USART) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_USART_H */
|
|
@ -0,0 +1,352 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Voltage Comparator (VCMP) peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_VCMP_H
|
||||
#define __EFM32_VCMP_H
|
||||
#include "efm32.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup VCMP
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Warm-up Time in High Frequency Peripheral Clock cycles */
|
||||
typedef enum
|
||||
{
|
||||
/** 4 cycles */
|
||||
vcmpWarmTime4Cycles = _VCMP_CTRL_WARMTIME_4CYCLES,
|
||||
/** 8 cycles */
|
||||
vcmpWarmTime8Cycles = _VCMP_CTRL_WARMTIME_8CYCLES,
|
||||
/** 16 cycles */
|
||||
vcmpWarmTime16Cycles = _VCMP_CTRL_WARMTIME_16CYCLES,
|
||||
/** 32 cycles */
|
||||
vcmpWarmTime32Cycles = _VCMP_CTRL_WARMTIME_32CYCLES,
|
||||
/** 64 cycles */
|
||||
vcmpWarmTime64Cycles = _VCMP_CTRL_WARMTIME_64CYCLES,
|
||||
/** 128 cycles */
|
||||
vcmpWarmTime128Cycles = _VCMP_CTRL_WARMTIME_128CYCLES,
|
||||
/** 256 cycles */
|
||||
vcmpWarmTime256Cycles = _VCMP_CTRL_WARMTIME_256CYCLES,
|
||||
/** 512 cycles */
|
||||
vcmpWarmTime512Cycles = _VCMP_CTRL_WARMTIME_512CYCLES
|
||||
} VCMP_WarmTime_TypeDef;
|
||||
|
||||
/** Hyseresis configuration */
|
||||
typedef enum
|
||||
{
|
||||
/** Normal operation, no hysteresis */
|
||||
vcmpHystNone,
|
||||
/** Digital output will not toggle until positive edge is at least
|
||||
* 20mV above or below negative input voltage */
|
||||
vcmpHyst20mV
|
||||
} VCMP_Hysteresis_TypeDef;
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** VCMP Initialization structure */
|
||||
typedef struct
|
||||
{
|
||||
/** If set to true, will reduce by half the bias current */
|
||||
bool halfBias;
|
||||
/** BIAS current configuration, depends on halfBias setting,
|
||||
* above, see reference manual */
|
||||
int biasProg;
|
||||
/** Enable interrupt for falling edge */
|
||||
bool irqFalling;
|
||||
/** Enable interrupt for rising edge */
|
||||
bool irqRising;
|
||||
/** Warm-up time in clock cycles */
|
||||
VCMP_WarmTime_TypeDef warmup;
|
||||
/** Hysteresis configuration */
|
||||
VCMP_Hysteresis_TypeDef hyst;
|
||||
/** Output value when comparator is inactive, should be 0 or 1 */
|
||||
int inactive;
|
||||
/** Enable low power mode for VDD and bandgap reference */
|
||||
bool lowPowerRef;
|
||||
/** Trigger level, according to formula
|
||||
* VDD Trigger Level = 1.667V + 0.034V x triggerLevel */
|
||||
int triggerLevel;
|
||||
/** Enable VCMP after configuration */
|
||||
bool enable;
|
||||
} VCMP_Init_TypeDef;
|
||||
|
||||
/** Default VCMP initialization structure */
|
||||
#define VCMP_INIT_DEFAULT \
|
||||
{ true, /** Half Bias enabled */ \
|
||||
0x7, /** Bias curernt 0.7 uA when half bias enabled */ \
|
||||
false, /** Falling edge sense not enabled */ \
|
||||
false, /** Rising edge sense not enabled */ \
|
||||
vcmpWarmTime4Cycles, /** 4 clock cycles warm-up time */ \
|
||||
vcmpHystNone, /** No hysteresis */ \
|
||||
0, /** 0 in digital ouput when inactive */ \
|
||||
true, /** Do not use low power reference */ \
|
||||
39, /** Trigger level just below 3V */ \
|
||||
true, /** Enable after init */ \
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
void VCMP_Init(const VCMP_Init_TypeDef *vcmpInit);
|
||||
void VCMP_LowPowerRefSet(bool enable);
|
||||
void VCMP_TriggerSet(int level);
|
||||
|
||||
static __INLINE void VCMP_Enable(void);
|
||||
static __INLINE void VCMP_Disable(void);
|
||||
static __INLINE uint32_t VCMP_VoltageToLevel(float v);
|
||||
static __INLINE bool VCMP_VDDLower(void);
|
||||
static __INLINE bool VCMP_VDDHigher(void);
|
||||
static __INLINE bool VCMP_Ready(void);
|
||||
static __INLINE void VCMP_IntClear(uint32_t flags);
|
||||
static __INLINE void VCMP_IntSet(uint32_t flags);
|
||||
static __INLINE void VCMP_IntDisable(uint32_t flags);
|
||||
static __INLINE void VCMP_IntEnable(uint32_t flags);
|
||||
static __INLINE uint32_t VCMP_IntGet(void);
|
||||
static __INLINE uint32_t VCMP_IntGetEnabled(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable Voltage Comparator
|
||||
******************************************************************************/
|
||||
static __INLINE void VCMP_Enable(void)
|
||||
{
|
||||
VCMP->CTRL |= VCMP_CTRL_EN;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable Voltage Comparator
|
||||
******************************************************************************/
|
||||
static __INLINE void VCMP_Disable(void)
|
||||
{
|
||||
VCMP->CTRL &= ~(VCMP_CTRL_EN);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Calculate voltage to trigger level
|
||||
*
|
||||
* @note
|
||||
* You need soft float support for this function to be working
|
||||
*
|
||||
* @param[in] v
|
||||
* Voltage Level for trigger
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t VCMP_VoltageToLevel(float v)
|
||||
{
|
||||
return (uint32_t)((v - (float)1.667) / (float)0.034);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns true, if Voltage Comparator indicated VDD < trigger level, else
|
||||
* false
|
||||
******************************************************************************/
|
||||
static __INLINE bool VCMP_VDDLower(void)
|
||||
{
|
||||
if (VCMP->STATUS & VCMP_STATUS_VCMPOUT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns true, if Voltage Comparator indicated VDD > trigger level, else
|
||||
* false
|
||||
******************************************************************************/
|
||||
static __INLINE bool VCMP_VDDHigher(void)
|
||||
{
|
||||
if (VCMP->STATUS & VCMP_STATUS_VCMPOUT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* VCMP output is ready
|
||||
******************************************************************************/
|
||||
static __INLINE bool VCMP_Ready(void)
|
||||
{
|
||||
if (VCMP->STATUS & VCMP_STATUS_VCMPACT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear one or more pending VCMP interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* VCMP interrupt sources to clear. Use a set of interrupt flags OR-ed
|
||||
* together to clear multiple interrupt sources for the VCMP module
|
||||
* (VCMP_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void VCMP_IntClear(uint32_t flags)
|
||||
{
|
||||
VCMP->IFC = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set one or more pending VCMP interrupts from SW.
|
||||
*
|
||||
* @param[in] flags
|
||||
* VCMP interrupt sources to set to pending. Use a set of interrupt flags
|
||||
* OR-ed together to set multiple interrupt sources for the VCMP module
|
||||
* (VCMP_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void VCMP_IntSet(uint32_t flags)
|
||||
{
|
||||
VCMP->IFS = flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more VCMP interrupts
|
||||
*
|
||||
* @param[in] flags
|
||||
* VCMP interrupt sources to enable. Use a set of interrupt flags OR-ed
|
||||
* together to set multiple interrupt sources for the VCMP module
|
||||
* (VCMP_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void VCMP_IntDisable(uint32_t flags)
|
||||
{
|
||||
VCMP->IEN &= ~(flags);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more VCMP interrupts
|
||||
*
|
||||
* @param[in] flags
|
||||
* VCMP interrupt sources to enable. Use a set of interrupt flags OR-ed
|
||||
* together to set multiple interrupt sources for the VCMP module
|
||||
* (VCMP_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE void VCMP_IntEnable(uint32_t flags)
|
||||
{
|
||||
VCMP->IEN |= flags;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get pending VCMP interrupt flags
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function
|
||||
*
|
||||
* @return
|
||||
* Pending VCMP interrupt sources. Returns a set of interrupt flags OR-ed
|
||||
* together for multiple interrupt sources in the VCMP module (VCMP_IFS_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t VCMP_IntGet(void)
|
||||
{
|
||||
return(VCMP->IF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get enabled and pending VCMP interrupt flags.
|
||||
*
|
||||
* @details
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @note
|
||||
* The event bits are not cleared by the use of this function.
|
||||
*
|
||||
* @return
|
||||
* Pending and enabled VCMP interrupt sources.
|
||||
* The return value is the bitwise AND combination of
|
||||
* - the OR combination of enabled interrupt sources in VCMP_IEN_nnn
|
||||
* register (VCMP_IEN_nnn) and
|
||||
* - the OR combination of valid interrupt flags of the VCMP module
|
||||
* (VCMP_IF_nnn).
|
||||
******************************************************************************/
|
||||
static __INLINE uint32_t VCMP_IntGetEnabled(void)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
/* Store VCMP->IEN in temporary variable in order to define explicit order
|
||||
* of volatile accesses. */
|
||||
tmp = VCMP->IEN;
|
||||
|
||||
/* Bitwise AND of pending and enabled interrupts */
|
||||
return VCMP->IF & tmp;
|
||||
}
|
||||
|
||||
/** @} (end addtogroup VCMP) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_VCMP_H */
|
|
@ -0,0 +1,146 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Watchdog (WDOG) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __EFM32_WDOG_H
|
||||
#define __EFM32_WDOG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "efm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup WDOG
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Watchdog clock selection. */
|
||||
typedef enum
|
||||
{
|
||||
wdogClkSelULFRCO = _WDOG_CTRL_CLKSEL_ULFRCO, /**< Ultra low frequency (1 kHz) clock */
|
||||
wdogClkSelLFRCO = _WDOG_CTRL_CLKSEL_LFRCO, /**< Low frequency RC oscillator */
|
||||
wdogClkSelLFXO = _WDOG_CTRL_CLKSEL_LFXO /**< Low frequency crystal oscillator */
|
||||
} WDOG_ClkSel_TypeDef;
|
||||
|
||||
/** Watchdog period selection. */
|
||||
typedef enum
|
||||
{
|
||||
wdogPeriod_9 = 0x0, /**< 9 clock periods */
|
||||
wdogPeriod_17 = 0x1, /**< 17 clock periods */
|
||||
wdogPeriod_33 = 0x2, /**< 33 clock periods */
|
||||
wdogPeriod_65 = 0x3, /**< 65 clock periods */
|
||||
wdogPeriod_129 = 0x4, /**< 129 clock periods */
|
||||
wdogPeriod_257 = 0x5, /**< 257 clock periods */
|
||||
wdogPeriod_513 = 0x6, /**< 513 clock periods */
|
||||
wdogPeriod_1k = 0x7, /**< 1025 clock periods */
|
||||
wdogPeriod_2k = 0x8, /**< 2049 clock periods */
|
||||
wdogPeriod_4k = 0x9, /**< 4097 clock periods */
|
||||
wdogPeriod_8k = 0xA, /**< 8193 clock periods */
|
||||
wdogPeriod_16k = 0xB, /**< 16385 clock periods */
|
||||
wdogPeriod_32k = 0xC, /**< 32769 clock periods */
|
||||
wdogPeriod_64k = 0xD, /**< 65537 clock periods */
|
||||
wdogPeriod_128k = 0xE, /**< 131073 clock periods */
|
||||
wdogPeriod_256k = 0xF /**< 262145 clock periods */
|
||||
} WDOG_PeriodSel_TypeDef;
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** Watchdog initialization structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Enable watchdog when init completed. */
|
||||
bool enable;
|
||||
|
||||
/** Counter shall keep running during debug halt. */
|
||||
bool debugRun;
|
||||
|
||||
/** Counter shall keep running when in EM2. */
|
||||
bool em2Run;
|
||||
|
||||
/** Counter shall keep running when in EM3. */
|
||||
bool em3Run;
|
||||
|
||||
/** Block EMU from entering EM4. */
|
||||
bool em4Block;
|
||||
|
||||
/** Block SW from disabling LFRCO/LFXO oscillators. */
|
||||
bool swoscBlock;
|
||||
|
||||
/** Block SW from modifying the configuration (a reset is needed to reconfigure). */
|
||||
bool lock;
|
||||
|
||||
/** Clock source to use for watchdog. */
|
||||
WDOG_ClkSel_TypeDef clkSel;
|
||||
|
||||
/** Watchdog timeout period. */
|
||||
WDOG_PeriodSel_TypeDef perSel;
|
||||
} WDOG_Init_TypeDef;
|
||||
|
||||
/** Suggested default config for WDOG init structure. */
|
||||
#define WDOG_INIT_DEFAULT \
|
||||
{ true, /* Start watchdog when init done */ \
|
||||
false, /* WDOG not counting during debug halt */ \
|
||||
false, /* WDOG not counting when in EM2 */ \
|
||||
false, /* WDOG not counting when in EM3 */ \
|
||||
false, /* EM4 can be entered */ \
|
||||
false, /* Do not block disabling LFRCO/LFXO in CMU */ \
|
||||
false, /* Do not lock WDOG configuration (if locked, reset needed to unlock) */ \
|
||||
wdogClkSelULFRCO, /* Select 1kHZ WDOG oscillator */ \
|
||||
wdogPeriod_256k /* Set longest possible timeout period */ \
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
void WDOG_Enable(bool enable);
|
||||
void WDOG_Feed(void);
|
||||
void WDOG_Init(const WDOG_Init_TypeDef *init);
|
||||
void WDOG_Lock(void);
|
||||
|
||||
/** @} (end addtogroup WDOG) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EFM32_WDOG_H */
|
|
@ -0,0 +1,294 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Analog Comparator (ACMP) peripheral module library implementation
|
||||
* for EFM32 devices.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <stdbool.h>
|
||||
#include "efm32_acmp.h"
|
||||
#include "efm32_bitband.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup ACMP
|
||||
* @brief Analog comparator (ACMP) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
|
||||
/** Validation of ACMP register block pointer reference
|
||||
* for assert statements. */
|
||||
#if (ACMP_COUNT == 1)
|
||||
#define ACMP_REF_VALID(ref) ((ref) == ACMP0)
|
||||
#elif (ACMP_COUNT == 2)
|
||||
#define ACMP_REF_VALID(ref) (((ref) == ACMP0) || ((ref) == ACMP1))
|
||||
#else
|
||||
#error Undefined number of analog comparators (ACMP).
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets up the ACMP for use in capacative sense applications.
|
||||
*
|
||||
* @details
|
||||
* This function sets up the ACMP for use in capacacitve sense applications.
|
||||
* To use the capacative sense functionality in the ACMP you need to use
|
||||
* the PRS output of the ACMP module to count the number of oscillations
|
||||
* in the capacative sense circuit (possibly using a TIMER).
|
||||
*
|
||||
* @note
|
||||
* A basic example of capacative sensing can be found in the STK BSP
|
||||
* (capsense demo).
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to initialization structure used to configure ACMP for capacative
|
||||
* sensing operation.
|
||||
******************************************************************************/
|
||||
void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init)
|
||||
{
|
||||
/* Make sure the module exists on the selected chip */
|
||||
EFM_ASSERT(ACMP_REF_VALID(acmp));
|
||||
|
||||
/* Make sure that vddLevel is within bounds */
|
||||
EFM_ASSERT(init->vddLevel < 64);
|
||||
|
||||
/* Make sure biasprog is within bounds */
|
||||
EFM_ASSERT(init->biasProg < 16);
|
||||
|
||||
/* Set control register. No need to set interrupt modes */
|
||||
acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT)
|
||||
| (init->halfBias << _ACMP_CTRL_HALFBIAS_SHIFT)
|
||||
| (init->biasProg << _ACMP_CTRL_BIASPROG_SHIFT)
|
||||
| (init->warmTime << _ACMP_CTRL_WARMTIME_SHIFT)
|
||||
| (init->hysteresisLevel << _ACMP_CTRL_HYSTSEL_SHIFT);
|
||||
|
||||
/* Select capacative sensing mode by selecting a resistor and enabling it */
|
||||
acmp->INPUTSEL = (init->resistor << _ACMP_INPUTSEL_CSRESSEL_SHIFT)
|
||||
| ACMP_INPUTSEL_CSRESEN
|
||||
| (init->lowPowerReferenceEnabled << _ACMP_INPUTSEL_LPREF_SHIFT)
|
||||
| (init->vddLevel << _ACMP_INPUTSEL_VDDLEVEL_SHIFT)
|
||||
| ACMP_INPUTSEL_NEGSEL_CAPSENSE;
|
||||
|
||||
/* Enable ACMP if requested.
|
||||
* Note: BITBAND_Peripheral() function is used for setting/clearing single
|
||||
* bit peripheral register bitfields. */
|
||||
BITBAND_Peripheral(&(acmp->CTRL),
|
||||
(uint32_t)_ACMP_CTRL_EN_SHIFT,
|
||||
(uint32_t)init->enable);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets the ACMP channel used for capacative sensing.
|
||||
*
|
||||
* @note
|
||||
* A basic example of capacative sensing can be found in the STK BSP
|
||||
* (capsense demo).
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
*
|
||||
* @param[in] channel
|
||||
* The ACMP channel to use for capacative sensing (Possel).
|
||||
******************************************************************************/
|
||||
void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel)
|
||||
{
|
||||
/* Make sure that only external channels are used */
|
||||
EFM_ASSERT(channel < _ACMP_INPUTSEL_NEGSEL_1V25);
|
||||
|
||||
/* Set channel as positive channel in ACMP */
|
||||
SET_BIT_FIELD(acmp->INPUTSEL, _ACMP_INPUTSEL_POSSEL_MASK, channel,
|
||||
_ACMP_INPUTSEL_POSSEL_SHIFT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disables the ACMP.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
******************************************************************************/
|
||||
void ACMP_Disable(ACMP_TypeDef *acmp)
|
||||
{
|
||||
acmp->CTRL &= ~ACMP_CTRL_EN;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables the ACMP.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to ACMP peripheral register block.
|
||||
******************************************************************************/
|
||||
void ACMP_Enable(ACMP_TypeDef *acmp)
|
||||
{
|
||||
acmp->CTRL |= ACMP_CTRL_EN;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset ACMP to same state as after a HW reset.
|
||||
*
|
||||
* @note
|
||||
* The ROUTE register is NOT reset by this function, in order to allow for
|
||||
* centralized setup of this feature.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to the ACMP peripheral register block.
|
||||
******************************************************************************/
|
||||
void ACMP_Reset(ACMP_TypeDef *acmp)
|
||||
{
|
||||
/* Make sure the module exists on the selected chip */
|
||||
EFM_ASSERT(ACMP_REF_VALID(acmp));
|
||||
|
||||
acmp->CTRL = _ACMP_CTRL_RESETVALUE;
|
||||
acmp->INPUTSEL = _ACMP_INPUTSEL_RESETVALUE;
|
||||
acmp->IEN = _ACMP_IEN_RESETVALUE;
|
||||
acmp->IFC = _ACMP_IF_MASK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets up GPIO output from the ACMP.
|
||||
*
|
||||
* @note
|
||||
* GPIO must be enabled in the CMU before this function call, i.e.
|
||||
* @verbatim CMU_ClockEnable(cmuClock_GPIO, true); @endverbatim
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to the ACMP peripheral register block.
|
||||
*
|
||||
* @param location
|
||||
* The pin location to use. See the datasheet for location to pin mappings.
|
||||
*
|
||||
* @param enable
|
||||
* Enable or disable pin output.
|
||||
*
|
||||
* @param invert
|
||||
* Invert output.
|
||||
******************************************************************************/
|
||||
void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert)
|
||||
{
|
||||
/* Sanity checking of location */
|
||||
EFM_ASSERT(location < 4);
|
||||
|
||||
/* Set GPIO inversion */
|
||||
SET_BIT_FIELD(acmp->CTRL, _ACMP_CTRL_GPIOINV_MASK, invert,
|
||||
_ACMP_CTRL_GPIOINV_SHIFT);
|
||||
|
||||
acmp->ROUTE = (location << _ACMP_ROUTE_LOCATION_SHIFT)
|
||||
| (enable << _ACMP_ROUTE_ACMPPEN_SHIFT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets which channels should be used in ACMP comparisons.
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to the ACMP peripheral register block.
|
||||
*
|
||||
* @param negSel
|
||||
* Channel to use on the negative input to the ACMP.
|
||||
*
|
||||
* @param posSel
|
||||
* Channel to use on the positive input to the ACMP.
|
||||
******************************************************************************/
|
||||
void ACMP_ChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef negSel,
|
||||
ACMP_Channel_TypeDef posSel)
|
||||
{
|
||||
/* Make sure that only external channels are used as ACMP positive input */
|
||||
EFM_ASSERT(posSel < _ACMP_INPUTSEL_NEGSEL_1V25);
|
||||
/* Sanity checking of ACMP negative input */
|
||||
EFM_ASSERT(negSel <= _ACMP_INPUTSEL_NEGSEL_VDD);
|
||||
|
||||
acmp->INPUTSEL = (acmp->INPUTSEL & ~(_ACMP_INPUTSEL_POSSEL_MASK |
|
||||
_ACMP_INPUTSEL_NEGSEL_MASK))
|
||||
| (negSel << _ACMP_INPUTSEL_NEGSEL_SHIFT)
|
||||
| (posSel << _ACMP_INPUTSEL_POSSEL_SHIFT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
*
|
||||
*
|
||||
* @param[in] acmp
|
||||
* Pointer to the ACMP peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to initialization structure used to configure ACMP for capacative
|
||||
* sensing operation.
|
||||
******************************************************************************/
|
||||
void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init)
|
||||
{
|
||||
/* Make sure the module exists on the selected chip */
|
||||
EFM_ASSERT(ACMP_REF_VALID(acmp));
|
||||
|
||||
/* Make sure biasprog is within bounds */
|
||||
EFM_ASSERT(init->biasProg < 16);
|
||||
|
||||
/* Set control register. No need to set interrupt modes */
|
||||
acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT)
|
||||
| (init->halfBias << _ACMP_CTRL_HALFBIAS_SHIFT)
|
||||
| (init->biasProg << _ACMP_CTRL_BIASPROG_SHIFT)
|
||||
| (init->interruptOnFallingEdge << _ACMP_CTRL_IFALL_SHIFT)
|
||||
| (init->interruptOnRisingEdge << _ACMP_CTRL_IRISE_SHIFT)
|
||||
| (init->warmTime << _ACMP_CTRL_WARMTIME_SHIFT)
|
||||
| (init->hysteresisLevel << _ACMP_CTRL_HYSTSEL_SHIFT)
|
||||
| (init->inactiveValue << _ACMP_CTRL_INACTVAL_SHIFT);
|
||||
|
||||
acmp->INPUTSEL = (init->lowPowerReferenceEnabled << _ACMP_INPUTSEL_LPREF_SHIFT)
|
||||
| (init->vddLevel << _ACMP_INPUTSEL_VDDLEVEL_SHIFT);
|
||||
|
||||
/* Enable ACMP if requested.
|
||||
* Note: BITBAND_Peripheral() function is used for setting/clearing single
|
||||
* bit peripheral register bitfields. */
|
||||
BITBAND_Peripheral(&(acmp->CTRL),
|
||||
(uint32_t)_ACMP_CTRL_EN_SHIFT,
|
||||
(uint32_t)init->enable);
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup ACMP) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,510 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Analog to Digital Converter (ADC) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32_adc.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup ADC
|
||||
* @brief Analog to Digital Converter (ADC) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of ADC register block pointer reference for assert statements. */
|
||||
#define ADC_REF_VALID(ref) ((ref) == ADC0)
|
||||
|
||||
/** Max ADC clock */
|
||||
#define ADC_MAX_CLOCK 13000000
|
||||
|
||||
/** Min ADC clock */
|
||||
#define ADC_MIN_CLOCK 32000
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** LOCAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Load SCAN calibrate register with predefined values for a certain
|
||||
* reference.
|
||||
*
|
||||
* @details
|
||||
* During production, calibration values are made and stored in the device
|
||||
* information page for known references. Notice that for external references,
|
||||
* calibration values must be determined explicitly, and this function
|
||||
* will not modify the calibration register.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] ref
|
||||
* Reference to load calibrated values for. No values are loaded for
|
||||
* external references.
|
||||
******************************************************************************/
|
||||
static void ADC_CalibrateLoadScan(ADC_TypeDef *adc, ADC_Ref_TypeDef ref)
|
||||
{
|
||||
uint32_t cal;
|
||||
|
||||
/* Load proper calibration data depending on selected reference */
|
||||
/* NOTE: We use ...SCAN... defines below, they are the same as */
|
||||
/* similar ...SINGLE... defines. */
|
||||
switch (ref)
|
||||
{
|
||||
case adcRef1V25:
|
||||
cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
case adcRef2V5:
|
||||
cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
case adcRefVDD:
|
||||
cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
case adcRef5VDIFF:
|
||||
cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
case adcRef2xVDD:
|
||||
/* Gain value not of relevance for this reference, leave as is */
|
||||
cal = adc->CAL & ~_ADC_CAL_SCANOFFSET_MASK;
|
||||
cal |= ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
/* For external references, the calibration must be determined for the */
|
||||
/* specific application and set explicitly. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Load SINGLE calibrate register with predefined values for a certain
|
||||
* reference.
|
||||
*
|
||||
* @details
|
||||
* During production, calibration values are made and stored in the device
|
||||
* information page for known references. Notice that for external references,
|
||||
* calibration values must be determined explicitly, and this function
|
||||
* will not modify the calibration register.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] ref
|
||||
* Reference to load calibrated values for. No values are loaded for
|
||||
* external references.
|
||||
******************************************************************************/
|
||||
static void ADC_CalibrateLoadSingle(ADC_TypeDef *adc, ADC_Ref_TypeDef ref)
|
||||
{
|
||||
uint32_t cal;
|
||||
|
||||
/* Load proper calibration data depending on selected reference */
|
||||
/* NOTE: We use ...SCAN... defines below, they are the same as */
|
||||
/* similar ...SINGLE... defines. */
|
||||
switch (ref)
|
||||
{
|
||||
case adcRef1V25:
|
||||
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
case adcRef2V5:
|
||||
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
case adcRefVDD:
|
||||
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
case adcRef5VDIFF:
|
||||
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
case adcRef2xVDD:
|
||||
/* Gain value not of relevance for this reference, leave as is */
|
||||
cal = adc->CAL & ~_ADC_CAL_SINGLEOFFSET_MASK;
|
||||
cal |= ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
break;
|
||||
|
||||
/* For external references, the calibration must be determined for the */
|
||||
/* specific application and set explicitly. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize ADC.
|
||||
*
|
||||
* @details
|
||||
* Initializes common parts for both single conversion and scan sequence.
|
||||
* In addition, single and/or scan control configuration must be done, please
|
||||
* refer to ADC_InitSingle() and ADC_InitScan() respectively.
|
||||
*
|
||||
* @note
|
||||
* This function will stop any ongoing conversion.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to ADC initialization structure.
|
||||
******************************************************************************/
|
||||
void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
EFM_ASSERT(ADC_REF_VALID(adc));
|
||||
|
||||
/* Make sure conversion is not in progress */
|
||||
adc->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP;
|
||||
|
||||
tmp = ((uint32_t)(init->ovsRateSel) << _ADC_CTRL_OVSRSEL_SHIFT) |
|
||||
(((uint32_t)(init->timebase) << _ADC_CTRL_TIMEBASE_SHIFT) & _ADC_CTRL_TIMEBASE_MASK) |
|
||||
(((uint32_t)(init->prescale) << _ADC_CTRL_PRESC_SHIFT) & _ADC_CTRL_PRESC_MASK) |
|
||||
((uint32_t)(init->lpfMode) << _ADC_CTRL_LPFMODE_SHIFT) |
|
||||
((uint32_t)(init->warmUpMode) << _ADC_CTRL_WARMUPMODE_SHIFT);
|
||||
|
||||
if (init->tailgate)
|
||||
{
|
||||
tmp |= ADC_CTRL_TAILGATE;
|
||||
}
|
||||
|
||||
adc->CTRL = tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize ADC scan sequence.
|
||||
*
|
||||
* @details
|
||||
* Please refer to ADC_StartScan() for starting scan sequence.
|
||||
*
|
||||
* When selecting an external reference, the gain and offset calibration
|
||||
* must be set explicitly (CAL register). For other references, the
|
||||
* calibration is updated with values defined during manufacturing.
|
||||
*
|
||||
* @note
|
||||
* This function will stop any ongoing scan sequence.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to ADC initialization structure.
|
||||
******************************************************************************/
|
||||
void ADC_InitScan(ADC_TypeDef *adc, const ADC_InitScan_TypeDef *init)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
EFM_ASSERT(ADC_REF_VALID(adc));
|
||||
|
||||
/* Make sure scan sequence is not in progress */
|
||||
adc->CMD = ADC_CMD_SCANSTOP;
|
||||
|
||||
/* Load proper calibration data depending on selected reference */
|
||||
ADC_CalibrateLoadScan(adc, init->reference);
|
||||
|
||||
tmp = ((uint32_t)(init->prsSel) << _ADC_SCANCTRL_PRSSEL_SHIFT) |
|
||||
((uint32_t)(init->acqTime) << _ADC_SCANCTRL_AT_SHIFT) |
|
||||
((uint32_t)(init->reference) << _ADC_SCANCTRL_REF_SHIFT) |
|
||||
init->input |
|
||||
((uint32_t)(init->resolution) << _ADC_SCANCTRL_RES_SHIFT);
|
||||
|
||||
if (init->prsEnable)
|
||||
{
|
||||
tmp |= ADC_SCANCTRL_PRSEN;
|
||||
}
|
||||
|
||||
if (init->leftAdjust)
|
||||
{
|
||||
tmp |= ADC_SCANCTRL_ADJ_LEFT;
|
||||
}
|
||||
|
||||
if (init->diff)
|
||||
{
|
||||
tmp |= ADC_SCANCTRL_DIFF;
|
||||
}
|
||||
|
||||
if (init->rep)
|
||||
{
|
||||
tmp |= ADC_SCANCTRL_REP;
|
||||
}
|
||||
|
||||
adc->SCANCTRL = tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize single ADC sample conversion.
|
||||
*
|
||||
* @details
|
||||
* Please refer to ADC_StartSingle() for starting single conversion.
|
||||
*
|
||||
* When selecting an external reference, the gain and offset calibration
|
||||
* must be set explicitly (CAL register). For other references, the
|
||||
* calibration is updated with values defined during manufacturing.
|
||||
*
|
||||
* @note
|
||||
* This function will stop any ongoing single conversion.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to ADC initialization structure.
|
||||
******************************************************************************/
|
||||
void ADC_InitSingle(ADC_TypeDef *adc, const ADC_InitSingle_TypeDef *init)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
EFM_ASSERT(ADC_REF_VALID(adc));
|
||||
|
||||
/* Make sure single conversion is not in progress */
|
||||
adc->CMD = ADC_CMD_SINGLESTOP;
|
||||
|
||||
/* Load proper calibration data depending on selected reference */
|
||||
ADC_CalibrateLoadSingle(adc, init->reference);
|
||||
|
||||
tmp = ((uint32_t)(init->prsSel) << _ADC_SINGLECTRL_PRSSEL_SHIFT) |
|
||||
((uint32_t)(init->acqTime) << _ADC_SINGLECTRL_AT_SHIFT) |
|
||||
((uint32_t)(init->reference) << _ADC_SINGLECTRL_REF_SHIFT) |
|
||||
((uint32_t)(init->input) << _ADC_SINGLECTRL_INPUTSEL_SHIFT) |
|
||||
((uint32_t)(init->resolution) << _ADC_SINGLECTRL_RES_SHIFT);
|
||||
|
||||
if (init->prsEnable)
|
||||
{
|
||||
tmp |= ADC_SINGLECTRL_PRSEN;
|
||||
}
|
||||
|
||||
if (init->leftAdjust)
|
||||
{
|
||||
tmp |= ADC_SINGLECTRL_ADJ_LEFT;
|
||||
}
|
||||
|
||||
if (init->diff)
|
||||
{
|
||||
tmp |= ADC_SINGLECTRL_DIFF;
|
||||
}
|
||||
|
||||
if (init->rep)
|
||||
{
|
||||
tmp |= ADC_SINGLECTRL_REP;
|
||||
}
|
||||
|
||||
adc->SINGLECTRL = tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Calculate prescaler value used to determine ADC clock.
|
||||
*
|
||||
* @details
|
||||
* The ADC clock is given by: HFPERCLK / (prescale + 1).
|
||||
*
|
||||
* @param[in] adcFreq ADC frequency wanted. The frequency will automatically
|
||||
* be adjusted to be within valid range according to reference manual.
|
||||
*
|
||||
* @param[in] hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to
|
||||
* use currently defined HFPER clock setting.
|
||||
*
|
||||
* @return
|
||||
* Prescaler value to use for ADC in order to achieve a clock value
|
||||
* <= @p adcFreq.
|
||||
******************************************************************************/
|
||||
uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
/* Make sure selected ADC clock is within valid range */
|
||||
if (adcFreq > ADC_MAX_CLOCK)
|
||||
{
|
||||
adcFreq = ADC_MAX_CLOCK;
|
||||
}
|
||||
else if (adcFreq < ADC_MIN_CLOCK)
|
||||
{
|
||||
adcFreq = ADC_MIN_CLOCK;
|
||||
}
|
||||
|
||||
/* Use current HFPER frequency? */
|
||||
if (!hfperFreq)
|
||||
{
|
||||
hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
|
||||
}
|
||||
|
||||
ret = (hfperFreq + adcFreq - 1) / adcFreq;
|
||||
if (ret)
|
||||
{
|
||||
ret--;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset ADC to same state as after a HW reset.
|
||||
*
|
||||
* @note
|
||||
* The ROUTE register is NOT reset by this function, in order to allow for
|
||||
* centralized setup of this feature.
|
||||
*
|
||||
* @param[in] adc
|
||||
* Pointer to ADC peripheral register block.
|
||||
******************************************************************************/
|
||||
void ADC_Reset(ADC_TypeDef *adc)
|
||||
{
|
||||
uint32_t cal;
|
||||
|
||||
/* Stop conversions, before resetting other registers. */
|
||||
adc->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP;
|
||||
adc->SINGLECTRL = _ADC_SINGLECTRL_RESETVALUE;
|
||||
adc->SCANCTRL = _ADC_SCANCTRL_RESETVALUE;
|
||||
adc->CTRL = _ADC_CTRL_RESETVALUE;
|
||||
adc->IEN = _ADC_IEN_RESETVALUE;
|
||||
adc->IFC = _ADC_IFC_MASK;
|
||||
adc->BIASPROG = _ADC_BIASPROG_RESETVALUE;
|
||||
|
||||
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
|
||||
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >>
|
||||
_DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
|
||||
adc->CAL = cal;
|
||||
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Calculate timebase value in order to get a timebase providing at least 1us.
|
||||
*
|
||||
* @param[in] hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to
|
||||
* use currently defined HFPER clock setting.
|
||||
*
|
||||
* @return
|
||||
* Timebase value to use for ADC in order to achieve at least 1 us.
|
||||
******************************************************************************/
|
||||
uint8_t ADC_TimebaseCalc(uint32_t hfperFreq)
|
||||
{
|
||||
if (!hfperFreq)
|
||||
{
|
||||
hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
|
||||
|
||||
/* Just in case, make sure we get non-zero freq for below calculation */
|
||||
if (!hfperFreq)
|
||||
{
|
||||
hfperFreq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine number of HFPERCLK cycle >= 1us */
|
||||
hfperFreq += 999999;
|
||||
hfperFreq /= 1000000;
|
||||
|
||||
/* Return timebase value (N+1 format) */
|
||||
return (uint8_t)(hfperFreq - 1);
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup ADC) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,64 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Assert API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_assert.h"
|
||||
|
||||
#if defined(DEBUG_EFM)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* EFM internal assert handling.
|
||||
*
|
||||
* This function is invoked through EFM_ASSERT() macro usage only, it should
|
||||
* not be used explicitly.
|
||||
*
|
||||
* Currently this implementation only enters an indefinite loop, allowing
|
||||
* the use of a debugger to determine cause of failure. By defining
|
||||
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
|
||||
* of this function must be defined and will be invoked instead, possibly
|
||||
* providing output of assertion location.
|
||||
*
|
||||
* Please notice that this function is not used unless DEBUG_EFM is defined
|
||||
* during preprocessing of EFM_ASSERT() usage.
|
||||
*
|
||||
* @par file
|
||||
* Name of source file where assertion failed.
|
||||
*
|
||||
* @par line
|
||||
* Line number in source file where assertion failed.
|
||||
******************************************************************************/
|
||||
void assertEFM(const char *file, int line)
|
||||
{
|
||||
(void)file; /* Unused parameter */
|
||||
(void)line; /* Unused parameter */
|
||||
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
#endif /* DEBUG_EFM */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,287 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Digital to Analog Coversion (DAC) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_dac.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_assert.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup DAC
|
||||
* @brief Digital to Analog Coversion (DAC) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of DAC channel for assert statements. */
|
||||
#define DAC_CH_VALID(ch) ((ch) <= 1)
|
||||
|
||||
/** Max DAC clock */
|
||||
#define DAC_MAX_CLOCK 1000000
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable DAC channel.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Channel to enable/disable.
|
||||
*
|
||||
* @param[in] enable
|
||||
* true to enable DAC channel, false to disable.
|
||||
******************************************************************************/
|
||||
void DAC_Enable(DAC_TypeDef *dac, unsigned int ch, bool enable)
|
||||
{
|
||||
volatile uint32_t *reg;
|
||||
|
||||
EFM_ASSERT(DAC_REF_VALID(dac));
|
||||
EFM_ASSERT(DAC_CH_VALID(ch));
|
||||
|
||||
if (!ch)
|
||||
{
|
||||
reg = &(dac->CH0CTRL);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg = &(dac->CH1CTRL);
|
||||
}
|
||||
|
||||
BITBAND_Peripheral(reg, _DAC_CH0CTRL_EN_SHIFT, (unsigned int)enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize DAC.
|
||||
*
|
||||
* @details
|
||||
* Initializes common parts for both channels. In addition, channel control
|
||||
* configuration must be done, please refer to DAC_InitChannel().
|
||||
*
|
||||
* @note
|
||||
* This function will disable both channels prior to configuration.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to DAC initialization structure.
|
||||
******************************************************************************/
|
||||
void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
EFM_ASSERT(DAC_REF_VALID(dac));
|
||||
|
||||
/* Make sure both channels are disabled. */
|
||||
BITBAND_Peripheral(&(dac->CH0CTRL), _DAC_CH0CTRL_EN_SHIFT, 0);
|
||||
BITBAND_Peripheral(&(dac->CH1CTRL), _DAC_CH0CTRL_EN_SHIFT, 0);
|
||||
|
||||
/* Load proper calibration data depending on selected reference */
|
||||
switch (init->reference)
|
||||
{
|
||||
case dacRef2V5:
|
||||
dac->CAL = DEVINFO->DAC0CAL1;
|
||||
break;
|
||||
|
||||
case dacRefVDD:
|
||||
dac->CAL = DEVINFO->DAC0CAL2;
|
||||
break;
|
||||
|
||||
default: /* 1.25V */
|
||||
dac->CAL = DEVINFO->DAC0CAL0;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = ((uint32_t)(init->refresh) << _DAC_CTRL_REFRSEL_SHIFT) |
|
||||
(((uint32_t)(init->prescale) << _DAC_CTRL_PRESC_SHIFT) & _DAC_CTRL_PRESC_MASK) |
|
||||
((uint32_t)(init->reference) << _DAC_CTRL_REFSEL_SHIFT) |
|
||||
((uint32_t)(init->outMode) << _DAC_CTRL_OUTMODE_SHIFT) |
|
||||
((uint32_t)(init->convMode) << _DAC_CTRL_CONVMODE_SHIFT);
|
||||
|
||||
if (init->ch0ResetPre)
|
||||
{
|
||||
tmp |= DAC_CTRL_CH0PRESCRST;
|
||||
}
|
||||
|
||||
if (init->outEnablePRS)
|
||||
{
|
||||
tmp |= DAC_CTRL_OUTENPRS;
|
||||
}
|
||||
|
||||
if (init->sineEnable)
|
||||
{
|
||||
tmp |= DAC_CTRL_SINEMODE;
|
||||
}
|
||||
|
||||
if (init->diff)
|
||||
{
|
||||
tmp |= DAC_CTRL_DIFF;
|
||||
}
|
||||
|
||||
dac->CTRL = tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize DAC channel.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to DAC initialization structure.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Channel number to initialize.
|
||||
******************************************************************************/
|
||||
void DAC_InitChannel(DAC_TypeDef *dac,
|
||||
const DAC_InitChannel_TypeDef *init,
|
||||
unsigned int ch)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
EFM_ASSERT(DAC_REF_VALID(dac));
|
||||
EFM_ASSERT(DAC_CH_VALID(ch));
|
||||
|
||||
tmp = (uint32_t)(init->prsSel) << _DAC_CH0CTRL_PRSSEL_SHIFT;
|
||||
|
||||
if (init->enable)
|
||||
{
|
||||
tmp |= DAC_CH0CTRL_EN;
|
||||
}
|
||||
|
||||
if (init->prsEnable)
|
||||
{
|
||||
tmp |= DAC_CH0CTRL_PRSEN;
|
||||
}
|
||||
|
||||
if (init->refreshEnable)
|
||||
{
|
||||
tmp |= DAC_CH0CTRL_REFREN;
|
||||
}
|
||||
|
||||
if (ch)
|
||||
{
|
||||
dac->CH1CTRL = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
dac->CH0CTRL = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Calculate prescaler value used to determine DAC clock.
|
||||
*
|
||||
* @details
|
||||
* The DAC clock is given by: HFPERCLK / (prescale ^ 2).
|
||||
*
|
||||
* @param[in] dacFreq DAC frequency wanted. The frequency will automatically
|
||||
* be adjusted to be below max allowed DAC clock.
|
||||
*
|
||||
* @param[in] hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to
|
||||
* use currently defined HFPER clock setting.
|
||||
*
|
||||
* @return
|
||||
* Prescaler value to use for DAC in order to achieve a clock value
|
||||
* <= @p dacFreq.
|
||||
******************************************************************************/
|
||||
uint8_t DAC_PrescaleCalc(uint32_t dacFreq, uint32_t hfperFreq)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
/* Make sure selected DAC clock is below max value */
|
||||
if (dacFreq > DAC_MAX_CLOCK)
|
||||
{
|
||||
dacFreq = DAC_MAX_CLOCK;
|
||||
}
|
||||
|
||||
/* Use current HFPER frequency? */
|
||||
if (!hfperFreq)
|
||||
{
|
||||
hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
|
||||
}
|
||||
|
||||
/* Iterate in order to determine best prescale value. Only a few possible */
|
||||
/* values. We start with lowest prescaler value in order to get first */
|
||||
/* equal or below wanted DAC frequency value. */
|
||||
for (ret = 0; ret <= (_DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT); ret++)
|
||||
{
|
||||
if ((hfperFreq >> ret) <= dacFreq)
|
||||
break;
|
||||
}
|
||||
|
||||
return((uint8_t)ret);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset DAC to same state as after a HW reset.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to ADC peripheral register block.
|
||||
******************************************************************************/
|
||||
void DAC_Reset(DAC_TypeDef *dac)
|
||||
{
|
||||
/* Disable channels, before resetting other registers. */
|
||||
dac->CH0CTRL = _DAC_CH0CTRL_RESETVALUE;
|
||||
dac->CH1CTRL = _DAC_CH1CTRL_RESETVALUE;
|
||||
dac->CTRL = _DAC_CTRL_RESETVALUE;
|
||||
dac->IEN = _DAC_IEN_RESETVALUE;
|
||||
dac->IFC = _DAC_IFC_MASK;
|
||||
dac->CAL = DEVINFO->DAC0CAL0;
|
||||
dac->BIASPROG = _DAC_BIASPROG_RESETVALUE;
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup DAC) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,109 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Debug (DBG) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_assert.h"
|
||||
#include "efm32_dbg.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_gpio.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup DBG
|
||||
* @brief Debug (DBG) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable Serial Wire Output (SWO) pin.
|
||||
*
|
||||
* @details
|
||||
* The SWO pin (sometimes denoted SWV, serial wire viewer) allows for
|
||||
* miscellaneous output to be passed from the Cortex-M3 debug trace module to
|
||||
* an external debug probe. By default, the debug trace module and pin output
|
||||
* may be disabled.
|
||||
*
|
||||
* Since the SWO pin is only useful when using a debugger, a suggested use
|
||||
* of this function during startup may be:
|
||||
* @verbatim
|
||||
* if (DBG_Connected())
|
||||
* {
|
||||
* DBG_SWOEnable(1);
|
||||
* }
|
||||
* @endverbatim
|
||||
* By checking if debugger is attached, some setup leading to higher energy
|
||||
* consumption when debugger is attached, can be avoided when not using
|
||||
* a debugger.
|
||||
*
|
||||
* Another alternative may be to set the debugger tool chain to configure
|
||||
* the required setup (similar to the content of this function) by some
|
||||
* sort of toolchain scripting during its attach/reset procedure. In that
|
||||
* case, the above suggested code for enabling the SWO pin is not required
|
||||
* in the application.
|
||||
*
|
||||
* @param[in] location
|
||||
* Pin location used for SWO pin on the application in use.
|
||||
******************************************************************************/
|
||||
void DBG_SWOEnable(unsigned int location)
|
||||
{
|
||||
int port;
|
||||
int pin;
|
||||
|
||||
EFM_ASSERT(location < AFCHANLOC_MAX);
|
||||
|
||||
port = AF_DBG_SWO_PORT(location);
|
||||
pin = AF_DBG_SWO_PIN(location);
|
||||
|
||||
/* Port/pin location not defined for device? */
|
||||
if ((pin < 0) || (port < 0))
|
||||
{
|
||||
EFM_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure auxiliary clock going to the Cortex debug trace module is enabled */
|
||||
CMU_OscillatorEnable(cmuOsc_AUXHFRCO, true, false);
|
||||
|
||||
/* Set selected pin location for SWO pin and enable it */
|
||||
GPIO_DbgLocationSet(location);
|
||||
GPIO_DbgSWOEnable(true);
|
||||
|
||||
/* Configure SWO pin for output */
|
||||
GPIO_PinModeSet((GPIO_Port_TypeDef)port, pin, gpioModePushPull, 0);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup DBG) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,499 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Energy Management Unit (EMU) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_emu.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EMU
|
||||
* @brief Energy Management Unit (EMU) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/* Consistency check, since restoring assumes similar bitpositions in */
|
||||
/* CMU OSCENCMD and STATUS regs */
|
||||
#if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
|
||||
#error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
|
||||
#endif
|
||||
#if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
|
||||
#error Conflict in HFXOENS and HFXOEN bitpositions
|
||||
#endif
|
||||
#if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
|
||||
#error Conflict in LFRCOENS and LFRCOEN bitpositions
|
||||
#endif
|
||||
#if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
|
||||
#error Conflict in LFXOENS and LFXOEN bitpositions
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
/**
|
||||
* CMU configured oscillator selection and oscillator enable status. When a
|
||||
* user configures oscillators, this varaiable shall shadow the configuration.
|
||||
* It is used by the EMU module in order to be able to restore the oscillator
|
||||
* config after having been in certain energy modes (since HW may automatically
|
||||
* alter config when going into an energy mode). It is the responsibility of
|
||||
* the CMU module to keep it up-to-date (or a user if not using the CMU API
|
||||
* for oscillator control).
|
||||
*/
|
||||
static uint16_t cmuStatus;
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL FUNCTIONS ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Restore oscillators and core clock after having been in EM2 or EM3.
|
||||
******************************************************************************/
|
||||
static void EMU_Restore(void)
|
||||
{
|
||||
uint32_t cmuLocked;
|
||||
|
||||
/* Although we could use the CMU API for most of the below handling, we */
|
||||
/* would like this function to be as efficient as possible. */
|
||||
|
||||
/* CMU registers may be locked */
|
||||
cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
|
||||
CMU_Unlock();
|
||||
|
||||
/* AUXHFRCO was automatically disabled (except if using debugger). */
|
||||
/* HFXO was automatically disabled. */
|
||||
/* LFRCO/LFXO were possibly disabled by SW in EM3. */
|
||||
/* Restore according to status prior to entering EM. */
|
||||
CMU->OSCENCMD = cmuStatus & (CMU_STATUS_AUXHFRCOENS |
|
||||
CMU_STATUS_HFXOENS |
|
||||
CMU_STATUS_LFRCOENS |
|
||||
CMU_STATUS_LFXOENS);
|
||||
|
||||
/* Restore oscillator used for clocking core */
|
||||
switch (cmuStatus & (CMU_STATUS_HFXOSEL | CMU_STATUS_HFRCOSEL |
|
||||
CMU_STATUS_LFXOSEL | CMU_STATUS_LFRCOSEL))
|
||||
{
|
||||
case CMU_STATUS_LFRCOSEL:
|
||||
/* Wait for LFRCO to stabilize */
|
||||
while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
|
||||
;
|
||||
CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
|
||||
break;
|
||||
|
||||
case CMU_STATUS_LFXOSEL:
|
||||
/* Wait for LFXO to stabilize */
|
||||
while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
|
||||
;
|
||||
CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
|
||||
break;
|
||||
|
||||
case CMU_STATUS_HFXOSEL:
|
||||
/* Wait for HFXO to stabilize */
|
||||
while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
|
||||
;
|
||||
CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
|
||||
break;
|
||||
|
||||
default: /* CMU_STATUS_HFRCOSEL */
|
||||
/* If core clock was HFRCO core clock, it is automatically restored to */
|
||||
/* state prior to entering energy mode. No need for further action. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* If HFRCO was disabled before entering Energy Mode, turn it off again */
|
||||
/* as it is automatically enabled by wake up */
|
||||
if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
|
||||
{
|
||||
CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
|
||||
}
|
||||
|
||||
/* Restore CMU register locking */
|
||||
if (cmuLocked)
|
||||
{
|
||||
CMU_Lock();
|
||||
}
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enter energy mode 2 (EM2).
|
||||
*
|
||||
* @details
|
||||
* When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
|
||||
* and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
|
||||
* EM0, HFRCO is re-enabled and the core will be clocked by the configured
|
||||
* HFRCO band. This ensures a quick wakeup from EM2.
|
||||
*
|
||||
* However, prior to entering EM2, the core may have been using another
|
||||
* oscillator than HFRCO. The @p restore parameter gives the user the option
|
||||
* to restore all HF oscillators according to state prior to entering EM2,
|
||||
* as well as the clock used to clock the core. This restore procedure is
|
||||
* handled by SW. However, since handled by SW, it will not be restored
|
||||
* before completing the interrupt function(s) waking up the core!
|
||||
*
|
||||
* @note
|
||||
* If restoring core clock to use the HFXO oscillator, which has been
|
||||
* disabled during EM2 mode, this function will stall until the oscillator
|
||||
* has stabilized. Stalling time can be reduced by adding interrupt
|
||||
* support detecting stable oscillator, and an asynchronous switch to the
|
||||
* original oscillator. See CMU documentation. Such a feature is however
|
||||
* outside the scope of the implementation in this function.
|
||||
* @par
|
||||
* If HFXO is re-enabled by this function, and NOT used to clock the core,
|
||||
* this function will not wait for HFXO to stabilize. This must be considered
|
||||
* by the application if trying to use features relying on that oscillator
|
||||
* upon return.
|
||||
* @par
|
||||
* If a debugger is attached, the AUXHFRCO will not be disabled if enabled
|
||||
* upon entering EM2. It will thus remain enabled when returning to EM0
|
||||
* regardless of the @p restore parameter.
|
||||
*
|
||||
* @param[in] restore
|
||||
* @li true - restore oscillators and clocks, see function details.
|
||||
* @li false - do not restore oscillators and clocks, see function details.
|
||||
* @par
|
||||
* The @p restore option should only be used if all clock control is done
|
||||
* via the CMU API.
|
||||
******************************************************************************/
|
||||
void EMU_EnterEM2(bool restore)
|
||||
{
|
||||
/* Auto-update CMU status just in case before entering energy mode. */
|
||||
/* This variable is normally kept up-to-date by the CMU API. */
|
||||
cmuStatus = (uint16_t)(CMU->STATUS);
|
||||
|
||||
/* Enter Cortex-M3 deep sleep mode */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
__WFI();
|
||||
|
||||
/* Restore oscillators/clocks if specified */
|
||||
if (restore)
|
||||
{
|
||||
EMU_Restore();
|
||||
}
|
||||
/* If not restoring, and original clock was not HFRCO, we have to */
|
||||
/* update CMSIS core clock variable since core clock has changed */
|
||||
/* to using HFRCO. */
|
||||
else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enter energy mode 3 (EM3).
|
||||
*
|
||||
* @details
|
||||
* When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
|
||||
* HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
|
||||
* the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
|
||||
* re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
|
||||
* configured HFRCO band. This ensures a quick wakeup from EM3.
|
||||
*
|
||||
* However, prior to entering EM3, the core may have been using another
|
||||
* oscillator than HFRCO. The @p restore parameter gives the user the option
|
||||
* to restore all HF/LF oscillators according to state prior to entering EM3,
|
||||
* as well as the clock used to clock the core. This restore procedure is
|
||||
* handled by SW. However, since handled by SW, it will not be restored
|
||||
* before completing the interrupt function(s) waking up the core!
|
||||
*
|
||||
* @note
|
||||
* If restoring core clock to use an oscillator other than HFRCO, this
|
||||
* function will stall until the oscillator has stabilized. Stalling time
|
||||
* can be reduced by adding interrupt support detecting stable oscillator,
|
||||
* and an asynchronous switch to the original oscillator. See CMU
|
||||
* documentation. Such a feature is however outside the scope of the
|
||||
* implementation in this function.
|
||||
* @par
|
||||
* If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
|
||||
* the core, this function will not wait for those oscillators to stabilize.
|
||||
* This must be considered by the application if trying to use features
|
||||
* relying on those oscillators upon return.
|
||||
* @par
|
||||
* If a debugger is attached, the AUXHFRCO will not be disabled if enabled
|
||||
* upon entering EM3. It will thus remain enabled when returning to EM0
|
||||
* regardless of the @p restore parameter.
|
||||
*
|
||||
* @param[in] restore
|
||||
* @li true - restore oscillators and clocks, see function details.
|
||||
* @li false - do not restore oscillators and clocks, see function details.
|
||||
* @par
|
||||
* The @p restore option should only be used if all clock control is done
|
||||
* via the CMU API.
|
||||
******************************************************************************/
|
||||
void EMU_EnterEM3(bool restore)
|
||||
{
|
||||
uint32_t cmuLocked;
|
||||
|
||||
/* Auto-update CMU status just in case before entering energy mode. */
|
||||
/* This variable is normally kept up-to-date by the CMU API. */
|
||||
cmuStatus = (uint16_t)(CMU->STATUS);
|
||||
|
||||
/* CMU registers may be locked */
|
||||
cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
|
||||
CMU_Unlock();
|
||||
|
||||
/* Disable LF oscillators */
|
||||
CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
|
||||
|
||||
/* Restore CMU register locking */
|
||||
if (cmuLocked)
|
||||
{
|
||||
CMU_Lock();
|
||||
}
|
||||
|
||||
/* Enter Cortex-M3 deep sleep mode */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
__WFI();
|
||||
|
||||
/* Restore oscillators/clocks if specified */
|
||||
if (restore)
|
||||
{
|
||||
EMU_Restore();
|
||||
}
|
||||
/* If not restoring, and original clock was not HFRCO, we have to */
|
||||
/* update CMSIS core clock variable since core clock has changed */
|
||||
/* to using HFRCO. */
|
||||
else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enter energy mode 4 (EM4).
|
||||
*
|
||||
* @note
|
||||
* Only a power on reset or external reset pin can wake the device from EM4.
|
||||
******************************************************************************/
|
||||
void EMU_EnterEM4(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Make sure register write lock is disabled */
|
||||
EMU->LOCK = EMU_LOCK_LOCKKEY_UNLOCK;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
|
||||
EMU->CTRL = (3 << _EMU_CTRL_EM4CTRL_SHIFT);
|
||||
}
|
||||
EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Power down memory block.
|
||||
*
|
||||
* @param[in] blocks
|
||||
* Specifies a logical OR of bits indicating memory blocks to power down.
|
||||
* Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
|
||||
* be disabled. Please refer to the EFM32 reference manual for available
|
||||
* memory blocks for a device.
|
||||
*
|
||||
* @note
|
||||
* Only a reset can make the specified memory block(s) available for use
|
||||
* after having been powered down. Function will be void for devices not
|
||||
* supporting this feature.
|
||||
******************************************************************************/
|
||||
void EMU_MemPwrDown(uint32_t blocks)
|
||||
{
|
||||
#if defined(_EMU_MEMCTRL_RESETVALUE)
|
||||
EFM_ASSERT(blocks <= _EMU_MEMCTRL_MASK);
|
||||
|
||||
EMU->MEMCTRL = blocks;
|
||||
#else
|
||||
(void)blocks;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Update EMU module with CMU oscillator selection/enable status.
|
||||
*
|
||||
* @details
|
||||
* When entering EM2 and EM3, the HW may change the core clock oscillator
|
||||
* used, as well as disabling some oscillators. The user may optionally select
|
||||
* to restore the oscillators after waking up from EM2 and EM3 through the
|
||||
* SW API.
|
||||
*
|
||||
* However, in order to support this in a safe way, the EMU module must
|
||||
* be kept up-to-date on the actual selected configuration. The CMU
|
||||
* module must keep the EMU module up-to-date.
|
||||
*
|
||||
* This function is mainly intended for internal use by the CMU module,
|
||||
* but if the applications changes oscillator configurations without
|
||||
* using the CMU API, this function can be used to keep the EMU module
|
||||
* up-to-date.
|
||||
******************************************************************************/
|
||||
void EMU_UpdateOscConfig(void)
|
||||
{
|
||||
/* Fetch current configuration */
|
||||
cmuStatus = (uint16_t)(CMU->STATUS);
|
||||
}
|
||||
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Update EMU module with Energy Mode 4 configuration
|
||||
*
|
||||
* @param[in] em4init
|
||||
* Energy Mode 4 configuration structure
|
||||
******************************************************************************/
|
||||
void EMU_EM4Init(EMU_EM4Init_TypeDef *em4init)
|
||||
{
|
||||
uint32_t em4conf = EMU->EM4CONF;
|
||||
|
||||
/* Clear fields that will be reconfigured */
|
||||
em4conf &= ~(
|
||||
_EMU_EM4CONF_LOCKCONF_MASK|
|
||||
_EMU_EM4CONF_OSC_MASK|
|
||||
_EMU_EM4CONF_BURTCWU_MASK|
|
||||
_EMU_EM4CONF_VREGEN_MASK);
|
||||
|
||||
/* Configure new settings */
|
||||
em4conf |= (
|
||||
(em4init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)|
|
||||
(em4init->osc)|
|
||||
(em4init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)|
|
||||
(em4init->vreg << _EMU_EM4CONF_VREGEN_SHIFT));
|
||||
|
||||
/* Apply configuration. Note that lock can be set after this stage. */
|
||||
EMU->EM4CONF = em4conf;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure BackUp Power Domain settings
|
||||
*
|
||||
* @note
|
||||
* stig note to self: Touches RMU->CTRL BUPD?
|
||||
*
|
||||
* @param[in] bupdInit
|
||||
* Backup power domain initialization structure
|
||||
******************************************************************************/
|
||||
void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
EFM_ASSERT(bupdInit->inactiveThresRange < 4);
|
||||
EFM_ASSERT(bupdInit->inactiveThreshold < 4);
|
||||
EFM_ASSERT(bupdInit->activeThresRange < 4);
|
||||
EFM_ASSERT(bupdInit->activeThreshold < 4);
|
||||
|
||||
/* Set power connection configuration */
|
||||
reg = EMU->PWRCONF & ~(
|
||||
_EMU_PWRCONF_PWRRES_MASK|
|
||||
_EMU_PWRCONF_VOUTSTRONG_MASK|
|
||||
_EMU_PWRCONF_VOUTMED_MASK|
|
||||
_EMU_PWRCONF_VOUTWEAK_MASK);
|
||||
|
||||
reg |= (bupdInit->resistor|
|
||||
(bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
|
||||
(bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)|
|
||||
(bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT));
|
||||
|
||||
EMU->PWRCONF = reg;
|
||||
|
||||
/* Set backup domain inactive mode configuration */
|
||||
reg = EMU->BUINACT & ~(
|
||||
_EMU_BUINACT_PWRCON_MASK|
|
||||
_EMU_BUINACT_BUENRANGE_MASK|
|
||||
_EMU_BUINACT_BUENTHRES_MASK);
|
||||
|
||||
reg |= (bupdInit->inactivePower|
|
||||
(bupdInit->inactiveThresRange << _EMU_BUINACT_BUENRANGE_SHIFT)|
|
||||
(bupdInit->inactiveThreshold << _EMU_BUINACT_BUENTHRES_SHIFT));
|
||||
|
||||
EMU->BUINACT = reg;
|
||||
|
||||
/* Set backup domain active mode configuration */
|
||||
reg = EMU->BUACT & ~(
|
||||
_EMU_BUACT_PWRCON_MASK|
|
||||
_EMU_BUACT_BUEXRANGE_MASK|
|
||||
_EMU_BUACT_BUEXTHRES_MASK);
|
||||
|
||||
reg |= (bupdInit->activePower|
|
||||
(bupdInit->activeThresRange << _EMU_BUACT_BUEXRANGE_SHIFT)|
|
||||
(bupdInit->activeThreshold << _EMU_BUACT_BUEXTHRES_SHIFT));
|
||||
|
||||
EMU->BUACT = reg;
|
||||
|
||||
/* Set power control configuration */
|
||||
reg = EMU->BUCTRL & ~(
|
||||
_EMU_BUCTRL_PROBE_MASK|
|
||||
_EMU_BUCTRL_BODCAL_MASK|
|
||||
_EMU_BUCTRL_STATEN_MASK|
|
||||
_EMU_BUCTRL_EN_MASK);
|
||||
|
||||
/* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
|
||||
release reset */
|
||||
reg |= (bupdInit->probe|
|
||||
(bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)|
|
||||
(bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
|
||||
(bupdInit->enable << _EMU_BUCTRL_EN_SHIFT));
|
||||
|
||||
/* Enable configuration */
|
||||
EMU->BUCTRL = reg;
|
||||
|
||||
/* If enable is true, enable BU_VIN input power pin, if not disable it */
|
||||
EMU_BUPinEnable(bupdInit->enable);
|
||||
|
||||
/* If enable is true, release BU reset, if not keep reset asserted */
|
||||
BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/** @} (end addtogroup EMU) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,487 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief General Purpose IO (GPIO) peripheral API for EFM32
|
||||
* devices.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_gpio.h"
|
||||
#include "efm32_bitband.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup GPIO
|
||||
* @brief General Purpose Input/Output (GPIO) API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of pin typically usable in assert statements. */
|
||||
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
|
||||
|
||||
/** Validation of pin typically usable in assert statements. */
|
||||
#define GPIO_PIN_VALID(pin) ((pin) < 16)
|
||||
|
||||
/** Validation of port typically usable in assert statements. */
|
||||
#define GPIO_PORT_VALID(port) ((port) <= gpioPortF)
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets the pin location of the debug pins (Serial Wire interface).
|
||||
*
|
||||
* @note
|
||||
* Changing the pins used for debugging uncontrolled, may result in a lockout.
|
||||
*
|
||||
* @param[in] location
|
||||
* The debug pin location to use (0-3).
|
||||
******************************************************************************/
|
||||
void GPIO_DbgLocationSet(unsigned int location)
|
||||
{
|
||||
EFM_ASSERT(location < AFCHANLOC_MAX);
|
||||
|
||||
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK) |
|
||||
(location << _GPIO_ROUTE_SWLOCATION_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets the drive mode for a GPIO port.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] mode
|
||||
* Drive mode to use for port.
|
||||
******************************************************************************/
|
||||
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
|
||||
|
||||
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
|
||||
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure GPIO interrupt.
|
||||
*
|
||||
* @details
|
||||
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
|
||||
* recommended to disable it first, see GPIO_Disable().
|
||||
*
|
||||
* The actual GPIO interrupt handler must be in place before enabling the
|
||||
* interrupt.
|
||||
*
|
||||
* Notice that any pending interrupt for the selected pin is cleared by this
|
||||
* function.
|
||||
*
|
||||
* @note
|
||||
* A certain pin number can only be associated with one port. Ie, if GPIO
|
||||
* interrupt 1 is assigned to port A/pin 1, then it is not possibly to use
|
||||
* pin 1 from any other ports for interrupts. Please refer to the reference
|
||||
* manual.
|
||||
*
|
||||
* @param[in] port
|
||||
* The port to associate with @p pin.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The GPIO interrupt number (= port pin).
|
||||
*
|
||||
* @param[in] risingEdge
|
||||
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
|
||||
*
|
||||
* @param[in] fallingEdge
|
||||
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
|
||||
*
|
||||
* @param[in] enable
|
||||
* Set to true if interrupt shall be enabled after configuration completed,
|
||||
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
|
||||
******************************************************************************/
|
||||
void GPIO_IntConfig(GPIO_Port_TypeDef port,
|
||||
unsigned int pin,
|
||||
bool risingEdge,
|
||||
bool fallingEdge,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
|
||||
|
||||
/* There are two registers controlling the interrupt configuration:
|
||||
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
|
||||
* pins 8-15. */
|
||||
if (pin < 8)
|
||||
{
|
||||
GPIO->EXTIPSELL = (GPIO->EXTIPSELL & ~(0xF << (4 * pin))) |
|
||||
(port << (4 * pin));
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = pin - 8;
|
||||
GPIO->EXTIPSELH = (GPIO->EXTIPSELH & ~(0xF << (4 * tmp))) |
|
||||
(port << (4 * tmp));
|
||||
}
|
||||
|
||||
/* Enable/disable rising edge */
|
||||
BITBAND_Peripheral(&(GPIO->EXTIRISE), pin, (unsigned int)risingEdge);
|
||||
|
||||
/* Enable/disable falling edge */
|
||||
BITBAND_Peripheral(&(GPIO->EXTIFALL), pin, (unsigned int)fallingEdge);
|
||||
|
||||
/* Clear any pending interrupt */
|
||||
GPIO->IFC = 1 << pin;
|
||||
|
||||
/* Finally enable/disable interrupt */
|
||||
BITBAND_Peripheral(&(GPIO->IEN), pin, (unsigned int)enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the pad value for a single pin in a GPIO port.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin number to read.
|
||||
*
|
||||
* @return
|
||||
* The pin value, 0 or 1.
|
||||
******************************************************************************/
|
||||
unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
|
||||
|
||||
return((unsigned int)((GPIO->P[port].DIN >> pin) & 0x1));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set the mode for a GPIO pin.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin number in the port.
|
||||
*
|
||||
* @param[in] mode
|
||||
* The desired pin mode.
|
||||
*
|
||||
* @param[in] out
|
||||
* Value to set for pin in DOUT register. The DOUT setting is important for
|
||||
* even some input mode configurations, determining pull-up/down direction.
|
||||
* Notice that this parameter is not used if disabling a pin, leaving the
|
||||
* corresponding DOUT bit unchanged.
|
||||
******************************************************************************/
|
||||
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
|
||||
unsigned int pin,
|
||||
GPIO_Mode_TypeDef mode,
|
||||
unsigned int out)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
|
||||
|
||||
/* If disabling pin, do not modify DOUT in order to reduce chance for */
|
||||
/* glitch/spike (may not be sufficient precaution in all use cases) */
|
||||
if (mode != gpioModeDisabled)
|
||||
{
|
||||
if (out)
|
||||
{
|
||||
GPIO->P[port].DOUTSET = 1 << pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO->P[port].DOUTCLR = 1 << pin;
|
||||
}
|
||||
}
|
||||
|
||||
/* There are two registers controlling the pins for each port. The MODEL
|
||||
* register controls pins 0-7 and MODEH controls pins 8-15. */
|
||||
if (pin < 8)
|
||||
{
|
||||
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xF << (pin * 4))) |
|
||||
(mode << (pin * 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xF << ((pin - 8) * 4))) |
|
||||
(mode << ((pin - 8) * 4));
|
||||
}
|
||||
|
||||
if (mode == gpioModeDisabled)
|
||||
{
|
||||
if (out)
|
||||
{
|
||||
GPIO->P[port].DOUTSET = 1 << pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO->P[port].DOUTCLR = 1 << pin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set a single pin in GPIO data out port register to 0.
|
||||
*
|
||||
* @note
|
||||
* In order for the setting to take effect on the output pad, the pin must
|
||||
* have been configured properly. If not, it will take effect whenever the
|
||||
* pin has been properly configured.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin to set.
|
||||
******************************************************************************/
|
||||
void GPIO_PinOutClear(GPIO_Port_TypeDef port, unsigned int pin)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
|
||||
|
||||
GPIO->P[port].DOUTCLR = 1 << pin;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current setting for a pin in a GPIO port data out register.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin to get setting for.
|
||||
*
|
||||
* @return
|
||||
* The DOUT setting for the requested pin, 0 or 1.
|
||||
******************************************************************************/
|
||||
unsigned int GPIO_PinOutGet(GPIO_Port_TypeDef port, unsigned int pin)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
|
||||
|
||||
return((unsigned int)((GPIO->P[port].DOUT >> pin) & 0x1));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set a single pin in GPIO data out register to 1.
|
||||
*
|
||||
* @note
|
||||
* In order for the setting to take effect on the output pad, the pin must
|
||||
* have been configured properly. If not, it will take effect whenever the
|
||||
* pin has been properly configured.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin to set.
|
||||
******************************************************************************/
|
||||
void GPIO_PinOutSet(GPIO_Port_TypeDef port, unsigned int pin)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
|
||||
|
||||
GPIO->P[port].DOUTSET = 1 << pin;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Toggle a single pin in GPIO port data out register.
|
||||
*
|
||||
* @note
|
||||
* In order for the setting to take effect on the output pad, the pin must
|
||||
* have been configured properly. If not, it will take effect whenever the
|
||||
* pin has been properly configured.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin to toggle.
|
||||
******************************************************************************/
|
||||
void GPIO_PinOutToggle(GPIO_Port_TypeDef port, unsigned int pin)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
|
||||
|
||||
GPIO->P[port].DOUTTGL = 1 << pin;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the pad values for GPIO port.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
******************************************************************************/
|
||||
uint32_t GPIO_PortInGet(GPIO_Port_TypeDef port)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port));
|
||||
|
||||
return(GPIO->P[port].DIN & _GPIO_P_DIN_DIN_MASK);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set bits in DOUT register for a port to 0.
|
||||
*
|
||||
* @note
|
||||
* In order for the setting to take effect on the output pad, the pin must
|
||||
* have been configured properly. If not, it will take effect whenever the
|
||||
* pin has been properly configured.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pins
|
||||
* Bit mask for bits to clear in DOUT register.
|
||||
******************************************************************************/
|
||||
void GPIO_PortOutClear(GPIO_Port_TypeDef port, uint32_t pins)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port));
|
||||
|
||||
GPIO->P[port].DOUTCLR = pins & _GPIO_P_DOUTCLR_DOUTCLR_MASK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current setting for a GPIO port data out register.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @return
|
||||
* The data out setting for the requested port.
|
||||
******************************************************************************/
|
||||
uint32_t GPIO_PortOutGet(GPIO_Port_TypeDef port)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port));
|
||||
|
||||
return(GPIO->P[port].DOUT & _GPIO_P_DOUT_DOUT_MASK);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set bits GPIO data out register to 1.
|
||||
*
|
||||
* @note
|
||||
* In order for the setting to take effect on the respective output pads, the
|
||||
* pins must have been configured properly. If not, it will take effect
|
||||
* whenever the pin has been properly configured.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pins
|
||||
* Bit mask for bits to set to 1 in DOUT register.
|
||||
******************************************************************************/
|
||||
void GPIO_PortOutSet(GPIO_Port_TypeDef port, uint32_t pins)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port));
|
||||
|
||||
GPIO->P[port].DOUTSET = pins & _GPIO_P_DOUTSET_DOUTSET_MASK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set GPIO port data out register.
|
||||
*
|
||||
* @note
|
||||
* In order for the setting to take effect on the respective output pads, the
|
||||
* pins must have been configured properly. If not, it will take effect
|
||||
* whenever the pin has been properly configured.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] val
|
||||
* Value to write to port data out register.
|
||||
*
|
||||
* @param[in] mask
|
||||
* Mask indicating which bits to modify.
|
||||
******************************************************************************/
|
||||
void GPIO_PortOutSetVal(GPIO_Port_TypeDef port, uint32_t val, uint32_t mask)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port));
|
||||
|
||||
GPIO->P[port].DOUT = (GPIO->P[port].DOUT & ~mask) | (val & mask);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Toggle a single pin in GPIO port data out register.
|
||||
*
|
||||
* @note
|
||||
* In order for the setting to take effect on the output pad, the pin must
|
||||
* have been configured properly. If not, it will take effect whenever the
|
||||
* pin has been properly configured.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pins
|
||||
* Bitmask with pins to toggle.
|
||||
******************************************************************************/
|
||||
void GPIO_PortOutToggle(GPIO_Port_TypeDef port, uint32_t pins)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port));
|
||||
|
||||
GPIO->P[port].DOUTTGL = pins & _GPIO_P_DOUTTGL_DOUTTGL_MASK;
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup GPIO) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,789 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Inter-integrated Circuit (I2C) Peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32.h"
|
||||
#include "efm32_i2c.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_bitband.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup I2C
|
||||
* @brief Inter-integrated Circuit (I2C) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of I2C register block pointer reference for assert statements. */
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
#define I2C_REF_VALID(ref) ((ref) == I2C0)
|
||||
#endif
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
#define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1))
|
||||
#endif
|
||||
|
||||
/** Error flags indicating I2C transfer has failed somehow. */
|
||||
/* Notice that I2C_IF_TXOF (transmit overflow) is not really possible with */
|
||||
/* this SW supporting master mode. Likewise for I2C_IF_RXUF (receive underflow) */
|
||||
/* RXUF is only likely to occur with this SW if using a debugger peeking into */
|
||||
/* RXDATA register. Thus, we ignore those types of fault. */
|
||||
#define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST)
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Master mode transfer states. */
|
||||
typedef enum
|
||||
{
|
||||
i2cStateStartAddrSend, /**< Send start + (first part of) address. */
|
||||
i2cStateAddrWFAckNack, /**< Wait for ACK/NACK on (first part of) address. */
|
||||
i2cStateAddrWF2ndAckNack, /**< Wait for ACK/NACK on second part of 10 bit address. */
|
||||
i2cStateRStartAddrSend, /**< Send repeated start + (first part of) address. */
|
||||
i2cStateRAddrWFAckNack, /**< Wait for ACK/NACK on address sent after repeated start. */
|
||||
i2cStateDataSend, /**< Send data. */
|
||||
i2cStateDataWFAckNack, /**< Wait for ACK/NACK on data sent. */
|
||||
i2cStateWFData, /**< Wait for data. */
|
||||
i2cStateWFStopSent, /**< Wait for STOP to have been transmitted. */
|
||||
i2cStateDone /**< Transfer completed successfully. */
|
||||
} I2C_TransferState_TypeDef;
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Structure used to store state information on an ongoing master mode transfer. */
|
||||
typedef struct
|
||||
{
|
||||
/** Current state. */
|
||||
I2C_TransferState_TypeDef state;
|
||||
|
||||
/** Result return code. */
|
||||
I2C_TransferReturn_TypeDef result;
|
||||
|
||||
/** Offset in current sequence buffer. */
|
||||
uint16_t offset;
|
||||
|
||||
/* Index to current sequence buffer in use. */
|
||||
uint8_t bufIndx;
|
||||
|
||||
/** Reference to I2C transfer sequence definition provided by user. */
|
||||
I2C_TransferSeq_TypeDef *seq;
|
||||
} I2C_Transfer_TypeDef;
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** LOCAL DATA *******^**************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/**
|
||||
* Lookup table for Nlow + Nhigh setting defined by CLHR. Set undefined
|
||||
* index (0x3) to reflect default setting just in case.
|
||||
*/
|
||||
static const uint8_t i2cNSum[] = { 4 + 4, 6 + 3, 11 + 3, 4 + 4 };
|
||||
|
||||
/** Transfer state info for ongoing master mode transfer */
|
||||
static I2C_Transfer_TypeDef i2cTransfer[I2C_COUNT];
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current configured I2C bus frequency.
|
||||
*
|
||||
* @details
|
||||
* This frequency is only of relevance when acting as master.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current I2C frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c)
|
||||
{
|
||||
uint32_t hfperclk;
|
||||
uint32_t n;
|
||||
|
||||
/* Max frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4) */
|
||||
hfperclk = CMU_ClockFreqGet(cmuClock_HFPER);
|
||||
n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
|
||||
|
||||
return(hfperclk / ((n * (i2c->CLKDIV + 1)) + 4));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set I2C bus frequency.
|
||||
*
|
||||
* @details
|
||||
* The bus frequency is only of relevance when acting as a master. The bus
|
||||
* frequency should not be set higher than the max frequency accepted by the
|
||||
* slowest device on the bus.
|
||||
*
|
||||
* Notice that due to asymmetric requirements on low and high I2C clock
|
||||
* cycles by the I2C specification, the actual max frequency allowed in order
|
||||
* to comply with the specification may be somewhat lower than expected.
|
||||
*
|
||||
* Please refer to the reference manual, details on I2C clock generation,
|
||||
* for max allowed theoretical frequencies for different modes.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] refFreq
|
||||
* I2C reference clock frequency in Hz that will be used. If set to 0,
|
||||
* the currently configured reference clock is assumed. Setting it to a higher
|
||||
* than actual configured value only has the consequence of reducing the real
|
||||
* I2C frequency.
|
||||
*
|
||||
* @param[in] freq
|
||||
* Bus frequency to set (actual bus speed may be lower due to integer
|
||||
* prescaling). Safe (according to I2C specification) max frequencies for
|
||||
* standard, fast and fast+ modes are available using I2C_FREQ_ defines.
|
||||
* (Using I2C_FREQ_ defines requires corresponding setting of @p type.)
|
||||
* Slowest slave device on bus must always be considered.
|
||||
*
|
||||
* @param[in] type
|
||||
* Clock low to high ratio type to use. If not using i2cClockHLRStandard,
|
||||
* make sure all devices on the bus support the specified mode. Using a
|
||||
* non-standard ratio is useful to achieve higher bus clock in fast and
|
||||
* fast+ modes.
|
||||
******************************************************************************/
|
||||
void I2C_BusFreqSet(I2C_TypeDef *i2c,
|
||||
uint32_t refFreq,
|
||||
uint32_t freq,
|
||||
I2C_ClockHLR_TypeDef type)
|
||||
{
|
||||
uint32_t n;
|
||||
uint32_t div;
|
||||
|
||||
/* Unused parameter */
|
||||
(void)type;
|
||||
|
||||
/* Avoid divide by 0 */
|
||||
EFM_ASSERT(freq);
|
||||
if (!freq)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4), thus */
|
||||
/* DIV = ((fHFPERCLK - 4fSCL)/((Nlow + Nhigh)fSCL)) - 1 */
|
||||
|
||||
if (!refFreq)
|
||||
{
|
||||
refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
|
||||
}
|
||||
n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
|
||||
|
||||
div = (refFreq - (4 * freq)) / (n * freq);
|
||||
EFM_ASSERT(div);
|
||||
if (div)
|
||||
{
|
||||
div--;
|
||||
}
|
||||
|
||||
/* Clock divisor must be at least 1 in slave mode according to reference */
|
||||
/* manual (in which case there is normally no need to set bus frequency). */
|
||||
if ((i2c->CTRL & I2C_CTRL_SLAVE) && !div)
|
||||
{
|
||||
div = 1;
|
||||
}
|
||||
|
||||
EFM_ASSERT(div <= _I2C_CLKDIV_DIV_MASK);
|
||||
i2c->CLKDIV = div;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable I2C.
|
||||
*
|
||||
* @note
|
||||
* After enabling the I2C (from being disabled), the I2C is in BUSY state.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] enable
|
||||
* true to enable counting, false to disable.
|
||||
******************************************************************************/
|
||||
void I2C_Enable(I2C_TypeDef *i2c, bool enable)
|
||||
{
|
||||
EFM_ASSERT(I2C_REF_VALID(i2c));
|
||||
|
||||
BITBAND_Peripheral(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, (unsigned int)enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize I2C.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to I2C initialization structure.
|
||||
******************************************************************************/
|
||||
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
|
||||
{
|
||||
EFM_ASSERT(I2C_REF_VALID(i2c));
|
||||
|
||||
i2c->IEN = 0;
|
||||
i2c->IFC = _I2C_IFC_MASK;
|
||||
|
||||
I2C_BusFreqSet(i2c, init->refFreq, init->freq, init->clhr);
|
||||
|
||||
BITBAND_Peripheral(&(i2c->CTRL),
|
||||
_I2C_CTRL_SLAVE_SHIFT,
|
||||
~((unsigned int)(init->master)));
|
||||
|
||||
BITBAND_Peripheral(&(i2c->CTRL),
|
||||
_I2C_CTRL_EN_SHIFT,
|
||||
(unsigned int)(init->enable));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset I2C to same state as after a HW reset.
|
||||
*
|
||||
* @note
|
||||
* The ROUTE register is NOT reset by this function, in order to allow for
|
||||
* centralized setup of this feature.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
******************************************************************************/
|
||||
void I2C_Reset(I2C_TypeDef *i2c)
|
||||
{
|
||||
i2c->CTRL = _I2C_CTRL_RESETVALUE;
|
||||
i2c->CLKDIV = _I2C_CLKDIV_RESETVALUE;
|
||||
i2c->SADDR = _I2C_SADDR_RESETVALUE;
|
||||
i2c->SADDRMASK = _I2C_SADDRMASK_RESETVALUE;
|
||||
i2c->IEN = _I2C_IEN_RESETVALUE;
|
||||
i2c->IFC = _I2C_IFC_MASK;
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Continue an initiated I2C transfer (single master mode only).
|
||||
*
|
||||
* @details
|
||||
* This function is used repeatedly after a I2C_TransferInit() in order to
|
||||
* complete a transfer. It may be used in polled mode as the below example
|
||||
* shows:
|
||||
* @verbatim
|
||||
* I2C_TransferReturn_TypeDef ret;
|
||||
*
|
||||
* // Do a polled transfer
|
||||
* ret = I2C_TransferInit(I2C0, seq);
|
||||
* while (ret == i2cTransferInProgress)
|
||||
* {
|
||||
* ret = I2C_Transfer(I2C0);
|
||||
* }
|
||||
* @endverbatim
|
||||
* It may also be used in interrupt driven mode, where this function is invoked
|
||||
* from the interrupt handler. Notice that if used in interrupt mode, NVIC
|
||||
* interrupts must be configured and enabled for the I2C bus used. I2C
|
||||
* peripheral specific interrupts are managed by this SW.
|
||||
*
|
||||
* @note
|
||||
* Only single master mode is supported.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Returns status for ongoing transfer.
|
||||
* @li #i2cTransferInProgress - indicates that transfer not finished.
|
||||
* @li #i2cTransferDone - transfer completed successfully.
|
||||
* @li otherwise some sort of error has occurred.
|
||||
*
|
||||
******************************************************************************/
|
||||
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c)
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t pending;
|
||||
I2C_Transfer_TypeDef *transfer;
|
||||
I2C_TransferSeq_TypeDef *seq;
|
||||
|
||||
EFM_ASSERT(I2C_REF_VALID(i2c));
|
||||
|
||||
/* Support up to 2 I2C buses */
|
||||
if (i2c == I2C0)
|
||||
{
|
||||
transfer = i2cTransfer;
|
||||
}
|
||||
#if (I2C_COUNT > 1)
|
||||
else if (i2c == I2C1)
|
||||
{
|
||||
transfer = i2cTransfer + 1;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return(i2cTransferUsageFault);
|
||||
}
|
||||
|
||||
seq = transfer->seq;
|
||||
for (;; )
|
||||
{
|
||||
pending = i2c->IF;
|
||||
|
||||
/* If some sort of fault, abort transfer. */
|
||||
if (pending & I2C_IF_ERRORS)
|
||||
{
|
||||
if (pending & I2C_IF_ARBLOST)
|
||||
{
|
||||
/* If arbitration fault, it indicates either a slave device */
|
||||
/* not responding as expected, or other master which is not */
|
||||
/* supported by this SW. */
|
||||
transfer->result = i2cTransferArbLost;
|
||||
}
|
||||
else if (pending & I2C_IF_BUSERR)
|
||||
{
|
||||
/* A bus error indicates a misplaced start or stop, which should */
|
||||
/* not occur in master mode controlled by this SW. */
|
||||
transfer->result = i2cTransferBusErr;
|
||||
}
|
||||
|
||||
/* If error situation occurred, it is difficult to know */
|
||||
/* exact cause and how to resolve. It will be up to a wrapper */
|
||||
/* to determine how to handle a fault/recovery if possible. */
|
||||
transfer->state = i2cStateDone;
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (transfer->state)
|
||||
{
|
||||
/***************************************************/
|
||||
/* Send first start+address (first byte if 10 bit) */
|
||||
/***************************************************/
|
||||
case i2cStateStartAddrSend:
|
||||
if (seq->flags & I2C_FLAG_10BIT_ADDR)
|
||||
{
|
||||
tmp = (((uint32_t)(seq->addr) >> 8) & 0x06) | 0xf0;
|
||||
|
||||
/* In 10 bit address mode, the address following the first */
|
||||
/* start always indicate write. */
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = (uint32_t)(seq->addr) & 0xfe;
|
||||
|
||||
if (seq->flags & I2C_FLAG_READ)
|
||||
{
|
||||
/* Indicate read request */
|
||||
tmp |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
transfer->state = i2cStateAddrWFAckNack;
|
||||
i2c->TXDATA = tmp; /* Data not transmitted until START sent */
|
||||
i2c->CMD = I2C_CMD_START;
|
||||
goto done;
|
||||
|
||||
/*******************************************************/
|
||||
/* Wait for ACK/NACK on address (first byte if 10 bit) */
|
||||
/*******************************************************/
|
||||
case i2cStateAddrWFAckNack:
|
||||
if (pending & I2C_IF_NACK)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_NACK;
|
||||
transfer->result = i2cTransferNack;
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
}
|
||||
else if (pending & I2C_IF_ACK)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_ACK;
|
||||
|
||||
/* If 10 bit address, send 2nd byte of address. */
|
||||
if (seq->flags & I2C_FLAG_10BIT_ADDR)
|
||||
{
|
||||
transfer->state = i2cStateAddrWF2ndAckNack;
|
||||
i2c->TXDATA = (uint32_t)(seq->addr) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Determine whether receiving or sending data */
|
||||
if (seq->flags & I2C_FLAG_READ)
|
||||
{
|
||||
transfer->state = i2cStateWFData;
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer->state = i2cStateDataSend;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
|
||||
/******************************************************/
|
||||
/* Wait for ACK/NACK on second byte of 10 bit address */
|
||||
/******************************************************/
|
||||
case i2cStateAddrWF2ndAckNack:
|
||||
if (pending & I2C_IF_NACK)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_NACK;
|
||||
transfer->result = i2cTransferNack;
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
}
|
||||
else if (pending & I2C_IF_ACK)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_ACK;
|
||||
|
||||
/* If using plain read sequence with 10 bit address, switch to send */
|
||||
/* repeated start. */
|
||||
if (seq->flags & I2C_FLAG_READ)
|
||||
{
|
||||
transfer->state = i2cStateRStartAddrSend;
|
||||
}
|
||||
/* Otherwise expected to write 0 or more bytes */
|
||||
else
|
||||
{
|
||||
transfer->state = i2cStateDataSend;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
goto done;
|
||||
|
||||
/*******************************/
|
||||
/* Send repeated start+address */
|
||||
/*******************************/
|
||||
case i2cStateRStartAddrSend:
|
||||
if (seq->flags & I2C_FLAG_10BIT_ADDR)
|
||||
{
|
||||
tmp = ((seq->addr >> 8) & 0x06) | 0xf0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = seq->addr & 0xfe;
|
||||
}
|
||||
|
||||
/* If this is a write+read combined sequence, then read is about to start */
|
||||
if (seq->flags & I2C_FLAG_WRITE_READ)
|
||||
{
|
||||
/* Indicate read request */
|
||||
tmp |= 1;
|
||||
}
|
||||
|
||||
transfer->state = i2cStateRAddrWFAckNack;
|
||||
/* We have to write START cmd first since repeated start, otherwise */
|
||||
/* data would be sent first. */
|
||||
i2c->CMD = I2C_CMD_START;
|
||||
i2c->TXDATA = tmp;
|
||||
goto done;
|
||||
|
||||
/**********************************************************************/
|
||||
/* Wait for ACK/NACK on repeated start+address (first byte if 10 bit) */
|
||||
/**********************************************************************/
|
||||
case i2cStateRAddrWFAckNack:
|
||||
if (pending & I2C_IF_NACK)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_NACK;
|
||||
transfer->result = i2cTransferNack;
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
}
|
||||
else if (pending & I2C_IF_ACK)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_ACK;
|
||||
|
||||
/* Determine whether receiving or sending data */
|
||||
if (seq->flags & I2C_FLAG_WRITE_READ)
|
||||
{
|
||||
transfer->state = i2cStateWFData;
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer->state = i2cStateDataSend;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
|
||||
/*****************************/
|
||||
/* Send a data byte to slave */
|
||||
/*****************************/
|
||||
case i2cStateDataSend:
|
||||
/* Reached end of data buffer? */
|
||||
if (transfer->offset >= seq->buf[transfer->bufIndx].len)
|
||||
{
|
||||
/* Move to next message part */
|
||||
transfer->offset = 0;
|
||||
transfer->bufIndx++;
|
||||
|
||||
/* Send repeated start when switching to read mode on 2nd buffer */
|
||||
if (seq->flags & I2C_FLAG_WRITE_READ)
|
||||
{
|
||||
transfer->state = i2cStateRStartAddrSend;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only writing from one buffer, or finished both buffers */
|
||||
if ((seq->flags & I2C_FLAG_WRITE) || (transfer->bufIndx > 1))
|
||||
{
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Reprocess in case next buffer is empty */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Send byte */
|
||||
i2c->TXDATA = (uint32_t)(seq->buf[transfer->bufIndx].data[transfer->offset++]);
|
||||
transfer->state = i2cStateDataWFAckNack;
|
||||
goto done;
|
||||
|
||||
/*********************************************************/
|
||||
/* Wait for ACK/NACK from slave after sending data to it */
|
||||
/*********************************************************/
|
||||
case i2cStateDataWFAckNack:
|
||||
if (pending & I2C_IF_NACK)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_NACK;
|
||||
transfer->result = i2cTransferNack;
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
}
|
||||
else if (pending & I2C_IF_ACK)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_ACK;
|
||||
transfer->state = i2cStateDataSend;
|
||||
continue;
|
||||
}
|
||||
goto done;
|
||||
|
||||
/****************************/
|
||||
/* Wait for data from slave */
|
||||
/****************************/
|
||||
case i2cStateWFData:
|
||||
if (pending & I2C_IF_RXDATAV)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
/* Must read out data in order to not block further progress */
|
||||
data = (uint8_t)(i2c->RXDATA);
|
||||
|
||||
/* Make sure not storing beyond end of buffer just in case */
|
||||
if (transfer->offset < seq->buf[transfer->bufIndx].len)
|
||||
{
|
||||
seq->buf[transfer->bufIndx].data[transfer->offset++] = data;
|
||||
}
|
||||
|
||||
/* If we have read all requested data, then the sequence should end */
|
||||
if (transfer->offset >= seq->buf[transfer->bufIndx].len)
|
||||
{
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_NACK;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send ACK and wait for next byte */
|
||||
i2c->CMD = I2C_CMD_ACK;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
|
||||
/***********************************/
|
||||
/* Wait for STOP to have been sent */
|
||||
/***********************************/
|
||||
case i2cStateWFStopSent:
|
||||
if (pending & I2C_IF_MSTOP)
|
||||
{
|
||||
i2c->IFC = I2C_IFC_MSTOP;
|
||||
transfer->state = i2cStateDone;
|
||||
}
|
||||
goto done;
|
||||
|
||||
/******************************/
|
||||
/* Unexpected state, SW fault */
|
||||
/******************************/
|
||||
default:
|
||||
transfer->result = i2cTransferSwFault;
|
||||
transfer->state = i2cStateDone;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (transfer->state == i2cStateDone)
|
||||
{
|
||||
/* Disable interrupt sources when done */
|
||||
i2c->IEN = 0;
|
||||
|
||||
/* Update result unless some fault already occurred */
|
||||
if (transfer->result == i2cTransferInProgress)
|
||||
{
|
||||
transfer->result = i2cTransferDone;
|
||||
}
|
||||
}
|
||||
/* Until transfer is done keep returning i2cTransferInProgress */
|
||||
else
|
||||
{
|
||||
return(i2cTransferInProgress);
|
||||
}
|
||||
|
||||
return transfer->result;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare and start an I2C transfer (single master mode only).
|
||||
*
|
||||
* @details
|
||||
* This function must be invoked in order to start an I2C transfer
|
||||
* sequence. In order to actually complete the transfer, I2C_Transfer() must
|
||||
* be used either in polled mode or by adding a small driver wrapper utilizing
|
||||
* interrupts.
|
||||
*
|
||||
* @note
|
||||
* Only single master mode is supported.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] seq
|
||||
* Pointer to sequence structure defining the I2C transfer to take place. The
|
||||
* referenced structure must exist until the transfer has fully completed.
|
||||
*
|
||||
* @return
|
||||
* Returns status for ongoing transfer:
|
||||
* @li #i2cTransferInProgress - indicates that transfer not finished.
|
||||
* @li otherwise some sort of error has occurred.
|
||||
******************************************************************************/
|
||||
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
|
||||
I2C_TransferSeq_TypeDef *seq)
|
||||
{
|
||||
I2C_Transfer_TypeDef *transfer;
|
||||
|
||||
EFM_ASSERT(I2C_REF_VALID(i2c));
|
||||
EFM_ASSERT(seq);
|
||||
|
||||
/* Support up to 2 I2C buses */
|
||||
if (i2c == I2C0)
|
||||
{
|
||||
transfer = i2cTransfer;
|
||||
}
|
||||
#if (I2C_COUNT > 1)
|
||||
else if (i2c == I2C1)
|
||||
{
|
||||
transfer = i2cTransfer + 1;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return(i2cTransferUsageFault);
|
||||
}
|
||||
|
||||
/* Check if in busy state. Since this SW assumes single master, we can */
|
||||
/* just issue an abort. The BUSY state is normal after a reset. */
|
||||
if (i2c->STATE & I2C_STATE_BUSY)
|
||||
{
|
||||
i2c->CMD = I2C_CMD_ABORT;
|
||||
}
|
||||
|
||||
/* Make sure user is not trying to read 0 bytes, it is not */
|
||||
/* possible according to I2C spec, since slave will always start */
|
||||
/* sending first byte ACK on address. The read operation can */
|
||||
/* only be stopped by NACKing a received byte, ie minimum 1 byte. */
|
||||
if (((seq->flags & I2C_FLAG_READ) && !(seq->buf[0].len)) ||
|
||||
((seq->flags & I2C_FLAG_WRITE_READ) && !(seq->buf[1].len))
|
||||
)
|
||||
{
|
||||
return(i2cTransferUsageFault);
|
||||
}
|
||||
|
||||
/* Prepare for a transfer */
|
||||
transfer->state = i2cStateStartAddrSend;
|
||||
transfer->result = i2cTransferInProgress;
|
||||
transfer->offset = 0;
|
||||
transfer->bufIndx = 0;
|
||||
transfer->seq = seq;
|
||||
|
||||
/* Ensure buffers are empty */
|
||||
i2c->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX;
|
||||
if (i2c->IF & I2C_IF_RXDATAV)
|
||||
{
|
||||
i2c->RXDATA;
|
||||
}
|
||||
|
||||
/* Clear all pending interrupts prior to starting transfer. */
|
||||
i2c->IFC = _I2C_IFC_MASK;
|
||||
|
||||
/* Enable those interrupts we are interested in throughout transfer. */
|
||||
/* Notice that the I2C interrupt must also be enabled in the NVIC, but */
|
||||
/* that is left for an additional driver wrapper. */
|
||||
i2c->IEN = I2C_IF_NACK | I2C_IF_ACK | I2C_IF_MSTOP |
|
||||
I2C_IF_RXDATAV | I2C_IF_ERRORS;
|
||||
|
||||
/* Start transfer */
|
||||
return(I2C_Transfer(i2c));
|
||||
}
|
||||
|
||||
/** @} (end addtogroup I2C) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,66 @@
|
|||
/**************************************************************************//**
|
||||
* @file
|
||||
* @brief Interrupt enable/disable unit API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "efm32_int.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup INT
|
||||
* @brief Safe nesting interrupt disable/enable API for EFM32.
|
||||
* @details
|
||||
* This module contains functions to safely disable and enable interrupts
|
||||
* at cpu level. INT_Disable() disables interrupts and increments a lock
|
||||
* level counter. INT_Enable() decrements the lock level counter and enable
|
||||
* interrupts if the counter was decremented to zero.
|
||||
*
|
||||
* These functions would normally be used to secure critical regions.
|
||||
*
|
||||
* These functions should also be used inside interrupt handlers:
|
||||
* @verbatim
|
||||
* void SysTick_Handler(void)
|
||||
* {
|
||||
* INT_Disable();
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* INT_Enable();
|
||||
* }
|
||||
* @endverbatim
|
||||
******************************************************************************/
|
||||
|
||||
/** Interrupt lock level counter. Set to zero initially as we normally enter
|
||||
* main with interrupts enabled */
|
||||
uint32_t INT_LockCnt = 0;
|
||||
|
||||
|
||||
/** @} (end addtogroup INT) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,758 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Liquid Crystal Display (LCD) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32_lcd.h"
|
||||
#if defined(LCD_COUNT) && (LCD_COUNT > 0)
|
||||
#include "efm32_assert.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup LCD
|
||||
* @brief Liquid Crystal Display (LCD) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initalize Liquid Crystal Display (LCD) controller
|
||||
*
|
||||
* @details
|
||||
* This function call will only configure the LCD controller. You must enable
|
||||
* it afterwards, potentially configuring Frame Control and interrupts first
|
||||
* according to requirements.
|
||||
*
|
||||
* @param[in] lcdInit
|
||||
* Pointer to initialization structure which configures LCD controller.
|
||||
*
|
||||
******************************************************************************/
|
||||
void LCD_Initialize(const LCD_Init_TypeDef *lcdInit)
|
||||
{
|
||||
uint32_t dispCtrl = LCD->DISPCTRL;
|
||||
|
||||
EFM_ASSERT(lcdInit != (void *) 0);
|
||||
|
||||
/* Disable controller before reconfiguration */
|
||||
LCD_Enable(false);
|
||||
|
||||
/* Make sure we don't touch other bit fields (i.e. voltage boost) */
|
||||
dispCtrl &= ~(
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
_LCD_DISPCTRL_MUXE_MASK |
|
||||
#endif
|
||||
_LCD_DISPCTRL_MUX_MASK |
|
||||
_LCD_DISPCTRL_BIAS_MASK |
|
||||
_LCD_DISPCTRL_WAVE_MASK |
|
||||
_LCD_DISPCTRL_VLCDSEL_MASK |
|
||||
_LCD_DISPCTRL_CONCONF_MASK);
|
||||
|
||||
/* Configure controller according to initialization structure */
|
||||
dispCtrl |= lcdInit->mux; /* also configures MUXE */
|
||||
dispCtrl |= lcdInit->bias;
|
||||
dispCtrl |= lcdInit->wave;
|
||||
dispCtrl |= lcdInit->vlcd;
|
||||
dispCtrl |= lcdInit->contrast;
|
||||
|
||||
/* Update display controller */
|
||||
LCD->DISPCTRL = dispCtrl;
|
||||
|
||||
/* Enable controller if wanted */
|
||||
if (lcdInit->enable)
|
||||
{
|
||||
LCD_Enable(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Select source for VLCD
|
||||
*
|
||||
* @param[in] vlcd
|
||||
* Select source for VLD voltage
|
||||
******************************************************************************/
|
||||
void LCD_VLCDSelect(LCD_VLCDSel_TypeDef vlcd)
|
||||
{
|
||||
uint32_t dispctrl = LCD->DISPCTRL;
|
||||
|
||||
/* Select VEXT or VDD */
|
||||
dispctrl &= ~(_LCD_DISPCTRL_VLCDSEL_MASK);
|
||||
switch (vlcd)
|
||||
{
|
||||
case lcdVLCDSelVExtBoost:
|
||||
dispctrl |= LCD_DISPCTRL_VLCDSEL_VEXTBOOST;
|
||||
break;
|
||||
case lcdVLCDSelVDD:
|
||||
dispctrl |= LCD_DISPCTRL_VLCDSEL_VDD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LCD->DISPCTRL = dispctrl;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure Update Control
|
||||
*
|
||||
* @param[in] ud
|
||||
* Configures LCD update method
|
||||
******************************************************************************/
|
||||
void LCD_UpdateCtrl(LCD_UpdateCtrl_TypeDef ud)
|
||||
{
|
||||
LCD->CTRL = (LCD->CTRL & ~_LCD_CTRL_UDCTRL_MASK) | ud;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize LCD Frame Counter
|
||||
*
|
||||
* @param[in] fcInit
|
||||
* Pointer to Frame Counter initialization structure
|
||||
******************************************************************************/
|
||||
void LCD_FrameCountInit(const LCD_FrameCountInit_TypeDef *fcInit)
|
||||
{
|
||||
uint32_t bactrl = LCD->BACTRL;
|
||||
|
||||
EFM_ASSERT(fcInit != (void *) 0);
|
||||
|
||||
/* Verify FC Top Counter to be within limits */
|
||||
EFM_ASSERT(fcInit->top < 64);
|
||||
|
||||
/* Reconfigure frame count configuration */
|
||||
bactrl &= ~(_LCD_BACTRL_FCTOP_MASK |
|
||||
_LCD_BACTRL_FCPRESC_MASK);
|
||||
bactrl |= (fcInit->top << _LCD_BACTRL_FCTOP_SHIFT);
|
||||
bactrl |= fcInit->prescale;
|
||||
|
||||
/* Set Blink and Animation Control Register */
|
||||
LCD->BACTRL = bactrl;
|
||||
|
||||
LCD_FrameCountEnable(fcInit->enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configures LCD controller Animation feature
|
||||
*
|
||||
* @param[in] animInit
|
||||
* Pointer to LCD Animation initialization structure
|
||||
******************************************************************************/
|
||||
void LCD_AnimInit(const LCD_AnimInit_TypeDef *animInit)
|
||||
{
|
||||
uint32_t bactrl = LCD->BACTRL;
|
||||
|
||||
EFM_ASSERT(animInit != (void *) 0);
|
||||
|
||||
/* Set Animation Register Values */
|
||||
LCD->AREGA = animInit->AReg;
|
||||
LCD->AREGB = animInit->BReg;
|
||||
|
||||
/* Configure Animation Shift and Logic */
|
||||
bactrl &= ~(_LCD_BACTRL_AREGASC_MASK |
|
||||
_LCD_BACTRL_AREGBSC_MASK |
|
||||
_LCD_BACTRL_ALOGSEL_MASK);
|
||||
|
||||
bactrl |= (animInit->AShift << _LCD_BACTRL_AREGASC_SHIFT);
|
||||
bactrl |= (animInit->BShift << _LCD_BACTRL_AREGBSC_SHIFT);
|
||||
bactrl |= animInit->animLogic;
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
if(animInit->startSeg == 0)
|
||||
{
|
||||
bactrl |= LCD_BACTRL_ALOC_SEG0TO7;
|
||||
}
|
||||
else if(animInit->startSeg == 8)
|
||||
{
|
||||
bactrl |= LCD_BACTRL_ALOC_SEG8TO15;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reconfigure */
|
||||
LCD->BACTRL = bactrl;
|
||||
|
||||
/* Enable */
|
||||
LCD_AnimEnable(animInit->enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables update of this range of LCD segment lines
|
||||
*
|
||||
* @param[in] segmentRange
|
||||
* Range of 4 LCD segments lines to enable or disable, for all enabled COM
|
||||
* lines
|
||||
*
|
||||
* @param[in] enable
|
||||
* Bool true to enable segment updates, false to disable updates
|
||||
******************************************************************************/
|
||||
void LCD_SegmentRangeEnable(LCD_SegmentRange_TypeDef segmentRange, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
LCD->SEGEN |= segmentRange;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD->SEGEN &= ~((uint32_t)segmentRange);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Turn on or clear a segment
|
||||
*
|
||||
* @note
|
||||
* On Gecko Family, max configuration is (COM-lines x Segment-Lines) 4x40
|
||||
* On Tiny Family, max configuration is 8x20 or 4x24
|
||||
* On Giant Family, max configuration is 8x36 or 4x40
|
||||
*
|
||||
* @param[in] com
|
||||
* COM line to change
|
||||
*
|
||||
* @param[in] bit
|
||||
* Bit index of which field to change
|
||||
*
|
||||
* @param[in] enable
|
||||
* When true will set segment, when false will clear segment
|
||||
******************************************************************************/
|
||||
void LCD_SegmentSet(int com, int bit, bool enable)
|
||||
{
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/* Tiny and Giant Family supports up to 8 COM lines */
|
||||
EFM_ASSERT(com < 8);
|
||||
#else
|
||||
/* Gecko Family supports up to 4 COM lines */
|
||||
EFM_ASSERT(com < 4);
|
||||
#endif
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
EFM_ASSERT(bit < 40);
|
||||
#else
|
||||
/* Tiny Gecko Family supports only "low" segment registers */
|
||||
EFM_ASSERT(bit < 32);
|
||||
#endif
|
||||
|
||||
/* Use bitband access for atomic bit set/clear of segment */
|
||||
switch (com)
|
||||
{
|
||||
case 0:
|
||||
if (bit < 32)
|
||||
{
|
||||
BITBAND_Peripheral(&(LCD->SEGD0L), bit, (unsigned int)enable);
|
||||
}
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
else
|
||||
{
|
||||
bit -= 32;
|
||||
BITBAND_Peripheral(&(LCD->SEGD0H), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 1:
|
||||
if (bit < 32)
|
||||
{
|
||||
BITBAND_Peripheral(&(LCD->SEGD1L), bit, (unsigned int)enable);
|
||||
}
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
else
|
||||
{
|
||||
bit -= 32;
|
||||
BITBAND_Peripheral(&(LCD->SEGD1H), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
if (bit < 32)
|
||||
{
|
||||
BITBAND_Peripheral(&(LCD->SEGD2L), bit, (unsigned int)enable);
|
||||
}
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
else
|
||||
{
|
||||
bit -= 32;
|
||||
BITBAND_Peripheral(&(LCD->SEGD2H), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 3:
|
||||
if (bit < 32)
|
||||
{
|
||||
BITBAND_Peripheral(&(LCD->SEGD3L), bit, (unsigned int)enable);
|
||||
}
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
else
|
||||
{
|
||||
bit -= 32;
|
||||
BITBAND_Peripheral(&(LCD->SEGD3H), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
if (bit < 32)
|
||||
{
|
||||
BITBAND_Peripheral(&(LCD->SEGD4L), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
else
|
||||
{
|
||||
bit -= 32;
|
||||
BITBAND_Peripheral(&(LCD->SEGD4H), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 5:
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
if (bit < 32)
|
||||
{
|
||||
BITBAND_Peripheral(&(LCD->SEGD5L), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
else
|
||||
{
|
||||
bit -= 32;
|
||||
BITBAND_Peripheral(&(LCD->SEGD5H), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 6:
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
if (bit < 32)
|
||||
{
|
||||
BITBAND_Peripheral(&(LCD->SEGD6L), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
else
|
||||
{
|
||||
bit -= 32;
|
||||
BITBAND_Peripheral(&(LCD->SEGD6H), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 7:
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
if (bit < 32)
|
||||
{
|
||||
BITBAND_Peripheral(&(LCD->SEGD7L), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
else
|
||||
{
|
||||
bit -= 32;
|
||||
BITBAND_Peripheral(&(LCD->SEGD7H), bit, (unsigned int)enable);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
EFM_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Updates the 0-31 lowest segments on a given COM-line in one operation,
|
||||
* according to bit mask
|
||||
*
|
||||
* @param[in] com
|
||||
* Which COM line to update
|
||||
*
|
||||
* @param[in] mask
|
||||
* Bit mask for segments 0-31
|
||||
*
|
||||
* @param[in] bits
|
||||
* Bit pattern for segments 0-31
|
||||
******************************************************************************/
|
||||
void LCD_SegmentSetLow(int com, uint32_t mask, uint32_t bits)
|
||||
{
|
||||
uint32_t segData;
|
||||
|
||||
/* Maximum number of com lines */
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
EFM_ASSERT(com < 8);
|
||||
#else
|
||||
/* Gecko Family supports up to 4 COM lines */
|
||||
EFM_ASSERT(com < 4);
|
||||
#endif
|
||||
|
||||
switch (com)
|
||||
{
|
||||
case 0:
|
||||
segData = LCD->SEGD0L;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD0L = segData;
|
||||
break;
|
||||
case 1:
|
||||
segData = LCD->SEGD1L;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD1L = segData;
|
||||
break;
|
||||
case 2:
|
||||
segData = LCD->SEGD2L;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD2L = segData;
|
||||
break;
|
||||
case 3:
|
||||
segData = LCD->SEGD3L;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD3L = segData;
|
||||
break;
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
case 4:
|
||||
segData = LCD->SEGD4L;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD4L = segData;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
case 5:
|
||||
segData = LCD->SEGD5L;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD5L = segData;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
case 6:
|
||||
segData = LCD->SEGD6L;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD6L = segData;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
case 7:
|
||||
segData = LCD->SEGD7L;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD7L = segData;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
EFM_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Updated the high (32-39) segments on a given COM-line in one operation
|
||||
*
|
||||
* @param[in] com
|
||||
* Which COM line to update
|
||||
*
|
||||
* @param[in] mask
|
||||
* Bit mask for segments 32-39
|
||||
*
|
||||
* @param[in] bits
|
||||
* Bit pattern for segments 32-39
|
||||
******************************************************************************/
|
||||
void LCD_SegmentSetHigh(int com, uint32_t mask, uint32_t bits)
|
||||
{
|
||||
uint32_t segData;
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
EFM_ASSERT(com < 8);
|
||||
#endif
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
EFM_ASSERT(com < 4);
|
||||
#endif
|
||||
|
||||
/* Maximum number of com lines */
|
||||
switch (com)
|
||||
{
|
||||
case 0:
|
||||
segData = LCD->SEGD0H;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD0H = segData;
|
||||
break;
|
||||
case 1:
|
||||
segData = LCD->SEGD1H;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD1H = segData;
|
||||
break;
|
||||
case 2:
|
||||
segData = LCD->SEGD2H;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD2H = segData;
|
||||
break;
|
||||
case 3:
|
||||
segData = LCD->SEGD3H;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD3H = segData;
|
||||
break;
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
case 4:
|
||||
segData = LCD->SEGD4H;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD4H = segData;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
case 5:
|
||||
segData = LCD->SEGD5H;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD5H = segData;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
case 6:
|
||||
segData = LCD->SEGD6H;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD6H = segData;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
case 7:
|
||||
segData = LCD->SEGD7H;
|
||||
segData &= ~(mask);
|
||||
segData |= (mask & bits);
|
||||
LCD->SEGD7H = segData;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure contrast level on LCD panel
|
||||
*
|
||||
* @param[in] level
|
||||
* Contrast level in the range 0-31
|
||||
******************************************************************************/
|
||||
void LCD_ContrastSet(int level)
|
||||
{
|
||||
EFM_ASSERT(level < 32);
|
||||
|
||||
LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_CONLEV_MASK)
|
||||
| (level << _LCD_DISPCTRL_CONLEV_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure voltage booster
|
||||
*
|
||||
* The resulting voltage level is described in each part number's data sheet
|
||||
*
|
||||
* @param[in] vboost
|
||||
* Voltage boost level
|
||||
******************************************************************************/
|
||||
void LCD_VBoostSet(LCD_VBoostLevel_TypeDef vboost)
|
||||
{
|
||||
/* Reconfigure Voltage Boost */
|
||||
LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_VBLEV_MASK) | vboost;
|
||||
}
|
||||
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure bias level for a specific segment line for Direct Segment Control
|
||||
*
|
||||
* @note
|
||||
* When DSC is active, each configuration takes up 4 bits in the Segment
|
||||
* Registers (SEGD0L/SEGD1H) which defines bias level.
|
||||
* For optimal use of this feature, the entire SEGD-registers should be set
|
||||
* at once in a optimized routine, so this function is mainly here to
|
||||
* demonstrate how to correctly configure the bias levels, and should be used
|
||||
* with care.
|
||||
*
|
||||
* @param[in] segmentLine
|
||||
* Segment line number
|
||||
*
|
||||
* @param[in] biasLevel
|
||||
* Bias configuration level, 0-4. This value must be within the constraint
|
||||
* defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet
|
||||
******************************************************************************/
|
||||
void LCD_BiasSegmentSet(int segmentLine, int biasLevel)
|
||||
{
|
||||
int biasRegister;
|
||||
int bitShift;
|
||||
volatile uint32_t *segmentRegister;
|
||||
|
||||
#if defined(_EFM32_TINY_FAMILY)
|
||||
EFM_ASSERT(segmentLine < 20);
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
EFM_ASSERT(segmentLine < 40);
|
||||
#endif
|
||||
#if defined(_EFM32_TINY_FAMILY)
|
||||
/* Bias config for 8 segment lines per SEGDnL register */
|
||||
biasRegister = segmentLine / 8;
|
||||
bitShift = (segmentLine % 8) * 4;
|
||||
|
||||
switch (biasRegister)
|
||||
{
|
||||
case 0:
|
||||
segmentRegister = &LCD->SEGD0L;
|
||||
break;
|
||||
case 1:
|
||||
segmentRegister = &LCD->SEGD1L;
|
||||
break;
|
||||
case 2:
|
||||
segmentRegister = &LCD->SEGD2L;
|
||||
break;
|
||||
case 3:
|
||||
segmentRegister = &LCD->SEGD3L;
|
||||
break;
|
||||
default:
|
||||
segmentRegister = (uint32_t *)0x00000000;
|
||||
EFM_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/* Bias config for 10 segment lines per SEGDn L+H registers */
|
||||
biasRegister = segmentLine / 10;
|
||||
bitShift = (segmentLine % 10) * 4;
|
||||
|
||||
switch (biasRegister)
|
||||
{
|
||||
case 0:
|
||||
if (bitShift < 32)
|
||||
{
|
||||
segmentRegister = &LCD->SEGD0L;
|
||||
}
|
||||
else
|
||||
{
|
||||
segmentRegister = &LCD->SEGD0H;
|
||||
bitShift -= 32;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (bitShift < 32)
|
||||
{
|
||||
segmentRegister = &LCD->SEGD1L;
|
||||
}
|
||||
else
|
||||
{
|
||||
segmentRegister = &LCD->SEGD1H;
|
||||
bitShift -= 32;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (bitShift < 32)
|
||||
{
|
||||
segmentRegister = &LCD->SEGD2L;
|
||||
}
|
||||
else
|
||||
{
|
||||
segmentRegister = &LCD->SEGD1H;
|
||||
bitShift -= 32;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (bitShift < 32)
|
||||
{
|
||||
segmentRegister = &LCD->SEGD3L;
|
||||
}
|
||||
else
|
||||
{
|
||||
segmentRegister = &LCD->SEGD3H;
|
||||
bitShift -= 32;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
segmentRegister = (uint32_t *)0x00000000;
|
||||
EFM_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Configure new bias setting */
|
||||
*segmentRegister = (*segmentRegister & ~(0xF << bitShift)) | (biasLevel << bitShift);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure bias level for a specific segment line
|
||||
*
|
||||
* @note
|
||||
* When DSC is active, each configuration takes up 4 bits in the Segment
|
||||
* Registers (SEGD4L/SEGD4H) which defines bias level.
|
||||
* For optimal use of this feature, the entire SEGD-registers should be set
|
||||
* at once in a optimized routine, so this function is mainly here to
|
||||
* demonstrate how to correctly configure the bias levels, and should be used
|
||||
* with care.
|
||||
*
|
||||
* @param[in] comLine
|
||||
* COM line number, 0-7
|
||||
*
|
||||
* @param[in] biasLevel
|
||||
* Bias configuration level, 0-4. This value must be within the constraint
|
||||
* defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet
|
||||
******************************************************************************/
|
||||
void LCD_BiasComSet(int comLine, int biasLevel)
|
||||
{
|
||||
int bitShift;
|
||||
EFM_ASSERT(comLine < 8);
|
||||
|
||||
bitShift = comLine * 4;
|
||||
LCD->SEGD4L = (LCD->SEGD4L & ~(0xF << bitShift)) | (biasLevel << bitShift);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup LCD) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#endif /* defined(LCD_COUNT) && (LCD_COUNT > 0) */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,529 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Low Energy Timer (LETIMER) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_letimer.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup LETIMER
|
||||
* @brief Low Energy Timer (LETIMER) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of valid comparator register for assert statements. */
|
||||
#define LETIMER_COMP_REG_VALID(reg) (((reg) <= 1))
|
||||
|
||||
/** Validation of LETIMER register block pointer reference for assert statements. */
|
||||
#define LETIMER_REF_VALID(ref) ((ref) == LETIMER0)
|
||||
|
||||
/** Validation of valid repeat counter register for assert statements. */
|
||||
#define LETIMER_REP_REG_VALID(reg) (((reg) <= 1))
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL FUNCTIONS ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Wait for ongoing sync of register(s) to low frequency domain to complete.
|
||||
*
|
||||
* @note
|
||||
* This only applies to the Gecko Family, see the reference manual
|
||||
* chapter about Access to Low Energy Peripherals (Asynchronos Registers)
|
||||
* for details.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block
|
||||
*
|
||||
* @param[in] mask
|
||||
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
|
||||
* registers that must complete any ongoing synchronization.
|
||||
******************************************************************************/
|
||||
static __INLINE void LETIMER_Sync(LETIMER_TypeDef *letimer, uint32_t mask)
|
||||
{
|
||||
/* Avoid deadlock if modifying the same register twice when freeze mode is */
|
||||
/* activated. */
|
||||
if (letimer->FREEZE & LETIMER_FREEZE_REGFREEZE)
|
||||
return;
|
||||
|
||||
/* Wait for any pending previous write operation to have been completed */
|
||||
/* in low frequency domain, only required for Gecko Family of devices */
|
||||
while (letimer->SYNCBUSY & mask)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get LETIMER compare register value.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block
|
||||
*
|
||||
* @param[in] comp
|
||||
* Compare register to get, either 0 or 1
|
||||
*
|
||||
* @return
|
||||
* Compare register value, 0 if invalid register selected.
|
||||
******************************************************************************/
|
||||
uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_COMP_REG_VALID(comp));
|
||||
|
||||
/* Initialize selected compare value */
|
||||
switch (comp)
|
||||
{
|
||||
case 0:
|
||||
ret = letimer->COMP0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ret = letimer->COMP1;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown compare register selected */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set LETIMER compare register value.
|
||||
*
|
||||
* @note
|
||||
* The setting of a compare register requires synchronization into the
|
||||
* low frequency domain. If the same register is modified before a previous
|
||||
* update has completed, this function will stall until the previous
|
||||
* synchronization has completed. This only applies to the Gecko Family, see
|
||||
* comment in the LETIMER_Sync() internal function call.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block
|
||||
*
|
||||
* @param[in] comp
|
||||
* Compare register to set, either 0 or 1
|
||||
*
|
||||
* @param[in] value
|
||||
* Initialization value (<= 0x0000ffff)
|
||||
******************************************************************************/
|
||||
void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
|
||||
unsigned int comp,
|
||||
uint32_t value)
|
||||
{
|
||||
volatile uint32_t *compReg;
|
||||
uint32_t syncbusy;
|
||||
|
||||
EFM_ASSERT(LETIMER_REF_VALID(letimer) &&
|
||||
LETIMER_COMP_REG_VALID(comp) &&
|
||||
((value & ~(_LETIMER_COMP0_COMP0_MASK >> _LETIMER_COMP0_COMP0_SHIFT)) == 0));
|
||||
|
||||
/* Initialize selected compare value */
|
||||
switch (comp)
|
||||
{
|
||||
case 0:
|
||||
compReg = &(letimer->COMP0);
|
||||
syncbusy = LETIMER_SYNCBUSY_COMP0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
compReg = &(letimer->COMP1);
|
||||
syncbusy = LETIMER_SYNCBUSY_COMP1;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown compare register selected, abort */
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LETIMER_Sync(letimer, syncbusy);
|
||||
#endif
|
||||
|
||||
*compReg = value;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Start/stop LETIMER.
|
||||
*
|
||||
* @note
|
||||
* The enabling/disabling of the LETIMER modifies the LETIMER CMD register
|
||||
* which requires synchronization into the low frequency domain. If this
|
||||
* register is modified before a previous update to the same register has
|
||||
* completed, this function will stall until the previous synchronization has
|
||||
* completed. This only applies to the Gecko Family, see comment in the
|
||||
* LETIMER_Sync() internal function call.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @param[in] enable
|
||||
* true to enable counting, false to disable.
|
||||
******************************************************************************/
|
||||
void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable)
|
||||
{
|
||||
EFM_ASSERT(LETIMER_REF_VALID(letimer));
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
|
||||
#endif
|
||||
|
||||
if (enable)
|
||||
{
|
||||
letimer->CMD = LETIMER_CMD_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
letimer->CMD = LETIMER_CMD_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* LETIMER register synchronization freeze control.
|
||||
*
|
||||
* @details
|
||||
* Some LETIMER registers require synchronization into the low frequency (LF)
|
||||
* domain. The freeze feature allows for several such registers to be
|
||||
* modified before passing them to the LF domain simultaneously (which
|
||||
* takes place when the freeze mode is disabled).
|
||||
*
|
||||
* @note
|
||||
* When enabling freeze mode, this function will wait for all current
|
||||
* ongoing LETIMER synchronization to LF domain to complete (Normally
|
||||
* synchronization will not be in progress.) However for this reason, when
|
||||
* using freeze mode, modifications of registers requiring LF synchronization
|
||||
* should be done within one freeze enable/disable block to avoid unecessary
|
||||
* stalling.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @param[in] enable
|
||||
* @li true - enable freeze, modified registers are not propagated to the
|
||||
* LF domain
|
||||
* @li false - disables freeze, modified registers are propagated to LF
|
||||
* domain
|
||||
******************************************************************************/
|
||||
void LETIMER_FreezeEnable(LETIMER_TypeDef *letimer, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
/*
|
||||
* Wait for any ongoing LF synchronization to complete. This is just to
|
||||
* protect against the rare case when a user
|
||||
* - modifies a register requiring LF sync
|
||||
* - then enables freeze before LF sync completed
|
||||
* - then modifies the same register again
|
||||
* since modifying a register while it is in sync progress should be
|
||||
* avoided.
|
||||
*/
|
||||
while (letimer->SYNCBUSY)
|
||||
;
|
||||
|
||||
letimer->FREEZE = LETIMER_FREEZE_REGFREEZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
letimer->FREEZE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize LETIMER.
|
||||
*
|
||||
* @details
|
||||
* Note that the compare/repeat values must be set separately with
|
||||
* LETIMER_CompareSet() and LETIMER_RepeatSet(). That should probably be done
|
||||
* prior to the use of this function if configuring the LETIMER to start when
|
||||
* initialization is completed.
|
||||
*
|
||||
* @note
|
||||
* The initialization of the LETIMER modifies the LETIMER CTRL/CMD registers
|
||||
* which require synchronization into the low frequency domain. If any of those
|
||||
* registers are modified before a previous update to the same register has
|
||||
* completed, this function will stall until the previous synchronization has
|
||||
* completed. This only applies to the Gecko Family, see comment in the
|
||||
* LETIMER_Sync() internal function call.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to LETIMER initialization structure.
|
||||
******************************************************************************/
|
||||
void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init)
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
|
||||
EFM_ASSERT(LETIMER_REF_VALID(letimer));
|
||||
|
||||
/* Stop timer if specified to be disabled and running */
|
||||
if (!(init->enable) && (letimer->STATUS & LETIMER_STATUS_RUNNING))
|
||||
{
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
|
||||
#endif
|
||||
letimer->CMD = LETIMER_CMD_STOP;
|
||||
}
|
||||
|
||||
/* Configure DEBUGRUN flag, sets whether or not counter should be
|
||||
* updated when debugger is active */
|
||||
if (init->debugRun)
|
||||
{
|
||||
tmp |= LETIMER_CTRL_DEBUGRUN;
|
||||
}
|
||||
|
||||
if (init->rtcComp0Enable)
|
||||
{
|
||||
tmp |= LETIMER_CTRL_RTCC0TEN;
|
||||
}
|
||||
|
||||
if (init->rtcComp1Enable)
|
||||
{
|
||||
tmp |= LETIMER_CTRL_RTCC1TEN;
|
||||
}
|
||||
|
||||
if (init->comp0Top)
|
||||
{
|
||||
tmp |= LETIMER_CTRL_COMP0TOP;
|
||||
}
|
||||
|
||||
if (init->bufTop)
|
||||
{
|
||||
tmp |= LETIMER_CTRL_BUFTOP;
|
||||
}
|
||||
|
||||
if (init->out0Pol)
|
||||
{
|
||||
tmp |= LETIMER_CTRL_OPOL0;
|
||||
}
|
||||
|
||||
if (init->out1Pol)
|
||||
{
|
||||
tmp |= LETIMER_CTRL_OPOL1;
|
||||
}
|
||||
|
||||
tmp |= init->ufoa0 << _LETIMER_CTRL_UFOA0_SHIFT;
|
||||
tmp |= init->ufoa1 << _LETIMER_CTRL_UFOA1_SHIFT;
|
||||
tmp |= init->repMode << _LETIMER_CTRL_REPMODE_SHIFT;
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CTRL);
|
||||
#endif
|
||||
letimer->CTRL = tmp;
|
||||
|
||||
/* Start timer if specified to be enabled and not already running */
|
||||
if (init->enable && !(letimer->STATUS & LETIMER_STATUS_RUNNING))
|
||||
{
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
|
||||
#endif
|
||||
letimer->CMD = LETIMER_CMD_START;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get LETIMER repeat register value.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block
|
||||
*
|
||||
* @param[in] rep
|
||||
* Repeat register to get, either 0 or 1
|
||||
*
|
||||
* @return
|
||||
* Repeat register value, 0 if invalid register selected.
|
||||
******************************************************************************/
|
||||
uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_REP_REG_VALID(rep));
|
||||
|
||||
/* Initialize selected compare value */
|
||||
switch (rep)
|
||||
{
|
||||
case 0:
|
||||
ret = letimer->REP0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ret = letimer->REP1;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown compare register selected */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set LETIMER repeat counter register value.
|
||||
*
|
||||
* @note
|
||||
* The setting of a repeat counter register requires synchronization into the
|
||||
* low frequency domain. If the same register is modified before a previous
|
||||
* update has completed, this function will stall until the previous
|
||||
* synchronization has completed. This only applies to the Gecko Family, see
|
||||
* comment in the LETIMER_Sync() internal function call.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block
|
||||
*
|
||||
* @param[in] rep
|
||||
* Repeat counter register to set, either 0 or 1
|
||||
*
|
||||
* @param[in] value
|
||||
* Initialization value (<= 0x0000ffff)
|
||||
******************************************************************************/
|
||||
void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
|
||||
unsigned int rep,
|
||||
uint32_t value)
|
||||
{
|
||||
volatile uint32_t *repReg;
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
uint32_t syncbusy;
|
||||
#endif
|
||||
EFM_ASSERT(LETIMER_REF_VALID(letimer) &&
|
||||
LETIMER_REP_REG_VALID(rep) &&
|
||||
((value & ~(_LETIMER_REP0_REP0_MASK >> _LETIMER_REP0_REP0_SHIFT)) == 0));
|
||||
|
||||
/* Initialize selected compare value */
|
||||
switch (rep)
|
||||
{
|
||||
case 0:
|
||||
repReg = &(letimer->REP0);
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
syncbusy = LETIMER_SYNCBUSY_REP0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 1:
|
||||
repReg = &(letimer->REP1);
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
syncbusy = LETIMER_SYNCBUSY_REP1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown compare register selected, abort */
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LETIMER_Sync(letimer, syncbusy);
|
||||
#endif
|
||||
|
||||
*repReg = value;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset LETIMER to same state as after a HW reset.
|
||||
*
|
||||
* @note
|
||||
* The ROUTE register is NOT reset by this function, in order to allow for
|
||||
* centralized setup of this feature.
|
||||
*
|
||||
* @param[in] letimer
|
||||
* Pointer to LETIMER peripheral register block.
|
||||
******************************************************************************/
|
||||
void LETIMER_Reset(LETIMER_TypeDef *letimer)
|
||||
{
|
||||
/* Freeze registers to avoid stalling for LF synchronization */
|
||||
LETIMER_FreezeEnable(letimer, true);
|
||||
|
||||
/* Make sure disabled first, before resetting other registers */
|
||||
letimer->CMD = LETIMER_CMD_STOP | LETIMER_CMD_CLEAR |
|
||||
LETIMER_CMD_CTO0 | LETIMER_CMD_CTO1;
|
||||
letimer->CTRL = _LETIMER_CTRL_RESETVALUE;
|
||||
letimer->COMP0 = _LETIMER_COMP0_RESETVALUE;
|
||||
letimer->COMP1 = _LETIMER_COMP1_RESETVALUE;
|
||||
letimer->REP0 = _LETIMER_REP0_RESETVALUE;
|
||||
letimer->REP1 = _LETIMER_REP1_RESETVALUE;
|
||||
letimer->IEN = _LETIMER_IEN_RESETVALUE;
|
||||
letimer->IFC = _LETIMER_IFC_MASK;
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
|
||||
/* Unfreeze registers, pass new settings on to LETIMER */
|
||||
LETIMER_FreezeEnable(letimer, false);
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup LETIMER) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,635 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Low Energy Universal Asynchronous Receiver/Transmitter (LEUART)
|
||||
* peripheral module peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_leuart.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup LEUART
|
||||
* @brief Low Energy Universal Asynchronous Receiver/Transmitter (LEUART)
|
||||
* Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
|
||||
/** Validation of LEUART register block pointer reference
|
||||
* for assert statements. */
|
||||
#if (LEUART_COUNT == 1)
|
||||
#define LEUART_REF_VALID(ref) ((ref) == LEUART0)
|
||||
#elif (LEUART_COUNT == 2)
|
||||
#define LEUART_REF_VALID(ref) (((ref) == LEUART0) || ((ref) == LEUART1))
|
||||
#else
|
||||
#error Undefined number of low energy UARTs (LEUART).
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL FUNCTIONS ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Wait for ongoing sync of register(s) to low frequency domain to complete.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block
|
||||
*
|
||||
* @param[in] mask
|
||||
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
|
||||
* registers that must complete any ongoing synchronization.
|
||||
******************************************************************************/
|
||||
static __INLINE void LEUART_Sync(LEUART_TypeDef *leuart, uint32_t mask)
|
||||
{
|
||||
/* Avoid deadlock if modifying the same register twice when freeze mode is */
|
||||
/* activated. */
|
||||
if (leuart->FREEZE & LEUART_FREEZE_REGFREEZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Wait for any pending previous write operation to have been completed */
|
||||
/* in low frequency domain */
|
||||
while (leuart->SYNCBUSY & mask)
|
||||
;
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Calculate baudrate for LEUART given reference frequency and clock division.
|
||||
*
|
||||
* @details
|
||||
* This function returns the baudrate that a LEUART module will use if
|
||||
* configured with the given frequency and clock divisor. Notice that
|
||||
* this function will not use actual HW configuration. It can be used
|
||||
* to determinate if a given configuration is sufficiently accurate for the
|
||||
* application.
|
||||
*
|
||||
* @param[in] refFreq
|
||||
* LEUART peripheral frequency used.
|
||||
*
|
||||
* @param[in] clkdiv
|
||||
* Clock division factor to be used.
|
||||
*
|
||||
* @return
|
||||
* Baudrate with given settings.
|
||||
******************************************************************************/
|
||||
uint32_t LEUART_BaudrateCalc(uint32_t refFreq, uint32_t clkdiv)
|
||||
{
|
||||
uint32_t divisor;
|
||||
uint32_t remainder;
|
||||
uint32_t quotient;
|
||||
uint32_t br;
|
||||
|
||||
/* Mask out unused bits */
|
||||
clkdiv &= _LEUART_CLKDIV_MASK;
|
||||
|
||||
/* We want to use integer division to avoid forcing in float division */
|
||||
/* utils, and yet keep rounding effect errors to a minimum. */
|
||||
|
||||
/*
|
||||
* Baudrate is given by:
|
||||
*
|
||||
* br = fLEUARTn/(1 + (CLKDIV / 256))
|
||||
*
|
||||
* which can be rewritten to
|
||||
*
|
||||
* br = (256 * fLEUARTn)/(256 + CLKDIV)
|
||||
*
|
||||
* Normally, with fLEUARTn appr 32768Hz, there is no problem with overflow
|
||||
* if using 32 bit arithmetic. However, since fLEUARTn may be derived from
|
||||
* HFCORECLK as well, we must consider overflow when using integer arithmetic.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The basic problem with integer division in the above formula is that
|
||||
* the dividend (256 * fLEUARTn) may become higher than max 32 bit
|
||||
* integer. Yet we want to evaluate dividend first before dividing in
|
||||
* order to get as small rounding effects as possible. We do not want
|
||||
* to make too harsh restrictions on max fLEUARTn value either.
|
||||
*
|
||||
* For division a/b, we can write
|
||||
*
|
||||
* a = qb + r
|
||||
*
|
||||
* where q is the quotient and r is the remainder, both integers.
|
||||
*
|
||||
* The orignal baudrate formula can be rewritten as
|
||||
*
|
||||
* br = 256a / b = 256(qb + r)/b = 256q + 256r/b
|
||||
*
|
||||
* where a is 'refFreq' and b is 'divisor', referring to variable names.
|
||||
*/
|
||||
|
||||
divisor = 256 + clkdiv;
|
||||
|
||||
quotient = refFreq / divisor;
|
||||
remainder = refFreq % divisor;
|
||||
|
||||
/* Since divisor >= 256, the below cannot exceed max 32 bit value. */
|
||||
br = 256 * quotient;
|
||||
|
||||
/*
|
||||
* Remainder < (256 + clkdiv), which means dividend (256 * remainder) worst case is
|
||||
* 256*(256 + 0x7ff8) = 0x80F800.
|
||||
*/
|
||||
br += (256 * remainder) / divisor;
|
||||
|
||||
return br;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current baudrate for LEUART.
|
||||
*
|
||||
* @details
|
||||
* This function returns the actual baudrate (not considering oscillator
|
||||
* inaccuracies) used by a LEUART peripheral.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current baudrate.
|
||||
******************************************************************************/
|
||||
uint32_t LEUART_BaudrateGet(LEUART_TypeDef *leuart)
|
||||
{
|
||||
uint32_t freq;
|
||||
CMU_Clock_TypeDef clock;
|
||||
|
||||
/* Get current frequency */
|
||||
if (leuart == LEUART0)
|
||||
{
|
||||
clock = cmuClock_LEUART0;
|
||||
}
|
||||
#if (LEUART_COUNT > 1)
|
||||
else if (leuart == LEUART1)
|
||||
{
|
||||
clock = cmuClock_LEUART1;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
EFM_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
freq = CMU_ClockFreqGet(clock);
|
||||
|
||||
return LEUART_BaudrateCalc(freq, leuart->CLKDIV);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure baudrate (or as close as possible to specified baudrate).
|
||||
*
|
||||
* @note
|
||||
* The setting of a baudrate requires synchronization into the
|
||||
* low frequency domain. If the same register is modified before a previous
|
||||
* update has completed, this function will stall until the previous
|
||||
* synchronization has completed.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] refFreq
|
||||
* LEUART reference clock frequency in Hz that will be used. If set to 0,
|
||||
* the currently configured reference clock is assumed.
|
||||
*
|
||||
* @param[in] baudrate
|
||||
* Baudrate to try to achieve for LEUART.
|
||||
******************************************************************************/
|
||||
void LEUART_BaudrateSet(LEUART_TypeDef *leuart,
|
||||
uint32_t refFreq,
|
||||
uint32_t baudrate)
|
||||
{
|
||||
uint32_t clkdiv;
|
||||
CMU_Clock_TypeDef clock;
|
||||
|
||||
/* Inhibit divide by 0 */
|
||||
EFM_ASSERT(baudrate);
|
||||
|
||||
/*
|
||||
* We want to use integer division to avoid forcing in float division
|
||||
* utils, and yet keep rounding effect errors to a minimum.
|
||||
*
|
||||
* CLKDIV in asynchronous mode is given by:
|
||||
*
|
||||
* CLKDIV = 256*(fLEUARTn/br - 1) = ((256*fLEUARTn)/br) - 256
|
||||
*
|
||||
* Normally, with fLEUARTn appr 32768Hz, there is no problem with overflow
|
||||
* if using 32 bit arithmetic. However, since fLEUARTn may be derived from
|
||||
* HFCORECLK as well, we must consider overflow when using integer arithmetic.
|
||||
*
|
||||
* The basic problem with integer division in the above formula is that
|
||||
* the dividend (256 * fLEUARTn) may become higher than max 32 bit
|
||||
* integer. Yet, we want to evaluate dividend first before dividing in
|
||||
* order to get as small rounding effects as possible. We do not want
|
||||
* to make too harsh restrictions on max fLEUARTn value either.
|
||||
*
|
||||
* Since the last 3 bits of CLKDIV are don't care, we can base our
|
||||
* integer arithmetic on the below formula
|
||||
*
|
||||
* CLKDIV/8 = ((32*fLEUARTn)/br) - 32
|
||||
*
|
||||
* and calculate 1/8 of CLKDIV first. This allows for fLEUARTn
|
||||
* up to 128MHz without overflowing a 32 bit value!
|
||||
*/
|
||||
|
||||
/* Get current frequency? */
|
||||
if (!refFreq)
|
||||
{
|
||||
if (leuart == LEUART0)
|
||||
{
|
||||
clock = cmuClock_LEUART0;
|
||||
}
|
||||
#if (LEUART_COUNT > 1)
|
||||
else if (leuart == LEUART1)
|
||||
{
|
||||
clock = cmuClock_LEUART1;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
EFM_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
refFreq = CMU_ClockFreqGet(clock);
|
||||
}
|
||||
|
||||
/* Calculate and set CLKDIV with fractional bits */
|
||||
clkdiv = (32 * refFreq) / baudrate;
|
||||
clkdiv -= 32;
|
||||
clkdiv *= 8;
|
||||
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LEUART_Sync(leuart, LEUART_SYNCBUSY_CLKDIV);
|
||||
|
||||
leuart->CLKDIV = clkdiv;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable LEUART receiver and/or transmitter.
|
||||
*
|
||||
* @details
|
||||
* Notice that this function does not do any configuration. Enabling should
|
||||
* normally be done after initialization is done (if not enabled as part
|
||||
* of init).
|
||||
*
|
||||
* @note
|
||||
* Enabling/disabling requires synchronization into the low frequency domain.
|
||||
* If the same register is modified before a previous update has completed,
|
||||
* this function will stall until the previous synchronization has completed.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] enable
|
||||
* Select status for receiver/transmitter.
|
||||
******************************************************************************/
|
||||
void LEUART_Enable(LEUART_TypeDef *leuart, LEUART_Enable_TypeDef enable)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Make sure the module exists on the selected chip */
|
||||
EFM_ASSERT(LEUART_REF_VALID(leuart));
|
||||
|
||||
/* Disable as specified */
|
||||
tmp = ~((uint32_t)(enable));
|
||||
tmp &= (_LEUART_CMD_RXEN_MASK | _LEUART_CMD_TXEN_MASK);
|
||||
tmp <<= 1;
|
||||
/* Enable as specified */
|
||||
tmp |= (uint32_t)(enable);
|
||||
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LEUART_Sync(leuart, LEUART_SYNCBUSY_CMD);
|
||||
|
||||
leuart->CMD = tmp;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* LEUART register synchronization freeze control.
|
||||
*
|
||||
* @details
|
||||
* Some LEUART registers require synchronization into the low frequency (LF)
|
||||
* domain. The freeze feature allows for several such registers to be
|
||||
* modified before passing them to the LF domain simultaneously (which
|
||||
* takes place when the freeze mode is disabled).
|
||||
*
|
||||
* @note
|
||||
* When enabling freeze mode, this function will wait for all current
|
||||
* ongoing LEUART synchronization to LF domain to complete (Normally
|
||||
* synchronization will not be in progress.) However for this reason, when
|
||||
* using freeze mode, modifications of registers requiring LF synchronization
|
||||
* should be done within one freeze enable/disable block to avoid unecessary
|
||||
* stalling.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] enable
|
||||
* @li true - enable freeze, modified registers are not propagated to the
|
||||
* LF domain
|
||||
* @li false - disables freeze, modified registers are propagated to LF
|
||||
* domain
|
||||
******************************************************************************/
|
||||
void LEUART_FreezeEnable(LEUART_TypeDef *leuart, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
/*
|
||||
* Wait for any ongoing LF synchronization to complete. This is just to
|
||||
* protect against the rare case when a user
|
||||
* - modifies a register requiring LF sync
|
||||
* - then enables freeze before LF sync completed
|
||||
* - then modifies the same register again
|
||||
* since modifying a register while it is in sync progress should be
|
||||
* avoided.
|
||||
*/
|
||||
while (leuart->SYNCBUSY)
|
||||
;
|
||||
|
||||
leuart->FREEZE = LEUART_FREEZE_REGFREEZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
leuart->FREEZE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Init LEUART.
|
||||
*
|
||||
* @details
|
||||
* This function will configure basic settings in order to operate in normal
|
||||
* asynchronous mode. Consider using LEUART_Reset() prior to this function if
|
||||
* state of configuration is not known, since only configuration settings
|
||||
* specified by @p init are set.
|
||||
*
|
||||
* Special control setup not covered by this function may be done either
|
||||
* before or after using this function (but normally before enabling)
|
||||
* by direct modification of the CTRL register.
|
||||
*
|
||||
* Notice that pins used by the LEUART module must be properly configured
|
||||
* by the user explicitly, in order for the LEUART to work as intended.
|
||||
* (When configuring pins, one should remember to consider the sequence of
|
||||
* configuration, in order to avoid unintended pulses/glitches on output
|
||||
* pins.)
|
||||
*
|
||||
* @note
|
||||
* Initializing requires synchronization into the low frequency domain.
|
||||
* If the same register is modified before a previous update has completed,
|
||||
* this function will stall until the previous synchronization has completed.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to initialization structure used to configure basic async setup.
|
||||
******************************************************************************/
|
||||
void LEUART_Init(LEUART_TypeDef *leuart, LEUART_Init_TypeDef *init)
|
||||
{
|
||||
/* Make sure the module exists on the selected chip */
|
||||
EFM_ASSERT(LEUART_REF_VALID(leuart));
|
||||
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LEUART_Sync(leuart, LEUART_SYNCBUSY_CMD);
|
||||
|
||||
/* Ensure disabled while doing config */
|
||||
leuart->CMD = LEUART_CMD_RXDIS | LEUART_CMD_TXDIS;
|
||||
|
||||
/* Freeze registers to avoid stalling for LF synchronization */
|
||||
LEUART_FreezeEnable(leuart, true);
|
||||
|
||||
/* Configure databits and stopbits */
|
||||
leuart->CTRL = (leuart->CTRL & ~(_LEUART_CTRL_PARITY_MASK |
|
||||
_LEUART_CTRL_STOPBITS_MASK)) |
|
||||
(uint32_t)(init->databits) |
|
||||
(uint32_t)(init->parity) |
|
||||
(uint32_t)(init->stopbits);
|
||||
|
||||
/* Configure baudrate */
|
||||
LEUART_BaudrateSet(leuart, init->refFreq, init->baudrate);
|
||||
|
||||
/* Finally enable (as specified) */
|
||||
leuart->CMD = (uint32_t)(init->enable);
|
||||
|
||||
/* Unfreeze registers, pass new settings on to LEUART */
|
||||
LEUART_FreezeEnable(leuart, false);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset LEUART to same state as after a HW reset.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
******************************************************************************/
|
||||
void LEUART_Reset(LEUART_TypeDef *leuart)
|
||||
{
|
||||
/* Make sure the module exists on the selected chip */
|
||||
EFM_ASSERT(LEUART_REF_VALID(leuart));
|
||||
|
||||
/* Freeze registers to avoid stalling for LF synchronization */
|
||||
LEUART_FreezeEnable(leuart, true);
|
||||
|
||||
/* Make sure disabled first, before resetting other registers */
|
||||
leuart->CMD = LEUART_CMD_RXDIS | LEUART_CMD_TXDIS | LEUART_CMD_RXBLOCKDIS |
|
||||
LEUART_CMD_CLEARTX | LEUART_CMD_CLEARRX;
|
||||
leuart->CTRL = _LEUART_CTRL_RESETVALUE;
|
||||
leuart->CLKDIV = _LEUART_CLKDIV_RESETVALUE;
|
||||
leuart->STARTFRAME = _LEUART_STARTFRAME_RESETVALUE;
|
||||
leuart->SIGFRAME = _LEUART_SIGFRAME_RESETVALUE;
|
||||
leuart->IEN = _LEUART_IEN_RESETVALUE;
|
||||
leuart->IFC = _LEUART_IFC_MASK;
|
||||
leuart->PULSECTRL = _LEUART_PULSECTRL_RESETVALUE;
|
||||
leuart->ROUTE = _LEUART_ROUTE_RESETVALUE;
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
|
||||
/* Unfreeze registers, pass new settings on to LEUART */
|
||||
LEUART_FreezeEnable(leuart, false);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Receive one 8 bit frame, (or part of 9 bit frame).
|
||||
*
|
||||
* @details
|
||||
* This function is normally used to receive one frame when operating with
|
||||
* frame length 8 bits. Please refer to LEUART_RxExt() for reception of
|
||||
* 9 bit frames.
|
||||
*
|
||||
* Notice that possible parity/stop bits are not considered part of specified
|
||||
* frame bit length.
|
||||
*
|
||||
* @note
|
||||
* This function will stall if buffer is empty, until data is received.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Data received.
|
||||
******************************************************************************/
|
||||
uint8_t LEUART_Rx(LEUART_TypeDef *leuart)
|
||||
{
|
||||
while (!(leuart->STATUS & LEUART_STATUS_RXDATAV))
|
||||
;
|
||||
|
||||
return (uint8_t)(leuart->RXDATA);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Receive one 8-9 bit frame, with extended information.
|
||||
*
|
||||
* @details
|
||||
* This function is normally used to receive one frame and additional RX
|
||||
* status information is required.
|
||||
*
|
||||
* @note
|
||||
* This function will stall if buffer is empty, until data is received.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Data received.
|
||||
******************************************************************************/
|
||||
uint16_t LEUART_RxExt(LEUART_TypeDef *leuart)
|
||||
{
|
||||
while (!(leuart->STATUS & LEUART_STATUS_RXDATAV))
|
||||
;
|
||||
|
||||
return (uint16_t)(leuart->RXDATAX);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Transmit one frame.
|
||||
*
|
||||
* @details
|
||||
* Depending on frame length configuration, 8 (least significant) bits from
|
||||
* @p data are transmitted. If frame length is 9, 8 bits are transmitted from
|
||||
* @p data and one bit as specified by CTRL register, BIT8DV field. Please
|
||||
* refer to LEUART_TxExt() for transmitting 9 bit frame with full control of
|
||||
* all 9 bits.
|
||||
*
|
||||
* Notice that possible parity/stop bits in asynchronous mode are not
|
||||
* considered part of specified frame bit length.
|
||||
*
|
||||
* @note
|
||||
* This function will stall if buffer is full, until buffer becomes available.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] data
|
||||
* Data to transmit. See details above for further info.
|
||||
******************************************************************************/
|
||||
void LEUART_Tx(LEUART_TypeDef *leuart, uint8_t data)
|
||||
{
|
||||
/* Check that transmit buffer is empty */
|
||||
while (!(leuart->STATUS & LEUART_STATUS_TXBL))
|
||||
;
|
||||
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LEUART_Sync(leuart, LEUART_SYNCBUSY_TXDATA);
|
||||
|
||||
leuart->TXDATA = (uint32_t)data;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Transmit one 8-9 bit frame with extended control.
|
||||
*
|
||||
* @details
|
||||
* Notice that possible parity/stop bits in asynchronous mode are not
|
||||
* considered part of specified frame bit length.
|
||||
*
|
||||
* @note
|
||||
* This function will stall if buffer is full, until buffer becomes available.
|
||||
*
|
||||
* @param[in] leuart
|
||||
* Pointer to LEUART peripheral register block.
|
||||
*
|
||||
* @param[in] data
|
||||
* Data to transmit with extended control. Least significant bits contains
|
||||
* frame bits, and additional control bits are available as documented in
|
||||
* the EFM32 reference manual (set to 0 if not used).
|
||||
******************************************************************************/
|
||||
void LEUART_TxExt(LEUART_TypeDef *leuart, uint16_t data)
|
||||
{
|
||||
/* Check that transmit buffer is empty */
|
||||
while (!(leuart->STATUS & LEUART_STATUS_TXBL))
|
||||
;
|
||||
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
LEUART_Sync(leuart, LEUART_SYNCBUSY_TXDATAX);
|
||||
|
||||
leuart->TXDATAX = (uint32_t)data;
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup LEUART) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,117 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Memory Protection Unit (MPU) Peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32_mpu.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup MPU
|
||||
* @brief Memory Protection Unit (MPU) Peripheral API for EFM32
|
||||
* @details
|
||||
* This module contains functions to enable, disable and setup the MPU.
|
||||
* The MPU is used to control access attributes and permissions in the
|
||||
* memory map. The settings that can be controlled are:
|
||||
*
|
||||
* @li Executable attribute.
|
||||
* @li Cachable, bufferable and shareable attributes.
|
||||
* @li Cache policy.
|
||||
* @li Access permissions: Priviliged or User state, read or write access,
|
||||
* and combinations of all these.
|
||||
*
|
||||
* The MPU can be activated and deactivated with functions:
|
||||
* @verbatim
|
||||
* MPU_Enable(..);
|
||||
* MPU_Disable();@endverbatim
|
||||
* The MPU can control 8 memory regions with individual access control
|
||||
* settings. Section attributes and permissions are set with:
|
||||
* @verbatim
|
||||
* MPU_ConfigureRegion(..);@endverbatim
|
||||
* It is advisable to disable the MPU when altering region settings.
|
||||
*
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure an MPU region.
|
||||
*
|
||||
* @details
|
||||
* Writes to MPU RBAR and RASR registers.
|
||||
* Refer to Cortex-M3 Reference Manual, MPU chapter for further details.
|
||||
* To disable a region it is only required to set init->regionNo to the
|
||||
* desired value and init->regionEnable = false.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to a structure containing MPU region init information.
|
||||
******************************************************************************/
|
||||
void MPU_ConfigureRegion(const MPU_RegionInit_TypeDef *init)
|
||||
{
|
||||
EFM_ASSERT(init->regionNo < ((MPU->TYPE & MPU_TYPE_DREGION_Msk) >>
|
||||
MPU_TYPE_DREGION_Pos));
|
||||
|
||||
MPU->RNR = init->regionNo;
|
||||
|
||||
if (init->regionEnable)
|
||||
{
|
||||
EFM_ASSERT(!(init->baseAddress & ~MPU_RBAR_ADDR_Msk));
|
||||
EFM_ASSERT(init->tex <= 0x7);
|
||||
|
||||
MPU->RBAR = init->baseAddress;
|
||||
MPU->RASR = ((init->disableExec ? 1 : 0) << MPU_RASR_XN_Pos) |
|
||||
(init->accessPermission << MPU_RASR_AP_Pos) |
|
||||
(init->tex << MPU_RASR_TEX_Pos) |
|
||||
((init->shareable ? 1 : 0) << MPU_RASR_S_Pos) |
|
||||
((init->cacheable ? 1 : 0) << MPU_RASR_C_Pos) |
|
||||
((init->bufferable ? 1 : 0) << MPU_RASR_B_Pos) |
|
||||
(init->srd << MPU_RASR_SRD_Pos) |
|
||||
(init->size << MPU_RASR_SIZE_Pos) |
|
||||
(1 << MPU_RASR_ENA_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
MPU->RBAR = 0;
|
||||
MPU->RASR = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup CMU) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,369 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Flash controller (MSC) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32_msc.h"
|
||||
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
#include "efm32_cmu.h"
|
||||
#endif
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup MSC
|
||||
* @brief Flash controller (MSC) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables the flash controller for writing.
|
||||
* @note
|
||||
* IMPORTANT: This function must be called before flash operations when
|
||||
* AUXHFRCO clock has been changed from default 14MHz band.
|
||||
******************************************************************************/
|
||||
void MSC_Init(void)
|
||||
{
|
||||
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
uint32_t freq, cycles;
|
||||
#endif
|
||||
/* Enable writing to the MSC */
|
||||
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
|
||||
/* Unlock the MSC */
|
||||
MSC->LOCK = MSC_UNLOCK_CODE;
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
|
||||
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/* Configure MSC->TIMEBASE according to selected frequency */
|
||||
freq = CMU_ClockFreqGet(cmuClock_AUX);
|
||||
|
||||
if( freq > 7000000)
|
||||
{
|
||||
/* Calculate number of clock cycles for 1us as base period */
|
||||
freq = (freq * 11) / 10;
|
||||
cycles = (freq / 1000000) + 1;
|
||||
|
||||
/* Configure clock cycles for flash timing */
|
||||
MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK|
|
||||
_MSC_TIMEBASE_PERIOD_MASK))|
|
||||
MSC_TIMEBASE_PERIOD_1US|
|
||||
(cycles << _MSC_TIMEBASE_BASE_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate number of clock cycles for 5us as base period */
|
||||
freq = (freq * 5 * 11) / 10;
|
||||
cycles = (freq / 1000000) + 1;
|
||||
|
||||
/* Configure clock cycles for flash timing */
|
||||
MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK|
|
||||
_MSC_TIMEBASE_PERIOD_MASK))|
|
||||
MSC_TIMEBASE_PERIOD_5US|
|
||||
(cycles << _MSC_TIMEBASE_BASE_SHIFT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disables the flash controller for writing.
|
||||
******************************************************************************/
|
||||
void MSC_Deinit(void)
|
||||
{
|
||||
/* Enable writing to the MSC */
|
||||
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
|
||||
/* Lock the MSC */
|
||||
MSC->LOCK = 0;
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Erases a page in flash memory.
|
||||
* @note
|
||||
* This function MUST be executed from RAM. Failure to execute this portion
|
||||
* of the code in RAM will result in a hardfault. For IAR, Rowley and
|
||||
* Codesourcery this will be achieved automatically. For Keil uVision 4 you
|
||||
* must define a section called "ram_code" and place this manually in your
|
||||
* project's scatter file.
|
||||
* @param[in] startAddress
|
||||
* Pointer to the flash page to erase. Must be aligned to beginning of page
|
||||
* boundary.
|
||||
* @return
|
||||
* Returns the status of erase operation, #msc_Return_TypeDef
|
||||
* @verbatim
|
||||
* flashReturnOk - Operation completed successfully.
|
||||
* flashReturnInvalidAddr - Operation tried to erase a non-flash area.
|
||||
* flashReturnLocked - Operation tried to erase a locked area of the flash.
|
||||
* flashReturnTimeOut - Operation timed out waiting for flash operation
|
||||
* to complete.
|
||||
* @endverbatim
|
||||
******************************************************************************/
|
||||
#ifdef __CC_ARM /* MDK-ARM compiler */
|
||||
#pragma arm section code="ram_code"
|
||||
#endif /* __CC_ARM */
|
||||
#if defined( __ICCARM__ )
|
||||
/* Suppress warnings originating from use of EFM_ASSERT(): */
|
||||
/* "Call to a non __ramfunc function from within a __ramfunc function" */
|
||||
/* "Possible rom access from within a __ramfunc function" */
|
||||
#pragma diag_suppress=Ta022
|
||||
#pragma diag_suppress=Ta023
|
||||
#endif
|
||||
msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress)
|
||||
{
|
||||
int timeOut = MSC_PROGRAM_TIMEOUT;
|
||||
|
||||
/* Address must be aligned to pages */
|
||||
EFM_ASSERT((((uint32_t)startAddress) & 0x1FF) == 0);
|
||||
|
||||
/* Enable writing to the MSC */
|
||||
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
|
||||
|
||||
/* Load address */
|
||||
MSC->ADDRB = (uint32_t)startAddress;
|
||||
MSC->WRITECMD = MSC_WRITECMD_LADDRIM;
|
||||
|
||||
/* Check for invalid address */
|
||||
if (MSC->STATUS & MSC_STATUS_INVADDR)
|
||||
{
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnInvalidAddr;
|
||||
}
|
||||
|
||||
/* Check for write protected page */
|
||||
if (MSC->STATUS & MSC_STATUS_LOCKED)
|
||||
{
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnLocked;
|
||||
}
|
||||
|
||||
/* Send erase page command */
|
||||
MSC->WRITECMD = MSC_WRITECMD_ERASEPAGE;
|
||||
|
||||
/* Wait for the erase to complete */
|
||||
while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
|
||||
{
|
||||
timeOut--;
|
||||
}
|
||||
|
||||
if (timeOut == 0)
|
||||
{
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnTimeOut;
|
||||
}
|
||||
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnOk;
|
||||
}
|
||||
#if defined( __ICCARM__ )
|
||||
#pragma diag_default=Ta022
|
||||
#pragma diag_default=Ta023
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Writes a single word to flash memory. Data to write must be aligned to
|
||||
* words and contain a number of bytes that is divisable by four.
|
||||
* @note
|
||||
* The flash must be erased prior to writing a new word.
|
||||
* This function must be run from RAM. Failure to execute this portion
|
||||
* of the code in RAM will result in a hardfault. For IAR, Rowley and
|
||||
* Codesourcery this will be achieved automatically. For Keil uVision 4 you
|
||||
* must define a section called "ram_code" and place this manually in your
|
||||
* project's scatter file.
|
||||
*
|
||||
* @param[in] address
|
||||
* Pointer to the flash word to write to. Must be aligned to words.
|
||||
* @param[in] data
|
||||
* Data to write to flash.
|
||||
* @param[in] numBytes
|
||||
* Number of bytes to write from flash. NB: Must be divisable by four.
|
||||
* @return
|
||||
* Returns the status of the write operation, #msc_Return_TypeDef
|
||||
* @verbatim
|
||||
* flashReturnOk - Operation completed successfully.
|
||||
* flashReturnInvalidAddr - Operation tried to erase a non-flash area.
|
||||
* flashReturnLocked - Operation tried to erase a locked area of the flash.
|
||||
* flashReturnTimeOut - Operation timed out waiting for flash operation
|
||||
* to complete.
|
||||
* @endverbatim
|
||||
******************************************************************************/
|
||||
#ifdef __CC_ARM /* MDK-ARM compiler */
|
||||
#pragma arm section code="ram_code"
|
||||
#endif /* __CC_ARM */
|
||||
#if defined( __ICCARM__ )
|
||||
/* Suppress warnings originating from use of EFM_ASSERT(): */
|
||||
/* "Call to a non __ramfunc function from within a __ramfunc function" */
|
||||
/* "Possible rom access from within a __ramfunc function" */
|
||||
#pragma diag_suppress=Ta022
|
||||
#pragma diag_suppress=Ta023
|
||||
#endif
|
||||
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes)
|
||||
{
|
||||
int timeOut;
|
||||
int wordCount;
|
||||
int numWords;
|
||||
|
||||
/* Check alignment (Must be aligned to words) */
|
||||
EFM_ASSERT(((uint32_t) address & 0x3) == 0);
|
||||
|
||||
/* Check number of bytes. Must be divisable by four */
|
||||
EFM_ASSERT((numBytes & 0x3) == 0);
|
||||
|
||||
/* Enable writing to the MSC */
|
||||
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
|
||||
|
||||
/* Convert bytes to words */
|
||||
numWords = numBytes >> 2;
|
||||
|
||||
for (wordCount = 0; wordCount < numWords; wordCount++)
|
||||
{
|
||||
/* Load address */
|
||||
MSC->ADDRB = (uint32_t)(address + wordCount);
|
||||
MSC->WRITECMD = MSC_WRITECMD_LADDRIM;
|
||||
|
||||
/* Check for invalid address */
|
||||
if (MSC->STATUS & MSC_STATUS_INVADDR)
|
||||
{
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnInvalidAddr;
|
||||
}
|
||||
|
||||
/* Check for write protected page */
|
||||
if (MSC->STATUS & MSC_STATUS_LOCKED)
|
||||
{
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnLocked;
|
||||
}
|
||||
|
||||
/* Wait for the MSC to be ready for a new data word */
|
||||
/* Due to the timing of this function, the MSC should already by ready */
|
||||
timeOut = MSC_PROGRAM_TIMEOUT;
|
||||
while (((MSC->STATUS & MSC_STATUS_WDATAREADY) == 0) && (timeOut != 0))
|
||||
{
|
||||
timeOut--;
|
||||
}
|
||||
|
||||
/* Check for timeout */
|
||||
if (timeOut == 0)
|
||||
{
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnTimeOut;
|
||||
}
|
||||
|
||||
/* Load data into write data register */
|
||||
MSC->WDATA = *(((uint32_t *)data) + wordCount);
|
||||
|
||||
/* Trigger write once */
|
||||
MSC->WRITECMD = MSC_WRITECMD_WRITEONCE;
|
||||
|
||||
/* Wait for the write to complete */
|
||||
timeOut = MSC_PROGRAM_TIMEOUT;
|
||||
while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
|
||||
{
|
||||
timeOut--;
|
||||
}
|
||||
|
||||
/* Check for timeout */
|
||||
if (timeOut == 0)
|
||||
{
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnTimeOut;
|
||||
}
|
||||
}
|
||||
/* Disable writing to the MSC */
|
||||
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
|
||||
return mscReturnOk;
|
||||
}
|
||||
#if defined( __ICCARM__ )
|
||||
#pragma diag_default=Ta022
|
||||
#pragma diag_default=Ta023
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Erase entire flash in one operation
|
||||
* @note
|
||||
* This command will erase the entire contents of the device.
|
||||
* Use with care, both a debug session and all contents of the flash will be
|
||||
* lost. The lock bit, MLW will prevent this operation from executing and
|
||||
* might prevent successful mass erase.
|
||||
******************************************************************************/
|
||||
#ifdef __CC_ARM /* MDK-ARM compiler */
|
||||
#pragma arm section code="ram_code"
|
||||
#endif /* __CC_ARM */
|
||||
msc_Return_TypeDef MSC_MassErase(void)
|
||||
{
|
||||
/* Enable writing to the MSC */
|
||||
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
|
||||
|
||||
/* Unlock device mass erase */
|
||||
MSC->MASSLOCK = MSC_MASSLOCK_LOCKKEY_UNLOCK;
|
||||
|
||||
/* Erase first 512K block */
|
||||
MSC->WRITECMD = MSC_WRITECMD_ERASEMAIN0;
|
||||
|
||||
/* Waiting for erase to complete */
|
||||
while ((MSC->STATUS & MSC_STATUS_BUSY)){}
|
||||
|
||||
#if FLASH_SIZE >= (512*1024)
|
||||
/* Erase second 512K block */
|
||||
MSC->WRITECMD = MSC_WRITECMD_ERASEMAIN1;
|
||||
|
||||
/* Waiting for erase to complete */
|
||||
while ((MSC->STATUS & MSC_STATUS_BUSY)){}
|
||||
#endif
|
||||
|
||||
/* Restore mass erase lock */
|
||||
MSC->MASSLOCK = MSC_MASSLOCK_LOCKKEY_LOCK;
|
||||
|
||||
/* This will only successfully return if calling function is also in SRAM */
|
||||
return mscReturnOk;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup MSC) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,402 @@
|
|||
/**************************************************************************//**
|
||||
* @file
|
||||
* @brief Operational Amplifier (OPAMP) peripheral API for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
||||
******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include "efm32.h"
|
||||
#if defined( OPAMP_PRESENT ) && ( OPAMP_COUNT == 1 )
|
||||
|
||||
#include "efm32_system.h"
|
||||
#include "efm32_assert.h"
|
||||
#include "efm32_opamp.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup OPAMP
|
||||
* @brief Operational Amplifier (OPAMP) peripheral API for EFM32.
|
||||
* @details
|
||||
* This module contains functions to:
|
||||
* @li OPAMP_Enable() Configure and enable an opamp.
|
||||
* @li OPAMP_Disable() Disable an opamp.
|
||||
*
|
||||
* All OPAMP functions assume that the DAC clock is running. If the DAC is not
|
||||
* used, the clock can be turned off when the opamp's are configured.
|
||||
*
|
||||
* If the available gain values dont suit the application at hand, the resistor
|
||||
* ladders can be disabled and external gain programming resistors used.
|
||||
*
|
||||
* A number of predefined opamp setup macros are available for configuration
|
||||
* of the most common opamp topologies (see figures below).
|
||||
*
|
||||
* @note
|
||||
* <em>The terms POSPAD and NEGPAD in the figures are used to indicate that these
|
||||
* pads should be connected to a suitable signal ground.</em>
|
||||
*
|
||||
* \n<b>Unity gain voltage follower.</b>\n
|
||||
* Use predefined macros @ref OPA_INIT_UNITY_GAIN and
|
||||
* @ref OPA_INIT_UNITY_GAIN_OPA2.
|
||||
* @verbatim
|
||||
|
||||
|\
|
||||
___________|+\
|
||||
| \_______
|
||||
___|_ / |
|
||||
| | / |
|
||||
| |/ |
|
||||
|___________|
|
||||
@endverbatim
|
||||
*
|
||||
* \n<b>Non-inverting amplifier.</b>\n
|
||||
* Use predefined macros @ref OPA_INIT_NON_INVERTING and
|
||||
* @ref OPA_INIT_NON_INVERTING_OPA2.
|
||||
* @verbatim
|
||||
|
||||
|\
|
||||
___________|+\
|
||||
| \_______
|
||||
___|_ / |
|
||||
| | / |
|
||||
| |/ |
|
||||
|_____R2____|
|
||||
|
|
||||
R1
|
||||
|
|
||||
NEGPAD @endverbatim
|
||||
*
|
||||
* \n<b>Inverting amplifier.</b>\n
|
||||
* Use predefined macros @ref OPA_INIT_INVERTING and
|
||||
* @ref OPA_INIT_INVERTING_OPA2.
|
||||
* @verbatim
|
||||
|
||||
_____R2____
|
||||
| |
|
||||
| |\ |
|
||||
____R1_|___|_\ |
|
||||
| \____|___
|
||||
___| /
|
||||
| |+/
|
||||
| |/
|
||||
|
|
||||
POSPAD @endverbatim
|
||||
*
|
||||
* \n<b>Cascaded non-inverting amplifiers.</b>\n
|
||||
* Use predefined macros @ref OPA_INIT_CASCADED_NON_INVERTING_OPA0,
|
||||
* @ref OPA_INIT_CASCADED_NON_INVERTING_OPA1 and
|
||||
* @ref OPA_INIT_CASCADED_NON_INVERTING_OPA2.
|
||||
* @verbatim
|
||||
|
||||
|\ |\ |\
|
||||
___________|+\ OPA0 ___________|+\ OPA1 ___________|+\ OPA2
|
||||
| \_________| | \_________| | \_______
|
||||
___|_ / | ___|_ / | ___|_ / |
|
||||
| | / | | | / | | | / |
|
||||
| |/ | | |/ | | |/ |
|
||||
|_____R2____| |_____R2____| |_____R2____|
|
||||
| | |
|
||||
R1 R1 R1
|
||||
| | |
|
||||
NEGPAD NEGPAD NEGPAD @endverbatim
|
||||
*
|
||||
* \n<b>Cascaded inverting amplifiers.</b>\n
|
||||
* Use predefined macros @ref OPA_INIT_CASCADED_INVERTING_OPA0,
|
||||
* @ref OPA_INIT_CASCADED_INVERTING_OPA1 and
|
||||
* @ref OPA_INIT_CASCADED_INVERTING_OPA2.
|
||||
* @verbatim
|
||||
|
||||
_____R2____ _____R2____ _____R2____
|
||||
| | | | | |
|
||||
| |\ | | |\ | | |\ |
|
||||
____R1_|___|_\ | ____R1_|___|_\ | ____R1_|___|_\ |
|
||||
| \____|____| | \____|___| | \____|__
|
||||
___| / ___| / ___| /
|
||||
| |+/ OPA0 | |+/ OPA1 | |+/ OPA2
|
||||
| |/ | |/ | |/
|
||||
| | |
|
||||
POSPAD POSPAD POSPAD @endverbatim
|
||||
*
|
||||
* \n<b>Differential driver with two opamp's.</b>\n
|
||||
* Use predefined macros @ref OPA_INIT_DIFF_DRIVER_OPA0 and
|
||||
* @ref OPA_INIT_DIFF_DRIVER_OPA1.
|
||||
* @verbatim
|
||||
|
||||
__________________________
|
||||
| +
|
||||
| _____R2____
|
||||
|\ | | |
|
||||
___________|+\ OPA0 | | |\ OPA1 |
|
||||
| \_________|____R1_|___|_\ | _
|
||||
___|_ / | | \____|______
|
||||
| | / | ___| /
|
||||
| |/ | | |+/
|
||||
|________________| | |/
|
||||
|
|
||||
POSPAD @endverbatim
|
||||
*
|
||||
* \n<b>Differential receiver with three opamp's.</b>\n
|
||||
* Use predefined macros @ref OPA_INIT_DIFF_RECEIVER_OPA0,
|
||||
* @ref OPA_INIT_DIFF_RECEIVER_OPA1 and @ref OPA_INIT_DIFF_RECEIVER_OPA2.
|
||||
* @verbatim
|
||||
|
||||
|\
|
||||
__________|+\ OPA1
|
||||
_ | \_________
|
||||
___|_ / | | _____R2____
|
||||
| | / | | | |
|
||||
| |/ | | | |\ |
|
||||
|___________| |____R1_|___|_\ |
|
||||
| \____|___
|
||||
|\ ____R1_ ___| /
|
||||
+__________|+\ OPA0 | | |+/ OPA2
|
||||
| \_________| | |/
|
||||
___|_ / | R2
|
||||
| | / | |
|
||||
| |/ | NEGPAD OPA0
|
||||
|___________|
|
||||
@endverbatim
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable an Operational Amplifier.
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] opa
|
||||
* Selects an OPA, valid vaules are @ref OPA0, @ref OPA1 and @ref OPA2.
|
||||
******************************************************************************/
|
||||
void OPAMP_Disable( DAC_TypeDef *dac, OPAMP_TypeDef opa )
|
||||
{
|
||||
EFM_ASSERT( DAC_REF_VALID( dac ) );
|
||||
EFM_ASSERT( DAC_OPA_VALID( opa ) );
|
||||
|
||||
if ( opa == OPA0 )
|
||||
{
|
||||
dac->CH0CTRL &= ~DAC_CH0CTRL_EN;
|
||||
dac->OPACTRL &= ~DAC_OPACTRL_OPA0EN;
|
||||
}
|
||||
else if ( opa == OPA1 )
|
||||
{
|
||||
dac->CH1CTRL &= ~DAC_CH1CTRL_EN;
|
||||
dac->OPACTRL &= ~DAC_OPACTRL_OPA1EN;
|
||||
}
|
||||
else /* OPA2 */
|
||||
{
|
||||
dac->OPACTRL &= ~DAC_OPACTRL_OPA2EN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure and enable an Operational Amplifier.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* @param[in] dac
|
||||
* Pointer to DAC peripheral register block.
|
||||
*
|
||||
* @param[in] opa
|
||||
* Selects an OPA, valid vaules are @ref OPA0, @ref OPA1 and @ref OPA2.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to a structure containing OPAMP init information.
|
||||
******************************************************************************/
|
||||
void OPAMP_Enable( DAC_TypeDef *dac, OPAMP_TypeDef opa, const OPAMP_Init_TypeDef *init )
|
||||
{
|
||||
uint32_t offset;
|
||||
|
||||
EFM_ASSERT( DAC_REF_VALID( dac ) );
|
||||
EFM_ASSERT( DAC_OPA_VALID( opa ) );
|
||||
EFM_ASSERT( init->bias <= ( _DAC_BIASPROG_BIASPROG_MASK >>
|
||||
_DAC_BIASPROG_BIASPROG_SHIFT ) );
|
||||
|
||||
if ( opa == OPA0 )
|
||||
{
|
||||
EFM_ASSERT( ( init->outPen & ~_DAC_OPA0MUX_OUTPEN_MASK ) == 0 );
|
||||
|
||||
dac->BIASPROG = ( dac->BIASPROG
|
||||
& ~( _DAC_BIASPROG_BIASPROG_MASK |
|
||||
DAC_BIASPROG_HALFBIAS ) ) |
|
||||
( init->bias << _DAC_BIASPROG_BIASPROG_SHIFT ) |
|
||||
( init->halfBias ? DAC_BIASPROG_HALFBIAS : 0 );
|
||||
|
||||
if ( init->defaultOffset )
|
||||
{
|
||||
offset = SYSTEM_GetCalibrationValue( &dac->CAL );
|
||||
dac->CAL = ( dac->CAL & ~_DAC_CAL_CH0OFFSET_MASK ) |
|
||||
( offset & _DAC_CAL_CH0OFFSET_MASK );
|
||||
}
|
||||
else
|
||||
{
|
||||
EFM_ASSERT( init->offset <= ( _DAC_CAL_CH0OFFSET_MASK >>
|
||||
_DAC_CAL_CH0OFFSET_SHIFT ) );
|
||||
|
||||
dac->CAL = ( dac->CAL & ~_DAC_CAL_CH0OFFSET_MASK ) |
|
||||
( init->offset << _DAC_CAL_CH0OFFSET_SHIFT );
|
||||
}
|
||||
|
||||
dac->OPA0MUX = (uint32_t)init->resSel |
|
||||
(uint32_t)init->outMode |
|
||||
init->outPen |
|
||||
(uint32_t)init->resInMux |
|
||||
(uint32_t)init->negSel |
|
||||
(uint32_t)init->posSel |
|
||||
( init->nextOut ? DAC_OPA0MUX_NEXTOUT : 0 ) |
|
||||
( init->npEn ? DAC_OPA0MUX_NPEN : 0 ) |
|
||||
( init->ppEn ? DAC_OPA0MUX_PPEN : 0 );
|
||||
|
||||
dac->CH0CTRL |= DAC_CH0CTRL_EN;
|
||||
dac->OPACTRL = ( dac->OPACTRL
|
||||
& ~( DAC_OPACTRL_OPA0SHORT |
|
||||
_DAC_OPACTRL_OPA0LPFDIS_MASK |
|
||||
DAC_OPACTRL_OPA0HCMDIS ) ) |
|
||||
( init->shortInputs ? DAC_OPACTRL_OPA0SHORT : 0 ) |
|
||||
( init->lpfPosPadDisable ?
|
||||
DAC_OPACTRL_OPA0LPFDIS_PLPFDIS : 0 ) |
|
||||
( init->lpfNegPadDisable ?
|
||||
DAC_OPACTRL_OPA0LPFDIS_NLPFDIS : 0 ) |
|
||||
( init->hcmDisable ? DAC_OPACTRL_OPA0HCMDIS : 0 ) |
|
||||
( DAC_OPACTRL_OPA0EN );
|
||||
}
|
||||
else if ( opa == OPA1 )
|
||||
{
|
||||
EFM_ASSERT( ( init->outPen & ~_DAC_OPA1MUX_OUTPEN_MASK ) == 0 );
|
||||
|
||||
dac->BIASPROG = ( dac->BIASPROG
|
||||
& ~( _DAC_BIASPROG_BIASPROG_MASK |
|
||||
DAC_BIASPROG_HALFBIAS ) ) |
|
||||
( init->bias << _DAC_BIASPROG_BIASPROG_SHIFT ) |
|
||||
( init->halfBias ? DAC_BIASPROG_HALFBIAS : 0 );
|
||||
|
||||
if ( init->defaultOffset )
|
||||
{
|
||||
offset = SYSTEM_GetCalibrationValue( &dac->CAL );
|
||||
dac->CAL = ( dac->CAL & ~_DAC_CAL_CH1OFFSET_MASK ) |
|
||||
( offset & _DAC_CAL_CH1OFFSET_MASK );
|
||||
}
|
||||
else
|
||||
{
|
||||
EFM_ASSERT( init->offset <= ( _DAC_CAL_CH1OFFSET_MASK >>
|
||||
_DAC_CAL_CH1OFFSET_SHIFT ) );
|
||||
|
||||
dac->CAL = ( dac->CAL & ~_DAC_CAL_CH1OFFSET_MASK ) |
|
||||
( init->offset << _DAC_CAL_CH1OFFSET_SHIFT );
|
||||
}
|
||||
|
||||
dac->OPA1MUX = (uint32_t)init->resSel |
|
||||
(uint32_t)init->outMode |
|
||||
init->outPen |
|
||||
(uint32_t)init->resInMux |
|
||||
(uint32_t)init->negSel |
|
||||
(uint32_t)init->posSel |
|
||||
( init->nextOut ? DAC_OPA1MUX_NEXTOUT : 0 ) |
|
||||
( init->npEn ? DAC_OPA1MUX_NPEN : 0 ) |
|
||||
( init->ppEn ? DAC_OPA1MUX_PPEN : 0 );
|
||||
|
||||
dac->CH1CTRL |= DAC_CH1CTRL_EN;
|
||||
dac->OPACTRL = ( dac->OPACTRL
|
||||
& ~( DAC_OPACTRL_OPA1SHORT |
|
||||
_DAC_OPACTRL_OPA1LPFDIS_MASK |
|
||||
DAC_OPACTRL_OPA1HCMDIS ) ) |
|
||||
( init->shortInputs ? DAC_OPACTRL_OPA1SHORT : 0 ) |
|
||||
( init->lpfPosPadDisable ?
|
||||
DAC_OPACTRL_OPA1LPFDIS_PLPFDIS : 0 ) |
|
||||
( init->lpfNegPadDisable ?
|
||||
DAC_OPACTRL_OPA1LPFDIS_NLPFDIS : 0 ) |
|
||||
( init->hcmDisable ? DAC_OPACTRL_OPA1HCMDIS : 0 ) |
|
||||
( DAC_OPACTRL_OPA1EN );
|
||||
}
|
||||
else /* OPA2 */
|
||||
{
|
||||
EFM_ASSERT( ( init->posSel == DAC_OPA2MUX_POSSEL_DISABLE ) ||
|
||||
( init->posSel == DAC_OPA2MUX_POSSEL_POSPAD ) ||
|
||||
( init->posSel == DAC_OPA2MUX_POSSEL_OPA1INP ) ||
|
||||
( init->posSel == DAC_OPA2MUX_POSSEL_OPATAP ) );
|
||||
|
||||
EFM_ASSERT( ( init->outMode & ~DAC_OPA2MUX_OUTMODE ) == 0 );
|
||||
|
||||
EFM_ASSERT( ( init->outPen & ~_DAC_OPA2MUX_OUTPEN_MASK ) == 0 );
|
||||
|
||||
dac->BIASPROG = ( dac->BIASPROG
|
||||
& ~( _DAC_BIASPROG_OPA2BIASPROG_MASK |
|
||||
DAC_BIASPROG_OPA2HALFBIAS ) ) |
|
||||
( init->bias << _DAC_BIASPROG_OPA2BIASPROG_SHIFT ) |
|
||||
( init->halfBias ? DAC_BIASPROG_OPA2HALFBIAS : 0 );
|
||||
|
||||
if ( init->defaultOffset )
|
||||
{
|
||||
offset = SYSTEM_GetCalibrationValue( &dac->OPAOFFSET );
|
||||
dac->OPAOFFSET = ( dac->OPAOFFSET & ~_DAC_OPAOFFSET_OPA2OFFSET_MASK ) |
|
||||
( offset & _DAC_OPAOFFSET_OPA2OFFSET_MASK );
|
||||
}
|
||||
else
|
||||
{
|
||||
EFM_ASSERT( init->offset <= ( _DAC_OPAOFFSET_OPA2OFFSET_MASK >>
|
||||
_DAC_OPAOFFSET_OPA2OFFSET_SHIFT ) );
|
||||
|
||||
dac->CAL = ( dac->CAL & ~_DAC_OPAOFFSET_OPA2OFFSET_MASK ) |
|
||||
( init->offset << _DAC_OPAOFFSET_OPA2OFFSET_SHIFT );
|
||||
}
|
||||
|
||||
dac->OPA2MUX = (uint32_t)init->resSel |
|
||||
(uint32_t)init->outMode |
|
||||
init->outPen |
|
||||
(uint32_t)init->resInMux |
|
||||
(uint32_t)init->negSel |
|
||||
(uint32_t)init->posSel |
|
||||
( init->nextOut ? DAC_OPA2MUX_NEXTOUT : 0 ) |
|
||||
( init->npEn ? DAC_OPA2MUX_NPEN : 0 ) |
|
||||
( init->ppEn ? DAC_OPA2MUX_PPEN : 0 );
|
||||
|
||||
dac->OPACTRL = ( dac->OPACTRL
|
||||
& ~( DAC_OPACTRL_OPA2SHORT |
|
||||
_DAC_OPACTRL_OPA2LPFDIS_MASK |
|
||||
DAC_OPACTRL_OPA2HCMDIS ) ) |
|
||||
( init->shortInputs ? DAC_OPACTRL_OPA2SHORT : 0 ) |
|
||||
( init->lpfPosPadDisable ?
|
||||
DAC_OPACTRL_OPA2LPFDIS_PLPFDIS : 0 ) |
|
||||
( init->lpfNegPadDisable ?
|
||||
DAC_OPACTRL_OPA2LPFDIS_NLPFDIS : 0 ) |
|
||||
( init->hcmDisable ? DAC_OPACTRL_OPA2HCMDIS : 0 ) |
|
||||
( DAC_OPACTRL_OPA2EN );
|
||||
}
|
||||
}
|
||||
|
||||
/** @} (end addtogroup OPAMP) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
||||
|
||||
#endif /* defined( OPAMP_PRESENT ) && ( OPAMP_COUNT == 1 ) */
|
|
@ -0,0 +1,654 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Pulse Counter (PCNT) peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32_pcnt.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_assert.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup PCNT
|
||||
* @brief Pulse Counter (PCNT) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
|
||||
/** Validation of PCNT register block pointer reference for assert statements. */
|
||||
#if (PCNT_COUNT == 1)
|
||||
#define PCNT_REF_VALID(ref) ((ref) == PCNT0)
|
||||
#elif (PCNT_COUNT == 2)
|
||||
#define PCNT_REF_VALID(ref) (((ref) == PCNT0) || ((ref) == PCNT1))
|
||||
#elif (PCNT_COUNT == 3)
|
||||
#define PCNT_REF_VALID(ref) (((ref) == PCNT0) || ((ref) == PCNT1) || \
|
||||
((ref) == PCNT2))
|
||||
#else
|
||||
#error Undefined number of pulse counters (PCNT).
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL FUNCTIONS ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Map PCNT structure into instance number.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block
|
||||
*
|
||||
* @return
|
||||
* Instance number.
|
||||
******************************************************************************/
|
||||
static __INLINE unsigned int PCNT_Map(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
return(((uint32_t)pcnt - PCNT0_BASE) / 0x400);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Wait for ongoing sync of register(s) to low frequency domain to complete.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block
|
||||
*
|
||||
* @param[in] mask
|
||||
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
|
||||
* registers that must complete any ongoing synchronization.
|
||||
******************************************************************************/
|
||||
static __INLINE void PCNT_Sync(PCNT_TypeDef *pcnt, uint32_t mask)
|
||||
{
|
||||
/* Avoid deadlock if modifying the same register twice when freeze mode is
|
||||
* activated. */
|
||||
if (pcnt->FREEZE & PCNT_FREEZE_REGFREEZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Wait for any pending previous write operation to have been completed in low
|
||||
* frequency domain. */
|
||||
while (pcnt->SYNCBUSY & mask)
|
||||
;
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset PCNT counters and TOP register.
|
||||
*
|
||||
* @note
|
||||
* Notice that special SYNCBUSY handling is not applicable for the RSTEN
|
||||
* bit of the control register, so we don't need to wait for it when only
|
||||
* modifying RSTEN. (It would mean undefined wait time if clocked by external
|
||||
* clock.) The SYNCBUSY bit will however be set, leading to a synchronization
|
||||
* in the LF domain, with in reality no changes.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
******************************************************************************/
|
||||
void PCNT_CounterReset(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
/* Enable reset of CNT and TOP register */
|
||||
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
|
||||
|
||||
/* Disable reset of CNT and TOP register */
|
||||
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set counter and top values.
|
||||
*
|
||||
* @details
|
||||
* The pulse counter is disabled while changing these values, and reenabled
|
||||
* (if originally enabled) when values have been set.
|
||||
*
|
||||
* @note
|
||||
* This function will stall until synchronization to low frequency domain is
|
||||
* completed. For that reason, it should normally not be used when using
|
||||
* an external clock to clock the PCNT module, since stall time may be
|
||||
* undefined in that case. The counter should normally only be set when
|
||||
* operating in (or about to enable) #pcntModeOvsSingle mode.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] count
|
||||
* Value to set in counter register.
|
||||
*
|
||||
* @param[in] top
|
||||
* Value to set in top register.
|
||||
******************************************************************************/
|
||||
void PCNT_CounterTopSet(PCNT_TypeDef *pcnt, uint32_t count, uint32_t top)
|
||||
{
|
||||
uint32_t ctrl;
|
||||
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
/* Keep current control setting, must be restored */
|
||||
ctrl = pcnt->CTRL;
|
||||
|
||||
/* If enabled, disable pulse counter before changing values */
|
||||
if ((ctrl & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
|
||||
{
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
|
||||
pcnt->CTRL = (ctrl & ~_PCNT_CTRL_MODE_MASK) | PCNT_CTRL_MODE_DISABLE;
|
||||
}
|
||||
|
||||
/* Load into TOPB */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
|
||||
pcnt->TOPB = count;
|
||||
|
||||
/* Load TOPB value into TOP */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
|
||||
|
||||
/* This bit has no effect on rev. C and onwards parts - for compatibility */
|
||||
pcnt->CMD = PCNT_CMD_LTOPBIM;
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
|
||||
|
||||
/* Load TOP into CNT */
|
||||
pcnt->CMD = PCNT_CMD_LCNTIM;
|
||||
|
||||
/* Restore TOP? ('count' setting has been loaded into pcnt->TOP, better
|
||||
* to use 'top' than pcnt->TOP in compare, since latter may in theory not
|
||||
* be visible yet.) */
|
||||
if (top != count)
|
||||
{
|
||||
/* Wait for command to sync LCNTIM before setting TOPB */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
|
||||
|
||||
/* Load into TOPB, we don't need to check for TOPB sync complete here,
|
||||
* it has been ensured above. */
|
||||
pcnt->TOPB = top;
|
||||
|
||||
/* Load TOPB value into TOP */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
|
||||
pcnt->CMD = PCNT_CMD_LTOPBIM;
|
||||
}
|
||||
|
||||
/* Reenable if it was enabled */
|
||||
if ((ctrl & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
|
||||
{
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL | PCNT_SYNCBUSY_CMD);
|
||||
pcnt->CTRL = ctrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set PCNT operational mode.
|
||||
*
|
||||
* @details
|
||||
* Notice that this function does not do any configuration. Setting operational
|
||||
* mode is normally only required after initialization is done, and if not
|
||||
* done as part of initialization. Or if requiring to disable/reenable pulse
|
||||
* counter.
|
||||
*
|
||||
* @note
|
||||
* This function may stall until synchronization to low frequency domain is
|
||||
* completed. For that reason, it should normally not be used when using
|
||||
* an external clock to clock the PCNT module, since stall time may be
|
||||
* undefined in that case.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] mode
|
||||
* Operational mode to use for PCNT.
|
||||
******************************************************************************/
|
||||
void PCNT_Enable(PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
/* Set as specified */
|
||||
tmp = pcnt->CTRL & ~_PCNT_CTRL_MODE_MASK;
|
||||
tmp |= (uint32_t)mode << _PCNT_CTRL_MODE_SHIFT;
|
||||
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
|
||||
pcnt->CTRL = tmp;
|
||||
}
|
||||
|
||||
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable the selected PRS input of PCNT.
|
||||
*
|
||||
* @details
|
||||
* Notice that this function does not do any configuration.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] prsInput
|
||||
* PRS input (S0 or S1) of the selected PCNT module.
|
||||
*
|
||||
* @param[in] enable
|
||||
* Set to true to enable, false to disable the selected PRS input.
|
||||
******************************************************************************/
|
||||
void PCNT_PRSInputEnable(PCNT_TypeDef *pcnt,
|
||||
PCNT_PRSInput_TypeDef prsInput,
|
||||
bool enable)
|
||||
{
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
/* Enable/disable the selected PRS input on the selected PCNT module. */
|
||||
switch (prsInput)
|
||||
{
|
||||
/* Enable/disable PRS input S0. */
|
||||
case pcntPRSInputS0:
|
||||
{
|
||||
BITBAND_Peripheral(&(pcnt->INPUT), _PCNT_INPUT_S0PRSEN_SHIFT, (uint32_t)enable);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Enable/disable PRS input S1. */
|
||||
case pcntPRSInputS1:
|
||||
{
|
||||
BITBAND_Peripheral(&(pcnt->INPUT), _PCNT_INPUT_S1PRSEN_SHIFT, (uint32_t)enable);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Invalid parameter, asserted. */
|
||||
default:
|
||||
{
|
||||
EFM_ASSERT(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* PCNT register synchronization freeze control.
|
||||
*
|
||||
* @details
|
||||
* Some PCNT registers require synchronization into the low frequency (LF)
|
||||
* domain. The freeze feature allows for several such registers to be
|
||||
* modified before passing them to the LF domain simultaneously (which
|
||||
* takes place when the freeze mode is disabled).
|
||||
*
|
||||
* @note
|
||||
* When enabling freeze mode, this function will wait for all current
|
||||
* ongoing PCNT synchronization to LF domain to complete (Normally
|
||||
* synchronization will not be in progress.) However for this reason, when
|
||||
* using freeze mode, modifications of registers requiring LF synchronization
|
||||
* should be done within one freeze enable/disable block to avoid unecessary
|
||||
* stalling.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] enable
|
||||
* @li true - enable freeze, modified registers are not propagated to the
|
||||
* LF domain
|
||||
* @li false - disables freeze, modified registers are propagated to LF
|
||||
* domain
|
||||
******************************************************************************/
|
||||
void PCNT_FreezeEnable(PCNT_TypeDef *pcnt, bool enable)
|
||||
{
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
if (enable)
|
||||
{
|
||||
/* Wait for any ongoing LF synchronization to complete. This is just to
|
||||
* protect against the rare case when a user:
|
||||
* - modifies a register requiring LF sync
|
||||
* - then enables freeze before LF sync completed
|
||||
* - then modifies the same register again
|
||||
* since modifying a register while it is in sync progress should be
|
||||
* avoided. */
|
||||
while (pcnt->SYNCBUSY)
|
||||
;
|
||||
|
||||
pcnt->FREEZE = PCNT_FREEZE_REGFREEZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcnt->FREEZE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Init pulse counter.
|
||||
*
|
||||
* @details
|
||||
* This function will configure the pulse counter. The clock selection is
|
||||
* configured as follows, depending on operational mode:
|
||||
*
|
||||
* @li #pcntModeOvsSingle - Use LFACLK.
|
||||
* @li #pcntModeExtSingle - Use external PCNTn_S0 pin.
|
||||
* @li #pcntModeExtQuad - Use external PCNTn_S0 pin.
|
||||
*
|
||||
* Notice that the LFACLK must be enabled in all modes, since some basic setup
|
||||
* is done with this clock even if external pin clock usage mode is chosen.
|
||||
* The pulse counter clock for the selected instance must also be enabled
|
||||
* prior to init.
|
||||
*
|
||||
* Notice that pins used by the PCNT module must be properly configured
|
||||
* by the user explicitly through setting the ROUTE register, in order for
|
||||
* the PCNT to work as intended.
|
||||
*
|
||||
* Writing to CNT will not occur in external clock modes (EXTCLKQUAD and
|
||||
* EXTCLKSINGLE) because the external clock rate is unknown. The user should
|
||||
* handle it manually depending on the application
|
||||
*
|
||||
* TOPB is written for all modes but in external clock mode it will take
|
||||
* 3 external clock cycles to sync to TOP
|
||||
*
|
||||
*
|
||||
* @note
|
||||
* Initializing requires synchronization into the low frequency domain. This
|
||||
* may cause some delay.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to initialization structure used to initialize.
|
||||
******************************************************************************/
|
||||
void PCNT_Init(PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init)
|
||||
{
|
||||
unsigned int inst;
|
||||
uint32_t tmp;
|
||||
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
/* Map pointer to instance */
|
||||
inst = PCNT_Map(pcnt);
|
||||
|
||||
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
|
||||
/* Selecting the PRS channels for the PRS input sources of the PCNT. These are
|
||||
* written with a Read-Modify-Write sequence in order to keep the value of the
|
||||
* input enable bits which can be modified using PCNT_PRSInputEnable(). */
|
||||
tmp = pcnt->INPUT & ~(_PCNT_INPUT_S0PRSSEL_MASK | _PCNT_INPUT_S1PRSSEL_MASK);
|
||||
tmp |= ((uint32_t)init->s0PRS << _PCNT_INPUT_S0PRSSEL_SHIFT) |
|
||||
((uint32_t)init->s1PRS << _PCNT_INPUT_S1PRSSEL_SHIFT);
|
||||
pcnt->INPUT = tmp;
|
||||
#endif
|
||||
|
||||
/* Build CTRL setting, except for mode */
|
||||
tmp = 0;
|
||||
if (init->negEdge)
|
||||
{
|
||||
tmp |= PCNT_CTRL_EDGE_NEG;
|
||||
}
|
||||
|
||||
if (init->countDown)
|
||||
{
|
||||
tmp |= PCNT_CTRL_CNTDIR_DOWN;
|
||||
}
|
||||
|
||||
if (init->filter)
|
||||
{
|
||||
tmp |= PCNT_CTRL_FILT;
|
||||
}
|
||||
|
||||
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
|
||||
if (init->hyst)
|
||||
{
|
||||
tmp |= PCNT_CTRL_HYST;
|
||||
}
|
||||
|
||||
if (init->s1CntDir)
|
||||
{
|
||||
tmp |= PCNT_CTRL_S1CDIR;
|
||||
}
|
||||
|
||||
/* Configure counter events for regular and auxiliary counter. */
|
||||
tmp |= init->cntEvent << _PCNT_CTRL_CNTEV_SHIFT;
|
||||
tmp |= init->auxCntEvent << _PCNT_CTRL_AUXCNTEV_SHIFT;
|
||||
#endif
|
||||
|
||||
/* Reset pulse counter while changing clock source. The reset bit */
|
||||
/* is asynchronous, we don't have to check for SYNCBUSY. */
|
||||
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
|
||||
|
||||
/* Select LFACLK to clock in control setting */
|
||||
CMU_PCNTClockExternalSet(inst, false);
|
||||
|
||||
/* Handling depends on whether using external clock or not. */
|
||||
switch (init->mode)
|
||||
{
|
||||
case pcntModeExtSingle:
|
||||
case pcntModeExtQuad:
|
||||
tmp |= init->mode << _PCNT_CTRL_MODE_SHIFT;
|
||||
|
||||
/* In most cases, the SYNCBUSY bit is set due to reset bit set, and waiting
|
||||
* for asynchronous reset bit is strictly not necessary.
|
||||
* But in theory, other operations on CTRL register may have been done
|
||||
* outside this function, so wait. */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
|
||||
|
||||
/* Enable PCNT Clock Domain Reset. The PCNT must be in reset before changing
|
||||
* the clock source to an external clock */
|
||||
pcnt->CTRL = PCNT_CTRL_RSTEN;
|
||||
|
||||
/* Wait until CTRL write synchronized into LF domain. */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
|
||||
|
||||
/* Change to external clock BEFORE disabling reset */
|
||||
CMU_PCNTClockExternalSet(inst, true);
|
||||
|
||||
/* Write to TOPB. If using external clock TOPB will sync to TOP at the same
|
||||
* time as the mode. This will insure that if the user chooses to count
|
||||
* down, the first "countable" pulse will make CNT go to TOP and not 0xFF
|
||||
* (default TOP value). */
|
||||
pcnt->TOPB = init->top;
|
||||
|
||||
/* This bit has no effect on rev. C and onwards parts - for compatibility */
|
||||
pcnt->CMD = PCNT_CMD_LTOPBIM;
|
||||
|
||||
/* Write the CTRL register with the configurations.
|
||||
* This should be written after TOPB in the eventuality of a pulse between
|
||||
* these two writes that would cause the CTRL register to be synced one
|
||||
* clock cycle earlier than the TOPB. */
|
||||
pcnt->CTRL = tmp;
|
||||
|
||||
/* There are no syncs for TOP, CMD or CTRL because the clock rate is unknown
|
||||
* and the program could stall
|
||||
* These will be synced within 3 clock cycles of the external clock /
|
||||
* For the same reason CNT cannot be written here. */
|
||||
break;
|
||||
|
||||
/* pcntModeDisable */
|
||||
/* pcntModeOvsSingle */
|
||||
default:
|
||||
/* No need to set disabled mode if already disabled. */
|
||||
if ((pcnt->CTRL & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
|
||||
{
|
||||
/* Set control to disabled mode, leave reset on until ensured disabled.
|
||||
* We don't need to wait for CTRL SYNCBUSY completion here, it was
|
||||
* triggered by reset bit above, which is asynchronous. */
|
||||
pcnt->CTRL = tmp | PCNT_CTRL_MODE_DISABLE | PCNT_CTRL_RSTEN;
|
||||
|
||||
/* Wait until CTRL write synchronized into LF domain before proceeding
|
||||
* to disable reset. */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
|
||||
}
|
||||
|
||||
/* Disable reset bit, counter should now be in disabled mode. */
|
||||
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
|
||||
|
||||
/* Set counter and top values as specified. */
|
||||
PCNT_CounterTopSet(pcnt, init->counter, init->top);
|
||||
|
||||
/* Enter oversampling mode if selected. */
|
||||
if (init->mode == pcntModeOvsSingle)
|
||||
{
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
|
||||
pcnt->CTRL = tmp | (init->mode << _PCNT_CTRL_MODE_SHIFT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset PCNT to same state as after a HW reset.
|
||||
*
|
||||
* @details
|
||||
* Notice the LFACLK must be enabled, since some basic reset is done with
|
||||
* this clock. The pulse counter clock for the selected instance must also
|
||||
* be enabled prior to init.
|
||||
*
|
||||
* @note
|
||||
* The ROUTE register is NOT reset by this function, in order to allow for
|
||||
* centralized setup of this feature.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
******************************************************************************/
|
||||
void PCNT_Reset(PCNT_TypeDef *pcnt)
|
||||
{
|
||||
unsigned int inst;
|
||||
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
/* Map pointer to instance and clock info */
|
||||
inst = PCNT_Map(pcnt);
|
||||
|
||||
pcnt->IEN = _PCNT_IEN_RESETVALUE;
|
||||
|
||||
/* Notice that special SYNCBUSY handling is not applicable for the RSTEN
|
||||
* bit of the control register, so we don't need to wait for it when only
|
||||
* modifying RSTEN. The SYNCBUSY bit will be set, leading to a
|
||||
* synchronization in the LF domain, with in reality no changes to LF domain.
|
||||
* Enable reset of CNT and TOP register. */
|
||||
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
|
||||
|
||||
/* Select LFACLK as default */
|
||||
CMU_PCNTClockExternalSet(inst, false);
|
||||
|
||||
PCNT_TopBufferSet(pcnt, _PCNT_TOPB_RESETVALUE);
|
||||
|
||||
/* Reset CTRL leaving RSTEN set */
|
||||
pcnt->CTRL = _PCNT_CTRL_RESETVALUE | PCNT_CTRL_RSTEN;
|
||||
|
||||
/* Disable reset after CTRL reg has been synchronized */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
|
||||
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
|
||||
|
||||
/* Clear pending interrupts */
|
||||
pcnt->IFC = _PCNT_IFC_MASK;
|
||||
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set top buffer value.
|
||||
*
|
||||
* @note
|
||||
* This function may stall until synchronization to low frequency domain is
|
||||
* completed. For that reason, it should normally not be used when using
|
||||
* an external clock to clock the PCNT module, since stall time may be
|
||||
* undefined in that case.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] val
|
||||
* Value to set in top buffer register.
|
||||
******************************************************************************/
|
||||
void PCNT_TopBufferSet(PCNT_TypeDef *pcnt, uint32_t val)
|
||||
{
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
|
||||
pcnt->TOPB = val;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set top value.
|
||||
*
|
||||
* @note
|
||||
* This function will stall until synchronization to low frequency domain is
|
||||
* completed. For that reason, it should normally not be used when using
|
||||
* an external clock to clock the PCNT module, since stall time may be
|
||||
* undefined in that case.
|
||||
*
|
||||
* @param[in] pcnt
|
||||
* Pointer to PCNT peripheral register block.
|
||||
*
|
||||
* @param[in] val
|
||||
* Value to set in top register.
|
||||
******************************************************************************/
|
||||
void PCNT_TopSet(PCNT_TypeDef *pcnt, uint32_t val)
|
||||
{
|
||||
EFM_ASSERT(PCNT_REF_VALID(pcnt));
|
||||
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
|
||||
/* Load into TOPB */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
|
||||
pcnt->TOPB = val;
|
||||
|
||||
/* Load TOPB value into TOP */
|
||||
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
|
||||
pcnt->CMD = PCNT_CMD_LTOPBIM;
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup PCNT) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,122 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Peripheral Reflex System (PRS) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_prs.h"
|
||||
#include "efm32_assert.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup PRS
|
||||
* @brief Peripheral Reflex System (PRS) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set source and signal to be used for a channel.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Channel to define signal and source for.
|
||||
*
|
||||
* @param[in] source
|
||||
* Source to select for channel. Use one of PRS_CH_CTRL_SOURCESEL_x defines.
|
||||
*
|
||||
* @param[in] signal
|
||||
* Signal (for selected @p source) to use. Use one of PRS_CH_CTRL_SIGSEL_x
|
||||
* defines.
|
||||
*
|
||||
* @param[in] edge
|
||||
* Edge (for selected source/signal) to generate pulse for.
|
||||
******************************************************************************/
|
||||
void PRS_SourceSignalSet(unsigned int ch,
|
||||
uint32_t source,
|
||||
uint32_t signal,
|
||||
PRS_Edge_TypeDef edge)
|
||||
{
|
||||
EFM_ASSERT(ch < 8);
|
||||
|
||||
PRS->CH[ch].CTRL = (source & _PRS_CH_CTRL_SOURCESEL_MASK) |
|
||||
(signal & _PRS_CH_CTRL_SIGSEL_MASK) |
|
||||
(uint32_t)edge;
|
||||
}
|
||||
|
||||
#if ((defined _EFM32_TINY_FAMILY) || (defined _EFM32_GIANT_FAMILY))
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set source and asynchronous signal to be used for a channel.
|
||||
*
|
||||
* @details
|
||||
* Asynchronous reflexes are not clocked on HFPERCLK, and can be used even in
|
||||
* EM2/EM3.
|
||||
* There is a limitation to reflexes operating in asynchronous mode: they can
|
||||
* only be used by a subset of the reflex consumers. Please refer to PRS
|
||||
* chapter in the reference manual for the complete list of supported
|
||||
* asynchronous signals and consumers.
|
||||
*
|
||||
* @note
|
||||
* This function is only supported on the following device families:
|
||||
* @li Tiny Gecko (EFM32TGxxxFxx)
|
||||
* @li Giant Gecko (EFM32GGxxxFxxx)
|
||||
* In asynchronous mode, the edge detector only works in EM0, hence it shall
|
||||
* not be used. The EDSEL parameter in PRS_CHx_CTRL register is set to 0 (OFF)
|
||||
* by default.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Channel to define source and asynchronous signal for.
|
||||
*
|
||||
* @param[in] source
|
||||
* Source to select for channel. Use one of PRS_CH_CTRL_SOURCESEL_x defines.
|
||||
*
|
||||
* @param[in] signal
|
||||
* Asynchronous signal (for selected @p source) to use. Use one of the
|
||||
* PRS_CH_CTRL_SIGSEL_x defines that support asynchronous operation.
|
||||
******************************************************************************/
|
||||
void PRS_SourceAsyncSignalSet(unsigned int ch,
|
||||
uint32_t source,
|
||||
uint32_t signal)
|
||||
{
|
||||
EFM_ASSERT(ch < 8);
|
||||
|
||||
PRS->CH[ch].CTRL = PRS_CH_CTRL_ASYNC |
|
||||
(source & _PRS_CH_CTRL_SOURCESEL_MASK) |
|
||||
(signal & _PRS_CH_CTRL_SIGSEL_MASK) |
|
||||
PRS_CH_CTRL_EDSEL_OFF;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup PRS) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,175 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Reset Management Unit (RMU) peripheral module peripheral API
|
||||
* for EFM32.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_rmu.h"
|
||||
#include "efm32_emu.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup RMU
|
||||
* @brief Reset Management Unit (RMU) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable/enable the lockup signal from the Cortex M-3.
|
||||
*
|
||||
* @param[in] disable
|
||||
* @li false - Allow lockup signal to reset.
|
||||
* @li true - Do not allow lockup signal to reset.
|
||||
******************************************************************************/
|
||||
void RMU_LockupResetDisable(bool disable)
|
||||
{
|
||||
BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_LOCKUPRDIS_SHIFT, (unsigned int)disable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear the reset cause register.
|
||||
******************************************************************************/
|
||||
void RMU_ResetCauseClear(void)
|
||||
{
|
||||
uint32_t locked;
|
||||
|
||||
RMU->CMD = RMU_CMD_RCCLR;
|
||||
|
||||
/* Clear some reset causes not cleared with RMU CMD register */
|
||||
/* (If EMU registers locked, they must be unlocked first) */
|
||||
locked = EMU->LOCK & EMU_LOCK_LOCKKEY_LOCKED;
|
||||
if (locked)
|
||||
{
|
||||
EMU_Unlock();
|
||||
}
|
||||
|
||||
BITBAND_Peripheral(&(EMU->AUXCTRL), 0, 1);
|
||||
BITBAND_Peripheral(&(EMU->AUXCTRL), 0, 0);
|
||||
|
||||
if (locked)
|
||||
{
|
||||
EMU_Lock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the cause of the last reset.
|
||||
*
|
||||
* @details
|
||||
* In order to be useful, the reset cause must be cleared by SW before a new
|
||||
* reset occurs, otherwise reset causes may accumulate. See
|
||||
* RMU_ResetCauseClear().
|
||||
*
|
||||
* @return
|
||||
* The reset cause, a bit mask of (typically, but not always, only one) of:
|
||||
* @li RMU_RSTCAUSE_PORST - Power on reset
|
||||
* @li RMU_RSTCAUSE_BODUNREGRST - Brown out detector, unregulated power
|
||||
* @li RMU_RSTCAUSE_BODREGRST - Brown out detector, regulated power
|
||||
* @li RMU_RSTCAUSE_EXTRST - External reset
|
||||
* @li RMU_RSTCAUSE_WDOGRST - Watchdog reset
|
||||
* @li RMU_RSTCAUSE_LOCKUPRST - Cortex-M3 lockup reset
|
||||
* @li RMU_RSTCAUSE_SYSREQRST - Cortex-M3 system request reset
|
||||
******************************************************************************/
|
||||
uint32_t RMU_ResetCauseGet(void)
|
||||
{
|
||||
uint32_t ret = RMU->RSTCAUSE;
|
||||
|
||||
/* Inspect and decode bits. The decoding must be done in correct order, */
|
||||
/* since some reset causes may trigger other reset causes due to internal */
|
||||
/* design. We are only interested in the main cause. */
|
||||
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
|
||||
/* Clear "stray" bits if EM4 bit is set, they will always be active */
|
||||
if (ret & RMU_RSTCAUSE_EM4RST)
|
||||
{
|
||||
ret &= ~(RMU_RSTCAUSE_BODREGRST|
|
||||
RMU_RSTCAUSE_BODUNREGRST|
|
||||
RMU_RSTCAUSE_LOCKUPRST|
|
||||
RMU_RSTCAUSE_SYSREQRST);
|
||||
}
|
||||
if (ret == RMU_RSTCAUSE_BODAVDD0)
|
||||
{
|
||||
ret = RMU_RSTCAUSE_BODAVDD0;
|
||||
}
|
||||
else if (ret == RMU_RSTCAUSE_BODAVDD1)
|
||||
{
|
||||
ret = RMU_RSTCAUSE_BODAVDD1;
|
||||
}
|
||||
else if (ret == (RMU_RSTCAUSE_EM4WURST|RMU_RSTCAUSE_EM4RST))
|
||||
{
|
||||
ret &= (RMU_RSTCAUSE_EM4WURST|RMU_RSTCAUSE_EM4RST);
|
||||
}
|
||||
else if (ret & (RMU_RSTCAUSE_EM4RST|RMU_RSTCAUSE_EXTRST))
|
||||
{
|
||||
ret &= (RMU_RSTCAUSE_EM4RST|RMU_RSTCAUSE_EXTRST);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (ret & RMU_RSTCAUSE_PORST)
|
||||
{
|
||||
ret = RMU_RSTCAUSE_PORST;
|
||||
}
|
||||
else if (ret & RMU_RSTCAUSE_BODUNREGRST)
|
||||
{
|
||||
ret = RMU_RSTCAUSE_BODUNREGRST;
|
||||
}
|
||||
else if ((ret & 0x1f) == RMU_RSTCAUSE_BODREGRST)
|
||||
{
|
||||
ret = RMU_RSTCAUSE_BODREGRST;
|
||||
}
|
||||
/* Both external and watchdog reset may occur at the same time */
|
||||
else if (ret & (RMU_RSTCAUSE_EXTRST | RMU_RSTCAUSE_WDOGRST))
|
||||
{
|
||||
ret &= RMU_RSTCAUSE_EXTRST | RMU_RSTCAUSE_WDOGRST;
|
||||
}
|
||||
/* Both lockup and system reset may occur at the same time */
|
||||
else if (ret & (RMU_RSTCAUSE_LOCKUPRST | RMU_RSTCAUSE_SYSREQRST))
|
||||
{
|
||||
ret &= RMU_RSTCAUSE_LOCKUPRST | RMU_RSTCAUSE_SYSREQRST;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup RMU) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,355 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Real Time Counter (RTC) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32_rtc.h"
|
||||
#include "efm32_assert.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup RTC
|
||||
* @brief Real Time Counter (RTC) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of valid comparator register for assert statements. */
|
||||
#define RTC_COMP_REG_VALID(reg) (((reg) <= 1))
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL FUNCTIONS ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Wait for ongoing sync of register(s) to low frequency domain to complete.
|
||||
*
|
||||
* @note
|
||||
* This only applies to the Gecko Family, see the reference manual
|
||||
* chapter about Access to Low Energy Peripherals (Asynchronos Registers)
|
||||
* for details. For Tiny Gecko and Giant Gecko, the RTC supports immediate
|
||||
* updates of registers, and will automatically hold the bus until the
|
||||
* register has been updated.
|
||||
*
|
||||
* @param[in] mask
|
||||
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
|
||||
* registers that must complete any ongoing synchronization.
|
||||
******************************************************************************/
|
||||
static __INLINE void RTC_Sync(uint32_t mask)
|
||||
{
|
||||
/* Avoid deadlock if modifying the same register twice when freeze mode is */
|
||||
/* activated. */
|
||||
if (RTC->FREEZE & RTC_FREEZE_REGFREEZE)
|
||||
return;
|
||||
|
||||
/* Wait for any pending previous write operation to have been completed */
|
||||
/* in low frequency domain. This is only required for the Gecko Family */
|
||||
while (RTC->SYNCBUSY & mask)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get RTC compare register value.
|
||||
*
|
||||
* @param[in] comp
|
||||
* Compare register to get, either 0 or 1
|
||||
*
|
||||
* @return
|
||||
* Compare register value, 0 if invalid register selected.
|
||||
******************************************************************************/
|
||||
uint32_t RTC_CompareGet(unsigned int comp)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
EFM_ASSERT(RTC_COMP_REG_VALID(comp));
|
||||
|
||||
/* Initialize selected compare value */
|
||||
switch (comp)
|
||||
{
|
||||
case 0:
|
||||
ret = RTC->COMP0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ret = RTC->COMP1;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown compare register selected */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set RTC compare register value.
|
||||
*
|
||||
* @note
|
||||
* The setting of a compare register requires synchronization into the
|
||||
* low frequency domain. If the same register is modified before a previous
|
||||
* update has completed, this function will stall until the previous
|
||||
* synchronization has completed. This only applies to the Gecko Family, see
|
||||
* comment in the RTC_Sync() internal function call.
|
||||
*
|
||||
* @param[in] comp
|
||||
* Compare register to set, either 0 or 1
|
||||
*
|
||||
* @param[in] value
|
||||
* Initialization value (<= 0x00ffffff)
|
||||
******************************************************************************/
|
||||
void RTC_CompareSet(unsigned int comp, uint32_t value)
|
||||
{
|
||||
volatile uint32_t *compReg;
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
uint32_t syncbusy;
|
||||
#endif
|
||||
|
||||
EFM_ASSERT(RTC_COMP_REG_VALID(comp) &&
|
||||
((value & ~(_RTC_COMP0_COMP0_MASK >> _RTC_COMP0_COMP0_SHIFT)) == 0));
|
||||
|
||||
/* Initialize selected compare value */
|
||||
switch (comp)
|
||||
{
|
||||
case 0:
|
||||
compReg = &(RTC->COMP0);
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
syncbusy = RTC_SYNCBUSY_COMP0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 1:
|
||||
compReg = &(RTC->COMP1);
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
syncbusy = RTC_SYNCBUSY_COMP1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown compare register selected, abort */
|
||||
return;
|
||||
}
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
RTC_Sync(syncbusy);
|
||||
#endif
|
||||
|
||||
*compReg = value;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable RTC.
|
||||
*
|
||||
* @note
|
||||
* The enabling/disabling of the RTC modifies the RTC CTRL register which
|
||||
* requires synchronization into the low frequency domain. If this register is
|
||||
* modified before a previous update to the same register has completed, this
|
||||
* function will stall until the previous synchronization has completed. This
|
||||
* only applies to the Gecko Family, see comment in the RTC_Sync() internal
|
||||
* function call.
|
||||
*
|
||||
* @param[in] enable
|
||||
* true to enable counting, false to disable.
|
||||
******************************************************************************/
|
||||
void RTC_Enable(bool enable)
|
||||
{
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
RTC_Sync(RTC_SYNCBUSY_CTRL);
|
||||
#endif
|
||||
|
||||
BITBAND_Peripheral(&(RTC->CTRL), _RTC_CTRL_EN_SHIFT, (unsigned int) enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* RTC register synchronization freeze control.
|
||||
*
|
||||
* @details
|
||||
* Some RTC registers require synchronization into the low frequency (LF)
|
||||
* domain. The freeze feature allows for several such registers to be
|
||||
* modified before passing them to the LF domain simultaneously (which
|
||||
* takes place when the freeze mode is disabled).
|
||||
*
|
||||
* @note
|
||||
* When enabling freeze mode, this function will wait for all current
|
||||
* ongoing RTC synchronization to LF domain to complete (Normally
|
||||
* synchronization will not be in progress.) However for this reason, when
|
||||
* using freeze mode, modifications of registers requiring LF synchronization
|
||||
* should be done within one freeze enable/disable block to avoid unecessary
|
||||
* stalling. This only applies to the Gecko Family, see the reference manual
|
||||
* chapter about Access to Low Energy Peripherals (Asynchronos Registers)
|
||||
* for details.
|
||||
*
|
||||
* @param[in] enable
|
||||
* @li true - enable freeze, modified registers are not propagated to the
|
||||
* LF domain
|
||||
* @li false - disables freeze, modified registers are propagated to LF
|
||||
* domain
|
||||
******************************************************************************/
|
||||
void RTC_FreezeEnable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* Wait for any ongoing LF synchronization to complete. This is just to */
|
||||
/* protect against the rare case when a user */
|
||||
/* - modifies a register requiring LF sync */
|
||||
/* - then enables freeze before LF sync completed */
|
||||
/* - then modifies the same register again */
|
||||
/* since modifying a register while it is in sync progress should be */
|
||||
/* avoided. */
|
||||
while (RTC->SYNCBUSY)
|
||||
;
|
||||
#endif
|
||||
RTC->FREEZE = RTC_FREEZE_REGFREEZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
RTC->FREEZE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize RTC.
|
||||
*
|
||||
* @details
|
||||
* Note that the compare values must be set separately with RTC_CompareSet().
|
||||
* That should probably be done prior to the use of this function if
|
||||
* configuring the RTC to start when initialization is completed.
|
||||
*
|
||||
* @note
|
||||
* The initialization of the RTC modifies the RTC CTRL register which requires
|
||||
* synchronization into the low frequency domain. If this register is
|
||||
* modified before a previous update to the same register has completed, this
|
||||
* function will stall until the previous synchronization has completed. This
|
||||
* only applies to the Gecko Family, see comment in the RTC_Sync() internal
|
||||
* function call.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to RTC initialization structure.
|
||||
******************************************************************************/
|
||||
void RTC_Init(const RTC_Init_TypeDef *init)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
if (init->enable)
|
||||
{
|
||||
tmp = RTC_CTRL_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = 0;
|
||||
}
|
||||
|
||||
/* Configure DEBUGRUN flag, sets whether or not counter should be
|
||||
* updated when debugger is active */
|
||||
if (init->debugRun)
|
||||
{
|
||||
tmp |= RTC_CTRL_DEBUGRUN;
|
||||
}
|
||||
|
||||
/* Configure COMP0TOP, this will use the COMP0 compare value as an
|
||||
* overflow value, instead of default 24-bit 0x00ffffff */
|
||||
if (init->comp0Top)
|
||||
{
|
||||
tmp |= RTC_CTRL_COMP0TOP;
|
||||
}
|
||||
|
||||
#if defined(_EFM32_GECKO_FAMILY)
|
||||
/* LF register about to be modified require sync. busy check */
|
||||
RTC_Sync(RTC_SYNCBUSY_CTRL);
|
||||
#endif
|
||||
|
||||
RTC->CTRL = tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Restore RTC to reset state
|
||||
******************************************************************************/
|
||||
void RTC_Reset(void)
|
||||
{
|
||||
/* Restore all essential RTC register to default config */
|
||||
RTC->FREEZE = _RTC_FREEZE_RESETVALUE;
|
||||
RTC->CTRL = _RTC_CTRL_RESETVALUE;
|
||||
RTC->COMP0 = _RTC_COMP0_RESETVALUE;
|
||||
RTC->COMP1 = _RTC_COMP1_RESETVALUE;
|
||||
RTC->IEN = _RTC_IEN_RESETVALUE;
|
||||
RTC->IFC = _RTC_IFC_RESETVALUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Restart RTC counter from zero
|
||||
******************************************************************************/
|
||||
void RTC_CounterReset(void)
|
||||
{
|
||||
/* A disable/enable sequnce will start the counter at zero */
|
||||
RTC_Enable(false);
|
||||
RTC_Enable(true);
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup RTC) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,106 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief System Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "efm32.h"
|
||||
#include "efm32_system.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup SYSTEM
|
||||
* @brief System Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get chip major/minor revision.
|
||||
*
|
||||
* @param[out] rev
|
||||
* Location to place chip revision info.
|
||||
******************************************************************************/
|
||||
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
|
||||
EFM_ASSERT(rev);
|
||||
|
||||
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
|
||||
|
||||
tmp = (ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK);
|
||||
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
|
||||
rev->minor = tmp;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get factory calibration value for a given peripheral register.
|
||||
*
|
||||
* @param[in] regAddress
|
||||
* Address of register to get a calibration value for.
|
||||
*
|
||||
* @return
|
||||
* Calibration value for the requested register.
|
||||
******************************************************************************/
|
||||
uint32_t SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
|
||||
{
|
||||
int regCount;
|
||||
CALIBRATE_TypeDef *p;
|
||||
|
||||
regCount = 1;
|
||||
p = CALIBRATE;
|
||||
|
||||
for (;; )
|
||||
{
|
||||
if ((regCount > CALIBRATE_MAX_REGISTERS) ||
|
||||
(p->VALUE == 0xFFFFFFFF))
|
||||
{
|
||||
EFM_ASSERT(false);
|
||||
return 0; /* End of device calibration table reached. */
|
||||
}
|
||||
|
||||
if (p->ADDRESS == (uint32_t)regAddress)
|
||||
{
|
||||
return p->VALUE; /* Calibration value found ! */
|
||||
}
|
||||
|
||||
p++;
|
||||
regCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} (end addtogroup SYSTEM) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,295 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Timer/counter (TIMER) Peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32_timer.h"
|
||||
#include "efm32_cmu.h"
|
||||
#include "efm32_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup TIMER
|
||||
* @brief Timer/Counter (TIMER) Peripheral API for EFM32
|
||||
* @details
|
||||
* The timer module consists of three main parts:
|
||||
* @li General timer config and enable control.
|
||||
* @li Compare/capture control.
|
||||
* @li Dead time insertion control (may not be available for all timers).
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
|
||||
/** Validation of TIMER register block pointer reference for assert statements. */
|
||||
#if (TIMER_COUNT == 1)
|
||||
#define TIMER_REF_VALID(ref) ((ref) == TIMER0)
|
||||
#elif (TIMER_COUNT == 2)
|
||||
#define TIMER_REF_VALID(ref) (((ref) == TIMER0) || ((ref) == TIMER1))
|
||||
#elif (TIMER_COUNT == 3)
|
||||
#define TIMER_REF_VALID(ref) (((ref) == TIMER0) || \
|
||||
((ref) == TIMER1) || \
|
||||
((ref) == TIMER2))
|
||||
#elif (TIMER_COUNT == 4)
|
||||
#define TIMER_REF_VALID(ref) (((ref) == TIMER0) || \
|
||||
((ref) == TIMER1) || \
|
||||
((ref) == TIMER2) || \
|
||||
((ref) == TIMER3))
|
||||
#else
|
||||
#error Undefined number of timers.
|
||||
#endif
|
||||
|
||||
/** Validation of TIMER compare/capture channel number */
|
||||
#define TIMER_CH_VALID(ch) ((ch) < 3)
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Start/stop TIMER.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] enable
|
||||
* true to enable counting, false to disable.
|
||||
******************************************************************************/
|
||||
void TIMER_Enable(TIMER_TypeDef *timer, bool enable)
|
||||
{
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
|
||||
if (enable)
|
||||
{
|
||||
timer->CMD = TIMER_CMD_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
timer->CMD = TIMER_CMD_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize TIMER.
|
||||
*
|
||||
* @details
|
||||
* Notice that counter top must be configured separately with for instance
|
||||
* TIMER_TopSet(). In addition, compare/capture and dead-time insertion
|
||||
* init must be initialized separately if used. That should probably
|
||||
* be done prior to the use of this function if configuring the TIMER to
|
||||
* start when initialization is completed.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to TIMER initialization structure.
|
||||
******************************************************************************/
|
||||
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init)
|
||||
{
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
|
||||
/* Stop timer if specified to be disabled (dosn't hurt if already stopped) */
|
||||
if (!(init->enable))
|
||||
{
|
||||
timer->CMD = TIMER_CMD_STOP;
|
||||
}
|
||||
|
||||
/* Reset counter */
|
||||
timer->CNT = _TIMER_CNT_RESETVALUE;
|
||||
|
||||
timer->CTRL =
|
||||
((uint32_t)(init->prescale) << _TIMER_CTRL_PRESC_SHIFT) |
|
||||
((uint32_t)(init->clkSel) << _TIMER_CTRL_CLKSEL_SHIFT) |
|
||||
((uint32_t)(init->fallAction) << _TIMER_CTRL_FALLA_SHIFT) |
|
||||
((uint32_t)(init->riseAction) << _TIMER_CTRL_RISEA_SHIFT) |
|
||||
((uint32_t)(init->mode) << _TIMER_CTRL_MODE_SHIFT) |
|
||||
(init->debugRun ? TIMER_CTRL_DEBUGRUN : 0) |
|
||||
(init->dmaClrAct ? TIMER_CTRL_DMACLRACT : 0) |
|
||||
(init->quadModeX4 ? TIMER_CTRL_QDM_X4 : 0) |
|
||||
(init->oneShot ? TIMER_CTRL_OSMEN : 0) |
|
||||
|
||||
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
||||
(init->count2x ? TIMER_CTRL_X2CNT : 0) |
|
||||
(init->ati ? TIMER_CTRL_ATI : 0) |
|
||||
#endif
|
||||
(init->sync ? TIMER_CTRL_SYNC : 0);
|
||||
|
||||
/* Start timer if specified to be enabled (dosn't hurt if already started) */
|
||||
if (init->enable)
|
||||
{
|
||||
timer->CMD = TIMER_CMD_START;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize TIMER compare/capture channel.
|
||||
*
|
||||
* @details
|
||||
* Notice that if operating channel in compare mode, the CCV and CCVB register
|
||||
* must be set separately as required.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Compare/capture channel to init for.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to TIMER initialization structure.
|
||||
******************************************************************************/
|
||||
void TIMER_InitCC(TIMER_TypeDef *timer,
|
||||
unsigned int ch,
|
||||
const TIMER_InitCC_TypeDef *init)
|
||||
{
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
EFM_ASSERT(TIMER_CH_VALID(ch));
|
||||
|
||||
timer->CC[ch].CTRL =
|
||||
((uint32_t)(init->eventCtrl) << _TIMER_CC_CTRL_ICEVCTRL_SHIFT) |
|
||||
((uint32_t)(init->edge) << _TIMER_CC_CTRL_ICEDGE_SHIFT) |
|
||||
((uint32_t)(init->prsSel) << _TIMER_CC_CTRL_PRSSEL_SHIFT) |
|
||||
((uint32_t)(init->cufoa) << _TIMER_CC_CTRL_CUFOA_SHIFT) |
|
||||
((uint32_t)(init->cofoa) << _TIMER_CC_CTRL_COFOA_SHIFT) |
|
||||
((uint32_t)(init->cmoa) << _TIMER_CC_CTRL_CMOA_SHIFT) |
|
||||
((uint32_t)(init->mode) << _TIMER_CC_CTRL_MODE_SHIFT) |
|
||||
(init->filter ? TIMER_CC_CTRL_FILT_ENABLE : 0) |
|
||||
(init->prsInput ? TIMER_CC_CTRL_INSEL_PRS : 0) |
|
||||
(init->coist ? TIMER_CC_CTRL_COIST : 0) |
|
||||
(init->outInvert ? TIMER_CC_CTRL_OUTINV : 0);
|
||||
}
|
||||
|
||||
#ifdef TIMER_DTLOCK_LOCKKEY_LOCK
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Lock the TIMER in order to protect some of its registers against unintended
|
||||
* modification.
|
||||
*
|
||||
* @details
|
||||
* Please refer to the reference manual for TIMER registers that will be
|
||||
* locked.
|
||||
*
|
||||
* @note
|
||||
* If locking the TIMER registers, they must be unlocked prior to using any
|
||||
* TIMER API functions modifying TIMER registers protected by the lock.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
******************************************************************************/
|
||||
void TIMER_Lock(TIMER_TypeDef *timer)
|
||||
{
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
|
||||
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_LOCK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset TIMER to same state as after a HW reset.
|
||||
*
|
||||
* @note
|
||||
* The ROUTE register is NOT reset by this function, in order to allow for
|
||||
* centralized setup of this feature.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
******************************************************************************/
|
||||
void TIMER_Reset(TIMER_TypeDef *timer)
|
||||
{
|
||||
int i;
|
||||
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
|
||||
/* Make sure disabled first, before resetting other registers */
|
||||
timer->CMD = TIMER_CMD_STOP;
|
||||
|
||||
timer->CTRL = _TIMER_CTRL_RESETVALUE;
|
||||
timer->IEN = _TIMER_IEN_RESETVALUE;
|
||||
timer->IFC = _TIMER_IFC_MASK;
|
||||
timer->TOP = _TIMER_TOP_RESETVALUE;
|
||||
timer->TOPB = _TIMER_TOPB_RESETVALUE;
|
||||
timer->CNT = _TIMER_CNT_RESETVALUE;
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
/* (Note: ROUTE register may be locked by DTLOCK register.) */
|
||||
|
||||
for (i = 0; TIMER_CH_VALID(i); i++)
|
||||
{
|
||||
timer->CC[i].CTRL = _TIMER_CC_CTRL_RESETVALUE;
|
||||
timer->CC[i].CCV = _TIMER_CC_CCV_RESETVALUE;
|
||||
timer->CC[i].CCVB = _TIMER_CC_CCVB_RESETVALUE;
|
||||
}
|
||||
|
||||
/* Reset dead time insertion module, no effect on timers without DTI */
|
||||
|
||||
#ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
|
||||
/* Unlock DTI registers first in case locked */
|
||||
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
|
||||
|
||||
timer->DTCTRL = _TIMER_DTCTRL_RESETVALUE;
|
||||
timer->DTTIME = _TIMER_DTTIME_RESETVALUE;
|
||||
timer->DTFC = _TIMER_DTFC_RESETVALUE;
|
||||
timer->DTOGEN = _TIMER_DTOGEN_RESETVALUE;
|
||||
timer->DTFAULTC = _TIMER_DTFAULTC_MASK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unlock the TIMER so that writing to locked registers again is possible.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
******************************************************************************/
|
||||
void TIMER_Unlock(TIMER_TypeDef *timer)
|
||||
{
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
|
||||
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @} (end addtogroup TIMER) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,176 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Voltage Comparator (VCMP) peripheral API for EFM32
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32_assert.h"
|
||||
#include "efm32_vcmp.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup VCMP
|
||||
* @brief Voltage Comparator (VCMP) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure and enable Voltage Comparator
|
||||
*
|
||||
* @param[in] vcmpInit
|
||||
* VCMP Initialization structure
|
||||
******************************************************************************/
|
||||
void VCMP_Init(const VCMP_Init_TypeDef *vcmpInit)
|
||||
{
|
||||
/* Verify input */
|
||||
EFM_ASSERT((vcmpInit->inactive == 0) || (vcmpInit->inactive == 1));
|
||||
EFM_ASSERT((vcmpInit->biasProg >= 0) && (vcmpInit->biasProg < 16));
|
||||
|
||||
/* Configure Half Bias setting */
|
||||
if (vcmpInit->halfBias)
|
||||
{
|
||||
VCMP->CTRL |= VCMP_CTRL_HALFBIAS;
|
||||
}
|
||||
else
|
||||
{
|
||||
VCMP->CTRL &= ~(VCMP_CTRL_HALFBIAS);
|
||||
}
|
||||
|
||||
/* Configure bias prog */
|
||||
VCMP->CTRL &= ~(_VCMP_CTRL_BIASPROG_MASK);
|
||||
VCMP->CTRL |= (vcmpInit->biasProg << _VCMP_CTRL_BIASPROG_SHIFT);
|
||||
|
||||
/* Configure sense for falling edge */
|
||||
if (vcmpInit->irqFalling)
|
||||
{
|
||||
VCMP->CTRL |= VCMP_CTRL_IFALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
VCMP->CTRL &= ~(VCMP_CTRL_IFALL);
|
||||
}
|
||||
|
||||
/* Configure sense for rising edge */
|
||||
if (vcmpInit->irqRising)
|
||||
{
|
||||
VCMP->CTRL |= VCMP_CTRL_IRISE;
|
||||
}
|
||||
else
|
||||
{
|
||||
VCMP->CTRL &= ~(VCMP_CTRL_IRISE);
|
||||
}
|
||||
|
||||
/* Configure warm-up time */
|
||||
VCMP->CTRL &= ~(_VCMP_CTRL_WARMTIME_MASK);
|
||||
VCMP->CTRL |= (vcmpInit->warmup << _VCMP_CTRL_WARMTIME_SHIFT);
|
||||
|
||||
/* Configure hysteresis */
|
||||
switch (vcmpInit->hyst)
|
||||
{
|
||||
case vcmpHyst20mV:
|
||||
VCMP->CTRL |= VCMP_CTRL_HYSTEN;
|
||||
break;
|
||||
case vcmpHystNone:
|
||||
VCMP->CTRL &= ~(VCMP_CTRL_HYSTEN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Configure inactive output value */
|
||||
VCMP->CTRL |= (vcmpInit->inactive << _VCMP_CTRL_INACTVAL_SHIFT);
|
||||
|
||||
/* Configure trigger level */
|
||||
VCMP_TriggerSet(vcmpInit->triggerLevel);
|
||||
|
||||
/* Enable or disable VCMP */
|
||||
if (vcmpInit->enable)
|
||||
{
|
||||
VCMP->CTRL |= VCMP_CTRL_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
VCMP->CTRL &= ~(VCMP_CTRL_EN);
|
||||
}
|
||||
|
||||
/* If Low Power Reference is enabled, wait until VCMP is ready */
|
||||
/* before enabling it, see reference manual for deatils */
|
||||
/* Configuring Low Power Ref without enable has no effect */
|
||||
if(vcmpInit->lowPowerRef && vcmpInit->enable)
|
||||
{
|
||||
/* Poll for VCMP ready */
|
||||
while(!VCMP_Ready());
|
||||
VCMP_LowPowerRefSet(vcmpInit->lowPowerRef);
|
||||
}
|
||||
|
||||
/* Clear edge interrupt */
|
||||
VCMP_IntClear(VCMP_IF_EDGE);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable or disable Low Power Reference setting
|
||||
*
|
||||
* @param[in] enable
|
||||
* If true, enables low power reference, if false disable low power reference
|
||||
******************************************************************************/
|
||||
void VCMP_LowPowerRefSet(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
VCMP->INPUTSEL |= VCMP_INPUTSEL_LPREF;
|
||||
}
|
||||
else
|
||||
{
|
||||
VCMP->INPUTSEL &= ~(VCMP_INPUTSEL_LPREF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure trigger level of voltage comparator
|
||||
*
|
||||
* @param[in] level
|
||||
* Trigger value, in range 0-63
|
||||
******************************************************************************/
|
||||
void VCMP_TriggerSet(int level)
|
||||
{
|
||||
/* Trigger range is 6 bits, value from 0-63 */
|
||||
EFM_ASSERT((level > 0) && (level < 64));
|
||||
|
||||
/* Set trigger level */
|
||||
VCMP->INPUTSEL = (VCMP->INPUTSEL & ~(_VCMP_INPUTSEL_TRIGLEVEL_MASK)) |
|
||||
(level << _VCMP_INPUTSEL_TRIGLEVEL_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup VCMP) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,205 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Watchdog (WDOG) peripheral API for EFM32
|
||||
* devices.
|
||||
* @author Energy Micro AS
|
||||
* @version 2.3.2
|
||||
*******************************************************************************
|
||||
* @section License
|
||||
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This source code is the property of Energy Micro AS. The source and compiled
|
||||
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
||||
*
|
||||
* This copyright notice may not be removed from the source code nor changed.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
||||
* obligation to support this Software. Energy Micro AS is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Energy Micro AS will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "efm32_wdog.h"
|
||||
#include "efm32_bitband.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup EFM32_Library
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup WDOG
|
||||
* @brief Watchdog (WDOG) Peripheral API for EFM32
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable the watchdog timer.
|
||||
*
|
||||
* @note
|
||||
* This function modifies the WDOG CTRL register which requires
|
||||
* synchronization into the low frequency domain. If this register is modified
|
||||
* before a previous update to the same register has completed, this function
|
||||
* will stall until the previous synchronization has completed.
|
||||
*
|
||||
* @param[in] enable
|
||||
* true to enable watchdog, false to disable. Watchdog cannot be disabled if
|
||||
* watchdog has been locked.
|
||||
******************************************************************************/
|
||||
void WDOG_Enable(bool enable)
|
||||
{
|
||||
if (!enable)
|
||||
{
|
||||
/* Wait for any pending previous write operation to have been completed in */
|
||||
/* low frequency domain */
|
||||
while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL)
|
||||
;
|
||||
}
|
||||
BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_EN_SHIFT, (unsigned int)enable);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Feed the watchdog.
|
||||
*
|
||||
* @details
|
||||
* When the watchdog is activated, it must be fed (ie clearing the counter)
|
||||
* before it reaches the defined timeout period. Otherwise, the watchdog
|
||||
* will generate a reset.
|
||||
******************************************************************************/
|
||||
void WDOG_Feed(void)
|
||||
{
|
||||
/* If a previous clearing is being synchronized to LF domain, then there */
|
||||
/* is no point in waiting for it to complete before clearing over again. */
|
||||
/* This avoids stalling the core in the typical use case where some idle loop */
|
||||
/* keeps clearing the watchdog. */
|
||||
if (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CMD)
|
||||
return;
|
||||
|
||||
WDOG->CMD = WDOG_CMD_CLEAR;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize watchdog (assuming the watchdog configuration has not been
|
||||
* locked).
|
||||
*
|
||||
* @note
|
||||
* This function modifies the WDOG CTRL register which requires
|
||||
* synchronization into the low frequency domain. If this register is modified
|
||||
* before a previous update to the same register has completed, this function
|
||||
* will stall until the previous synchronization has completed.
|
||||
*
|
||||
* @param[in] init
|
||||
* Structure holding watchdog configuration. A default setting
|
||||
* #WDOG_INIT_DEFAULT is available for init.
|
||||
******************************************************************************/
|
||||
void WDOG_Init(const WDOG_Init_TypeDef *init)
|
||||
{
|
||||
uint32_t setting;
|
||||
|
||||
if (init->enable)
|
||||
{
|
||||
setting = WDOG_CTRL_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
setting = 0;
|
||||
}
|
||||
|
||||
if (init->debugRun)
|
||||
{
|
||||
setting |= WDOG_CTRL_DEBUGRUN;
|
||||
}
|
||||
|
||||
if (init->em2Run)
|
||||
{
|
||||
setting |= WDOG_CTRL_EM2RUN;
|
||||
}
|
||||
|
||||
if (init->em3Run)
|
||||
{
|
||||
setting |= WDOG_CTRL_EM3RUN;
|
||||
}
|
||||
|
||||
if (init->em4Block)
|
||||
{
|
||||
setting |= WDOG_CTRL_EM4BLOCK;
|
||||
}
|
||||
|
||||
if (init->swoscBlock)
|
||||
{
|
||||
setting |= WDOG_CTRL_SWOSCBLOCK;
|
||||
}
|
||||
|
||||
setting |= ((uint32_t)(init->clkSel) << _WDOG_CTRL_CLKSEL_SHIFT) |
|
||||
((uint32_t)(init->perSel) << _WDOG_CTRL_PERSEL_SHIFT);
|
||||
|
||||
/* Wait for any pending previous write operation to have been completed in */
|
||||
/* low frequency domain */
|
||||
while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL)
|
||||
;
|
||||
|
||||
WDOG->CTRL = setting;
|
||||
|
||||
/* Optional register locking */
|
||||
if (init->lock)
|
||||
{
|
||||
if (init->enable)
|
||||
{
|
||||
WDOG_Lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_LOCK_SHIFT, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Lock the watchdog configuration.
|
||||
*
|
||||
* @details
|
||||
* This prevents errors from overwriting the watchdog configuration, possibly
|
||||
* disabling it. Only a reset can unlock the watchdog config, once locked.
|
||||
*
|
||||
* If the LFRCO or LFXO clocks are used to clock the watchdog, one should
|
||||
* consider using the option of inhibiting those clocks to be disabled,
|
||||
* please see the WDOG_Enable() init structure.
|
||||
*
|
||||
* @note
|
||||
* This function modifies the WDOG CTRL register which requires
|
||||
* synchronization into the low frequency domain. If this register is modified
|
||||
* before a previous update to the same register has completed, this function
|
||||
* will stall until the previous synchronization has completed.
|
||||
******************************************************************************/
|
||||
void WDOG_Lock(void)
|
||||
{
|
||||
/* Wait for any pending previous write operation to have been completed in */
|
||||
/* low frequency domain */
|
||||
while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL)
|
||||
;
|
||||
|
||||
/* Disable writing to the control register */
|
||||
BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_LOCK_SHIFT, 1);
|
||||
}
|
||||
|
||||
|
||||
/** @} (end addtogroup WDOG) */
|
||||
/** @} (end addtogroup EFM32_Library) */
|
|
@ -0,0 +1,118 @@
|
|||
/****************************************************************************************
|
||||
| Description: bootloader application source file
|
||||
| File Name: main.c
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| C O P Y R I G H T
|
||||
|----------------------------------------------------------------------------------------
|
||||
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| L I C E N S E
|
||||
|----------------------------------------------------------------------------------------
|
||||
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
||||
| modify it under the terms of the GNU General Public License as published by the Free
|
||||
| Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
| version.
|
||||
|
|
||||
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
| PURPOSE. See the GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License along with OpenBLT.
|
||||
| If not, see <http://www.gnu.org/licenses/>.
|
||||
|
|
||||
| A special exception to the GPL is included to allow you to distribute a combined work
|
||||
| that includes OpenBLT without being obliged to provide the source code for any
|
||||
| proprietary components. The exception text is included at the bottom of the license
|
||||
| file <license.html>.
|
||||
|
|
||||
****************************************************************************************/
|
||||
|
||||
/****************************************************************************************
|
||||
* Include files
|
||||
****************************************************************************************/
|
||||
#include "boot.h" /* bootloader generic header */
|
||||
#include "efm32.h" /* EFM32 registers */
|
||||
#include "efm32_chip.h" /* EFM32 chip initialization */
|
||||
#include "efm32_cmu.h" /* EFM32 clock management */
|
||||
#include "efm32_gpio.h"
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************************/
|
||||
static void Init(void);
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: main
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: program return code
|
||||
** DESCRIPTION: This is the entry point for the bootloader application and is called
|
||||
** by the reset interrupt vector after the C-startup routines executed.
|
||||
**
|
||||
****************************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
/* initialize the microcontroller */
|
||||
Init();
|
||||
/* initialize the bootloader */
|
||||
BootInit();
|
||||
|
||||
/* start the infinite program loop */
|
||||
while (1)
|
||||
{
|
||||
/* run the bootloader task */
|
||||
BootTask();
|
||||
}
|
||||
|
||||
/* program should never get here */
|
||||
return 0;
|
||||
} /*** end of main ***/
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: Init
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Initializes the microcontroller. The interrupts are disabled, the
|
||||
** clocks are configured and the flash wait states are configured.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static void Init(void)
|
||||
{
|
||||
/* initialize the system and its clocks */
|
||||
SystemInit();
|
||||
/* handle chip errate workarounds */
|
||||
CHIP_Init();
|
||||
/* enable the low frequency crystal oscillator */
|
||||
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
|
||||
/* turn on clocking of all the modules */
|
||||
CMU->HFCORECLKEN0 |= 0x0F;
|
||||
CMU->HFPERCLKEN0 |= 0xFFFF;
|
||||
/* disable clocking of the modules that are not in use */
|
||||
CMU_ClockEnable(cmuClock_AES, false);
|
||||
CMU_ClockEnable(cmuClock_DMA, false);
|
||||
CMU_ClockEnable(cmuClock_EBI, false);
|
||||
CMU_ClockEnable(cmuClock_PRS, false);
|
||||
CMU_ClockEnable(cmuClock_USART0, false);
|
||||
CMU_ClockEnable(cmuClock_USART1, false);
|
||||
CMU_ClockEnable(cmuClock_USART2, false);
|
||||
CMU_ClockEnable(cmuClock_UART0, false);
|
||||
CMU_ClockEnable(cmuClock_ACMP0, false);
|
||||
CMU_ClockEnable(cmuClock_ACMP1, false);
|
||||
CMU_ClockEnable(cmuClock_DAC0, false);
|
||||
CMU_ClockEnable(cmuClock_ADC0, false);
|
||||
CMU_ClockEnable(cmuClock_I2C0, false);
|
||||
CMU_ClockEnable(cmuClock_VCMP, false);
|
||||
#if (BOOT_COM_UART_ENABLE > 0)
|
||||
/* enable power to U2 (RS232_PWR_E) */
|
||||
GPIO_PinModeSet(gpioPortB, 9, gpioModePushPullDrive, 1);
|
||||
/* set port B outputs to drive up to 20 mA */
|
||||
GPIO_DriveModeSet(gpioPortB, gpioDriveModeHigh);
|
||||
#endif
|
||||
} /*** end of Init ***/
|
||||
|
||||
|
||||
/*********************************** end of main.c *************************************/
|
|
@ -0,0 +1,240 @@
|
|||
#****************************************************************************************
|
||||
#| Description: Makefile for EFM32 using CodeSourcery GNU GCC compiler toolset
|
||||
#| File Name: makefile
|
||||
#|
|
||||
#|---------------------------------------------------------------------------------------
|
||||
#| C O P Y R I G H T
|
||||
#|---------------------------------------------------------------------------------------
|
||||
#| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
||||
#|
|
||||
#|---------------------------------------------------------------------------------------
|
||||
#| L I C E N S E
|
||||
#|---------------------------------------------------------------------------------------
|
||||
#| This file is part of OpenBTL. OpenBTL is free software: you can redistribute it and/or
|
||||
#| modify it under the terms of the GNU General Public License as published by the Free
|
||||
#| Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
#| version.
|
||||
#|
|
||||
#| OpenBTL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
#| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
#| PURPOSE. See the GNU General Public License for more details.
|
||||
#|
|
||||
#| You should have received a copy of the GNU General Public License along with OpenBTL.
|
||||
#| If not, see <http://www.gnu.org/licenses/>.
|
||||
#|
|
||||
#****************************************************************************************
|
||||
SHELL = sh
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Configure project name |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
PROJ_NAME=openbtl_olimex_efm32g880
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Speficy project source files |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
PROJ_FILES= \
|
||||
config.h \
|
||||
hooks.c \
|
||||
main.c \
|
||||
./lib/CMSIS/CM3/CoreSupport/core_cm3.c \
|
||||
./lib/CMSIS/CM3/CoreSupport/core_cm3.h \
|
||||
./lib/CMSIS/CM3/CoreSupport/core_cmFunc.h \
|
||||
./lib/CMSIS/CM3/CoreSupport/core_cmInstr.h \
|
||||
./lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32.h \
|
||||
./lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32g880f128.h \
|
||||
./lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.c \
|
||||
./lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.h \
|
||||
./lib/efm32lib/inc/efm32_acmp.h \
|
||||
./lib/efm32lib/inc/efm32_adc.h \
|
||||
./lib/efm32lib/inc/efm32_aes.h \
|
||||
./lib/efm32lib/inc/efm32_assert.h \
|
||||
./lib/efm32lib/inc/efm32_bitband.h \
|
||||
./lib/efm32lib/inc/efm32_chip.h \
|
||||
./lib/efm32lib/inc/efm32_cmu.h \
|
||||
./lib/efm32lib/inc/efm32_common.h \
|
||||
./lib/efm32lib/inc/efm32_dac.h \
|
||||
./lib/efm32lib/inc/efm32_dbg.h \
|
||||
./lib/efm32lib/inc/efm32_dma.h \
|
||||
./lib/efm32lib/inc/efm32_ebi.h \
|
||||
./lib/efm32lib/inc/efm32_emu.h \
|
||||
./lib/efm32lib/inc/efm32_gpio.h \
|
||||
./lib/efm32lib/inc/efm32_i2c.h \
|
||||
./lib/efm32lib/inc/efm32_int.h \
|
||||
./lib/efm32lib/inc/efm32_lcd.h \
|
||||
./lib/efm32lib/inc/efm32_lesense.h \
|
||||
./lib/efm32lib/inc/efm32_letimer.h \
|
||||
./lib/efm32lib/inc/efm32_leuart.h \
|
||||
./lib/efm32lib/inc/efm32_mpu.h \
|
||||
./lib/efm32lib/inc/efm32_msc.h \
|
||||
./lib/efm32lib/inc/efm32_opamp.h \
|
||||
./lib/efm32lib/inc/efm32_pcnt.h \
|
||||
./lib/efm32lib/inc/efm32_prs.h \
|
||||
./lib/efm32lib/inc/efm32_rmu.h \
|
||||
./lib/efm32lib/inc/efm32_rtc.h \
|
||||
./lib/efm32lib/inc/efm32_system.h \
|
||||
./lib/efm32lib/inc/efm32_timer.h \
|
||||
./lib/efm32lib/inc/efm32_usart.h \
|
||||
./lib/efm32lib/inc/efm32_vcmp.h \
|
||||
./lib/efm32lib/inc/efm32_wdog.h \
|
||||
./lib/efm32lib/src/efm32_acmp.c \
|
||||
./lib/efm32lib/src/efm32_adc.c \
|
||||
./lib/efm32lib/src/efm32_aes.c \
|
||||
./lib/efm32lib/src/efm32_assert.c \
|
||||
./lib/efm32lib/src/efm32_cmu.c \
|
||||
./lib/efm32lib/src/efm32_dac.c \
|
||||
./lib/efm32lib/src/efm32_dbg.c \
|
||||
./lib/efm32lib/src/efm32_dma.c \
|
||||
./lib/efm32lib/src/efm32_ebi.c \
|
||||
./lib/efm32lib/src/efm32_emu.c \
|
||||
./lib/efm32lib/src/efm32_gpio.c \
|
||||
./lib/efm32lib/src/efm32_i2c.c \
|
||||
./lib/efm32lib/src/efm32_int.c \
|
||||
./lib/efm32lib/src/efm32_lcd.c \
|
||||
./lib/efm32lib/src/efm32_lesense.c \
|
||||
./lib/efm32lib/src/efm32_letimer.c \
|
||||
./lib/efm32lib/src/efm32_leuart.c \
|
||||
./lib/efm32lib/src/efm32_mpu.c \
|
||||
./lib/efm32lib/src/efm32_msc.c \
|
||||
./lib/efm32lib/src/efm32_opamp.c \
|
||||
./lib/efm32lib/src/efm32_pcnt.c \
|
||||
./lib/efm32lib/src/efm32_prs.c \
|
||||
./lib/efm32lib/src/efm32_rmu.c \
|
||||
./lib/efm32lib/src/efm32_rtc.c \
|
||||
./lib/efm32lib/src/efm32_system.c \
|
||||
./lib/efm32lib/src/efm32_timer.c \
|
||||
./lib/efm32lib/src/efm32_usart.c \
|
||||
./lib/efm32lib/src/efm32_vcmp.c \
|
||||
./lib/efm32lib/src/efm32_wdog.c \
|
||||
../../../Source/boot.c \
|
||||
../../../Source/boot.h \
|
||||
../../../Source/com.c \
|
||||
../../../Source/com.h \
|
||||
../../../Source/xcp.c \
|
||||
../../../Source/xcp.h \
|
||||
../../../Source/backdoor.c \
|
||||
../../../Source/backdoor.h \
|
||||
../../../Source/cop.c \
|
||||
../../../Source/cop.h \
|
||||
../../../Source/assert.c \
|
||||
../../../Source/assert.h \
|
||||
../../../Source/plausibility.h \
|
||||
../../../Source/ARMCM3_EFM32/types.h \
|
||||
../../../Source/ARMCM3_EFM32/cpu.c \
|
||||
../../../Source/ARMCM3_EFM32/cpu.h \
|
||||
../../../Source/ARMCM3_EFM32/uart.c \
|
||||
../../../Source/ARMCM3_EFM32/uart.h \
|
||||
../../../Source/ARMCM3_EFM32/nvm.c \
|
||||
../../../Source/ARMCM3_EFM32/nvm.h \
|
||||
../../../Source/ARMCM3_EFM32/timer.c \
|
||||
../../../Source/ARMCM3_EFM32/timer.h \
|
||||
../../../Source/ARMCM3_EFM32/GCC/flash.c \
|
||||
../../../Source/ARMCM3_EFM32/GCC/flash.h \
|
||||
../../../Source/ARMCM3_EFM32/GCC/vectors.c \
|
||||
../../../Source/ARMCM3_EFM32/GCC/cstart.c
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Compiler binaries |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
CC = arm-none-eabi-gcc
|
||||
LN = arm-none-eabi-gcc
|
||||
OC = arm-none-eabi-objcopy
|
||||
OD = arm-none-eabi-objdump
|
||||
AS = arm-none-eabi-as
|
||||
SZ = arm-none-eabi-size
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Extract file names |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
PROJ_ASRCS = $(filter %.s,$(foreach file,$(PROJ_FILES),$(notdir $(file))))
|
||||
PROJ_CSRCS = $(filter %.c,$(foreach file,$(PROJ_FILES),$(notdir $(file))))
|
||||
PROJ_CHDRS = $(filter %.h,$(foreach file,$(PROJ_FILES),$(notdir $(file))))
|
||||
PROJ_CCMPL = $(patsubst %.c,%.cpl,$(PROJ_CSRCS))
|
||||
PROJ_ACMPL = $(patsubst %.s,%.cpl,$(PROJ_ASRCS))
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Set important path variables |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
VPATH = $(foreach path,$(sort $(foreach file,$(PROJ_FILES),$(dir $(file)))) $(subst \,/,$(OBJ_PATH)),$(path) :)
|
||||
OBJ_PATH = obj
|
||||
BIN_PATH = bin
|
||||
INC_PATH = $(patsubst %,-I%,$(sort $(foreach file,$(filter %.h,$(PROJ_FILES)),$(dir $(file)))))
|
||||
INC_PATH += -I. -I./lib
|
||||
LIB_PATH = -L../../../Source/ARMCM3_EFM32/GCC/
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Options for compiler binaries |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
CFLAGS = -g -D inline= -mthumb -mcpu=cortex-m3 -Os -T memory.x
|
||||
CFLAGS += -D PACK_STRUCT_END=__attribute\(\(packed\)\) -Wno-main
|
||||
CFLAGS += -D ALIGN_STRUCT_END=__attribute\(\(aligned\(4\)\)\)
|
||||
CFLAGS += -ffunction-sections -fdata-sections $(INC_PATH) -D EFM32G880F128
|
||||
CFLAGS += -Wa,-adhlns="$(OBJ_PATH)/$(subst .o,.lst,$@)"
|
||||
LFLAGS = -nostartfiles -Xlinker -M -Xlinker -Map=$(BIN_PATH)/$(PROJ_NAME).map
|
||||
LFLAGS += $(LIB_PATH) -Xlinker --gc-sections
|
||||
OFLAGS = -O binary
|
||||
ODFLAGS = -x
|
||||
SZFLAGS = -B -d
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Specify library files |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
LIBS =
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Define targets |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
AOBJS = $(patsubst %.s,%.o,$(PROJ_ASRCS))
|
||||
COBJS = $(patsubst %.c,%.o,$(PROJ_CSRCS))
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Make ALL |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
all : $(BIN_PATH)/$(PROJ_NAME).bin
|
||||
|
||||
|
||||
$(BIN_PATH)/$(PROJ_NAME).bin : $(BIN_PATH)/$(PROJ_NAME).elf
|
||||
@$(OC) $< $(OFLAGS) $@
|
||||
@$(OD) $(ODFLAGS) $< > $(BIN_PATH)/$(PROJ_NAME).map
|
||||
@echo +++ Summary of memory consumption:
|
||||
@$(SZ) $(SZFLAGS) $<
|
||||
@echo +++ Build complete [$(notdir $@)]
|
||||
|
||||
$(BIN_PATH)/$(PROJ_NAME).elf : $(AOBJS) $(COBJS)
|
||||
@echo +++ Linking [$(notdir $@)]
|
||||
@$(LN) $(CFLAGS) -o $@ $(patsubst %.o,$(OBJ_PATH)/%.o,$(^F)) $(LIBS) $(LFLAGS)
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Compile and assemble |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
$(AOBJS): %.o: %.s $(PROJ_CHDRS)
|
||||
@echo +++ Assembling [$(notdir $<)]
|
||||
@$(AS) $(AFLAGS) $< -o $(OBJ_PATH)/$(@F)
|
||||
|
||||
$(COBJS): %.o: %.c $(PROJ_CHDRS)
|
||||
@echo +++ Compiling [$(notdir $<)]
|
||||
@$(CC) $(CFLAGS) -c $< -o $(OBJ_PATH)/$(@F)
|
||||
|
||||
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
#| Make CLEAN |
|
||||
#|---------------------------------------------------------------------------------------|
|
||||
clean :
|
||||
@echo +++ Cleaning build environment
|
||||
@rm -f $(foreach file,$(AOBJS),$(OBJ_PATH)/$(file))
|
||||
@rm -f $(foreach file,$(COBJS),$(OBJ_PATH)/$(file))
|
||||
@rm -f $(patsubst %.o,%.lst,$(foreach file,$(COBJS),$(OBJ_PATH)/$(file)))
|
||||
@rm -f $(BIN_PATH)/$(PROJ_NAME).elf $(BIN_PATH)/$(PROJ_NAME).map
|
||||
@rm -f $(BIN_PATH)/$(PROJ_NAME).bin
|
||||
@echo +++ Clean complete
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,174 @@
|
|||
|
||||
bin/demoprog_olimex_efm32g880.elf: file format elf32-littlearm
|
||||
bin/demoprog_olimex_efm32g880.elf
|
||||
architecture: arm, flags 0x00000112:
|
||||
EXEC_P, HAS_SYMS, D_PAGED
|
||||
start address 0x00002000
|
||||
|
||||
Program Header:
|
||||
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**15
|
||||
filesz 0x0000344c memsz 0x0000344c flags r-x
|
||||
LOAD off 0x00008000 vaddr 0x20000000 paddr 0x0000344c align 2**15
|
||||
filesz 0x00000008 memsz 0x00000168 flags rw-
|
||||
private flags = 5000002: [Version5 EABI] [has entry point]
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
0 .text 0000144c 00002000 00002000 00002000 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
1 .data 00000008 20000000 0000344c 00008000 2**2
|
||||
CONTENTS, ALLOC, LOAD, DATA
|
||||
2 .bss 00000160 20000008 00003454 00008008 2**2
|
||||
ALLOC
|
||||
3 .debug_abbrev 000039ba 00000000 00000000 00008008 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
4 .debug_info 0000db0e 00000000 00000000 0000b9c2 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
5 .debug_line 0000554b 00000000 00000000 000194d0 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
6 .debug_loc 000065d3 00000000 00000000 0001ea1b 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
7 .debug_pubnames 0000138d 00000000 00000000 00024fee 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
8 .debug_pubtypes 00001700 00000000 00000000 0002637b 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
9 .debug_aranges 00000b10 00000000 00000000 00027a7b 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
10 .debug_ranges 000008f0 00000000 00000000 0002858b 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
11 .debug_str 000051e2 00000000 00000000 00028e7b 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
12 .comment 0000002a 00000000 00000000 0002e05d 2**0
|
||||
CONTENTS, READONLY
|
||||
13 .ARM.attributes 00000031 00000000 00000000 0002e087 2**0
|
||||
CONTENTS, READONLY
|
||||
14 .debug_frame 000017ac 00000000 00000000 0002e0b8 2**2
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
SYMBOL TABLE:
|
||||
00002000 l d .text 00000000 .text
|
||||
20000000 l d .data 00000000 .data
|
||||
20000008 l d .bss 00000000 .bss
|
||||
00000000 l d .debug_abbrev 00000000 .debug_abbrev
|
||||
00000000 l d .debug_info 00000000 .debug_info
|
||||
00000000 l d .debug_line 00000000 .debug_line
|
||||
00000000 l d .debug_loc 00000000 .debug_loc
|
||||
00000000 l d .debug_pubnames 00000000 .debug_pubnames
|
||||
00000000 l d .debug_pubtypes 00000000 .debug_pubtypes
|
||||
00000000 l d .debug_aranges 00000000 .debug_aranges
|
||||
00000000 l d .debug_ranges 00000000 .debug_ranges
|
||||
00000000 l d .debug_str 00000000 .debug_str
|
||||
00000000 l d .comment 00000000 .comment
|
||||
00000000 l d .ARM.attributes 00000000 .ARM.attributes
|
||||
00000000 l d .debug_frame 00000000 .debug_frame
|
||||
00000000 l df *ABS* 00000000 vectors.c
|
||||
00000000 l df *ABS* 00000000 boot.c
|
||||
000020bc l F .text 00000034 UartReceiveByte
|
||||
20000008 l O .bss 00000001 xcpCtoRxLength.2654
|
||||
20000009 l O .bss 00000001 xcpCtoRxInProgress.2655
|
||||
0000343c l O .text 00000010 C.3.3551
|
||||
2000000c l O .bss 00000041 xcpCtoReqPacket.2653
|
||||
00000000 l df *ABS* 00000000 cstart.c
|
||||
000022de l F .text 00000000 zero_loop
|
||||
00000000 l df *ABS* 00000000 irq.c
|
||||
00000000 l df *ABS* 00000000 led.c
|
||||
20000050 l O .bss 00000004 timer_counter_last.2646
|
||||
20000054 l O .bss 00000001 led_toggle_state.2645
|
||||
00000000 l df *ABS* 00000000 main.c
|
||||
00000000 l df *ABS* 00000000 timer.c
|
||||
20000058 l O .bss 00000004 millisecond_counter
|
||||
00000000 l df *ABS* 00000000 system_efm32.c
|
||||
20000000 l O .data 00000004 SystemLFXOClock
|
||||
20000004 l O .data 00000004 SystemHFXOClock
|
||||
00000000 l df *ABS* 00000000 lcdcontroller.c
|
||||
000027e4 l F .text 00000060 LCD_enableSegment
|
||||
00002844 l F .text 00000070 LCD_disableSegment
|
||||
00000000 l df *ABS* 00000000 efm32_cmu.c
|
||||
00002a40 l F .text 00000010 BITBAND_Peripheral
|
||||
00002a50 l F .text 00000038 CMU_FlashWaitStateMax
|
||||
00002a88 l F .text 0000000c CMU_DivToLog2
|
||||
00002a94 l F .text 00000064 CMU_FlashWaitStateControl
|
||||
00002af8 l F .text 0000000a CMU_AUXClkGet
|
||||
00002b04 l F .text 00000020 CMU_Sync
|
||||
00002b24 l F .text 00000052 CMU_LFClkGet
|
||||
00000000 l df *ABS* 00000000 efm32_emu.c
|
||||
20000060 l O .bss 00000002 cmuStatus
|
||||
00000000 l df *ABS* 00000000 efm32_gpio.c
|
||||
00000000 l df *ABS* 00000000 efm32_leuart.c
|
||||
000032f8 l F .text 00000010 LEUART_Sync
|
||||
00000000 l df *ABS* 00000000 efm32_system.c
|
||||
00000000 l df *ABS* 00000000 core_cm3.c
|
||||
00000000 l df *ABS* 00000000 efm32_acmp.c
|
||||
00000000 l df *ABS* 00000000 efm32_adc.c
|
||||
00000000 l df *ABS* 00000000 efm32_aes.c
|
||||
00000000 l df *ABS* 00000000 efm32_assert.c
|
||||
00000000 l df *ABS* 00000000 efm32_dac.c
|
||||
00000000 l df *ABS* 00000000 efm32_dbg.c
|
||||
00000000 l df *ABS* 00000000 efm32_dma.c
|
||||
00000000 l df *ABS* 00000000 efm32_ebi.c
|
||||
00000000 l df *ABS* 00000000 efm32_i2c.c
|
||||
00000000 l df *ABS* 00000000 efm32_int.c
|
||||
00000000 l df *ABS* 00000000 efm32_lcd.c
|
||||
00000000 l df *ABS* 00000000 efm32_lesense.c
|
||||
00000000 l df *ABS* 00000000 efm32_letimer.c
|
||||
00000000 l df *ABS* 00000000 efm32_mpu.c
|
||||
00000000 l df *ABS* 00000000 efm32_msc.c
|
||||
00000000 l df *ABS* 00000000 efm32_opamp.c
|
||||
00000000 l df *ABS* 00000000 efm32_pcnt.c
|
||||
00000000 l df *ABS* 00000000 efm32_prs.c
|
||||
00000000 l df *ABS* 00000000 efm32_rmu.c
|
||||
00000000 l df *ABS* 00000000 efm32_rtc.c
|
||||
00000000 l df *ABS* 00000000 efm32_timer.c
|
||||
00000000 l df *ABS* 00000000 efm32_usart.c
|
||||
00000000 l df *ABS* 00000000 efm32_vcmp.c
|
||||
00000000 l df *ABS* 00000000 efm32_wdog.c
|
||||
00000000 l df *ABS* 00000000 strlen.c
|
||||
000031f4 g F .text 0000001e GPIO_DriveModeSet
|
||||
000031dc g F .text 00000016 EMU_UpdateOscConfig
|
||||
00002298 g F .text 0000005c reset_handler
|
||||
00002e5c g F .text 000001e6 CMU_ClockFreqGet
|
||||
0000336c g F .text 00000022 LEUART_Enable
|
||||
00003390 g F .text 00000018 LEUART_FreezeEnable
|
||||
00002300 g F .text 00000004 IrqInterruptEnable
|
||||
2000005c g O .bss 00000004 frameCounter
|
||||
00003044 g F .text 00000074 CMU_OscillatorEnable
|
||||
000028f0 g F .text 000000a8 LCD_Symbol
|
||||
0000344c g .text 00000000 _etext
|
||||
000026d0 g F .text 00000012 TimerISRHandler
|
||||
00002db0 g F .text 000000aa CMU_ClockSelectGet
|
||||
20000064 g O .bss 00000004 SystemCoreClock
|
||||
000027d8 g F .text 0000000c SystemLFXOClockGet
|
||||
00002d28 g F .text 00000088 CMU_ClockEnable
|
||||
000028d4 g F .text 0000001c LCD_AllOff
|
||||
00003408 g F .text 0000000e LEUART_Rx
|
||||
20000068 g .bss 00000000 _ebss
|
||||
000028b4 g F .text 00000020 LCD_IRQHandler
|
||||
00000100 g *ABS* 00000000 __STACKSIZE__
|
||||
000026e4 g F .text 00000002 UnusedISR
|
||||
00002304 g F .text 00000016 LedInit
|
||||
000033a8 g F .text 0000005e LEUART_Init
|
||||
000030b8 g F .text 00000122 CMU_ClockSelectSet
|
||||
20000008 g .bss 00000000 _bss
|
||||
000026e8 g F .text 000000b6 SystemHFClockGet
|
||||
00002998 g F .text 000000a6 LCD_Init
|
||||
0000239c g F .text 000002b0 main
|
||||
0000265c g F .text 0000000c TimerSet
|
||||
00003214 g F .text 000000e2 GPIO_PinModeSet
|
||||
000020f0 g F .text 000000ea BootComInit
|
||||
000027cc g F .text 00000002 SystemInit
|
||||
00002b78 g F .text 000001b0 CMU_ClockDivSet
|
||||
0000264c g F .text 00000010 TimerDeinit
|
||||
20000000 g .data 00000000 _data
|
||||
0000231c g F .text 00000080 LedToggle
|
||||
000027d0 g F .text 00000006 SystemLFRCOClockGet
|
||||
00003308 g F .text 00000064 LEUART_BaudrateSet
|
||||
00003418 g F .text 00000024 SYSTEM_ChipRevisionGet
|
||||
000027a0 g F .text 0000002a SystemCoreClockGet
|
||||
20000168 g .bss 00000000 _estack
|
||||
20000008 g .data 00000000 _edata
|
||||
00002000 g O .text 000000bc _vectab
|
||||
000021dc g F .text 000000bc BootComCheckActivationRequest
|
||||
20000068 g .bss 00000000 _stack
|
||||
000026c4 g F .text 0000000c TimerGet
|
||||
00002668 g F .text 0000005a TimerInit
|
||||
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
S025000062696E2F64656D6F70726F675F6F6C696D65785F65666D3332673838302E737265634A
|
||||
S11320006801002099220000E5260000E526000072
|
||||
S1132010E5260000E5260000E5260000E526000090
|
||||
S1132020E5260000E5260000E5260000E526000080
|
||||
S1132030E5260000E5260000E5260000D126000084
|
||||
S1132040E5260000E5260000E5260000E526000060
|
||||
S1132050E5260000E5260000E5260000E526000050
|
||||
S1132060E5260000E5260000E5260000E526000040
|
||||
S1132070E5260000E5260000E5260000E526000030
|
||||
S1132080E5260000E5260000E5260000E526000020
|
||||
S1132090E5260000E5260000E5260000E526000010
|
||||
S11320A0E5260000E5260000E5260000B52800002E
|
||||
S11320B0E5260000E5260000EE11AA5510B50446F9
|
||||
S11320C04FF48843C4F20803DB6A13F0040F0CD006
|
||||
S11320D04FF48840C4F2080043F20943C0F20003FD
|
||||
S11320E0984720704FF0010010BD4FF0000010BD64
|
||||
S11320F070B584B043F23C43C0F200036E460FCB8C
|
||||
S113210086E80F004FF44240C0F202004FF0010194
|
||||
S113211042F62954C0F20004A0474FF002004FF0E9
|
||||
S113212006014FF004024FF0010343F21525C0F2FB
|
||||
S11321300005A8474FF002004FF007014FF00102DD
|
||||
S11321404FF00003A8474FF40C50C0F204004FF0C6
|
||||
S11321500101A0474FF00300C0F212004FF002014A
|
||||
S113216043F2B903C0F2000398474FF4AA55C0F2F2
|
||||
S1132170160528464FF0010142F67933C0F20003F8
|
||||
S1132180984728464FF00101A0474FF000058DF80D
|
||||
S113219000504FF48844C4F208042046694643F2D0
|
||||
S11321A0A933C0F200039847204629464FF416523B
|
||||
S11321B043F20933C0F2000398474FF00303636509
|
||||
S11321C04FF00403636320464FF0050143F26D337F
|
||||
S11321D0C0F20003984704B070BD00BF08B540F2D8
|
||||
S11321E00903C2F200031B78CBB940F20C00C2F21F
|
||||
S11321F0000042F2BD03C0F200039847012848D111
|
||||
S113220040F20903C2F200034FF001021A7040F2D7
|
||||
S11322100803C2F200034FF000021A7008BD40F236
|
||||
S11322200803C2F2000318781A4BC01842F2BD0327
|
||||
S1132230C0F20003984701282BD140F20803C2F2F0
|
||||
S113224000031A7802F10102D2B21A7040F20C03B0
|
||||
S1132250C2F200031B7893421BD140F20903C2F27D
|
||||
S113226000034FF000021A7040F20C03C2F20003A4
|
||||
S11322705B78FF2B0DD140F20C03C2F200039B7874
|
||||
S11322803BB942F24D63C0F2000398474FF0B903E3
|
||||
S1132290984708BD0D00002008B516498D4640F248
|
||||
S11322A00002C2F2000240F20803C2F200039A42A2
|
||||
S11322B011D243F24C42C0F2000240F20003C2F2D7
|
||||
S11322C0000340F20800C2F2000052F8041B43F875
|
||||
S11322D0041B8342F9D3084808494FF0000288429E
|
||||
S11322E0B8BF40F8042BFADB42F29D33C0F200037E
|
||||
S11322F0984708BD680100200800002068000020FD
|
||||
S113230062B6704708B54FF42040C4F2080042F6A4
|
||||
S11323109913C0F20003984708BD00BF10B542F2FC
|
||||
S1132320C563C0F200039847044640F25003C2F26A
|
||||
S113233000031B68C31AB3F5FA7F2ED340F254038B
|
||||
S1132340C2F200031B7893B940F25403C2F20003B3
|
||||
S11323504FF001021A704FF42040C4F208004FF00D
|
||||
S1132360000142F6F103C0F20003984710E040F286
|
||||
S11323705403C2F200034FF000021A704FF42040DD
|
||||
S1132380C4F20800114642F6F103C0F20003984774
|
||||
S113239040F25003C2F200031C6010BD30B583B09C
|
||||
S11323A042F2CD73C0F20003984748F2FC13C0F622
|
||||
S11323B0E0731B681B0E14D14AF20C03C4F20C0325
|
||||
S11323C01A6822F070021A6046F22003C4F20C0369
|
||||
S11323D01A6822F060421A601A6862F060621A6039
|
||||
S11323E001E0032B22D846F22003C4F20C031A683E
|
||||
S11323F022F4FC521A6048F24002C4F20C024FF07C
|
||||
S11324000003136048F24402C4F20C02136048F261
|
||||
S11324105802C4F20C02136048F26002C4F20C02C7
|
||||
S1132420136048F27802C4F20C02136001A843F26C
|
||||
S11324301943C0F2000398479DF80430012B17D1CB
|
||||
S11324409DF805303BB948F24003C4F20C031A6806
|
||||
S113245042F002021A609DF80530012B9FBF48F23A
|
||||
S11324604403C4F20C031A6842F0010298BF1A60D4
|
||||
S113247048F2F013C0F6E0731A684BF6FF13C4F683
|
||||
S11324808A439A4230D848F24403C4F20C031A68CF
|
||||
S113249042F490421A6048F2B412C0F6E072116835
|
||||
S11324A001F4FE4110681568146804F07F0405F413
|
||||
S11324B0FE4244EA020200F07F0042EA004242EA9D
|
||||
S11324C0014142F23402C4F20002116048F2C8121F
|
||||
S11324D0C0F6E072116844F22C02C4F200021160EA
|
||||
S11324E01A6822F490421A604FF000004FF0010184
|
||||
S11324F00A4643F24503C0F2000398474FF40043F1
|
||||
S1132500C4F20C031A6C42F00F021A645A6C6FEA9C
|
||||
S113251012426FEA02425A644FF44070C0F204005F
|
||||
S11325204FF0000142F62954C0F20004A0474FF4D2
|
||||
S11325309850C0F204004FF00001A0474FF44C50F3
|
||||
S1132540C0F204004FF00001A0474FF42240C0F253
|
||||
S113255002004FF00001A0474FF40070C0F20200E7
|
||||
S11325604FF00001A0474FF49050C0F202004FF02A
|
||||
S11325700001A0474FF40850C0F202004FF00001E0
|
||||
S1132580A0474FF44850C0F202004FF00001A047AA
|
||||
S11325904FF4E440C0F202004FF00001A0474FF4B2
|
||||
S11325A00240C0F202004FF00001A0474FF4324055
|
||||
S11325B0C0F202004FF00001A0474FF46240C0F2A5
|
||||
S11325C002004FF00001A0474FF47240C0F2020035
|
||||
S11325D04FF00001A0474FF45240C0F202004FF008
|
||||
S11325E00001A0474FF001004FF009014FF0050230
|
||||
S11325F0034643F21524C0F20004A0474FF0010043
|
||||
S11326004FF0020143F2F513C0F20003984742F27F
|
||||
S11326100533C0F20003984742F26963C0F2000335
|
||||
S1132620984742F20133C0F20003984742F2F103A3
|
||||
S1132630C0F20003984742F21D35C0F2000542F291
|
||||
S1132640DD14C0F20004A847A047FCE74EF21003D3
|
||||
S1132650CEF200034FF000021A60704740F25803B4
|
||||
S1132660C2F200031860704708B54FF02000C0F2B2
|
||||
S1132670040042F65D63C0F20003984744F6D35366
|
||||
S1132680C1F26203A3FB00204FEA901000F1FF3077
|
||||
S11326904EF21003CEF2000358604FF46D42CEF2B6
|
||||
S11326A000024FF0E00182F823104FF00000986020
|
||||
S11326B04FF007021A6042F25D63C0F200039847CC
|
||||
S11326C008BD00BF40F25803C2F200031868704707
|
||||
S11326D040F25803C2F200031A6802F101021A60C0
|
||||
S11326E0704700BFFEE700BF4FF40043C4F20C0381
|
||||
S11326F0DB6A03F47053B3F5805F48D0B3F5005F31
|
||||
S113270003D0B3F5006F0CD105E040F20003C2F230
|
||||
S113271000031868704740F20403C2F2000318680B
|
||||
S113272070474FF40043C4F20C03DB6803F4E06326
|
||||
S1132730B3F5007F19D004D80BB3B3F5807F23D150
|
||||
S113274018E0B3F5806F25D0B3F5A06F03D0B3F5CF
|
||||
S1132750407F19D104E04FF47C50C0F2AB107047B5
|
||||
S113276049F68070C0F2D50070474DF6C000C0F243
|
||||
S1132770A70070474CF6C070C0F26A00704744F27C
|
||||
S11327804020C0F20F0070474FF0000070474FF434
|
||||
S11327900040704746F64070C0F24010704700BFDA
|
||||
S11327A008B542F2E963C0F2000398474FF40043CE
|
||||
S11327B0C4F20C035B6803F00F0320FA03F040F249
|
||||
S11327C06402C2F20002106008BD00BF704700BF7F
|
||||
S11327D04FF40040704700BF40F20003C2F2000310
|
||||
S11327E0186870471F2AC4BF203A04314FF0010310
|
||||
S11327F003FA02F2072924D8DFE801F004080C10D8
|
||||
S113280014181C20036C1A4302647047436C1A4367
|
||||
S113281042647047836C1A4382647047C36C1A43E2
|
||||
S1132820C2647047036D1A4302657047436D1A43CF
|
||||
S113283042657047836D1A4382657047C36D1A43BE
|
||||
S1132840C26570471F2AC4BF203A04314FF0010308
|
||||
S113285003FA02F207292CD8DFE801F004090E1369
|
||||
S1132860181D2227036C23EA020202647047436C9A
|
||||
S113287023EA020242647047836C23EA0202826400
|
||||
S11328807047C36C23EA0202C2647047036D23EAF3
|
||||
S1132890020202657047436D23EA020242657047F3
|
||||
S11328A0836D23EA020282657047C36D23EA020244
|
||||
S11328B0C26570474FF42043C4F208034FF0FF325F
|
||||
S11328C05A6240F25C03C2F200031A6802F1010288
|
||||
S11328D01A6070474FF00003036403654364436563
|
||||
S11328E083648365C364C365436E002BFCD1704766
|
||||
S11328F038B50B293FD8DFE801F03A060B0F14195D
|
||||
S11329001E23282D31354FF003034FF0010432E02C
|
||||
S11329104FF003031C462EE04FF003034FF0000476
|
||||
S113292029E04FF003034FF0020424E04FF02703A3
|
||||
S11329304FF000041FE04FF027034FF003041AE0A8
|
||||
S11329404FF001034FF0030415E04FF001034FF083
|
||||
S1132950020410E04FF001031C460CE04FF00103A9
|
||||
S11329601C4608E04FF007034FF0030403E04FF068
|
||||
S11329700F034FF003043AB121461A4642F2E573BD
|
||||
S1132980C0F20003984738BD21461A4642F6450373
|
||||
S1132990C0F20003984738BD10B504464FF4004315
|
||||
S11329A0C4F20C039A6A22F003029A629A6A42F011
|
||||
S11329B002029A629A6D42F004029A659A6E22F4B7
|
||||
S11329C040729A669A6E42F440729A664FF000031F
|
||||
S11329D08362636E002BFCD14FF0FF3363624FF4CC
|
||||
S11329E06143CEF200034FF000621A604FF001031E
|
||||
S11329F0A36241F60B7363604FF40043C4F20C030B
|
||||
S1132A004FF00002DA67204642F6D503C0F2000315
|
||||
S1132A10984740F2FF33A3604FF005032360636ED1
|
||||
S1132A20002BFCD14FF48073C0F21C03E360636E8F
|
||||
S1132A30002BFCD14FF001036362A36210BD00BF01
|
||||
S1132A4000F1047001EBC0004FEA8000026070479F
|
||||
S1132A504FF00003C4F20C035B6803F00702032A7F
|
||||
S1132A600CD8DFE802F00202070723F0070343F063
|
||||
S1132A70010303E023F0070343F003034FF00002D4
|
||||
S1132A80C4F20C0253607047B0FA80F0C0B2C0F1D7
|
||||
S1132A901F0070474FF00003C4F20C035B684DF64F
|
||||
S1132AA0FF32CFF60B72821842F2FF31C0F2F4010A
|
||||
S1132AB08A420BD803F00702A2F10202012A23F092
|
||||
S1132AC0070394BF43F0030343F001034FF4105290
|
||||
S1132AD0C0F2F402904209D803F00702A2F1020204
|
||||
S1132AE0012A23F0070398BF43F002034FF00002CA
|
||||
S1132AF0C4F20C025360704749F68070C0F2D500EE
|
||||
S1132B00704700BF4FF40043C4F20C035B6D13F035
|
||||
S1132B10010F06D14FF40042C4F20C02136D1842A7
|
||||
S1132B20FCD1704708B54FF40043C4F20C039B6A10
|
||||
S1132B304FEA400023FA00F303F00303022B09D009
|
||||
S1132B40032B0DD0012B13D142F2D173C0F2000339
|
||||
S1132B50984708BD42F2D973C0F20003984708BDF4
|
||||
S1132B6042F2A173C0F2000398474FEA500008BD37
|
||||
S1132B704FF0000008BD00BF10B50C46C0F30313AE
|
||||
S1132B8003F1FF33032B00F2CE80DFE803F00213DE
|
||||
S1132B903390084642F68923C0F2000398474FF465
|
||||
S1132BA00043C4F20C039A6822F00F0240EA0202C6
|
||||
S1132BB09A6010BD42F65123C0F2000398472046A4
|
||||
S1132BC042F68923C0F2000398474FF40043C4F24D
|
||||
S1132BD00C035A6822F00F0240EA02025A6042F2E1
|
||||
S1132BE0A173C0F20003984742F69523C0F2000394
|
||||
S1132BF0984710BD41F23043C0F20A03984224D0F2
|
||||
S1132C004FF03003C0F20C03984236D04FF4866381
|
||||
S1132C10C0F20803984240F086804FF0040042F668
|
||||
S1132C200533C0F200039847204642F68923C0F2D8
|
||||
S1132C30000398474FF40043C4F20C039A6E22F049
|
||||
S1132C400F0240EA02029A6610BD4FF0040042F6F9
|
||||
S1132C500533C0F200039847204642F68923C0F2A8
|
||||
S1132C60000398474FF40043C4F20C039A6E22F019
|
||||
S1132C70F00242EA00129A6610BD4FF0040042F6D8
|
||||
S1132C800533C0F200039847204642F68923C0F278
|
||||
S1132C90000398474FF40043C4F20C039A6EA0F16A
|
||||
S1132CA0100022F4407242EA00229A6610BD4FF4EA
|
||||
S1132CB0A863C0F21403984206D04FF4AA53C0F29A
|
||||
S1132CC0160398422FD117E04FF0400042F6053327
|
||||
S1132CD0C0F200039847204642F68923C0F200035D
|
||||
S1132CE098474FF40043C4F20C031A6F22F0030216
|
||||
S1132CF040EA02021A6710BD4FF0400042F6053365
|
||||
S1132D00C0F200039847204642F68923C0F200032C
|
||||
S1132D1098474FF40043C4F20C031A6F22F03002B8
|
||||
S1132D2042EA00121A6710BD70B50D46C0F30323C2
|
||||
S1132D3003F1FF33052B3AD8DFE803F0082D3217EF
|
||||
S1132D401E0348F27804C4F20C042DE0C0F30436E8
|
||||
S1132D5048F20804C4F20C04204631462A4642F6DE
|
||||
S1132D604123C0F20003984770BD4FF0010348F2BD
|
||||
S1132D705804C4F20C0405E04FF0100348F2600458
|
||||
S1132D80C4F20C04C0F30436184642F60533C0F20C
|
||||
S1132D9000039847E0E748F24404C4F20C0403E05B
|
||||
S1132DA048F24004C4F20C04C0F30436D4E770BD06
|
||||
S1132DB000F00F0000F1FF30032842D8DFE800F0F4
|
||||
S1132DC0051B2E024FF0070070474FF40043C4F276
|
||||
S1132DD00C03D86A00F47050B0F5805F34D0B0F5BD
|
||||
S1132DE0005F05D0B0F5006F0CBF042005207047CC
|
||||
S1132DF04FF0020070474FF40043C4F20C03986A8A
|
||||
S1132E0000F00300022822D0032804D001280CBFBC
|
||||
S1132E100320012070474FF0060070474FF4004331
|
||||
S1132E20C4F20C03986A00F00C00022812D00328A4
|
||||
S1132E3004D001280CBF0320012070474FF0060086
|
||||
S1132E4070474FF0000070474FF0030070474FF099
|
||||
S1132E50020070474FF00200704700BF08B500F44D
|
||||
S1132E607810B0F5402F74D014D8B0F5802F40D02E
|
||||
S1132E7005D848B3B0F5003F40F0E0802AE0B0F553
|
||||
S1132E80002F44D0B0F5202F52D0B0F5C02F40F021
|
||||
S1132E90D58034E0B0F5A01F00F08C8007D8B0F5E1
|
||||
S1132EA0602F67D0B0F5901F40F0C8807AE0B0F58D
|
||||
S1132EB0C01F00F0A180B0F5D01F00F0B980B0F5BC
|
||||
S1132EC0B01F40F0BB8086E042F2E963C0F2000329
|
||||
S1132ED0984708BD42F2E963C0F2000398474FF4F3
|
||||
S1132EE00043C4F20C039B6803F00F0320FA03F0C1
|
||||
S1132EF008BD42F2A173C0F20003984708BD4FF029
|
||||
S1132F00000042F62533C0F20003984708BD4FF095
|
||||
S1132F10000042F62533C0F2000398474FF4004303
|
||||
S1132F20C4F20C039B6E03F00F0320FA03F008BDF8
|
||||
S1132F304FF0000042F62533C0F2000398474FF4E7
|
||||
S1132F400043C4F20C039B6EC3F3031320FA03F093
|
||||
S1132F5008BD4FF0000042F62533C0F20003984745
|
||||
S1132F604FF40043C4F20C039B6EC3F3012320FA15
|
||||
S1132F7003F008BD4FF0000042F62533C0F2000311
|
||||
S1132F8098474FF40043C4F20C039A6EC2F3012233
|
||||
S1132F9020FA02F0DB6F03F0070303F10103B0FB37
|
||||
S1132FA0F3F008BD4FF0010042F62533C0F20003F0
|
||||
S1132FB0984708BD4FF0010042F62533C0F20003E4
|
||||
S1132FC098474FF40043C4F20C031B6F03F0030350
|
||||
S1132FD020FA03F008BD4FF0010042F62533C0F299
|
||||
S1132FE0000398474FF40043C4F20C031B6FC3F370
|
||||
S1132FF0011320FA03F008BD4FF00400C0F21800DA
|
||||
S113300042F6B153C0F200039847072807D00828B6
|
||||
S11330100BD142F2E963C0F20003984708BD42F6BF
|
||||
S1133020F923C0F20003984708BD4FF0000008BD23
|
||||
S113303042F6F923C0F20003984708BD4FF00000A0
|
||||
S113304008BD00BF10B5042835D8DFE800F0120D24
|
||||
S1133050170308004FF001044FF0020012E04FF094
|
||||
S113306010044FF020000DE04FF040044FF08000BA
|
||||
S113307008E04FF480744FF4007003E04FF0040450
|
||||
S11330804FF0080069B14FF40043C4F20C031C6212
|
||||
S113309062B14FF40042C4F20C02D36A1842FCD06D
|
||||
S11330A004E04FF40043C4F20C03186243F2DD134E
|
||||
S11330B0C0F20003984710BD10B500F00F000128BE
|
||||
S11330C006D0002800F08880032800F285803BE0C9
|
||||
S11330D0A1F1020103297FD8DFE801F00210070BF8
|
||||
S11330E04FF000004FF004040CE04FF002000446DF
|
||||
S11330F008E04FF003004FF0010403E04FF001003B
|
||||
S11331004FF003044FF001010A4643F24503C0F2B5
|
||||
S11331100003984742F65123C0F2000398474FF446
|
||||
S11331200043C4F20C035C6243F2DD13C0F20003FB
|
||||
S1133130984742F2A173C0F20003984742F69523E0
|
||||
S1133140C0F20003984710BD022814BF02240024D3
|
||||
S113315001F1FF3105293FD8DFE801F02C03103ECF
|
||||
S11331603E1C4FF000004FF001010A4643F24503B4
|
||||
S1133170C0F2000398474FF002021DE04FF0010037
|
||||
S11331800146024643F24503C0F2000398474FF05C
|
||||
S1133190010211E048F24000C4F20C004FF00201B9
|
||||
S11331A04FF0010242F64123C0F2000398474FF06A
|
||||
S11331B0030201E04FF000024FF40043C4F20C0399
|
||||
S11331C0996A02FA04F24FF0030000FA04F421EAC7
|
||||
S11331D0040442EA04049C6210BD00BF4FF400439F
|
||||
S11331E0C4F20C03DA6A40F26003C2F200031A80EC
|
||||
S11331F0704700BF4FF4C043C4F2000300EBC000AB
|
||||
S113320053F8202022F0030241EA020243F820206E
|
||||
S1133210704700BFF0B41446E2B16BB14FF0010542
|
||||
S113322005FA01F500EBC0024FEA820202F1804286
|
||||
S113323002F5C04215610DE04FF0010505FA01F5F4
|
||||
S113324000EBC0064FEA860646F21002C4F2000202
|
||||
S1133250B2185560072916D800EBC0024FEA820263
|
||||
S113326002F1804202F5C04257684FEA81054FF0EF
|
||||
S11332700F0606FA05F627EA060604FA05F546EAF5
|
||||
S11332800505556017E000EBC0024FEA820202F127
|
||||
S1133290804202F5C04297684FEA8105A5F12005F6
|
||||
S11332A04FF00F0606FA05F627EA060604FA05F5B6
|
||||
S11332B046EA05059560E4B96BB14FF0010303FAE2
|
||||
S11332C001F100EBC0004FEA800000F1804000F5FE
|
||||
S11332D0C04001610DE04FF0010303FA01F100EB7E
|
||||
S11332E0C0004FEA800046F21003C4F20003C31882
|
||||
S11332F05960F0BC704700BF036C13F0010F02D19A
|
||||
S1133300436C1942FCD1704738B50446154608464B
|
||||
S1133310D1B94FF48043C4F208039C420BD04FF45C
|
||||
S11333208843C4F208039C4204BF4FF4AA50C0F27D
|
||||
S113333016001AD103E04FF4A860C0F2140042F65C
|
||||
S11333405D63C0F2000398474FEA4010B0FBF5F507
|
||||
S1133350A5F120054FEAC50520464FF0040143F2CC
|
||||
S1133360F923C0F200039847E56038BD38B5044638
|
||||
S11333706FEA010505F0050541EA45054FF0020134
|
||||
S113338043F2F923C0F200039847656038BD00BFDB
|
||||
S113339031B1436C002BFCD14FF00103036470473F
|
||||
S11333A04FF000030364704770B504460D464FF0B8
|
||||
S11333B0020143F2F923C0F2000398474FF00A03D5
|
||||
S11333C0636020464FF0010143F29136C0F20006DB
|
||||
S11333D0B04723682A7B23F01C0342EA03036A7B79
|
||||
S11333E01343AA7B1343236020466968AA6843F207
|
||||
S11333F00933C0F2000398472B78636020464FF0EE
|
||||
S11334000001B04770BD00BF836813F0200FFBD0EC
|
||||
S1133410C069C0B2704700BF4FF6D073CEF20F033D
|
||||
S11334201A6902F03F0202709A6902F0F002DB6945
|
||||
S1133430C3F3031342EA030343707047050000001B
|
||||
S10F3440000000008025000000000000D7
|
||||
S10B344C008000000048E801C3
|
||||
S9032000DC
|
|
@ -0,0 +1,183 @@
|
|||
/****************************************************************************************
|
||||
| Description: demo program bootloader interface source file
|
||||
| File Name: boot.c
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| C O P Y R I G H T
|
||||
|----------------------------------------------------------------------------------------
|
||||
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| L I C E N S E
|
||||
|----------------------------------------------------------------------------------------
|
||||
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
||||
| modify it under the terms of the GNU General Public License as published by the Free
|
||||
| Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
| version.
|
||||
|
|
||||
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
| PURPOSE. See the GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License along with OpenBLT.
|
||||
| If not, see <http://www.gnu.org/licenses/>.
|
||||
|
|
||||
| A special exception to the GPL is included to allow you to distribute a combined work
|
||||
| that includes OpenBLT without being obliged to provide the source code for any
|
||||
| proprietary components. The exception text is included at the bottom of the license
|
||||
| file <license.html>.
|
||||
|
|
||||
****************************************************************************************/
|
||||
|
||||
/****************************************************************************************
|
||||
* Include files
|
||||
****************************************************************************************/
|
||||
#include "header.h" /* generic header */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: BootActivate
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Bootloader activation function.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static void BootActivate(void)
|
||||
{
|
||||
void (*pEntryFromProgFnc)(void);
|
||||
|
||||
/* stop the timer interrupt */
|
||||
TimerDeinit();
|
||||
/* set pointer to the address of function EntryFromProg in the bootloader. note that
|
||||
* 1 is added to this address to enable a switch from Thumb2 to Thumb mode
|
||||
*/
|
||||
pEntryFromProgFnc = (void*)0x000000B8 + 1;
|
||||
/* call EntryFromProg to activate the bootloader. */
|
||||
pEntryFromProgFnc();
|
||||
} /*** end of BootActivate ***/
|
||||
|
||||
|
||||
#if (BOOT_COM_UART_ENABLE > 0)
|
||||
/****************************************************************************************
|
||||
* U N I V E R S A L A S Y N C H R O N O U S R X T X I N T E R F A C E
|
||||
****************************************************************************************/
|
||||
|
||||
/****************************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************************/
|
||||
static unsigned char UartReceiveByte(unsigned char *data);
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: BootComInit
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Initializes the UART communication interface
|
||||
**
|
||||
****************************************************************************************/
|
||||
void BootComInit(void)
|
||||
{
|
||||
LEUART_Init_TypeDef init = LEUART_INIT_DEFAULT;
|
||||
|
||||
/* configure GPIO pins */
|
||||
CMU_ClockEnable(cmuClock_GPIO, true);
|
||||
/* to avoid false start, configure output as high */
|
||||
GPIO_PinModeSet(gpioPortC, 6, gpioModePushPull, 1);
|
||||
GPIO_PinModeSet(gpioPortC, 7, gpioModeInput, 0);
|
||||
/* enable CORE LE clock in order to access LE modules */
|
||||
CMU_ClockEnable(cmuClock_CORELE, true);
|
||||
/* select LFXO for LEUARTs (and wait for it to stabilize) */
|
||||
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
|
||||
/* do not prescale clock */
|
||||
CMU_ClockDivSet(cmuClock_LEUART1, cmuClkDiv_1);
|
||||
/* enable LEUART1 clock */
|
||||
CMU_ClockEnable(cmuClock_LEUART1, true);
|
||||
/* configure LEUART */
|
||||
init.enable = leuartDisable;
|
||||
LEUART_Init(LEUART1, &init);
|
||||
LEUART_BaudrateSet(LEUART1, 0, BOOT_COM_UART_BAUDRATE);
|
||||
/* enable pins at default location */
|
||||
LEUART1->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN;
|
||||
/* clear previous RX interrupts */
|
||||
LEUART_IntClear(LEUART1, LEUART_IF_RXDATAV);
|
||||
/* finally enable it */
|
||||
LEUART_Enable(LEUART1, leuartEnable);
|
||||
} /*** end of BootComInit ***/
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: BootComCheckActivationRequest
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Receives the CONNECT request from the host, which indicates that the
|
||||
** bootloader should be activated and, if so, activates it.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void BootComCheckActivationRequest(void)
|
||||
{
|
||||
static unsigned char xcpCtoReqPacket[BOOT_COM_UART_RX_MAX_DATA+1];
|
||||
static unsigned char xcpCtoRxLength;
|
||||
static unsigned char xcpCtoRxInProgress = 0;
|
||||
|
||||
/* start of cto packet received? */
|
||||
if (xcpCtoRxInProgress == 0)
|
||||
{
|
||||
/* store the message length when received */
|
||||
if (UartReceiveByte(&xcpCtoReqPacket[0]) == 1)
|
||||
{
|
||||
/* indicate that a cto packet is being received */
|
||||
xcpCtoRxInProgress = 1;
|
||||
|
||||
/* reset packet data count */
|
||||
xcpCtoRxLength = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* store the next packet byte */
|
||||
if (UartReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == 1)
|
||||
{
|
||||
/* increment the packet data count */
|
||||
xcpCtoRxLength++;
|
||||
|
||||
/* check to see if the entire packet was received */
|
||||
if (xcpCtoRxLength == xcpCtoReqPacket[0])
|
||||
{
|
||||
/* done with cto packet reception */
|
||||
xcpCtoRxInProgress = 0;
|
||||
|
||||
/* check if this was an XCP CONNECT command */
|
||||
if ((xcpCtoReqPacket[1] == 0xff) && (xcpCtoReqPacket[2] == 0x00))
|
||||
{
|
||||
/* connection request received so start the bootloader */
|
||||
BootActivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /*** end of BootComCheckActivationRequest ***/
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: UartReceiveByte
|
||||
** PARAMETER: data pointer to byte where the data is to be stored.
|
||||
** RETURN VALUE: 1 if a byte was received, 0 otherwise.
|
||||
** DESCRIPTION: Receives a communication interface byte if one is present.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static unsigned char UartReceiveByte(unsigned char *data)
|
||||
{
|
||||
/* check to see if a new bytes was received */
|
||||
if ((LEUART1->IF & LEUART_IF_RXDATAV) != 0)
|
||||
{
|
||||
/* store the received data byte and set return value to positive */
|
||||
*data = LEUART_Rx(LEUART1);
|
||||
return 1;
|
||||
}
|
||||
/* still here to no new byte received */
|
||||
return 0;
|
||||
} /*** end of UartReceiveByte ***/
|
||||
#endif /* BOOT_COM_UART_ENABLE > 0 */
|
||||
|
||||
|
||||
/*********************************** end of boot.c *************************************/
|
|
@ -0,0 +1,42 @@
|
|||
/****************************************************************************************
|
||||
| Description: demo program bootloader interface header file
|
||||
| File Name: boot.h
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| C O P Y R I G H T
|
||||
|----------------------------------------------------------------------------------------
|
||||
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| L I C E N S E
|
||||
|----------------------------------------------------------------------------------------
|
||||
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
||||
| modify it under the terms of the GNU General Public License as published by the Free
|
||||
| Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
| version.
|
||||
|
|
||||
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
| PURPOSE. See the GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License along with OpenBLT.
|
||||
| If not, see <http://www.gnu.org/licenses/>.
|
||||
|
|
||||
| A special exception to the GPL is included to allow you to distribute a combined work
|
||||
| that includes OpenBLT without being obliged to provide the source code for any
|
||||
| proprietary components. The exception text is included at the bottom of the license
|
||||
| file <license.html>.
|
||||
|
|
||||
****************************************************************************************/
|
||||
#ifndef BOOT_H
|
||||
#define BOOT_H
|
||||
|
||||
/****************************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************************/
|
||||
void BootComInit(void);
|
||||
void BootComCheckActivationRequest(void);
|
||||
|
||||
|
||||
#endif /* BOOT_H */
|
||||
/*********************************** end of boot.h *************************************/
|
|
@ -0,0 +1,2 @@
|
|||
@echo off
|
||||
make --directory=../ all
|
|
@ -0,0 +1,2 @@
|
|||
@echo off
|
||||
make --directory=../ clean
|
|
@ -0,0 +1,94 @@
|
|||
/****************************************************************************************
|
||||
| Description: Demo program C startup source file
|
||||
| File Name: cstart.c
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| C O P Y R I G H T
|
||||
|----------------------------------------------------------------------------------------
|
||||
| Copyright (c) 2011 by Feaser http://www.feaser.com All rights reserved
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| L I C E N S E
|
||||
|----------------------------------------------------------------------------------------
|
||||
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
||||
| modify it under the terms of the GNU General Public License as published by the Free
|
||||
| Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
| version.
|
||||
|
|
||||
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
| PURPOSE. See the GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License along with OpenBLT.
|
||||
| If not, see <http://www.gnu.org/licenses/>.
|
||||
|
|
||||
| A special exception to the GPL is included to allow you to distribute a combined work
|
||||
| that includes OpenBLT without being obliged to provide the source code for any
|
||||
| proprietary components. The exception text is included at the bottom of the license
|
||||
| file <license.html>.
|
||||
|
|
||||
****************************************************************************************/
|
||||
|
||||
/****************************************************************************************
|
||||
* Include files
|
||||
****************************************************************************************/
|
||||
#include "header.h" /* generic header */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* External function protoypes
|
||||
****************************************************************************************/
|
||||
extern int main(void);
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* External data declarations
|
||||
****************************************************************************************/
|
||||
/* these externals are declared by the linker */
|
||||
extern unsigned long _etext;
|
||||
extern unsigned long _data;
|
||||
extern unsigned long _edata;
|
||||
extern unsigned long _bss;
|
||||
extern unsigned long _ebss;
|
||||
extern unsigned long _estack;
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
** NAME: reset_handler
|
||||
** PARAMETER: none
|
||||
** RETURN VALUE: none
|
||||
** DESCRIPTION: Reset interrupt service routine. Configures the stack, initializes
|
||||
** RAM and jumps to function main.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void reset_handler(void)
|
||||
{
|
||||
unsigned long *pSrc, *pDest;
|
||||
|
||||
/* initialize stack pointer */
|
||||
__asm(" ldr r1, =_estack\n"
|
||||
" mov sp, r1");
|
||||
/* copy the data segment initializers from flash to SRAM */
|
||||
pSrc = &_etext;
|
||||
for(pDest = &_data; pDest < &_edata; )
|
||||
{
|
||||
*pDest++ = *pSrc++;
|
||||
}
|
||||
/* zero fill the bss segment. this is done with inline assembly since this will
|
||||
* clear the value of pDest if it is not kept in a register.
|
||||
*/
|
||||
__asm(" ldr r0, =_bss\n"
|
||||
" ldr r1, =_ebss\n"
|
||||
" mov r2, #0\n"
|
||||
" .thumb_func\n"
|
||||
"zero_loop:\n"
|
||||
" cmp r0, r1\n"
|
||||
" it lt\n"
|
||||
" strlt r2, [r0], #4\n"
|
||||
" blt zero_loop");
|
||||
/* start the software application by calling its entry point */
|
||||
main();
|
||||
} /*** end of reset_handler ***/
|
||||
|
||||
|
||||
/************************************ end of cstart.c **********************************/
|
|
@ -0,0 +1,50 @@
|
|||
/****************************************************************************************
|
||||
| Description: generic header file
|
||||
| File Name: header.h
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| C O P Y R I G H T
|
||||
|----------------------------------------------------------------------------------------
|
||||
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
||||
|
|
||||
|----------------------------------------------------------------------------------------
|
||||
| L I C E N S E
|
||||
|----------------------------------------------------------------------------------------
|
||||
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
|
||||
| modify it under the terms of the GNU General Public License as published by the Free
|
||||
| Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
| version.
|
||||
|
|
||||
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
| PURPOSE. See the GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License along with OpenBLT.
|
||||
| If not, see <http://www.gnu.org/licenses/>.
|
||||
|
|
||||
| A special exception to the GPL is included to allow you to distribute a combined work
|
||||
| that includes OpenBLT without being obliged to provide the source code for any
|
||||
| proprietary components. The exception text is included at the bottom of the license
|
||||
| file <license.html>.
|
||||
|
|
||||
****************************************************************************************/
|
||||
#ifndef HEADER_H
|
||||
#define HEADER_H
|
||||
|
||||
/****************************************************************************************
|
||||
* Include files
|
||||
****************************************************************************************/
|
||||
#include "../Boot/config.h" /* bootloader configuration */
|
||||
#include "efm32.h" /* EFM32 registers */
|
||||
#include "efm32_chip.h" /* EFM32 chip initialization */
|
||||
#include "efm32_cmu.h" /* EFM32 clock management */
|
||||
#include "efm32_gpio.h" /* EFM32 GPIO management */
|
||||
#include "efm32_leuart.h" /* EFM32 LEUART management */
|
||||
#include "boot.h" /* bootloader interface driver */
|
||||
#include "irq.h" /* IRQ driver */
|
||||
#include "led.h" /* LED driver */
|
||||
#include "timer.h" /* Timer driver */
|
||||
|
||||
|
||||
#endif /* HEADER_H */
|
||||
/*********************************** end of header.h ***********************************/
|
|
@ -0,0 +1,193 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CodeLite_Project Name="DemoProg" InternalType="">
|
||||
<VirtualDirectory Name="Demo">
|
||||
<VirtualDirectory Name="ARMCM3_EFM32_Olimex_EM32G880F128STK_GCC">
|
||||
<VirtualDirectory Name="Prog">
|
||||
<VirtualDirectory Name="lib">
|
||||
<VirtualDirectory Name="efm32lib">
|
||||
<VirtualDirectory Name="inc">
|
||||
<File Name="../lib/efm32lib/inc/efm32_acmp.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_adc.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_aes.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_assert.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_bitband.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_chip.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_cmu.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_common.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_dac.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_dbg.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_dma.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_ebi.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_emu.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_gpio.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_i2c.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_int.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_lcd.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_lesense.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_letimer.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_leuart.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_mpu.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_msc.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_opamp.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_pcnt.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_prs.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_rmu.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_rtc.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_system.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_timer.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_usart.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_vcmp.h"/>
|
||||
<File Name="../lib/efm32lib/inc/efm32_wdog.h"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="src">
|
||||
<File Name="../lib/efm32lib/src/efm32_acmp.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_adc.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_aes.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_assert.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_cmu.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_dac.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_dbg.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_dma.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_ebi.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_emu.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_gpio.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_i2c.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_int.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_lcd.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_lesense.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_letimer.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_leuart.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_mpu.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_msc.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_opamp.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_pcnt.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_prs.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_rmu.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_rtc.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_system.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_timer.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_usart.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_vcmp.c"/>
|
||||
<File Name="../lib/efm32lib/src/efm32_wdog.c"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="CMSIS">
|
||||
<VirtualDirectory Name="CM3">
|
||||
<VirtualDirectory Name="DeviceSupport">
|
||||
<VirtualDirectory Name="EnergyMicro">
|
||||
<VirtualDirectory Name="EFM32">
|
||||
<File Name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32.h"/>
|
||||
<File Name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32g880f128.h"/>
|
||||
<File Name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.c"/>
|
||||
<File Name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.h"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="CoreSupport">
|
||||
<File Name="../lib/CMSIS/CM3/CoreSupport/core_cm3.c"/>
|
||||
<File Name="../lib/CMSIS/CM3/CoreSupport/core_cm3.h"/>
|
||||
<File Name="../lib/CMSIS/CM3/CoreSupport/core_cmFunc.h"/>
|
||||
<File Name="../lib/CMSIS/CM3/CoreSupport/core_cmInstr.h"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="lcd">
|
||||
<File Name="../lib/lcd/lcdcontroller.c"/>
|
||||
<File Name="../lib/lcd/lcdcontroller.h"/>
|
||||
<File Name="../lib/lcd/lcddisplay.h"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<File Name="../boot.c"/>
|
||||
<File Name="../boot.h"/>
|
||||
<File Name="../cstart.c"/>
|
||||
<File Name="../header.h"/>
|
||||
<File Name="../irq.c"/>
|
||||
<File Name="../irq.h"/>
|
||||
<File Name="../led.c"/>
|
||||
<File Name="../led.h"/>
|
||||
<File Name="../main.c"/>
|
||||
<File Name="../timer.c"/>
|
||||
<File Name="../timer.h"/>
|
||||
<File Name="../vectors.c"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<Plugins>
|
||||
<Plugin Name="qmake">
|
||||
<![CDATA[00010001N0005Debug000000000000]]>
|
||||
</Plugin>
|
||||
</Plugins>
|
||||
<Description/>
|
||||
<Dependencies/>
|
||||
<Settings Type="Dynamic Library">
|
||||
<GlobalSettings>
|
||||
<Compiler Options="" C_Options="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="">
|
||||
<LibraryPath Value="."/>
|
||||
</Linker>
|
||||
<ResourceCompiler Options=""/>
|
||||
</GlobalSettings>
|
||||
<Configuration Name="Debug" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
|
||||
<Compiler Options="-g" C_Options="-g" Required="yes" PreCompiledHeader="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="" Required="yes"/>
|
||||
<ResourceCompiler Options="" Required="no"/>
|
||||
<General OutputFile="" IntermediateDirectory="../obj" Command="demoprog_olimex_lpc_l2294_20mhz.elf" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(WorkspacePath)/../bin" PauseExecWhenProcTerminates="yes"/>
|
||||
<Environment EnvVarSetName="<Use Defaults>" DbgSetName="<Use Defaults>"/>
|
||||
<Debugger IsRemote="yes" RemoteHostName="localhost" RemoteHostPort="3333" DebuggerPath="C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin\arm-none-eabi-gdb.exe">
|
||||
<PostConnectCommands/>
|
||||
<StartupCommands>break main
|
||||
continue
|
||||
</StartupCommands>
|
||||
</Debugger>
|
||||
<PreBuild/>
|
||||
<PostBuild/>
|
||||
<CustomBuild Enabled="yes">
|
||||
<RebuildCommand/>
|
||||
<CleanCommand>make clean</CleanCommand>
|
||||
<BuildCommand>make</BuildCommand>
|
||||
<PreprocessFileCommand/>
|
||||
<SingleFileCommand/>
|
||||
<MakefileGenerationCommand/>
|
||||
<ThirdPartyToolName>None</ThirdPartyToolName>
|
||||
<WorkingDirectory>$(WorkspacePath)/..</WorkingDirectory>
|
||||
</CustomBuild>
|
||||
<AdditionalRules>
|
||||
<CustomPostBuild/>
|
||||
<CustomPreBuild/>
|
||||
</AdditionalRules>
|
||||
</Configuration>
|
||||
<Configuration Name="Release" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
|
||||
<Compiler Options="" C_Options="" Required="yes" PreCompiledHeader="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="-O2" Required="yes"/>
|
||||
<ResourceCompiler Options="" Required="no"/>
|
||||
<General OutputFile="" IntermediateDirectory="./Release" Command="" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
|
||||
<Environment EnvVarSetName="<Use Defaults>" DbgSetName="<Use Defaults>"/>
|
||||
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
|
||||
<PostConnectCommands/>
|
||||
<StartupCommands/>
|
||||
</Debugger>
|
||||
<PreBuild/>
|
||||
<PostBuild/>
|
||||
<CustomBuild Enabled="yes">
|
||||
<RebuildCommand/>
|
||||
<CleanCommand>make clean</CleanCommand>
|
||||
<BuildCommand>make</BuildCommand>
|
||||
<PreprocessFileCommand/>
|
||||
<SingleFileCommand/>
|
||||
<MakefileGenerationCommand/>
|
||||
<ThirdPartyToolName>None</ThirdPartyToolName>
|
||||
<WorkingDirectory>$(WorkspacePath)</WorkingDirectory>
|
||||
</CustomBuild>
|
||||
<AdditionalRules>
|
||||
<CustomPostBuild/>
|
||||
<CustomPreBuild/>
|
||||
</AdditionalRules>
|
||||
</Configuration>
|
||||
</Settings>
|
||||
</CodeLite_Project>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CodeLite_Workspace Name="DemoProg" Database="./DemoProg.tags">
|
||||
<Project Name="DemoProg" Path="DemoProg.project" Active="Yes"/>
|
||||
<BuildMatrix>
|
||||
<WorkspaceConfiguration Name="Debug" Selected="yes">
|
||||
<Project Name="DemoProg" ConfigName="Debug"/>
|
||||
</WorkspaceConfiguration>
|
||||
<WorkspaceConfiguration Name="Release" Selected="yes">
|
||||
<Project Name="DemoProg" ConfigName="Release"/>
|
||||
</WorkspaceConfiguration>
|
||||
</BuildMatrix>
|
||||
</CodeLite_Workspace>
|
|
@ -0,0 +1,4 @@
|
|||
Integrated Development Environment
|
||||
----------------------------------
|
||||
Codelite was used as the editor during the development of this software program. This directory contains the Codelite
|
||||
workspace and project files. Codelite is a cross platform open source C/C++ IDE, available at http://www.codelite.org/.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue