- 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:
Frank Voorburg 2012-03-04 20:51:40 +00:00
parent 4eda0f2e1f
commit 9ddc8b2dba
192 changed files with 94382 additions and 1 deletions

View File

@ -1,6 +1,6 @@
[sci]
port=3
baudrate=3
baudrate=8
[xcp]
seedkey=
t1=1000

View File

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

View File

@ -0,0 +1,2 @@
@echo off
make --directory=../ all

View File

@ -0,0 +1,2 @@
@echo off
make --directory=../ clean

View File

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

View File

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

View File

@ -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="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;"/>
<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="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;"/>
<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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,2 @@
@echo off
make --directory=../ all

View File

@ -0,0 +1,2 @@
@echo off
make --directory=../ clean

View File

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

View File

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

View File

@ -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="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;"/>
<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="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;"/>
<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>

View File

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

View File

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