1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-05-28 05:10:40 -07:00

Initial transfer from other repository

This commit is contained in:
Peter Antypas 2016-05-29 08:31:51 -07:00
parent 001ab38269
commit 3eb9be6ced
158 changed files with 78920 additions and 1 deletions

2
.gitignore vendored
View File

@ -7,3 +7,5 @@
*~
/Debug/
/Release/

27
.project Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ais_transponder</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1894012880" name="Debug">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1378871764096978077" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.436813973" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1414503461445076851" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

1
README
View File

@ -1 +0,0 @@
This is a placeholder file

1
README.md Normal file
View File

@ -0,0 +1 @@
# ais_transponder

82
include/stm32f30x_conf.h Normal file
View File

@ -0,0 +1,82 @@
/**
******************************************************************************
* @file Project/STM32F30x_StdPeriph_Templates/stm32f30x_conf.h
* @author MCD Application Team
* @version V1.0.0
* @date 23-October-2012
* @brief Library configuration file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F30X_CONF_H
#define __STM32F30X_CONF_H
/* Includes ------------------------------------------------------------------*/
/* Comment the line below to disable peripheral header file inclusion */
#include "stm32f30x_adc.h"
#include "stm32f30x_can.h"
#include "stm32f30x_crc.h"
#include "stm32f30x_comp.h"
#include "stm32f30x_dac.h"
#include "stm32f30x_dbgmcu.h"
#include "stm32f30x_dma.h"
#include "stm32f30x_exti.h"
#include "stm32f30x_flash.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_syscfg.h"
#include "stm32f30x_i2c.h"
#include "stm32f30x_iwdg.h"
#include "stm32f30x_opamp.h"
#include "stm32f30x_pwr.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_rtc.h"
#include "stm32f30x_spi.h"
#include "stm32f30x_tim.h"
#include "stm32f30x_usart.h"
#include "stm32f30x_wwdg.h"
#include "stm32f30x_misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT 1 */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function which reports
* the name of the source file and the source line number of the call
* that failed. If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
#endif /* __STM32F30X_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

8
ldscripts/libs.ld Normal file
View File

@ -0,0 +1,8 @@
/*
* Placeholder to list other libraries required by the application.
GROUP(
)
*/

32
ldscripts/mem.ld Normal file
View File

@ -0,0 +1,32 @@
/*
* Memory Spaces Definitions.
*
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*
* The values below can be addressed in further linker scripts
* using functions like 'ORIGIN(RAM)' or 'LENGTH(RAM)'.
*/
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 40K
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
MEMORY_ARRAY (xrw) : ORIGIN = 0x20002000, LENGTH = 0
}
/*
* For external ram use something like:
RAM (xrw) : ORIGIN = 0x64000000, LENGTH = 2048K
*/

445
ldscripts/sections.ld Normal file
View File

@ -0,0 +1,445 @@
/*
* Default linker script for Cortex-M (it includes specifics for STM32F[34]xx).
*
* To make use of the multi-region initialisations, define
* OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS for the _startup.c file.
*/
/*
* The '__stack' definition is required by crt0, do not remove it.
*/
__stack = ORIGIN(RAM) + LENGTH(RAM);
_estack = __stack; /* STM specific definition */
/*
* Default stack sizes.
* These are used by the startup in order to allocate stacks
* for the different modes.
*/
__Main_Stack_Size = 1024 ;
PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;
__Main_Stack_Limit = __stack - __Main_Stack_Size ;
/* "PROVIDE" allows to easily override these values from an
* object file or the command line. */
PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ;
/*
* There will be a link error if there is not this amount of
* RAM free at the end.
*/
_Minimum_Stack_Size = 256 ;
/*
* Default heap definitions.
* The heap start immediately after the last statically allocated
* .sbss/.noinit section, and extends up to the main stack limit.
*/
PROVIDE ( _Heap_Begin = _end_noinit ) ;
PROVIDE ( _Heap_Limit = __stack - __Main_Stack_Size ) ;
/*
* The entry point is informative, for debuggers and simulators,
* since the Cortex-M vector points to it anyway.
*/
ENTRY(_start)
/* Sections Definitions */
SECTIONS
{
/*
* For Cortex-M devices, the beginning of the startup code is stored in
* the .isr_vector section, which goes to FLASH.
*/
.isr_vector : ALIGN(4)
{
FILL(0xFF)
__vectors_start = ABSOLUTE(.) ;
__vectors_start__ = ABSOLUTE(.) ; /* STM specific definition */
KEEP(*(.isr_vector)) /* Interrupt vectors */
KEEP(*(.cfmconfig)) /* Freescale configuration words */
/*
* This section is here for convenience, to store the
* startup code at the beginning of the flash area, hoping that
* this will increase the readability of the listing.
*/
*(.after_vectors .after_vectors.*) /* Startup code and ISR */
} >FLASH
.inits : ALIGN(4)
{
/*
* Memory regions initialisation arrays.
*
* Thee are two kinds of arrays for each RAM region, one for
* data and one for bss. Each is iterrated at startup and the
* region initialisation is performed.
*
* The data array includes:
* - from (LOADADDR())
* - region_begin (ADDR())
* - region_end (ADDR()+SIZEOF())
*
* The bss array includes:
* - region_begin (ADDR())
* - region_end (ADDR()+SIZEOF())
*
* WARNING: It is mandatory that the regions are word aligned,
* since the initialisation code works only on words.
*/
__data_regions_array_start = .;
LONG(LOADADDR(.data));
LONG(ADDR(.data));
LONG(ADDR(.data)+SIZEOF(.data));
LONG(LOADADDR(.data_CCMRAM));
LONG(ADDR(.data_CCMRAM));
LONG(ADDR(.data_CCMRAM)+SIZEOF(.data_CCMRAM));
__data_regions_array_end = .;
__bss_regions_array_start = .;
LONG(ADDR(.bss));
LONG(ADDR(.bss)+SIZEOF(.bss));
LONG(ADDR(.bss_CCMRAM));
LONG(ADDR(.bss_CCMRAM)+SIZEOF(.bss_CCMRAM));
__bss_regions_array_end = .;
/* End of memory regions initialisation arrays. */
/*
* These are the old initialisation sections, intended to contain
* naked code, with the prologue/epilogue added by crti.o/crtn.o
* when linking with startup files. The standalone startup code
* currently does not run these, better use the init arrays below.
*/
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
/*
* The preinit code, i.e. an array of pointers to initialisation
* functions to be performed before constructors.
*/
PROVIDE_HIDDEN (__preinit_array_start = .);
/*
* Used to run the SystemInit() before anything else.
*/
KEEP(*(.preinit_array_sysinit .preinit_array_sysinit.*))
/*
* Used for other platform inits.
*/
KEEP(*(.preinit_array_platform .preinit_array_platform.*))
/*
* The application inits. If you need to enforce some order in
* execution, create new sections, as before.
*/
KEEP(*(.preinit_array .preinit_array.*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/*
* The init code, i.e. an array of pointers to static constructors.
*/
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/*
* The fini code, i.e. an array of pointers to static destructors.
*/
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/*
* For some STRx devices, the beginning of the startup code
* is stored in the .flashtext section, which goes to FLASH.
*/
.flashtext : ALIGN(4)
{
*(.flashtext .flashtext.*) /* Startup code */
} >FLASH
/*
* The program code is stored in the .text section,
* which goes to FLASH.
*/
.text : ALIGN(4)
{
*(.text .text.*) /* all remaining code */
/* read-only data (constants) */
*(.rodata .rodata.* .constdata .constdata.*)
*(vtable) /* C++ virtual tables */
KEEP(*(.eh_frame*))
/*
* Stub sections generated by the linker, to glue together
* ARM and Thumb code. .glue_7 is used for ARM code calling
* Thumb code, and .glue_7t is used for Thumb code calling
* ARM code. Apparently always generated by the linker, for some
* architectures, so better leave them here.
*/
*(.glue_7)
*(.glue_7t)
} >FLASH
/* ARM magic sections */
.ARM.extab : ALIGN(4)
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
. = ALIGN(4);
__exidx_start = .;
.ARM.exidx : ALIGN(4)
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
. = ALIGN(4);
_etext = .;
__etext = .;
/* MEMORY_ARRAY */
/*
.ROarraySection :
{
*(.ROarraySection .ROarraySection.*)
} >MEMORY_ARRAY
*/
/*
* The secondary initialised data section.
*/
.data_CCMRAM : ALIGN(4)
{
FILL(0xFF)
*(.data.CCMRAM .data.CCMRAM.*)
. = ALIGN(4) ;
} > CCMRAM AT>FLASH
/*
* This address is used by the startup code to
* initialise the .data section.
*/
_sidata = LOADADDR(.data);
/*
* The initialised data section.
*
* The program executes knowing that the data is in the RAM
* but the loader puts the initial values in the FLASH (inidata).
* It is one task of the startup to copy the initial values from
* FLASH to RAM.
*/
.data : ALIGN(4)
{
FILL(0xFF)
/* This is used by the startup code to initialise the .data section */
_sdata = . ; /* STM specific definition */
__data_start__ = . ;
*(.data_begin .data_begin.*)
*(.data .data.*)
*(.data_end .data_end.*)
. = ALIGN(4);
/* This is used by the startup code to initialise the .data section */
_edata = . ; /* STM specific definition */
__data_end__ = . ;
} >RAM AT>FLASH
/*
* The uninitialised data sections. NOLOAD is used to avoid
* the "section `.bss' type changed to PROGBITS" warning
*/
/* The secondary uninitialised data section. */
.bss_CCMRAM (NOLOAD) : ALIGN(4)
{
*(.bss.CCMRAM .bss.CCMRAM.*)
} > CCMRAM
/* The primary uninitialised data section. */
.bss (NOLOAD) : ALIGN(4)
{
__bss_start__ = .; /* standard newlib definition */
_sbss = .; /* STM specific definition */
*(.bss_begin .bss_begin.*)
*(.bss .bss.*)
*(COMMON)
*(.bss_end .bss_end.*)
. = ALIGN(4);
__bss_end__ = .; /* standard newlib definition */
_ebss = . ; /* STM specific definition */
} >RAM
.noinit_CCMRAM (NOLOAD) : ALIGN(4)
{
*(.noinit.CCMRAM .noinit.CCMRAM.*)
} > CCMRAM
.noinit (NOLOAD) : ALIGN(4)
{
_noinit = .;
*(.noinit .noinit.*)
. = ALIGN(4) ;
_end_noinit = .;
} > RAM
/* Mandatory to be word aligned, _sbrk assumes this */
PROVIDE ( end = _end_noinit ); /* was _ebss */
PROVIDE ( _end = _end_noinit );
PROVIDE ( __end = _end_noinit );
PROVIDE ( __end__ = _end_noinit );
/*
* Used for validation only, do not allocate anything here!
*
* This is just to check that there is enough RAM left for the Main
* stack. It should generate an error if it's full.
*/
._check_stack : ALIGN(4)
{
. = . + _Minimum_Stack_Size ;
} >RAM
/*
* The FLASH Bank1.
* The C or assembly source must explicitly place the code
* or data there using the "section" attribute.
*/
.b1text : ALIGN(4)
{
*(.b1text) /* remaining code */
*(.b1rodata) /* read-only data (constants) */
*(.b1rodata.*)
} >FLASHB1
/*
* The EXTMEM.
* The C or assembly source must explicitly place the code or data there
* using the "section" attribute.
*/
/* EXTMEM Bank0 */
.eb0text : ALIGN(4)
{
*(.eb0text) /* remaining code */
*(.eb0rodata) /* read-only data (constants) */
*(.eb0rodata.*)
} >EXTMEMB0
/* EXTMEM Bank1 */
.eb1text : ALIGN(4)
{
*(.eb1text) /* remaining code */
*(.eb1rodata) /* read-only data (constants) */
*(.eb1rodata.*)
} >EXTMEMB1
/* EXTMEM Bank2 */
.eb2text : ALIGN(4)
{
*(.eb2text) /* remaining code */
*(.eb2rodata) /* read-only data (constants) */
*(.eb2rodata.*)
} >EXTMEMB2
/* EXTMEM Bank0 */
.eb3text : ALIGN(4)
{
*(.eb3text) /* remaining code */
*(.eb3rodata) /* read-only data (constants) */
*(.eb3rodata.*)
} >EXTMEMB3
/* After that there are only debugging sections. */
/* This can remove the debugging information from the standard libraries */
/*
DISCARD :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
*/
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/*
* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0.
*/
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

92
src/AISChannels.h Normal file
View File

@ -0,0 +1,92 @@
/*
* channels.h
*
* Created on: May 8, 2016
* Author: peter
*/
#ifndef AISCHANNELS_H_
#define AISCHANNELS_H_
#include <inttypes.h>
#define NUM_AIS_CHANNELS 22
/*
* This unit can utilize the top 525KHz of the VHF band, from 161.500Mhz to 162.025Mhz. Base stations
* can force all traffic to switch to any of those frequencies via AIS message 22 and scheduled DSC transmissions
* on marine channel 70 (156.525Mhz). It is rare, but it can happen.
* Absent this override or when outside the range of any coastal base stations, the default channels are
* always 87 and 88.
*
* Marine VHF channels have an ITU designated number that is interleaved (Rec. ITU-R M.1084). They can never fit
* the Silabs WDS channel definition scheme, so they must be associated with those channels instead.
* For now (and maybe forever), given an ITU channel number, we'll scan the AIS_CHANNELS array to find
* its corresponding RF IC channel ordinal.
*/
typedef struct {
uint8_t itu; // The ITU channel #
uint8_t ordinal; // A zero-based index as defined by WDS in radio_config.h
char designation; // 'A', 'B' or '?'
double frequency; // Frequency in MHz, mostly for reference
}
ais_channel;
typedef enum {
CH_18 = 0,
CH_78,
CH_19,
CH_79,
CH_20,
CH_80,
CH_21,
CH_81,
CH_22,
CH_82,
CH_23,
CH_83,
CH_24,
CH_84,
CH_25,
CH_85,
CH_26,
CH_86,
CH_27,
CH_87,
CH_28,
CH_88
} VHFChannel;
static const ais_channel AIS_CHANNELS[] = {
{18, 0, '?', 161.500},
{78, 1, '?', 161.525},
{19, 2, '?', 161.550},
{79, 3, '?', 161.575},
{20, 4, '?', 161.600},
{80, 5, '?', 161.625},
{21, 6, '?', 161.650},
{81, 7, '?', 161.675},
{22, 8, '?', 161.700},
{82, 9, '?', 161.725},
{23, 10, '?', 161.750},
{83, 11, '?', 161.775},
{24, 12, '?', 161.800},
{84, 13, '?', 161.825},
{25, 14, '?', 161.850},
{85, 15, '?', 161.875},
{26, 16, '?', 161.900},
{86, 17, '?', 161.925},
{27, 18, '?', 161.950},
{87, 19, 'A', 161.975}, // Default channel A
{28, 20, '?', 162.000},
{88, 21, 'B', 162.025} // Default channel B
};
#define ITU_TO_ORDINAL(C) (C < 78 ? (C-18)*2 : (C-78)*2+1)
#endif /* AISCHANNELS_H_ */

393
src/AISMessages.cpp Normal file
View File

@ -0,0 +1,393 @@
/*
* AISMessages.cpp
*
* Created on: Dec 12, 2015
* Author: peter
*/
#include <cmath>
#include "AISMessages.hpp"
#include "Utils.hpp"
#include <cassert>
#include <cstring>
#include <sstream>
#include <diag/Trace.h>
#define USE_MSB
// A good quick reference for AIS message format: http://www.navcen.uscg.gov/?pageName=AISMessages
AISMessage::AISMessage ()
{
mmsi = STATION_MMSI;
repeatIndicator = 0;
messageType = 0;
}
AISMessage::~AISMessage ()
{
}
bool AISMessage::decode(RXPacket &)
{
// The base class method should never be called
ASSERT(false);
// This will never execute but the compiler is not smart enough to know it
return false;
}
void AISMessage::encode(TXPacket &)
{
// The base class method should never be called
ASSERT(false);
}
void AISMessage::addBits(uint8_t *bitVector, uint16_t &size, uint32_t value, uint8_t numBits)
{
ASSERT(numBits > 0 && numBits <= 32);
uint16_t pos = size;
for ( uint8_t bit = 0; bit < numBits; ++bit, value >>= 1 ) {
bitVector[pos + numBits-bit-1] = value & 1;
}
size += numBits;
}
void AISMessage::putBits(uint8_t *bitVector, uint32_t value, uint8_t numBits)
{
// This is used for HDLC framing
uint16_t pos = 0;
for ( uint8_t bit = 0; bit < numBits; ++bit, value >>= 1 ) {
bitVector[pos++] = value & 0x01;
}
}
void AISMessage::reverseEachByte(uint8_t *bitVector, uint16_t size)
{
ASSERT(size % 8 == 0);
for ( uint16_t i = 0; i < size; i += 8 ) {
for ( uint8_t j = 0; j < 4; ++j ) {
swap(bitVector[i+j], bitVector[i+7-j]);
}
}
}
void AISMessage::addString(uint8_t *bitVector, uint16_t &size, const string &value, uint8_t maxChars)
{
ASSERT(value.length() <= maxChars);
ASSERT(maxChars < 30); // There should be no application for such long strings here
char s[30];
memset(s, 0, sizeof s);
strncpy(s, value.c_str(), value.length());
uint8_t buffer[32];
for ( uint8_t c = 0; c < maxChars; ++c ) {
uint8_t byte = s[c] >= 64 ? s[c]-64 : s[c];
buffer[c] = byte;
}
for ( uint8_t c = 0; c < maxChars; ++c )
addBits(bitVector, size, buffer[c], 6);
}
void AISMessage::payloadToBytes(uint8_t *bitVector, uint16_t numBits, uint8_t *byteArray)
{
for ( uint16_t i = 0; i < numBits; i += 8 ) {
uint8_t byte = 0;
for ( uint8_t b = 0; b < 8; ++b ) {
byte |= (bitVector[i+b] << b);
}
byteArray[i/8] = byte;
}
}
void AISMessage::finalize(uint8_t *payload, uint16_t &size, TXPacket &packet)
{
// Nothing we send exceeds 256 bits, including preambles and such. 40 bytes is more than enough.
uint8_t bytes[40];
// CRC-CCITT calculation
payloadToBytes(payload, size, bytes);
uint16_t crc = Utils::crc16(bytes, size/8);
uint8_t crcL = crc & 0x00ff;
uint8_t crcH = (crc & 0xff00) >> 8;
addBits(payload, size, crcL, 8);
addBits(payload, size, crcH, 8);
payloadToBytes(payload, size, bytes);
// Encoding for transmission
reverseEachByte(payload, size);
bitStuff(payload, size);
constructHDLCFrame(payload, size);
nrziEncode(payload, size, packet);
packet.pad();
}
void AISMessage::bitStuff(uint8_t *buff, uint16_t &size)
{
uint16_t numOnes = 0;
for ( uint16_t i = 0; i < size; ++i ) {
switch(buff[i]) {
case 0:
numOnes = 0;
break;
case 1:
++numOnes;
if ( numOnes == 5 ) {
// Insert a 0 right after this one
memmove(buff + i + 2, buff + i + 1, size-i-1);
buff[i+1] = 0;
++size;
}
break;
default:
ASSERT(false);
}
}
}
void AISMessage::constructHDLCFrame(uint8_t *buff, uint16_t &size)
{
/*
* As a class B "CS" transponder, we don't transmit a full ramp byte because
* we have to listen for a few bits into each slot for Clear Channel Assessment.
* Also, this implementation only adds 3 bits for ramp down, just in case
* our TX bit clock is a little lazy. Not what the ITU standard says, but no
* reasonable receiver should care about ramp-down bits. It's only what goes
* between the 0x7E markers that counts.
*/
// Make room for 35 bits at the front
memmove(buff+35, buff, size);
size += 35;
putBits(buff, 0xFF, 3); // 3 ramp bits. That's all we can afford.
putBits(buff+3, 0b010101010101010101010101, 24); // 24 training bits
putBits(buff+27, 0x7e, 8); // HDLC start flag
// Now append the end marker and ramp-down bits
addBits(buff, size, 0x7e, 8); // HDLC stop flag
addBits(buff, size, 0x00, 3); // Ramp down
}
void AISMessage::nrziEncode(uint8_t *buff, uint16_t &size, TXPacket &packet)
{
uint8_t prevBit = 1; // Arbitrarily starting with 1
packet.addBit(prevBit);
for ( uint16_t i = 0; i < size; ++i ) {
if ( buff[i] == 0 ) {
packet.addBit(!prevBit);
prevBit = !prevBit;
}
else {
packet.addBit(prevBit);
}
}
// The TXPacket is now populated with the sequence of bits that need to be sent
}
///////////////////////////////////////////////////////////////////////////////
//
// AISMessage123
//
///////////////////////////////////////////////////////////////////////////////
AISMessage123::AISMessage123()
{
}
bool AISMessage123::decode(RXPacket &packet)
{
messageType = packet.messageType();
repeatIndicator = packet.repeatIndicator();
mmsi = packet.mmsi();
sog = packet.bits(50, 10) / 10.0f;
longitude = Utils::coordinateFromUINT32(packet.bits(61, 28), 28);
latitude = Utils::coordinateFromUINT32(packet.bits(89, 27), 27);
return true;
}
///////////////////////////////////////////////////////////////////////////////
//
// AISMessage18
//
///////////////////////////////////////////////////////////////////////////////
AISMessage18::AISMessage18()
{
messageType = 18;
}
void AISMessage18::encode(TXPacket &packet)
{
// TODO: Perhaps this shouldn't live on the stack?
uint8_t payload[MAX_AIS_TX_PACKET_SIZE];
uint16_t size = 0;
uint32_t value;
value = messageType;
addBits(payload, size, value, 6); // Message type
value = repeatIndicator;
addBits(payload, size, value, 2); // Repeat Indicator
value = mmsi;
addBits(payload, size, value, 30); // MMSI
value = 0;
addBits(payload, size, value, 8); // Spare bits
value = (uint32_t)(sog * 10);
addBits(payload, size, value, 10); // Speed (knots x 10)
value = 1;
addBits(payload, size, value, 1); // Position accuracy is high
value = Utils::coordinateToUINT32(longitude);
addBits(payload, size, value, 28); // Longitude
value = Utils::coordinateToUINT32(latitude);
addBits(payload, size, value, 27); // Latitude
value = (uint32_t)(cog * 10);
addBits(payload, size, value, 12); // COG
value = 511;
addBits(payload, size, value, 9); // We don't know our heading
value = utc % 60;
addBits(payload, size, value, 6); // UTC second. Possibly incorrect.
value = 0;
addBits(payload, size, value, 2); // Spare
value = 1;
addBits(payload, size, value, 1); // We are a "CS" unit
value = 0;
addBits(payload, size, value, 1); // We have no display
value = 0;
addBits(payload, size, value, 1); // We have no DSC
value = 0;
addBits(payload, size, value, 1); // We don't switch frequencies so this doesn't matter
value = 0;
addBits(payload, size, value, 1); // We do not respond to message 22 to switch frequency
value = 0;
addBits(payload, size, value, 1); // We operate in autonomous and continuous mode
value = 0;
addBits(payload, size, value, 1); // No RAIM
value = 1;
addBits(payload, size, value, 1); // We use ITDMA (as a CS unit)
value = DEFAULT_COMM_STATE;
addBits(payload, size, value, 19); // Standard communication state flag for CS units
#if DEV_MODE
ASSERT(size == 168);
#endif
finalize(payload, size, packet);
}
bool AISMessage18::decode(RXPacket &packet)
{
messageType = packet.messageType();
repeatIndicator = packet.repeatIndicator();
mmsi = packet.mmsi();
sog = packet.bits(46, 10) / 10.0f;
longitude = Utils::coordinateFromUINT32(packet.bits(57, 28), 28);
latitude = Utils::coordinateFromUINT32(packet.bits(85, 27), 27);
return true;
}
///////////////////////////////////////////////////////////////////////////////
//
// AISMessage24A
//
///////////////////////////////////////////////////////////////////////////////
AISMessage24A::AISMessage24A()
{
messageType = 24;
name = STATION_NAME;
}
void AISMessage24A::encode(TXPacket &packet)
{
uint8_t payload[MAX_AIS_TX_PACKET_SIZE];
uint16_t size = 0;
uint32_t value;
value = messageType;
addBits(payload, size, value, 6); // Message type
value = repeatIndicator;
addBits(payload, size, value, 2); // Repeat Indicator
value = mmsi;
addBits(payload, size, value, 30); // MMSI
value = 0;
addBits(payload, size, value, 2); // Part number (0 for 24A)
addString(payload, size, name, 20); // Station name
finalize(payload, size, packet);
}
///////////////////////////////////////////////////////////////////////////////
//
// AISMessage24B
//
///////////////////////////////////////////////////////////////////////////////
AISMessage24B::AISMessage24B()
{
messageType = 24;
vendorId = "";
callSign = "";
}
void AISMessage24B::encode(TXPacket &packet)
{
uint8_t payload[MAX_AIS_TX_PACKET_SIZE];
uint16_t size = 0;
uint32_t value;
value = messageType;
addBits(payload, size, value, 6); // Message type
value = repeatIndicator;
addBits(payload, size, value, 2); // Repeat Indicator
value = mmsi;
addBits(payload, size, value, 30); // MMSI
value = 1;
addBits(payload, size, value, 2); // Part number (1 for 24B)
value = 0;
addBits(payload, size, value, 8); // Type of ship unknown
addString(payload, size, vendorId, 7);
addString(payload, size, callSign, 7);
value = 0;
addBits(payload, size, value, 30); // No dimension information
value = 1;
addBits(payload, size, value, 4); // Using GPS
value = 0;
addBits(payload, size, value, 2); // Spare bits
finalize(payload, size, packet);
}

101
src/AISMessages.hpp Normal file
View File

@ -0,0 +1,101 @@
/*
* AISMessages.hpp
*
* Created on: Dec 12, 2015
* Author: peter
*/
#ifndef AISMESSAGES_HPP_
#define AISMESSAGES_HPP_
#include "TXPacket.hpp"
#include "RXPacket.hpp"
#include <time.h>
#include <string>
#include "globals.h"
using namespace std;
// These are the AIS messages that this unit will actually work with
// For message 18 -- all class B "CS" stations send this
#define DEFAULT_COMM_STATE 0b1100000000000000110
class AISMessage
{
public:
AISMessage ();
virtual ~AISMessage ();
virtual bool decode(RXPacket &packet);
virtual void encode(TXPacket &packet);
uint8_t messageType;
uint8_t repeatIndicator;
uint32_t mmsi;
protected:
void appendCRC(uint8_t *buff, uint16_t &size);
void addBits(uint8_t *buff, uint16_t &size, uint32_t value, uint8_t numBits);
void putBits(uint8_t *buff, uint32_t value, uint8_t numBits);
void addString(uint8_t *buff, uint16_t &size, const string &name, uint8_t maxChars);
void finalize(uint8_t *buff, uint16_t &size, TXPacket &packet);
private:
void bitStuff(uint8_t *buff, uint16_t &size);
void constructHDLCFrame(uint8_t *buff, uint16_t &size);
void nrziEncode(uint8_t *buff, uint16_t &size, TXPacket &packet);
void payloadToBytes(uint8_t *bitVector, uint16_t numBits, uint8_t *bytes);
void reverseEachByte(uint8_t *bitVector, uint16_t numBits);
};
class AISMessage123 : public AISMessage
{
public:
double latitude;
double longitude;
double sog;
double cog;
AISMessage123();
bool decode(RXPacket &packet);
};
class AISMessage18 : public AISMessage
{
public:
double latitude;
double longitude;
double sog;
double cog;
time_t utc;
AISMessage18();
bool decode(RXPacket &packet);
void encode(TXPacket &packet);
};
class AISMessage24A : public AISMessage
{
public:
string name;
AISMessage24A();
void encode(TXPacket &packet);
};
class AISMessage24B : public AISMessage
{
public:
AISMessage24B();
string vendorId;
string callSign;
void encode(TXPacket &packet);
};
#endif /* AISMESSAGES_HPP_ */

51
src/ChannelManager.cpp Normal file
View File

@ -0,0 +1,51 @@
/*
* ChannelManager.cpp
*
* Created on: May 8, 2016
* Author: peter
*/
#include "ChannelManager.hpp"
#include "EventQueue.hpp"
ChannelManager &ChannelManager::instance()
{
static ChannelManager __instance;
return __instance;
}
ChannelManager::ChannelManager()
: mChannelA(19), mChannelB(21)
{
EventQueue::instance().addObserver(this, AIS_PACKET_EVENT);
}
ChannelManager::~ChannelManager()
{
// TODO Auto-generated destructor stub
}
const ais_channel &ChannelManager::channelA()
{
return AIS_CHANNELS[mChannelA];
}
const ais_channel &ChannelManager::channelB()
{
return AIS_CHANNELS[mChannelB];
}
bool ChannelManager::channelsDetermined()
{
// For now ...
return true;
}
void ChannelManager::processEvent(Event *)
{
//AISPacketEvent *pe = static_cast<AISPacketEvent*>(e);
}

34
src/ChannelManager.hpp Normal file
View File

@ -0,0 +1,34 @@
/*
* ChannelManager.hpp
*
* Created on: May 8, 2016
* Author: peter
*/
#ifndef CHANNELMANAGER_HPP_
#define CHANNELMANAGER_HPP_
#include "AISChannels.h"
#include "Events.hpp"
class ChannelManager : public EventConsumer
{
public:
static ChannelManager &instance();
virtual ~ChannelManager();
void processEvent(Event *e);
const ais_channel &channelA();
const ais_channel &channelB();
bool channelsDetermined();
private:
ChannelManager();
uint8_t mChannelA;
uint8_t mChannelB;
};
#endif /* CHANNELMANAGER_HPP_ */

75
src/CircularQueue.hpp Normal file
View File

@ -0,0 +1,75 @@
/*
* CircularQueue.hpp
*
* Created on: Mar 5, 2016
* Author: peter
*/
#ifndef CIRCULARQUEUE_HPP_
#define CIRCULARQUEUE_HPP_
#include "_assert.h"
//#define NUMQELEMENTS 100
template<typename T> class CircularQueue
{
public:
CircularQueue(size_t size)
{
mReadPosition = 0;
mWritePosition = 0;
mSize = size;
mBuffer = new T[mSize];
}
bool empty()
{
return mReadPosition == mWritePosition;
}
bool push(T &Element)
{
int nextElement = (mWritePosition + 1) % mSize;
if ( isSafeToWrite(nextElement) ) {
mBuffer[mWritePosition] = Element;
mWritePosition = nextElement;
return true;
}
else
return false;
}
bool pop(T &Element)
{
if ( empty() )
return false;
int nextElement = (mReadPosition + 1) % mSize;
Element = mBuffer[mReadPosition];
mReadPosition = nextElement;
return true;
}
T top()
{
ASSERT(!empty());
return mBuffer[mReadPosition];
}
private:
bool isSafeToWrite(int nextElement)
{
return nextElement != mReadPosition;
}
private:
volatile int mReadPosition;
volatile int mWritePosition;
size_t mSize;
T* mBuffer;
};
#endif /* CIRCULARQUEUE_HPP_ */

194
src/DataTerminal.cpp Normal file
View File

@ -0,0 +1,194 @@
/*
* Terminal.cpp
*
* Created on: Apr 19, 2016
* Author: peter
*/
#include "DataTerminal.hpp"
#include "stm32f30x.h"
#include "printf2.h"
#include "MenuScreens.hpp"
#include "Events.hpp"
#include <stdio.h>
#ifdef ENABLE_TERMINAL
DataTerminal &DataTerminal::instance()
{
static DataTerminal __instance;
return __instance;
}
void DataTerminal::init()
{
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); // For USART3
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_7);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_7);
// Initialize pins as alternative function 7 (USART)
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_Init(GPIOB, &GPIO_InitStruct);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = 38400;
USART_Init(USART3, &USART_InitStructure);
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Cmd(USART3, ENABLE);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_Init(&NVIC_InitStruct);
}
DataTerminal::DataTerminal()
: mEscapes(0), mCurrentScreen(MAIN_SCREEN), mInteractive(false)
{
EventQueue::instance().addObserver(this, CLOCK_EVENT|KEYPRESS_EVENT);
}
void DataTerminal::processEvent(Event *e)
{
if ( e->type() == CLOCK_EVENT ) {
ClockEvent *c = static_cast<ClockEvent*>(e);
if ( c->mTime % 2 == 0 ) {
mEscapes = 0;
}
}
else if ( e->type() == KEYPRESS_EVENT ) {
KeyPressEvent *k = static_cast<KeyPressEvent*>(e);
processCharacter(k->key);
}
}
void DataTerminal::processCharacter(char c)
{
if ( !mInteractive ) {
if ( c == 27 )
++mEscapes;
if ( mEscapes == 3 ) {
mInteractive = true;
printf2("Entering interactive mode\r\n");
showScreen(MAIN_SCREEN);
}
}
else {
if ( c == 13 ) {
clearScreen();
printf2("Exiting interactive mode\r\n");
mInteractive = false;
}
}
}
void write_char(USART_TypeDef* USARTx, char c)
{
while (!(USARTx->ISR & 0x00000040))
;
USART_SendData(USARTx, c);
}
void DataTerminal::write(const char* s, bool interactive)
{
if ( mInteractive && !interactive )
return;
for ( int i = 0; s[i] != 0; ++i )
write_char(USART3, s[i]);
}
void DataTerminal::clearScreen()
{
_write("\033[2J");
_write("\033[H");
}
void DataTerminal::_write(const char *s)
{
write(s, true);
}
void DataTerminal::showScreen(MenuScreen screen)
{
char buff[100];
switch(screen) {
case MAIN_SCREEN: {
clearScreen();
//_write("****************************** Interactive Mode ******************************\r\n");
//_write("NOTICE: IT IS AGAINST USCG REGULATIONS FOR END USERS TO ALTER THEIR MMSI,\r\n");
//_write("STATION NAME AND CALL SIGN AFTER INITIAL INSTALLATION.\r\n");
//_write("IF YOUR UNIT HAS BEEN FACTORY PROGRAMMED, THIS TERMINAL WILL PROMPT YOU\r\n");
//_write("FOR A SPECIAL CODE BEFORE ALLOWING THIS OPERATION. YOU CAN ONLY OBTAIN THE\r\n");
//_write("CODE BY CONTACTING US AND PROVIDING THE UNIT'S SERIAL NUMBER AND CURRENT MMSI.\r\n\r\n");
sprintf(buff, "Model: %s\r\n", MODEL);
_write(buff);
sprintf(buff, "Software revision: %s\r\n", REVISION);
_write(buff);
sprintf(buff, "MMSI: %d\r\n", STATION_MMSI);
_write(buff);
sprintf(buff, "Name: %s\r\n", STATION_NAME);
_write(buff);
sprintf(buff, "Call sign: %s\r\n", STATION_CALLSIGN);
_write(buff);
_write("\r\n");
_write("****************************** AIS Transponder Menu ******************************\r\n\r\n");
_write("\t\033[1mP\033[0m\tProgram MMSI, station name and call sign \r\n");
_write("\t\033[1mD\033[0m\tPerform diagnostics \r\n");
_write("\t\033[1m<Enter>\033[0m\tReturn to AIS data mode\r\n\r\n");
_write("**********************************************************************************\r\n\r\n");
//_write("Note: The device will automatically return to AIS data mode if rebooted.\r\n");
break;
}
case PROGRAMMING_SCREEN:
break;
}
mCurrentScreen = screen;
}
extern "C" {
void USART3_IRQHandler(void)
{
if ( USART_GetITStatus(USART3, USART_IT_RXNE) ) {
char c = (char) USART3->RDR; // This clears the interrupt right away
KeyPressEvent *e = static_cast<KeyPressEvent*>(EventPool::instance().newEvent(KEYPRESS_EVENT));
if ( e == NULL )
return;
e->key = c;
EventQueue::instance().push(e);
//DataTerminal::instance().processCharacter(c);
}
}
}
#endif

50
src/DataTerminal.hpp Normal file
View File

@ -0,0 +1,50 @@
/*
* Terminal.hpp
*
* Created on: Apr 19, 2016
* Author: peter
*/
#ifndef DATATERMINAL_HPP_
#define DATATERMINAL_HPP_
#include "globals.h"
#include "EventQueue.hpp"
#ifdef ENABLE_TERMINAL
class DataTerminal : public EventConsumer
{
public:
static DataTerminal &instance();
void init();
void processEvent(Event *e);
void write(const char* line, bool interactive = false);
void processCharacter(char c);
private:
DataTerminal();
typedef enum {
MAIN_SCREEN = 0,
PROGRAMMING_SCREEN = 1
}
MenuScreen;
void showScreen(MenuScreen s);
void clearScreen();
void _write(const char* s);
private:
//uint32_t mTimeSlot;
uint8_t mEscapes;
MenuScreen mCurrentScreen;
bool mInteractive;
};
#endif
#endif /* DATATERMINAL_HPP_ */

26
src/DebugPrinter.cpp Normal file
View File

@ -0,0 +1,26 @@
/*
* DebugPrinter.cpp
*
* Created on: Apr 6, 2016
* Author: peter
*/
#include "DebugPrinter.hpp"
#include "EventQueue.hpp"
#include "printf2.h"
DebugPrinter::DebugPrinter()
{
EventQueue::instance().addObserver(this, DEBUG_EVENT);
}
DebugPrinter::~DebugPrinter()
{
}
void DebugPrinter::processEvent(Event *e)
{
DebugEvent *event = static_cast<DebugEvent*>(e);
printf2(event->mBuffer);
}

22
src/DebugPrinter.hpp Normal file
View File

@ -0,0 +1,22 @@
/*
* DebugPrinter.hpp
*
* Created on: Apr 6, 2016
* Author: peter
*/
#ifndef DEBUGPRINTER_HPP_
#define DEBUGPRINTER_HPP_
#include "Events.hpp"
class DebugPrinter : public EventConsumer
{
public:
DebugPrinter();
virtual ~DebugPrinter();
void processEvent(Event* e);
};
#endif /* DEBUGPRINTER_HPP_ */

149
src/EEPROM.cpp Normal file
View File

@ -0,0 +1,149 @@
/*
* EEPROM.cpp
*
* Created on: May 26, 2016
* Author: peter
*/
#include "EEPROM.hpp"
#include "printf2.h"
#include <stm32f30x_i2c.h>
#include "Utils.hpp"
/*
* The Microchip EEPROM doesn't really expect to share the I2C bus with any other EEPROM.
* So the four high bits of the address are 1010 (same for most EEPROMs) and the lower 3 don't matter.
*/
#define EEPROM_ADDR (0x50 << 1)
EEPROM &EEPROM::instance()
{
static EEPROM __instance;
return __instance;
}
EEPROM::EEPROM()
{
// TODO Auto-generated constructor stub
}
void EEPROM::init()
{
//printf2("Size of station data: %d\r\n", sizeof(StationData));
//printf2("Size of special region: %d\r\n", sizeof(SpecialRegion));
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// We're using I2C1 via PB6 (SCL) and PB7 (SDA) as alternate function 4
GPIO_InitTypeDef gpio;
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
gpio.GPIO_PuPd = GPIO_PuPd_UP; // Using the internal pull-up resistors for SDA/SCL. They seem to work fine.
gpio.GPIO_Mode = GPIO_Mode_AF;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_4);
GPIO_Init(GPIOB, &gpio);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_DeInit(I2C1);
RCC_I2CCLKConfig(RCC_I2C1CLK_HSI); // Use the internal 8MHz clock for I2C, not the 72 MHz system clock
I2C_InitTypeDef i2c;
I2C_StructInit(&i2c);
i2c.I2C_Mode = I2C_Mode_I2C;
i2c.I2C_AnalogFilter = I2C_AnalogFilter_Disable;
i2c.I2C_DigitalFilter = 0x00;
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
i2c.I2C_Ack = I2C_Ack_Enable;
i2c.I2C_OwnAddress1 = 0x00;
// Borrowed these settings from libopencm3 for the STM32F3 (https://github.com/libopencm3/libopencm3)
i2c.I2C_Timing = (0x01 << 28) | (0x04 << 20) | (0x02 << 16) | (0xf << 8) | 0x13;
I2C_Cmd(I2C1, DISABLE);
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
}
uint8_t EEPROM::readByte(uint8_t addr)
{
uint8_t result = 0;
//printf2("EEPROM read waiting for non-busy status\r\n");
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) == SET );
I2C_TransferHandling(I2C1, EEPROM_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);
//printf2("EEPROM read sending address\r\n");
I2C_SendData(I2C1, (uint8_t)addr);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET);
I2C_TransferHandling(I2C1, EEPROM_ADDR|1, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
//printf2("EEPROM read waiting for RX register\r\n");
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET);
result = I2C_ReceiveData(I2C1);
//printf2("EEPROM read waiting for STOP flag\r\n");
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET);
I2C_ClearFlag(I2C1, I2C_FLAG_STOPF);
return result;
}
void EEPROM::writeByte(uint8_t address, uint8_t byte)
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) == SET );
I2C_TransferHandling(I2C1, EEPROM_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);
I2C_SendData(I2C1, (uint8_t)address);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TCR) == RESET);
I2C_TransferHandling(I2C1, EEPROM_ADDR, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);
I2C_SendData(I2C1, byte);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET);
I2C_ClearFlag(I2C1, I2C_FLAG_STOPF);
// Should be about 5ms
Utils::delay(360000);
}
void EEPROM::writeStationData(const StationData &data)
{
uint8_t addr = EEPROM_STATION_ADDR;
const uint8_t *p = (uint8_t*)&data;
for ( size_t i = 0; i < sizeof data; ++i )
writeByte(addr++, *p++);
}
void EEPROM::readStationData(StationData &data)
{
uint8_t addr = EEPROM_STATION_ADDR;
uint8_t *p = (uint8_t*)&data;
for ( size_t i = 0; i < sizeof data; ++i ) {
uint8_t byte = readByte(addr++);
*p++ = byte;
}
}

70
src/EEPROM.hpp Normal file
View File

@ -0,0 +1,70 @@
/*
* EEPROM.hpp
*
* Created on: May 26, 2016
* Author: peter
*/
#ifndef EEPROM_HPP_
#define EEPROM_HPP_
#include <inttypes.h>
#include <time.h>
#include "AISChannels.h"
struct StationData {
uint32_t mmsi; // Vessel MMSI (should be 30 bit)
char name[21]; // Vessel name (all caps)
char callsign[8]; // Radio station call sign assigned with MMSI
uint8_t len; // Length in meters (default: 0)
uint8_t beam; // Beam in meters (default: 0)
uint8_t flags; // Reserved - 0 for now
};
/*
static struct StationData __default_station_data = {
987654321UL,
"TEST STATION 01",
"0N0000",
0,
0,
0
};
*/
typedef struct {
float swLat;
float swLng;
float neLat;
float neLng;
VHFChannel channA;
VHFChannel channB;
time_t expiration;
} SpecialRegion;
#define EEPROM_STATION_ADDR 0x00 // A StationData structure starts here
#define EEPROM_REGION_CNT_ADDR 0x24 // Number of active special regions goes here (single byte)
#define EEPROM_REGION_ADDR 0x25 // Special region data array starts here
//static SpecialRegion* __special_regions = new SpecialRegion[3];
class EEPROM
{
public:
static EEPROM &instance();
void init();
void writeStationData(const StationData &data);
void readStationData(StationData &data);
void writeRegionArray(SpecialRegion *regions, uint8_t numRegions);
uint8_t readByte(uint8_t address);
void writeByte(uint8_t address, uint8_t byte);
private:
EEPROM();
};
#endif /* EEPROM_HPP_ */

164
src/EZRadioPRO.h Normal file
View File

@ -0,0 +1,164 @@
/*
* EZRadioPRO.hpp
*
* Created on: Nov 24, 2015
* Author: peter
*/
#ifndef EZRADIOPRO_H_
#define EZRADIOPRO_H_
#include <inttypes.h>
#include "radio_config.h"
// API COMMANDS
typedef enum
{
NOP = 0x00,
PART_INFO = 0x01,
POWER_UP = 0x02,
FUNC_INFO = 0x10,
SET_PROPERTY = 0x11,
GET_PROPERTY = 0x12,
GPIO_PIN_CFG = 0x13,
GET_ADC_READING = 0x14,
FIFO_INFO = 0x15,
PACKET_INFO = 0x16,
IRCAL = 0x17,
PROTOCOL_CFG = 0x18,
GET_INT_STATUS = 0x20,
GET_PH_STATUS = 0x21,
GET_MODEM_STATUS = 0x22,
GET_CHIP_STATUS = 0x23,
START_TX = 0x31,
START_RX = 0x32,
REQ_DEVICE_STATE = 0x33,
CHANGE_STATE = 0x34,
RX_HOP = 0x36,
READ_CMD_BUFFER = 0x44,
FRR_A_READ = 0x50,
FRR_B_READ = 0x51,
FRR_C_READ = 0x53,
FRR_D_READ = 0x57,
WRITE_TX_FIFO = 0x66,
READ_RX_FIFO = 0x77
} Command;
typedef struct
{
uint8_t ChipRevision;
uint8_t PartNumberH;
uint8_t PartNumberL;
uint8_t Build;
uint8_t PartIDH;
uint8_t PartIDL;
uint8_t Customer;
uint8_t ROMID;
} PART_INFO_REPLY;
typedef struct
{
uint8_t BootOptions;
uint8_t CrystalOptions;
uint8_t CrystalFrequency3;
uint8_t CrystalFrequency2;
uint8_t CrystalFrequency1;
uint8_t CrystalFrequency0;
} POWER_UP_PARAMS;
typedef struct
{
uint8_t Group;
uint8_t NumProperties;
uint8_t StartProperty;
uint8_t Data[11];
} SET_PROPERTY_PARAMS;
typedef struct
{
uint8_t Group;
uint8_t NumProperties;
uint8_t StartProperty;
} GET_PROPERTY_REQUEST;
typedef struct
{
uint8_t Data[16];
} GET_PROPERTY_REPLY;
typedef struct
{
uint8_t GPIO0;
uint8_t GPIO1;
uint8_t GPIO2;
uint8_t GPIO3;
uint8_t NIRQ;
uint8_t SDO;
uint8_t GENCFG;
} GPIO_PIN_CFG_PARAMS;
typedef GPIO_PIN_CFG_PARAMS GPIO_PIN_CFG_REPLY;
typedef struct
{
uint8_t Pending;
uint8_t Current;
uint8_t Error;
//uint8_t CommandErrorCmdId;
} CHIP_STATUS_REPLY;
typedef struct
{
uint8_t Pending;
uint8_t Status;
uint8_t CurrentRSSI;
uint8_t LatchedRSSI;
uint8_t Ant1RSSI;
uint8_t Ant2RSSI;
uint8_t AFCFreqOffH;
uint8_t AFCFreqOffL;
} MODEM_STATUS_REPLY;
typedef struct
{
uint8_t INT_Pending;
uint8_t INT_Status;
uint8_t PH_Pending;
uint8_t PH_Status;
uint8_t MDM_Pending;
uint8_t MDM_Status;
uint8_t CHP_Pending;
uint8_t CHP_Status;
} INT_STATUS_REPLY;
typedef struct
{
uint8_t channel;
uint8_t condition;
uint16_t tx_len;
uint8_t tx_delay;
uint8_t repeats;
} TX_OPTIONS;
typedef struct
{
uint8_t channel;
uint8_t condition;
uint16_t rx_len;
uint8_t next_state1;
uint8_t next_state2;
uint8_t next_state3;
} RX_OPTIONS;
typedef struct
{
uint8_t state;
uint8_t channel;
}
DEVICE_STATE;
#endif /* EZRADIOPRO_H_ */

69
src/EventQueue.cpp Normal file
View File

@ -0,0 +1,69 @@
/*
* EventQueue.cpp
*
* Created on: Dec 7, 2015
* Author: peter
*/
#include "EventQueue.hpp"
#include <cassert>
#include "printf2.h"
#include "LEDManager.hpp"
#include <stm32f30x.h>
#include "printf2.h"
#include "Utils.hpp"
EventQueue &EventQueue::instance()
{
static EventQueue __instance;
return __instance;
}
EventQueue::EventQueue()
{
mQueue = new CircularQueue<Event*>(100);
}
void EventQueue::init()
{
}
void EventQueue::push(Event *event)
{
assert(event);
if ( !mQueue->push(event) ) {
EventPool::instance().deleteEvent(event);
printf2("EventQueue full!!!\r\n");
}
}
void EventQueue::addObserver(EventConsumer *c, uint32_t eventMask)
{
mConsumers[c] = eventMask;
}
void EventQueue::removeObserver(EventConsumer *c)
{
map<EventConsumer*, uint32_t>::iterator i = mConsumers.find(c);
if ( i == mConsumers.end() )
return;
mConsumers.erase(i);
}
void EventQueue::dispatch()
{
Event *e = NULL;
if (mQueue->pop(e)) {
for ( map<EventConsumer*, uint32_t>::iterator c = mConsumers.begin(); c != mConsumers.end(); ++c ) {
// Utils::delay(1000);
if ( c->second & e->type() )
c->first->processEvent(e);
}
EventPool::instance().deleteEvent(e);
if ( e->type() == AIS_PACKET_EVENT )
LEDManager::instance().blink(LEDManager::GREEN_LED);
}
}

49
src/EventQueue.hpp Normal file
View File

@ -0,0 +1,49 @@
/*
* EventQueue.hpp
*
* Created on: Dec 7, 2015
* Author: peter
*/
#ifndef EVENTQUEUE_HPP_
#define EVENTQUEUE_HPP_
#include <map>
#include "CircularQueue.hpp"
#include "Events.hpp"
using namespace std;
class EventQueue
{
public:
static EventQueue &instance();
void init();
/*
* Consumer registration
*/
void addObserver(EventConsumer *c, uint32_t eventMask);
/*
* Consumer de-registration
*/
void removeObserver(EventConsumer *c);
/*
* Interrupt code must push events to this queue to be processed by main() out of band.
*/
void push(Event* event);
/*
* This method must be called repeatedly either by main() or some timer ISR.
*/
void dispatch();
private:
EventQueue();
CircularQueue<Event*> *mQueue;
map<EventConsumer *, uint32_t> mConsumers;
};
#endif /* EVENTQUEUE_HPP_ */

33
src/EventTypes.h Normal file
View File

@ -0,0 +1,33 @@
/*
* EventTypes.h
*
* Created on: Dec 7, 2015
* Author: peter
*/
#ifndef EVENTTYPES_H_
#define EVENTTYPES_H_
/*
* Various events that flow through the system. Their identifiers form a bit mask for quick filtering,
* which means we are limited to 32 distinct events.
*/
typedef enum {
UNKNOWN_EVENT = 0, // Invalid, not a real event id
GPS_NMEA_SENTENCE = 1, // A NMEA sentence was received from the GPS.
GPS_FIX_EVENT = 2, // The GPS obtained a fix.
CLOCK_EVENT = 4, // One pulse per second as triggered by GPS. This is a convenient 1 Hz "wall" clock, as it carries UTC.
AIS_PACKET_EVENT = 8, // A packet was just decoded (not necessarily valid, must still be CRC checked, etc)
PACKET_SENT_EVENT = 16,
DEBUG_EVENT = 32,
KEYPRESS_EVENT = 64
//GPS_ERROR_EVENT = 64, // A GPS failure
//TRX_ERROR_EVENT = 128 // A radio failure
}
EventType;
#endif /* EVENTTYPES_H_ */

111
src/Events.cpp Normal file
View File

@ -0,0 +1,111 @@
/*
* Event.cpp
*
* Created on: Dec 7, 2015
* Author: peter
*/
#include "Events.hpp"
#include "printf2.h"
EventPool &EventPool::instance()
{
static EventPool __instance;
return __instance;
}
void EventPool::init()
{
mAISPacketPool = new ObjectPool<AISPacketEvent>(20);
mGPSNMEAPool = new ObjectPool<GPSNMEASentence>(20);
mGPSFixPool = new ObjectPool<GPSFIXEvent>(10);
mClockPool = new ObjectPool<ClockEvent>(10);
mAISPacketSentPool = new ObjectPool<AISPacketSentEvent>(5);
mDebugEventPool = new ObjectPool<DebugEvent>(2);
mKeyPressPool = new ObjectPool<KeyPressEvent>(20);
}
Event *EventPool::newEvent(EventType type)
{
Event *result = NULL;
switch(type) {
case GPS_NMEA_SENTENCE:
result = mGPSNMEAPool->get();
break;
case GPS_FIX_EVENT:
result = mGPSFixPool->get();
break;
case CLOCK_EVENT:
result = mClockPool->get();
break;
case AIS_PACKET_EVENT: {
result = mAISPacketPool->get();
break;
}
case PACKET_SENT_EVENT: {
result = mAISPacketSentPool->get();
break;
}
case DEBUG_EVENT: {
result = mDebugEventPool->get();
break;
}
case KEYPRESS_EVENT: {
result = mKeyPressPool->get();
break;
}
default:
result = NULL;
}
if ( result )
result->prepare();
return result;
}
void EventPool::deleteEvent(Event *event)
{
event->clear();
switch(event->type()) {
case GPS_NMEA_SENTENCE: {
GPSNMEASentence *e = static_cast<GPSNMEASentence*>(event);
mGPSNMEAPool->put(e);
break;
}
case GPS_FIX_EVENT: {
GPSFIXEvent *e = static_cast<GPSFIXEvent*>(event);
mGPSFixPool->put(e);
break;
}
case CLOCK_EVENT:{
ClockEvent *e = static_cast<ClockEvent*>(event);
mClockPool->put(e);
break;
}
case AIS_PACKET_EVENT: {
AISPacketEvent *p = static_cast<AISPacketEvent*>(event);
mAISPacketPool->put(p);
break;
}
case PACKET_SENT_EVENT: {
AISPacketSentEvent *p = static_cast<AISPacketSentEvent*>(event);
mAISPacketSentPool->put(p);
break;
}
case DEBUG_EVENT: {
DebugEvent *e = static_cast<DebugEvent*>(event);
mDebugEventPool->put(e);
break;
}
case KEYPRESS_EVENT: {
KeyPressEvent *e = static_cast<KeyPressEvent*>(event);
mKeyPressPool->put(e);
break;
}
default:
break;
}
}

157
src/Events.hpp Normal file
View File

@ -0,0 +1,157 @@
/*
* Event.hpp
*
* Created on: Dec 7, 2015
* Author: peter
*/
#ifndef EVENTS_HPP_
#define EVENTS_HPP_
#include "EventTypes.h"
#include <time.h>
#include <cstring>
#include "NMEASentence.hpp"
#include <string>
#include "RXPacket.hpp"
#include "ObjectPool.hpp"
using namespace std;
/*
* All events extend this class
*/
class Event
{
public:
Event () {};
virtual ~Event () {};
virtual void prepare() {}
virtual void clear() {}
virtual EventType type() = 0;
};
/*
* Event consumer abstract definition.
*/
class EventConsumer
{
public:
virtual ~EventConsumer() {}
virtual void processEvent(Event *event)=0;
};
class GPSNMEASentence : public Event
{
public:
EventType type() {
return GPS_NMEA_SENTENCE;
}
char mSentence[100];
};
class GPSFIXEvent: public Event
{
public:
EventType type() {
return GPS_FIX_EVENT;
}
time_t mUTC;
double mLat;
double mLng;
double mSpeed;
double mCOG;
};
class ClockEvent : public Event
{
public:
EventType type() {
return CLOCK_EVENT;
}
time_t mTime;
};
class AISPacketEvent: public Event
{
public:
EventType type() {
return AIS_PACKET_EVENT;
}
void prepare()
{
//mPacket = RXPacketPool::instance().newRXPacket();
//mPacket->reset();
}
void clear()
{
RXPacketPool::instance().deleteRXPacket(mPacket);
mPacket = NULL;
}
RXPacket *mPacket;
};
class AISPacketSentEvent : public Event
{
public:
EventType type() {
return PACKET_SENT_EVENT;
}
uint8_t mChannel;
uint16_t mSize;
};
class DebugEvent: public Event
{
public:
EventType type() {
return DEBUG_EVENT;
}
char mBuffer[256];
};
class KeyPressEvent : public Event
{
public:
EventType type() {
return KEYPRESS_EVENT;
}
char key;
};
class EventPool
{
public:
static EventPool &instance();
void init();
Event *newEvent(EventType type);
void deleteEvent(Event *event);
private:
ObjectPool<AISPacketEvent> *mAISPacketPool;
ObjectPool<GPSNMEASentence> *mGPSNMEAPool;
ObjectPool<GPSFIXEvent> *mGPSFixPool;
ObjectPool<ClockEvent> *mClockPool;
ObjectPool<AISPacketSentEvent> *mAISPacketSentPool;
ObjectPool<DebugEvent> *mDebugEventPool;
ObjectPool<KeyPressEvent> *mKeyPressPool;
};
#endif /* EVENTS_HPP_ */

390
src/GPS.cpp Normal file
View File

@ -0,0 +1,390 @@
/*
* GPS.cpp
*
* Created on: Nov 9, 2015
* Author: peter
*/
#include "GPS.hpp"
#include "stm32f30x.h"
#include <cstdio>
#include <cassert>
#include <cstring>
#include "DataTerminal.hpp"
#include "NMEASentence.hpp"
#include "Utils.hpp"
#include "EventQueue.hpp"
#include "printf2.h"
#include "globals.h"
//#include "LEDManager.hpp"
GPS &
GPS::instance()
{
static GPS __instance;
return __instance;
}
GPS::GPS()
: mBuffPos(0), mUTC(0), mLat(0), mLng(0), mStarted(false), mSlotNumber(0), mDelegate(NULL), mCOG(511), mSpeed(0)
{
mPeriod = (SystemCoreClock / 37.5) - 1;
memset(&mTime, 0, sizeof(mTime));
}
GPS::~GPS()
{
}
time_t GPS::UTC()
{
return mUTC;
}
struct tm &GPS::time()
{
return mTime;
}
uint32_t GPS::aisSlot()
{
return mSlotNumber;
}
double GPS::lat()
{
return mLat;
}
double GPS::lng()
{
return mLng;
}
void GPS::setDelegate(GPSDelegate *delegate)
{
mDelegate = delegate;
}
void GPS::init()
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); // For RX
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
// Initialize pins as alternative function
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_2;
GPIO_Init(GPIOA, &GPIO_InitStruct);
/* PA0 is connected to EXTI_Line0 -- currently the PPS signal from the GPS */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStruct);
/**
* Enable clock for USART1 peripheral
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE);
EventQueue::instance().addObserver(this, GPS_NMEA_SENTENCE);
/**
* Enable RX interrupt
*/
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init(&NVIC_InitStruct);
/*
* Enable clock for TIM2 on APB1
*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
resetTimer();
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
printf2("GPS Initialized\r\n");
}
void GPS::onRX(char c)
{
mBuff[mBuffPos++] = c;
if (mBuffPos > 90) {
// We screwed up!
mBuffPos = 0;
mBuff[mBuffPos] = 0;
}
else if (c == '\n') {
mBuff[mBuffPos] = 0;
GPSNMEASentence *event = static_cast<GPSNMEASentence*>(EventPool::instance().newEvent(GPS_NMEA_SENTENCE));
if ( event ) {
memcpy(event->mSentence, mBuff, sizeof event->mSentence);
EventQueue::instance ().push (event);
}
mBuffPos = 0;
mBuff[mBuffPos] = 0;
}
}
void GPS::onPPS()
{
if (mUTC) {
++mUTC; // PPS := advance clock by one second!
localtime_r (&mUTC, &mTime); // Now we know exactly what UTC second it is, with only microseconds of latency
if (!mStarted) {
// To keep things simple, we only start the AIS slot timer if we're on an even second (it has a 37.5 Hz frequency)
mSlotNumber = (mTime.tm_sec % 60) * 2250; // We know what AIS slot number we're in
if (!(mTime.tm_sec & 0x00000001))
startTimer ();
}
else {
// The timer is on, now let's re-calibrate ...
if (mTime.tm_sec & 0x00000001) {
// On odd seconds, we expect the timer value to be half its period. Just correct it.
uint32_t nominalTimerValue = mPeriod / 2 - 1;
TIM2->CNT = nominalTimerValue;
}
else {
// On even seconds, things are a bit more tricky ...
uint32_t currentTimerValue = TIM2->CNT;
if (currentTimerValue >= mPeriod / 2 - 1) {
// The timer is a little behind, so kick it forward
TIM2->CNT = mPeriod - 1;
}
else {
// The timer is a little ahead, so pull it back
TIM2->CNT = 0;
}
}
}
ClockEvent *event = static_cast<ClockEvent*>(EventPool::instance().newEvent(CLOCK_EVENT));
if ( event ) {
event->mTime = mUTC;
EventQueue::instance ().push(event);
}
} // We have a valid UTC timestamp
}
void GPS::processEvent(Event *event)
{
//printf2("-> GPS::processEvent()\r\n");
GPSNMEASentence *s = static_cast<GPSNMEASentence*>(event);
processLine(s->mSentence);
//printf2("<- GPS::processEvent()\r\n");
}
void GPS::processLine(const char* buff)
{
if ( buff[0] == '$' && buff[1] != '$' ) {
unsigned reportedHash;
char *starPos = strstr(buff, "*");
if ( starPos && sscanf(starPos + 1, "%x", &reportedHash) == 1 ) {
unsigned actualHash = 0;
for ( const char* c = buff + 1; c < starPos; ++c )
actualHash ^= *c;
if ( reportedHash == actualHash ) {
parseSentence(buff);
}
}
}
}
void GPS::parseSentence(const char *buff)
{
//printf2(buff);
//if ( strstr(buff, "RMC") != buff+3 )
// return;
NMEASentence sentence(buff);
if ( sentence.code().find("RMC") == 2 ) {
#ifdef ENABLE_TERMINAL
#ifdef OUTPUT_GPS_NMEA
DataTerminal::instance().write(buff);
#endif
#endif
// This is the time that corresponds to the previous PPS
const vector<string> &fields = sentence.fields();
/*
* Sometimes the GPS indicates errors with sentences like
* $GPRMC,1420$0*74\r\n
* Although the sentence structure is valid, its content is not what we expect.
*
* TODO: Should we consider the GPS non-functioning at this point and thus prevent transmission until it recovers?
*/
if ( fields.size() < 10 )
return;
// GPS updates arrive even with no time or fix information
if ( fields[1].length() < 6 || fields[9].length() < 6 )
return;
//printf2(buff);
//LEDManager::instance().blink();
if ( mUTC == 0 ) {
const string &timestr = fields[1].substr(0, 6);
const string &datestr = fields[9].substr(0, 6);
mTime.tm_hour = Utils::toInt(timestr.substr(0, 2));
mTime.tm_min = Utils::toInt(timestr.substr(2, 2));
mTime.tm_sec = Utils::toInt(timestr.substr(4, 2));
mTime.tm_mday = Utils::toInt(datestr.substr(0, 2));
mTime.tm_mon = Utils::toInt(datestr.substr(2, 2)) - 1; // Month is 0-based
mTime.tm_year = 100 + Utils::toInt(datestr.substr(4, 2)); // Year is 1900-based
mUTC = mktime(&mTime);
//printf2("UTC=%d\r\n", mUTC);
}
// Do we have a fix?
if ( mUTC && sentence.fields()[3].length() > 0 && sentence.fields()[5].length() > 0 ) {
mLat = Utils::latitudeFromNMEA(sentence.fields()[3], sentence.fields()[4]);
mLng = Utils::longitudeFromNMEA(sentence.fields()[5], sentence.fields()[6]);
mSpeed = Utils::toDouble(sentence.fields()[7]);
mCOG = Utils::toDouble(sentence.fields()[8]);
GPSFIXEvent *event = static_cast<GPSFIXEvent*>(EventPool::instance().newEvent(GPS_FIX_EVENT));
if ( event ) {
event->mUTC = mUTC;
event->mLat = mLat;
event->mLng = mLng;
event->mSpeed = mSpeed;
event->mCOG = mCOG;
EventQueue::instance().push(event);
}
//printf2("Lat: %f, Lng: %f\r\n", mLat, mLng);
}
}
}
void GPS::resetTimer()
{
TIM_TimeBaseInitTypeDef timerInitStructure;
timerInitStructure.TIM_Prescaler = 0;
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_Period = mPeriod;
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2, &timerInitStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}
void GPS::startTimer()
{
TIM_Cmd(TIM2, ENABLE);
mStarted = true;
printf2("Started SOTDMA timer\r\n");
}
void GPS::stopTimer()
{
mStarted = false;
TIM_Cmd(TIM2, DISABLE);
printf2("Stopped SOTDMA timer\r\n");
}
void GPS::reset()
{
stopTimer();
resetTimer();
startTimer();
}
void GPS::onTimerIRQ()
{
if ( mStarted ) {
++mSlotNumber;
if ( mSlotNumber == 2250 )
mSlotNumber = 0;
// Delegates need real-time information
if ( mDelegate )
mDelegate->timeSlotStarted(mSlotNumber);
/*
if ( mSlotNumber % 2 )
GPIO_SetBits(GPIOB, GPIO_Pin_3);
else
GPIO_ResetBits(GPIOB, GPIO_Pin_3);
*/
}
}
extern "C" {
void TIM2_IRQHandler(void)
{
if ( TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET ) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPS::instance().onTimerIRQ();
}
}
void EXTI0_IRQHandler(void)
{
if ( EXTI_GetITStatus(EXTI_Line0) != RESET ) {
EXTI_ClearITPendingBit(EXTI_Line0);
GPS::instance().onPPS();
}
}
void USART1_IRQHandler(void)
{
if ( USART_GetITStatus(USART1, USART_IT_RXNE) ) {
char c = (char) USART1->RDR; // This clears the interrupt right away
GPS::instance().onRX(c);
}
}
}

67
src/GPS.hpp Normal file
View File

@ -0,0 +1,67 @@
/*
* GPS.hpp
*
* Created on: Nov 9, 2015
* Author: peter
*/
#ifndef GPS_HPP_
#define GPS_HPP_
#include <cstdint>
#include <time.h>
#include "EventQueue.hpp"
class GPSDelegate
{
public:
virtual ~GPSDelegate()
{
}
//virtual void locationResolved(time_t UTC, double lat, double lng)=0;
virtual void timeSlotStarted(uint32_t slotNumber)=0;
};
class GPS : public EventConsumer
{
public:
static GPS &instance();
virtual ~GPS();
void init();
void onRX(char c);
void onPPS();
void startTimer();
void stopTimer();
void resetTimer();
void onTimerIRQ();
time_t UTC();
struct tm &time();
uint32_t aisSlot();
double lat();
double lng();
void setDelegate(GPSDelegate *delegate);
void onIRQ(uint32_t mask, void *data);
void processEvent(Event *event);
private:
GPS();
void reset();
void processLine(const char *buff);
void parseSentence(const char *buff);
private:
char mBuff[100];
uint8_t mBuffPos;
time_t mUTC;
double mLat;
double mLng;
bool mStarted;
uint32_t mSlotNumber;
GPSDelegate *mDelegate;
double mCOG;
double mSpeed;
uint32_t mPeriod;
struct tm mTime;
};
#endif /* GPS_HPP_ */

101
src/LEDManager.cpp Normal file
View File

@ -0,0 +1,101 @@
/*
* LEDManager.cpp
*
* Created on: Dec 25, 2015
* Author: peter
*/
#include "LEDManager.hpp"
#include "stm32f30x.h"
#include <cstring>
const uint16_t LEDMAP[] = { GPIO_Pin_14, GPIO_Pin_15 };
LEDManager &LEDManager::instance()
{
static LEDManager __instance;
return __instance;
}
LEDManager::LEDManager()
{
memset(&mLEDState, 0, sizeof mLEDState);
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); // For LEDs
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStruct);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// The desired frequency is 20Hz so we can "blink" LEDs by toggling them at every tick (10Hz)
uint32_t timerPeriod = (SystemCoreClock / 20) - 1;
timerPeriod /= 10000;
TIM_TimeBaseInitTypeDef timerInitStructure;
timerInitStructure.TIM_Prescaler = 10000;
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_Period = timerPeriod;
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 10;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 10;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseInit(TIM3, &timerInitStructure);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM3, ENABLE);
GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15);
}
LEDManager::~LEDManager()
{
}
void LEDManager::clear()
{
GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15);
}
void LEDManager::onTimer()
{
for ( int i = 0; i < 2; ++i ) {
if ( mLEDState[i] ) {
GPIO_ResetBits(GPIOB, LEDMAP[i]);
mLEDState[i] = 0;
}
}
}
void LEDManager::blink(uint8_t led)
{
GPIO_SetBits(GPIOB, LEDMAP[led]);
mLEDState[led] = 1;
}
extern "C" {
void TIM3_IRQHandler(void)
{
if ( TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET ) {
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
LEDManager::instance().onTimer();
}
}
}

37
src/LEDManager.hpp Normal file
View File

@ -0,0 +1,37 @@
/*
* LEDManager.hpp
*
* Created on: Dec 25, 2015
* Author: peter
*/
#ifndef LEDMANAGER_HPP_
#define LEDMANAGER_HPP_
#include <inttypes.h>
class LEDManager
{
public:
static const uint8_t GREEN_LED = 0;
//static const uint8_t ORANGE_LED = 1;
//static const uint8_t RED_LED = 2;
static const uint8_t BLUE_LED = 1;
static LEDManager &instance();
virtual ~LEDManager();
void clear();
void blink(uint8_t led);
//void blink();
void onTimer();
private:
LEDManager();
private:
uint8_t mLEDState[2];
//bool mLEDState;
};
#endif /* LEDMANAGER_HPP_ */

10
src/MenuScreens.cpp Normal file
View File

@ -0,0 +1,10 @@
/*
* MenuScreens.cpp
*
* Created on: Apr 19, 2016
* Author: peter
*/

15
src/MenuScreens.hpp Normal file
View File

@ -0,0 +1,15 @@
/*
* MenuScreens.hpp
*
* Created on: Apr 19, 2016
* Author: peter
*/
#ifndef MENUSCREENS_HPP_
#define MENUSCREENS_HPP_
#endif /* MENUSCREENS_HPP_ */

33
src/MetricUnits.hpp Normal file
View File

@ -0,0 +1,33 @@
/*
* MetricUnits.hpp
*
* Created on: Jan 16, 2016
* Author: peter
*/
#ifndef METRICUNITS_HPP_
#define METRICUNITS_HPP_
#include <math.h>
//#include <proj_api.h>
static const double EARTH_RADIUS_IN_METERS = 6378137.0;
static const double EARTH_CIRCUMFERENCE_IN_METERS = EARTH_RADIUS_IN_METERS * 2.0 * M_PI;
static const double MILES_PER_METER = 0.000621371192;
static const double METERS_PER_FOOT = 0.30408;
static const double FEET_PER_METER = 1.0/METERS_PER_FOOT;
static const double DEG_TO_RAD = M_PI/180.0;
static const double RAD_TO_DEG = 180.0/M_PI;
static const double METERS_PER_NAUTICAL_MILE = 1852.0;
enum MetricSystem
{
METRIC_SYSTEM_NONE,
METRIC_SYSTEM_SI,
METRIC_SYSTEM_IMPERIAL
};
#endif /* METRICUNITS_HPP_ */

108
src/NMEAEncoder.cpp Normal file
View File

@ -0,0 +1,108 @@
/*
* NMEAEncoder.cpp
*
* Created on: Jan 18, 2016
* Author: peter
*/
#include "NMEAEncoder.hpp"
#include "Utils.hpp"
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <diag/Trace.h>
#include "AISChannels.h"
using namespace std;
NMEAEncoder::NMEAEncoder()
: mSequence(0)
{
}
NMEAEncoder::~NMEAEncoder()
{
}
void NMEAEncoder::encode(RXPacket &packet, list<string> &sentences)
{
static uint16_t MAX_SENTENCE_BYTES = 56;
static uint16_t MAX_SENTENCE_BITS = MAX_SENTENCE_BYTES * 6;
packet.discardCRC();
uint16_t numBits = packet.size();
uint16_t fillBits = 0;
if ( numBits % 6 ) {
fillBits = 6 - (numBits%6);
packet.addFillBits(fillBits);
numBits = packet.size();
}
uint16_t numSentences = 1;
while ( numBits > MAX_SENTENCE_BITS ) {
++numSentences;
numBits -= MAX_SENTENCE_BITS;
}
numBits = packet.size();
if ( numSentences > 1 ) {
++mSequence;
if ( mSequence > 9 )
mSequence = 0;
}
// Now we know how many sentences we need
char sentence[85];
uint16_t pos = 0;
for ( uint16_t i = 1; i <= numSentences; ++i ) {
uint8_t k = 0;
if ( numSentences > 1 )
sprintf(sentence, "!AIVDM,%d,%d,%d,%c,", numSentences, i, mSequence, AIS_CHANNELS[packet.channel()].designation);
else
sprintf(sentence, "!AIVDM,%d,%d,,%c,", numSentences, i, AIS_CHANNELS[packet.channel()].designation);
k = strlen(sentence);
uint16_t sentenceBits = 0;
for ( ; pos < numBits && sentenceBits < MAX_SENTENCE_BITS; pos += 6, sentenceBits += 6 ) {
uint8_t nmeaByte = (uint8_t)packet.bits(pos, 6);
nmeaByte += (nmeaByte < 40) ? 48 : 56;
sentence[k++] = nmeaByte;
}
//trace_printf("Sentence bits: %d\n", sentenceBits);
sentence[k++] = ',';
if ( numSentences > 1 ) {
if ( i == numSentences )
sentence[k++] = '0' + fillBits;
else
sentence[k++] = '0';
}
else
sentence[k++] = '0';
sentence[k++] = '*';
sprintf(sentence+k, "%.2X", nmeaCRC(sentence));
sentences.push_back(string(sentence));
}
}
uint8_t NMEAEncoder::nmeaCRC(const char* buff)
{
uint8_t p = 1;
uint8_t crc = buff[p++];
while ( buff[p] != '*' )
crc ^= buff[p++];
return crc;
}

30
src/NMEAEncoder.hpp Normal file
View File

@ -0,0 +1,30 @@
/*
* NMEAEncoder.hpp
*
* Created on: Jan 18, 2016
* Author: peter
*/
#ifndef NMEAENCODER_HPP_
#define NMEAENCODER_HPP_
#include <list>
#include <string>
#include "RXPacket.hpp"
using namespace std;
class NMEAEncoder
{
public:
NMEAEncoder();
virtual ~NMEAEncoder();
void encode(RXPacket &packet, list<string> &sentences);
private:
uint8_t nmeaCRC(const char* buff);
private:
uint8_t mSequence;
};
#endif /* NMEAENCODER_HPP_ */

42
src/NMEASentence.cpp Normal file
View File

@ -0,0 +1,42 @@
#include "NMEASentence.hpp"
#include "Utils.hpp"
NMEASentence::NMEASentence(const string &raw)
: mRaw(raw)
{
parse();
}
const string &NMEASentence::code() const
{
return mCode;
}
const string &NMEASentence::raw() const
{
return mRaw;
}
const vector<string> &NMEASentence::fields() const
{
return mFields;
}
bool NMEASentence::parse()
{
if ( mRaw.empty() )
return false;
if ( mRaw[0] != '$' && mRaw[0] != '!' )
return false;
Utils::tokenize(mRaw, ',', mFields);
mFields[0] = mFields[0].substr(1); // Remove the $ or ! from the first field
string &lastField = *mFields.rbegin();
size_t p = lastField.find("*");
lastField = lastField.substr(0, p);
mCode = mFields[0];
return true;
}

29
src/NMEASentence.hpp Normal file
View File

@ -0,0 +1,29 @@
#ifndef __NMEA_H__
#define __NMEA_H__
#include <string>
#include <vector>
using namespace std;
class NMEASentence
{
public:
NMEASentence(const string &raw);
const string &code() const;
const vector<string> &fields() const;
const string &raw() const;
private:
bool parse();
const string &mRaw;
string mCode;
vector<string> mFields;
};
#endif
/*
Local Variables: ***
mode: c++ ***
End: ***
*/

134
src/NoiseFloorDetector.cpp Normal file
View File

@ -0,0 +1,134 @@
/*
* NoiseFloorDetector.cpp
*
* Created on: May 22, 2016
* Author: peter
*/
#include "NoiseFloorDetector.hpp"
#include "EventQueue.hpp"
#include <algorithm>
#include "printf2.h"
#include "AISChannels.h"
#define WINDOW_SIZE 10
NoiseFloorDetector &NoiseFloorDetector::instance()
{
static NoiseFloorDetector __instance;
return __instance;
}
NoiseFloorDetector::NoiseFloorDetector()
: mUTC(0), mStartTime(0), mLastDumpTime(0)
{
EventQueue::instance().addObserver(this, CLOCK_EVENT);
}
uint8_t NoiseFloorDetector::report(VHFChannel channel, uint8_t rssi)
{
// If we don't have time yet, we certainly don't have fix so we can't be transmitting anyway, so no data collection
if ( mUTC == 0 )
return 0xff;
if ( mData.find(channel) == mData.end() ) {
ChannelReadings r;
r.reserve(WINDOW_SIZE);
mData[channel] = r;
}
ChannelReadings &window = mData[channel];
return processSample(window, rssi);
}
uint8_t NoiseFloorDetector::getNoiseFloor(VHFChannel channel)
{
if ( mData.find(channel) == mData.end() )
return 0xff;
return medianValue(mData[channel]);
}
void NoiseFloorDetector::processEvent(Event *e)
{
ClockEvent *ce = static_cast<ClockEvent*>(e);
if ( mUTC == 0 ) {
printf2("Starting RSSI sample collection\r\n");
mStartTime = ce->mTime;
mLastDumpTime = mStartTime;
}
mUTC = ce->mTime;
if ( mUTC - mLastDumpTime >= 30 )
dump();
if ( mUTC - mStartTime > 180 ) {
reset();
mStartTime = mUTC;
}
}
uint8_t NoiseFloorDetector::processSample(ChannelReadings &window, uint8_t rssi)
{
while ( window.size() >= WINDOW_SIZE )
window.pop_back();
if ( window.empty() ) {
Reading r;
r.timestamp = mUTC;
r.reading = rssi;
window.push_back(r);
return 0xff;
}
// Insert the reading at the start if it qualifies
for ( ChannelReadings::iterator i = window.begin(); i != window.end(); ++i ) {
if ( rssi <= i->reading ) {
Reading r;
r.timestamp = mUTC;
r.reading = rssi;
window.insert(window.begin(), r);
break;
}
}
if ( mUTC - mStartTime < 30 )
return 0xff;
return medianValue(window);
}
uint8_t NoiseFloorDetector::medianValue(ChannelReadings &window)
{
if ( window.empty() )
return 0xff;
vector<uint8_t> sorted;
sorted.reserve(WINDOW_SIZE);
for ( ChannelReadings::iterator i = window.begin(); i != window.end(); ++i )
sorted.push_back(i->reading);
sort(sorted.begin(), sorted.end());
return sorted[sorted.size()/2];
}
void NoiseFloorDetector::dump()
{
//printf2("Dumping RSSI stats:\r\n");
for ( ChannelData::iterator cIt = mData.begin(); cIt != mData.end(); ++cIt ) {
uint8_t value = medianValue(cIt->second);
printf2("[Channel %d noise floor: 0x%.2x]\r\n", AIS_CHANNELS[cIt->first].itu, value);
}
mLastDumpTime = mUTC;
}
void NoiseFloorDetector::reset()
{
mData.clear();
}

View File

@ -0,0 +1,53 @@
/*
* NoiseFloorDetector.hpp
*
* Created on: May 22, 2016
* Author: peter
*/
#ifndef NOISEFLOORDETECTOR_HPP_
#define NOISEFLOORDETECTOR_HPP_
#include "AISChannels.h"
#include "Events.hpp"
#include <map>
using namespace std;
class NoiseFloorDetector : public EventConsumer
{
public:
static NoiseFloorDetector &instance();
// Called directly by each receiver to report every RSSI reading at every SOTDMA slot, returns latest noise floor or 0xff if not enough data exists
uint8_t report(VHFChannel channel, uint8_t rssi);
void reset();
// Returns the current noise floor of the channel, 0xff if unknown
uint8_t getNoiseFloor(VHFChannel channelIndex);
void processEvent(Event *e);
private:
typedef struct {
time_t timestamp;
uint8_t reading;
} Reading;
typedef vector<Reading> ChannelReadings;
typedef map<VHFChannel, ChannelReadings> ChannelData;
private:
NoiseFloorDetector();
uint8_t processSample(ChannelReadings &window, uint8_t rssi);
uint8_t medianValue(ChannelReadings &window);
void dump();
private:
time_t mUTC;
time_t mStartTime;
time_t mLastDumpTime;
ChannelData mData;
};
#endif /* NOISEFLOORDETECTOR_HPP_ */

70
src/ObjectPool.hpp Normal file
View File

@ -0,0 +1,70 @@
/*
* ObjectPool.hpp
*
* Created on: Mar 5, 2016
* Author: peter
*/
#ifndef OBJECTPOOL_HPP_
#define OBJECTPOOL_HPP_
using namespace std;
#include <cstdlib>
#include <cassert>
#include "printf2.h"
#include "_assert.h"
template<typename T> class ObjectPool
{
public:
ObjectPool<T>(uint32_t size)
{
mSize = size;
mPool = new T[size];
mState = new bool[size];
for ( uint32_t i = 0; i < mSize; ++i ) {
mState[i] = true; // Available
ASSERT(&mPool[i]);
}
printf2("Initialized pool of size %d\r\n", mSize);
}
T *get()
{
for ( uint32_t i = 0; i < mSize; ++i ) {
if ( mState[i] ) {
mState[i] = false;
return &mPool[i];
}
}
return NULL;
}
void put(T* o)
{
for ( uint32_t i = 0; i < mSize; ++i ) {
if ( o == &mPool[i] ) {
ASSERT(!mState[i]);
mState[i] = true;
return;
}
}
ASSERT(false);
}
private:
uint32_t mSize;
T* mPool;
bool* mState; // Not ideal. How about a bit vector instead?
};
#endif /* OBJECTPOOL_HPP_ */

194
src/RFIC.cpp Normal file
View File

@ -0,0 +1,194 @@
/*
* RFIC.cpp
*
* Created on: May 21, 2016
* Author: peter
*/
#include "RFIC.hpp"
#include "radio_config.h"
#include "Utils.hpp"
#include "printf2.h"
#include "EZRadioPRO.h"
#include <cstring>
#include "_assert.h"
RFIC::RFIC( SPI_TypeDef *spi,
GPIO_TypeDef *sdnPort,
uint16_t sdnPin,
GPIO_TypeDef *csPort,
uint16_t csPin,
GPIO_TypeDef *gpio1Port,
uint16_t gpio1Pin,
GPIO_TypeDef *gpio3Port,
uint16_t gpio3Pin)
{
mSPI = spi;
mSDNP = sdnPort;
mCSP = csPort;
mGPIO1P = gpio1Port;
mGPIO3P = gpio3Port;
mSDNPin = sdnPin;
mCSPin = csPin;
mGPIO1Pin = gpio1Pin;
mGPIO3Pin = gpio3Pin;
mRSSIAdjustment = 0;
mSPIBusy = false;
if ( !isUp() )
powerOnReset();
}
RFIC::~RFIC()
{
}
void RFIC::setRSSIAdjustment(short adj)
{
mRSSIAdjustment = adj;
}
void RFIC::spiOn()
{
GPIO_ResetBits(mCSP, mCSPin);
}
void RFIC::spiOff()
{
GPIO_SetBits(mCSP, mCSPin);
}
uint8_t RFIC::sendSPIByte(uint8_t data)
{
/*
* See this URL for an explanation:
http://www.eevblog.com/forum/microcontrollers/stm32f0-spi-8bit-communication-frame-(errata)/
*/
while((mSPI->SR & SPI_I2S_FLAG_TXE)==RESET)
;
SPI_SendData8(mSPI, data);
while((mSPI->SR & SPI_I2S_FLAG_RXNE)==RESET)
;
return SPI_ReceiveData8(mSPI);
}
void RFIC::sendCmd(uint8_t cmd, void* params, uint8_t paramLen, void* result, uint8_t resultLen)
{
ASSERT(!mSPIBusy);
mSPIBusy = true;
spiOn();
sendSPIByte(cmd);
uint8_t *b = (uint8_t*) params;
for ( int i = 0; i < paramLen; ++i ) {
sendSPIByte(b[i]);
}
spiOff(); // The Si446x needs CS asserted after every request to trigger an internal interrupt
while (receiveSPIData(result, resultLen) == false)
; // wait for valid response
mSPIBusy = false;
}
// This is borrowed from the dAISy project. Thank you Adrian :)
bool RFIC::receiveSPIData(void *data, uint8_t length)
{
spiOn();
sendSPIByte(0x44);
if ( sendSPIByte(0) != 0xff ) {
spiOff();
return false;
}
uint8_t* b = (uint8_t*) data;
uint8_t i = 0;
while (i < length) {
b[i] = sendSPIByte(0);
++i;
}
spiOff();
return true;
}
void RFIC::configure()
{
uint8_t radio_configuration[] = RADIO_CONFIGURATION_DATA_ARRAY;
uint8_t *cfg = radio_configuration;
while (*cfg) { // configuration array stops with 0
uint8_t count = (*cfg++) - 1; // 1st byte: number of bytes, incl. command
uint8_t cmd = *cfg++; // 2nd byte: command
sendCmd(cmd, cfg, count, NULL, 0); // send bytes to chip
cfg += count; // point at next line
}
}
bool RFIC::isUp()
{
GPIO_SetBits(mSDNP, mSDNPin);
Utils::delay(1000000);
GPIO_ResetBits(mSDNP, mSDNPin);
Utils::delay(10000000);
printf2("Checking RF chip status\r\n");
CHIP_STATUS_REPLY chip_status;
memset(&chip_status, 0, sizeof chip_status);
sendCmd(GET_CHIP_STATUS, NULL, 0, &chip_status, sizeof chip_status);
printf2("Chip status: %.2x\r\n", chip_status.Current);
if ( chip_status.Current & 0x08 ) {
return false;
}
else {
return true;
}
}
void RFIC::powerOnReset()
{
// Put SDN high
GPIO_SetBits(mSDNP, mSDNPin);
// Wait at least 10 microseconds
Utils::delay(500000);
// Put SDN low and poll the status of GPIO1
GPIO_ResetBits(mSDNP, mSDNPin);
printf2("Waiting for GPIO1\r\n");
while ( GPIO_ReadInputDataBit(mGPIO1P, mGPIO1Pin) == 0 )
;
// We're done!
printf2("Radio Ready!\r\n");
}
uint8_t RFIC::readRSSI()
{
MODEM_STATUS_REPLY s;
sendCmd(GET_MODEM_STATUS, NULL, 0, &s, sizeof s);
return s.CurrentRSSI;
}
bool RFIC::checkStatus()
{
DEVICE_STATE s;
sendCmd(REQ_DEVICE_STATE, NULL, 0, &s, sizeof s);
if ( s.state != 8 && s.state != 7 )
return false;
else
return true;
}

66
src/RFIC.hpp Normal file
View File

@ -0,0 +1,66 @@
/*
* RFIC.hpp
*
* Created on: May 21, 2016
* Author: peter
*/
#ifndef RFIC_HPP_
#define RFIC_HPP_
#include <inttypes.h>
#include "stm32f30x.h"
typedef enum
{
BIT_STATE_PREAMBLE_SYNC,
BIT_STATE_IN_PACKET
} BitState;
class RFIC
{
public:
RFIC( SPI_TypeDef *spi,
GPIO_TypeDef *sdnPort,
uint16_t sdnPin,
GPIO_TypeDef *csPort,
uint16_t csPin,
GPIO_TypeDef *gpio1Port,
uint16_t gpio1Pin,
GPIO_TypeDef *gpio3Port,
uint16_t gpio3Pin);
virtual ~RFIC();
void setRSSIAdjustment(short rssiAdj);
protected:
virtual void configure();
void sendCmd(uint8_t cmd, void* params, uint8_t paramLen, void* result, uint8_t resultLen);
bool isUp();
void powerOnReset();
bool isReceiving();
uint8_t readRSSI();
bool checkStatus();
private:
uint8_t sendSPIByte(uint8_t);
bool receiveSPIData(void *data, uint8_t len);
void spiOn();
void spiOff();
protected:
SPI_TypeDef *mSPI ; // The SPI bus we use
GPIO_TypeDef *mSDNP; // The MCU GPIO assigned to SDN for this IC (GPIOA, GPIOB or GPIOC)
GPIO_TypeDef *mCSP; // The MCU GPIO assigned to CS for SPI
GPIO_TypeDef *mGPIO1P; // The MCU GPIO assigned to GPIO1 of the IC
GPIO_TypeDef *mGPIO3P; // The MCU GPIO assigned to GPIO3 of the IC
uint16_t mSDNPin;
uint16_t mCSPin;
uint16_t mGPIO1Pin;
uint16_t mGPIO3Pin;
uint8_t mLastNRZIBit;
BitState mBitState;
short mRSSIAdjustment;
bool mSPIBusy;
};
#endif /* RFIC_HPP_ */

279
src/RXPacket.cpp Normal file
View File

@ -0,0 +1,279 @@
/*
* AISPacket.cpp
*
* Created on: Dec 6, 2015
* Author: peter
*/
#include <cassert>
#include <diag/Trace.h>
#include <cstring>
#include "RXPacket.hpp"
RXPacket::RXPacket ()
{
reset();
}
RXPacket::~RXPacket ()
{
}
void RXPacket::setChannel(VHFChannel channel)
{
mChannel = channel;
}
VHFChannel RXPacket::channel()
{
return mChannel;
}
RXPacket::RXPacket(const RXPacket &copy)
{
memcpy(mPacket, copy.mPacket, sizeof mPacket);
mSize = copy.mSize;
mCRC = copy.mCRC;
mRSSI = copy.mRSSI;
mType = copy.mType;
mRI = copy.mRI;
mMMSI = copy.mMMSI;
mSlot = copy.mSlot;
mChannel = copy.mChannel;
}
RXPacket &RXPacket::operator =(const RXPacket &copy)
{
memcpy(mPacket, copy.mPacket, sizeof mPacket);
mSize = copy.mSize;
mCRC = copy.mCRC;
mType = copy.mType;
mRSSI = copy.mRSSI;
mRI = copy.mRI;
mMMSI = copy.mMMSI;
mChannel = copy.mChannel;
mSlot = copy.mSlot;
return *this;
}
void RXPacket::reset()
{
mType = 0;
mRI = 0;
mMMSI = 0;
mSize = 0;
mCRC = 0xffff;
mSlot = 0xffffffff;
mRSSI = 0;
memset(mPacket, 0, sizeof mPacket);
}
void RXPacket::setSlot(uint32_t slot)
{
mSlot = slot;
}
uint32_t RXPacket::slot()
{
return mSlot;
}
void RXPacket::setRSSI(uint8_t rssi)
{
mRSSI = rssi;
}
uint8_t RXPacket::rssi()
{
return mRSSI;
}
void RXPacket::addBit(uint8_t bit)
{
ASSERT(mSize < MAX_AIS_RX_PACKET_SIZE);
uint16_t index = mSize / 8;
uint8_t offset = mSize % 8;
if ( bit )
mPacket[index] |= ( 1 << offset );
else
mPacket[index] &= ~( 1 << offset );
++mSize;
}
uint8_t RXPacket::bit(uint16_t pos)
{
if ( pos < mSize ) {
uint16_t index = pos / 8;
uint8_t offset = pos % 8;
return (mPacket[index] & (1 << offset)) != 0;
}
else
return 0;
}
uint32_t RXPacket::bits(uint16_t pos, uint8_t count)
{
ASSERT(count <= 32);
uint32_t result = 0;
for ( uint16_t i = pos; i < pos+count; ++i ) {
result <<= 1;
result |= bit(i);
}
return result;
}
void RXPacket::addBitCRC(uint8_t data)
{
if ( (data ^ mCRC) & 0x0001 )
mCRC = (mCRC >> 1) ^ 0x8408;
else
mCRC >>= 1;
}
void RXPacket::addByte(uint8_t byte)
{
// The payload is LSB (inverted MSB bytes). This brings it back into MSB format
addBit(byte & 0x01);
addBit(byte & 0x02);
addBit(byte & 0x04);
addBit(byte & 0x08);
addBit(byte & 0x10);
addBit(byte & 0x20);
addBit(byte & 0x40);
addBit(byte & 0x80);
// Now we can update our CRC in MSB order which is how it was calculated during encoding by the sender ...
addBitCRC((byte & 0x80) >> 7);
addBitCRC((byte & 0x40) >> 6);
addBitCRC((byte & 0x20) >> 5);
addBitCRC((byte & 0x10) >> 4);
addBitCRC((byte & 0x08) >> 3);
addBitCRC((byte & 0x04) >> 2);
addBitCRC((byte & 0x02) >> 1);
addBitCRC(byte & 0x01);
}
uint16_t RXPacket::size()
{
return mSize;
}
bool RXPacket::isBad()
{
/*
* We don't anticipate anything less than 168 + 16 = 184 bits
*/
//return mSize < 184;
return mSize < 64;
}
uint16_t RXPacket::crc()
{
return mCRC;
}
void RXPacket::discardCRC()
{
if ( mCRC == 0xffff )
return;
mSize -= 16;
mCRC = 0xffff;
}
void RXPacket::addFillBits(uint8_t numBits)
{
for ( uint8_t i = 0; i < numBits; ++i )
addBit(0);
}
bool RXPacket::checkCRC()
{
//uint16_t rcrc = ((mCRC & 0xff00) >> 8) | ((mCRC & 0x00ff) << 8);
//trace_printf("%.4x %.4x %.4x\n", mCRC, ~(mCRC), ~(rcrc));
return mCRC == 0xf0b8;
}
uint8_t RXPacket::messageType()
{
if ( mType )
return mType;
for ( int i = 0; i < 6; ++i ) {
mType <<= 1;
mType |= bit(i);
}
return mType;
}
uint8_t RXPacket::repeatIndicator()
{
if ( mRI )
return mRI;
mRI = bit(6) << 1 | bit(7);
return mRI;
}
uint32_t RXPacket::mmsi()
{
if ( mMMSI )
return mMMSI;
for ( int i = 8; i < 38; ++i ) {
mMMSI <<= 1;
mMMSI |= bit(i);
}
return mMMSI;
}
///////////////////////////////////////////////////////////////////////////////
//
// RXPacketPool
//
///////////////////////////////////////////////////////////////////////////////
RXPacketPool &RXPacketPool::instance()
{
static RXPacketPool __instance;
return __instance;
}
void RXPacketPool::init()
{
mPool = new ObjectPool<RXPacket>(40);
}
RXPacket *RXPacketPool::newRXPacket()
{
return mPool->get();
}
void RXPacketPool::deleteRXPacket(RXPacket *p)
{
ASSERT(p);
mPool->put(p);
}

93
src/RXPacket.hpp Normal file
View File

@ -0,0 +1,93 @@
/*
* AISPacket.hpp
*
* Created on: Dec 6, 2015
* Author: peter
*/
#ifndef RXPACKET_HPP_
#define RXPACKET_HPP_
#include <inttypes.h>
#include "ObjectPool.hpp"
#include "globals.h"
#include "AISChannels.h"
using namespace std;
class RXPacket
{
friend class RXPacketPool;
public:
RXPacket ();
private:
RXPacket(const RXPacket &copy);
RXPacket &operator=(const RXPacket &copy);
~RXPacket ();
public:
//void setStuffed(bool);
void setSlot(uint32_t slot);
void setChannel(VHFChannel channel);
VHFChannel channel();
void discardCRC();
void addFillBits(uint8_t numBits);
void addByte(uint8_t byte);
uint16_t size();
uint8_t bit(uint16_t pos);
uint32_t bits(uint16_t pos, uint8_t count);
uint16_t crc();
bool checkCRC();
bool isBad();
void reset();
// Every AIS message contains these 3 attributes at a minimum, so we expose them at the packet level
uint8_t messageType();
uint8_t repeatIndicator();
uint32_t mmsi();
// These are link-level attributes
uint32_t slot();
uint8_t rssi();
void setRSSI(uint8_t);
private:
void addBit(uint8_t bit);
void addBitCRC(uint8_t bit);
private:
uint8_t mPacket[MAX_AIS_RX_PACKET_SIZE/8+1];
uint16_t mSize;
uint16_t mCRC;
uint8_t mType;
uint8_t mRI;
uint32_t mMMSI;
uint32_t mSlot;
VHFChannel mChannel;
uint8_t mRSSI;
};
class RXPacketPool
{
public:
static RXPacketPool &instance();
void init();
RXPacket *newRXPacket();
void deleteRXPacket(RXPacket*);
private:
ObjectPool<RXPacket> *mPool;
};
#endif /* RXPACKET_HPP_ */

170
src/RXPacketProcessor.cpp Normal file
View File

@ -0,0 +1,170 @@
/*
* PacketProcessor.cpp
*
* Created on: Dec 7, 2015
* Author: peter
*/
#include <stdio.h>
#include "RXPacketProcessor.hpp"
#include "AISMessages.hpp"
#include "DataTerminal.hpp"
#include "EventQueue.hpp"
#include "Utils.hpp"
#include "LEDManager.hpp"
#include "MetricUnits.hpp"
#include "printf2.h"
#include "AISChannels.h"
RXPacketProcessor::RXPacketProcessor ()
: mLastDumpTime(0), mGoodCount(0), mBadCRCCount(0), mInvalidCount(0), mLat(-200), mLng(-200)
{
EventQueue::instance().addObserver(this, AIS_PACKET_EVENT | CLOCK_EVENT | GPS_FIX_EVENT);
}
RXPacketProcessor::~RXPacketProcessor ()
{
// Should never be called
}
void RXPacketProcessor::processEvent(Event *e)
{
//printf2("-> RXPacketProcessor::processEvent()\r\n");
switch(e->type()) {
case GPS_FIX_EVENT: {
GPSFIXEvent *gfe = static_cast<GPSFIXEvent*> (e);
mLat = gfe->mLat;
mLng = gfe->mLng;
break;
}
case CLOCK_EVENT: {
ClockEvent *pe = static_cast<ClockEvent*>(e);
if ( mLastDumpTime == 0 ) {
mLastDumpTime = pe->mTime;
}
else if ( pe->mTime - mLastDumpTime >= 60 ) {
mLastDumpTime = pe->mTime;
float yield = (float)mGoodCount / (float)(mGoodCount+mBadCRCCount+mInvalidCount);
printf2("\n[Yield: %.1fpct, Valid: %d, Wrong CRC: %d, Malformed: %d]\r\n", yield*100.0, mGoodCount, mBadCRCCount, mInvalidCount);
printf2("[Unique MMSIs: %d]\r\n\n", mUniqueMMSIs.size());
mUniqueMMSIs.clear();
mBadCRCCount = 0;
mInvalidCount = 0;
mGoodCount = 0;
}
break;
}
case AIS_PACKET_EVENT: {
AISPacketEvent *pe = static_cast<AISPacketEvent*>(e);
if ( pe->mPacket->isBad() ) {
++mInvalidCount;
break;
}
if ( pe->mPacket->checkCRC() ) {
++mGoodCount;
list<string> sentences;
#ifdef ENABLE_TERMINAL
mEncoder.encode(*pe->mPacket, sentences);
for ( list<string>::iterator i = sentences.begin(); i != sentences.end(); ++i ) {
DataTerminal::instance().write(i->c_str());
DataTerminal::instance().write("\r\n");
}
#endif
mUniqueMMSIs.insert(pe->mPacket->mmsi());
switch(pe->mPacket->messageType()) {
case 1:
case 2:
case 3: {
AISMessage123 msg;
if ( msg.decode(*pe->mPacket) ) {
double distance = Utils::haversineDistance(mLat, mLng, msg.latitude, msg.longitude);
double miles = distance / METERS_PER_NAUTICAL_MILE;
printf2("RSSI: %.2x, Ch: %c, Type: %d, MMSI: %d, Speed: %.1f kts, Pos: %.5f,%.5f, Dist: %.1f NM\r\n",
pe->mPacket->rssi(),
AIS_CHANNELS[pe->mPacket->channel()].designation,
msg.messageType,
msg.mmsi,
msg.sog,
msg.latitude,
msg.longitude,
miles);
}
break;
}
case 18: {
AISMessage18 msg;
if ( msg.decode(*pe->mPacket) ) {
double distance = Utils::haversineDistance(mLat, mLng, msg.latitude, msg.longitude);
double miles = distance / METERS_PER_NAUTICAL_MILE;
printf2("RSSI: %.2x, Ch: %c, Type: %d, MMSI: %d, Speed: %.1f kts, Pos: %.5f,%.5f, Dist: %.1f NM\r\n",
pe->mPacket->rssi(),
AIS_CHANNELS[pe->mPacket->channel()].designation,
msg.messageType,
msg.mmsi,
msg.sog,
msg.latitude,
msg.longitude,
miles);
}
break;
}
default: {
printf2("RSSI: %.2x, Ch: %c, Type: %d, RI: %d, MMSI: %d\r\n",
pe->mPacket->rssi(),
AIS_CHANNELS[pe->mPacket->channel()].designation,
pe->mPacket->messageType(),
pe->mPacket->repeatIndicator(),
pe->mPacket->mmsi());
break;
}
}
// TODO: Move this out of here
switch(pe->mPacket->messageType()) {
case 15:
// TODO: This is an interrogation. Check if we are any of the 3 possible recipients and respond with message 18
break;
case 20:
// TODO: This is a time slot reservation from a base station. Possibly use this information to augment CCA?
break;
case 22:
/*
* TODO: This is the frequency management message. If we support all the VHF channels in the specification
* (161.500Mhz to 162.025Mhz), we use this to switch our primary 2 channels where instructed.
*/
break;
case 23:
/*
* TODO: This is the group assignment message. Base stations can use this to configure our transmission interval.
*/
break;
}
}
else {
++mBadCRCCount;
}
break;
}
default:
break;
}
//printf2("<- RXPacketProcessor::processEvent()\r\n");
}

35
src/RXPacketProcessor.hpp Normal file
View File

@ -0,0 +1,35 @@
/*
* PacketProcessor.hpp
*
* Created on: Dec 7, 2015
* Author: peter
*/
#ifndef RXPACKETPROCESSOR_HPP_
#define RXPACKETPROCESSOR_HPP_
#include "Events.hpp"
#include "NMEAEncoder.hpp"
#include <set>
class RXPacketProcessor : public EventConsumer
{
public:
RXPacketProcessor ();
virtual
~RXPacketProcessor ();
void processEvent(Event *e);
private:
NMEAEncoder mEncoder;
time_t mLastDumpTime;
uint32_t mGoodCount;
uint32_t mBadCRCCount;
uint32_t mInvalidCount;
double mLat;
double mLng;
std::set<uint32_t> mUniqueMMSIs;
};
#endif /* RXPACKETPROCESSOR_HPP_ */

318
src/RadioManager.cpp Normal file
View File

@ -0,0 +1,318 @@
/*
* RadioManager.cpp
*
* Created on: May 21, 2016
* Author: peter
*/
#include "RadioManager.hpp"
RadioManager &RadioManager::instance()
{
static RadioManager __instance;
return __instance;
}
RadioManager::RadioManager()
{
mTransceiverIC = NULL;
mReceiverIC = NULL;
mInitializing = true;
mTXQueue = new CircularQueue<TXPacket*>(5);
mUTC = 0;
EventQueue::instance().addObserver(this, CLOCK_EVENT);
}
bool RadioManager::initialized()
{
return !mInitializing;
}
void RadioManager::init()
{
printf2("Starting Radio layer initialization\r\n");
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
// Pins PA5 PA6 and PA7 will be SCLK, MISO and MOSI
GPIO_InitTypeDef gpio;
gpio.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
gpio.GPIO_Mode = GPIO_Mode_AF;
gpio.GPIO_Speed = GPIO_Speed_Level_3;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_5);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_5);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_5);
// PB1 will be the CS2
gpio.GPIO_Pin = GPIO_Pin_1;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Speed = GPIO_Speed_Level_2;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &gpio);
// PB8 is SDN2
gpio.GPIO_Pin = GPIO_Pin_8;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Speed = GPIO_Speed_Level_2;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &gpio);
// PC13 starts as input, used for POR status (RFIC2 GPIO1 -> MCU), then switched between RX/TX DATA as necessary
gpio.GPIO_Pin = GPIO_Pin_13;
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_Speed = GPIO_Speed_Level_1;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &gpio);
// PB9 is input for bit clock, both RX and TX (RFIC2 GPIO3 -> MCU)
gpio.GPIO_Pin = GPIO_Pin_9;
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_Speed = GPIO_Speed_Level_2;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpio);
// PA4 will be the CS1 pin
gpio.GPIO_Pin = GPIO_Pin_4;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Speed = GPIO_Speed_Level_2;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &gpio);
// PA3 will be the SDN1 pin
gpio.GPIO_Pin = GPIO_Pin_3;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Speed = GPIO_Speed_Level_2;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &gpio);
// PB2 starts as input, used for POR status (RFIC1 GPIO1 -> MCU), then switched between RX/TX DATA as necessary
gpio.GPIO_Pin = GPIO_Pin_2;
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_Speed = GPIO_Speed_Level_1;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpio);
// PA1 is input for bit clock, both RX and TX (RFIC1 GPIO3 -> MCU)
gpio.GPIO_Pin = GPIO_Pin_1;
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_Speed = GPIO_Speed_Level_2;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio);
// PA8 will be CTX
gpio.GPIO_Pin = GPIO_Pin_8;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Speed = GPIO_Speed_Level_2;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio);
// PA9 will be BYP
gpio.GPIO_Pin = GPIO_Pin_9;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Speed = GPIO_Speed_Level_2;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio);
spiOff();
// Initialize the SPI bus
SPI_InitTypeDef spi;
spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi.SPI_Mode = SPI_Mode_Master;
spi.SPI_DataSize = SPI_DataSize_8b;
spi.SPI_NSS = SPI_NSS_Soft;
spi.SPI_FirstBit = SPI_FirstBit_MSB;
spi.SPI_CPOL = SPI_CPOL_Low;
spi.SPI_CPHA = SPI_CPHA_1Edge;
spi.SPI_CRCPolynomial = 0x01;
/*
* See this URL for an explanation:
http://www.eevblog.com/forum/microcontrollers/stm32f0-spi-8bit-communication-frame-(errata)/
*/
SPI_Init(SPI1, &spi);
SPI_CalculateCRC(SPI1, DISABLE);
SPI_Cmd(SPI1, ENABLE);
SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);
// This is IC1 (transceiver)
printf2("Initializing RF IC 1\r\n");
mTransceiverIC = new Transceiver(SPI1, GPIOA, GPIO_Pin_3, GPIOA, GPIO_Pin_4, GPIOB, GPIO_Pin_2, GPIOA, GPIO_Pin_1, GPIOA, GPIO_Pin_8, GPIOA, GPIO_Pin_9);
mTransceiverIC->init();
// This is IC2 (receiver)
printf2("Initializing RF IC 2\r\n");
mReceiverIC = new Receiver(SPI1, GPIOB, GPIO_Pin_8, GPIOB, GPIO_Pin_1, GPIOC, GPIO_Pin_13, GPIOB, GPIO_Pin_9);
mReceiverIC->init();
mReceiverIC->setRSSIAdjustment(-12); // IC2 gets 6dB more signal than IC1 because of PCB layout
mInitializing = false;
}
void RadioManager::spiOff()
{
GPIO_SetBits(GPIOB, GPIO_Pin_1);
GPIO_SetBits(GPIOA, GPIO_Pin_4);
}
void RadioManager::transmitCW(VHFChannel channel)
{
mTransceiverIC->transmitCW(channel);
}
void RadioManager::start()
{
configureInterrupts();
mTransceiverIC->startReceiving(CH_87);
mReceiverIC->startReceiving(CH_88);
GPS::instance().setDelegate(this);
}
void RadioManager::configureInterrupts()
{
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
// Set up interrupt for PB9 (RX/TX bit clock) on EXTI line 9
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource9);
EXTI_InitStruct.EXTI_Line = EXTI_Line9;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
// Set up interrupt for PA1 (RX/TX bit clock) on EXTI line 1
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource1);
EXTI_InitStruct.EXTI_Line = EXTI_Line1;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
void RadioManager::processEvent(Event *e)
{
ClockEvent *ce = static_cast<ClockEvent*>(e);
mUTC = ce->mTime;
// Evaluate the state of the transceiver IC and our queue ...
if ( mTransceiverIC->assignedTXPacket() == NULL ) {
if ( !mTXQueue->empty() ) {
// There is no current TX operation pending, so we assign one
TXPacket *packet = NULL;
mTXQueue->pop(packet);
ASSERT(packet);
VHFChannel txChannel = packet->channel();
// Do we need to swap channels?
if ( txChannel != mTransceiverIC->channel() ) {
//printf2("RadioManager swapping channels for ICs\r\n");
// The receiver needs to be explicitly told to switch channels
mReceiverIC->switchToChannel(alternateChannel(txChannel));
}
//printf2("RadioManager assigned TX packet\r\n");
// The transceiver will switch channel if the packet channel is different
mTransceiverIC->assignTXPacket(packet);
}
}
}
VHFChannel RadioManager::alternateChannel(VHFChannel channel)
{
// TODO: Delegate this to the ChannelManager
return channel == CH_88 ? CH_87 : CH_88;
}
void RadioManager::onBitClock(uint8_t ic)
{
if ( mInitializing )
return;
if ( ic == 1 )
mTransceiverIC->onBitClock();
else
mReceiverIC->onBitClock();
}
void RadioManager::timeSlotStarted(uint32_t slotNumber)
{
if ( mInitializing )
return;
mTransceiverIC->timeSlotStarted(slotNumber);
mReceiverIC->timeSlotStarted(slotNumber);
}
void RadioManager::scheduleTransmission(TXPacket *packet)
{
if ( mTXQueue->push(packet) ) {
//printf2("RadioManager queued TX packet for channel %d\r\n", packet->channel());
}
else {
printf2("RadioManager rejected TX packet for channel %d\r\n", packet->channel());
TXPacketPool::instance().deleteTXPacket(packet);
}
}
extern "C" {
void EXTI9_5_IRQHandler(void)
{
if ( EXTI_GetITStatus(EXTI_Line9) != RESET ) {
RadioManager::instance().onBitClock(2);
EXTI_ClearITPendingBit(EXTI_Line9);
}
}
void EXTI1_IRQHandler(void)
{
if ( EXTI_GetITStatus(EXTI_Line1) != RESET ) {
RadioManager::instance().onBitClock(1);
EXTI_ClearITPendingBit(EXTI_Line1);
}
}
}

49
src/RadioManager.hpp Normal file
View File

@ -0,0 +1,49 @@
/*
* RadioManager.hpp
*
* Created on: May 21, 2016
* Author: peter
*/
#ifndef RADIOMANAGER_HPP_
#define RADIOMANAGER_HPP_
#include "Receiver.hpp"
#include "Transceiver.hpp"
#include "GPS.hpp"
#include "TXPacket.hpp"
#include "CircularQueue.hpp"
#include "EventQueue.hpp"
#include "AISChannels.h"
class RadioManager : public GPSDelegate, public EventConsumer
{
public:
static RadioManager &instance();
void init();
void start();
void onBitClock(uint8_t ic);
void timeSlotStarted(uint32_t slotNumber);
void scheduleTransmission(TXPacket *p);
bool initialized();
void processEvent(Event *e);
void transmitCW(VHFChannel channel);
VHFChannel alternateChannel(VHFChannel channel);
private:
RadioManager();
void spiOff();
void configureInterrupts();
private:
Transceiver *mTransceiverIC;
Receiver *mReceiverIC;
bool mInitializing;
CircularQueue<TXPacket*> *mTXQueue;
time_t mUTC;
};
#endif /* RADIOMANAGER_HPP_ */

20
src/RadioState.hpp Normal file
View File

@ -0,0 +1,20 @@
/*
* RadioState.hpp
*
* Created on: May 21, 2016
* Author: peter
*/
#ifndef RADIOSTATE_HPP_
#define RADIOSTATE_HPP_
typedef enum {
RADIO_RECEIVING,
RADIO_TRANSMITTING
} RadioState;
// By default, we are in receiving mode
static volatile RadioState gRadioState = RADIO_RECEIVING;
#endif /* RADIOSTATE_HPP_ */

256
src/Receiver.cpp Normal file
View File

@ -0,0 +1,256 @@
/*
* Receiver.cpp
*
* Created on: May 21, 2016
* Author: peter
*/
#include "Receiver.hpp"
#include "EZRadioPRO.h"
#include "Events.hpp"
#include "EventQueue.hpp"
#include "NoiseFloorDetector.hpp"
Receiver::Receiver(SPI_TypeDef *spi, GPIO_TypeDef *sdnPort, uint16_t sdnPin, GPIO_TypeDef *csPort, uint16_t csPin, GPIO_TypeDef *gpio1Port, uint16_t gpio1Pin,
GPIO_TypeDef *gpio3Port, uint16_t gpio3Pin)
: RFIC(spi, sdnPort, sdnPin, csPort, csPin, gpio1Port, gpio1Pin, gpio3Port, gpio3Pin)
{
mSlotBitNumber = 0xffff;
mSwitchAtNextSlot = false;
}
Receiver::~Receiver()
{
}
VHFChannel Receiver::channel()
{
return mChannel;
}
bool Receiver::init()
{
printf2("Configuring IC\r\n");
configure();
mRXPacket = RXPacketPool::instance().newRXPacket();
resetBitScanner();
return true;
}
void Receiver::startReceiving(VHFChannel channel)
{
mChannel = channel;
startListening(mChannel);
resetBitScanner();
}
void Receiver::switchToChannel(VHFChannel channel)
{
mSwitchAtNextSlot = true;
mSwitchToChannel = channel;
}
void Receiver::startListening(VHFChannel channel)
{
mChannel = channel;
RX_OPTIONS options;
options.channel = AIS_CHANNELS[channel].ordinal;
options.condition = 0;
options.rx_len = 0;
options.next_state1 = 0;
options.next_state2 = 0;
options.next_state3 = 0;
configureGPIOs();
sendCmd (START_RX, &options, sizeof options, NULL, 0);
}
void Receiver::resetBitScanner()
{
mBitWindow = 0;
mBitCount = 0;
mOneBitCount = 0;
mLastNRZIBit = 0xff;
mRXByte = 0;
mBitState = BIT_STATE_PREAMBLE_SYNC;
ASSERT(mRXPacket);
mRXPacket->reset();
}
void Receiver::onBitClock()
{
// Don't waste time processing bits when the transceiver is transmitting
if ( gRadioState == RADIO_TRANSMITTING )
return;
uint8_t rssi = 0;
uint8_t bit = GPIO_ReadInputDataBit(mGPIO1P, mGPIO1Pin);
processNRZIBit(bit);
if ( (mSlotBitNumber != 0xffff) && (mSlotBitNumber++ == CCA_SLOT_BIT) ) {
rssi = readRSSI();
rssi += mRSSIAdjustment;
NoiseFloorDetector::instance().report(mChannel, rssi);
mRXPacket->setRSSI(rssi);
}
}
void Receiver::timeSlotStarted(uint32_t slot)
{
// This should never be called while transmitting. Transmissions start after the slot boundary and end before the end of it.
//assert(gRadioState == RADIO_RECEIVING);
if ( gRadioState != RADIO_RECEIVING )
printf2(" **** WTF??? Transmitting past slot boundary? **** \r\n");
mSlotBitNumber = 0;
if ( mBitState == BIT_STATE_IN_PACKET )
return;
mRXPacket->setSlot(slot);
if ( mSwitchAtNextSlot ) {
mSwitchAtNextSlot = false;
startReceiving(mSwitchToChannel);
}
}
void Receiver::processNRZIBit(uint8_t bit)
{
if ( mLastNRZIBit == 0xff ) {
mLastNRZIBit = bit;
return;
}
uint8_t decodedBit = !(mLastNRZIBit ^ bit);
switch (mBitState) {
case BIT_STATE_PREAMBLE_SYNC: {
mLastNRZIBit = bit;
mBitWindow <<= 1;
mBitWindow |= decodedBit;
/*
* By checking for the last few training bits plus the HDLC start flag,
* we gain enough confidence that this is not random noise.
*/
if ( mBitWindow == 0b1010101001111110 || mBitWindow == 0b0101010101111110 ) {
mBitState = BIT_STATE_IN_PACKET;
mRXPacket->setChannel(mChannel);
}
break;
}
case BIT_STATE_IN_PACKET: {
if ( mRXPacket->size() >= MAX_AIS_RX_PACKET_SIZE ) {
// Start over
startReceiving(mChannel);
//resetBitScanner();
return;
}
if ( mOneBitCount >= 7 ) {
// Bad packet!
resetBitScanner();
startReceiving(mChannel);
return;
}
mLastNRZIBit = bit;
mBitWindow <<= 1;
mBitWindow |= decodedBit;
if ( (mBitWindow & 0x00ff) == 0x7E ) {
mBitState = BIT_STATE_PREAMBLE_SYNC;
pushPacket();
startReceiving(mChannel);
}
else {
addBit(decodedBit);
}
break;
}
}
}
bool Receiver::addBit(uint8_t bit)
{
bool result = true;
if ( bit ) {
++mOneBitCount;
}
else {
// Don't put stuffed bits into the packet
if ( mOneBitCount == 5 )
result = false;
mOneBitCount = 0;
}
if ( result ) {
mRXByte <<= 1;
mRXByte |= bit;
++mBitCount;
}
if ( mBitCount == 8 ) {
// Commit to the packet!
mRXPacket->addByte(mRXByte);
mBitCount = 0;
mRXByte = 0;
}
return result;
}
void Receiver::pushPacket()
{
AISPacketEvent *p = static_cast<AISPacketEvent*>(EventPool::instance().newEvent(AIS_PACKET_EVENT));
if ( p == NULL ) {
printf2("AISPacket allocation failed\r\n");
return;
}
p->mPacket = mRXPacket;
mRXPacket = RXPacketPool::instance().newRXPacket();
ASSERT(mRXPacket);
EventQueue::instance().push(p);
}
void Receiver::configureGPIOs()
{
// Configure MCU pin for RFIC GPIO1 as input (RX_DATA below)
GPIO_InitTypeDef gpio;
gpio.GPIO_Pin = mGPIO1Pin;
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_Speed = GPIO_Speed_Level_1;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(mGPIO1P, &gpio);
/*
* Configure radio GPIOs for RX:
* GPIO 0: Don't care
* GPIO 1: RX_DATA
* GPIO 2: Don't care
* GPIO 3: RX_TX_DATA_CLK
* NIRQ : SYNC_WORD_DETECT
*/
GPIO_PIN_CFG_PARAMS gpiocfg;
gpiocfg.GPIO0 = 0x00; // No change
gpiocfg.GPIO1 = 0x14; // RX data bits
gpiocfg.GPIO2 = 0x00; // No change
gpiocfg.GPIO3 = 0x1F; // RX/TX data clock
gpiocfg.NIRQ = 0x1A; // Sync word detect
gpiocfg.SDO = 0x00; // No change
gpiocfg.GENCFG = 0x00; // No change
sendCmd(GPIO_PIN_CFG, &gpiocfg, sizeof gpiocfg, &gpiocfg, sizeof gpiocfg);
}

59
src/Receiver.hpp Normal file
View File

@ -0,0 +1,59 @@
/*
* Receiver.hpp
*
* Created on: May 21, 2016
* Author: peter
*/
#ifndef RECEIVER_HPP_
#define RECEIVER_HPP_
#include "RXPacket.hpp"
#include "RadioState.hpp"
#include "RFIC.hpp"
#include "AISChannels.h"
class Receiver : public RFIC
{
public:
Receiver(SPI_TypeDef *spi,
GPIO_TypeDef *sdnPort,
uint16_t sdnPin,
GPIO_TypeDef *csPort,
uint16_t csPin,
GPIO_TypeDef *gpio1Port,
uint16_t gpio1Pin,
GPIO_TypeDef *gpio3Port,
uint16_t gpio3Pin);
virtual ~Receiver();
bool init();
VHFChannel channel();
virtual void startReceiving(VHFChannel channel);
virtual void onBitClock();
virtual void timeSlotStarted(uint32_t slot);
void processNRZIBit(uint8_t level);
bool addBit(uint8_t bit);
void pushPacket();
void startListening(VHFChannel channel);
void switchToChannel(VHFChannel channel);
private:
void resetBitScanner();
void configureGPIOs();
protected:
RXPacket *mRXPacket;
uint16_t mBitWindow;
uint8_t mLastNRZIBit;
uint32_t mBitCount;
uint32_t mOneBitCount;
BitState mBitState;
uint8_t mRXByte;
VHFChannel mChannel;
uint16_t mSlotBitNumber;
bool mSwitchAtNextSlot;
VHFChannel mSwitchToChannel;
};
#endif /* RECEIVER_HPP_ */

126
src/TXPacket.cpp Normal file
View File

@ -0,0 +1,126 @@
/*
* TXPacket.cpp
*
* Created on: Dec 12, 2015
* Author: peter
*/
#include <cstring>
#include <cassert>
#include "TXPacket.hpp"
TXPacket::TXPacket ()
{
reset();
}
void TXPacket::configure(VHFChannel channel, time_t txTime)
{
mChannel = channel;
mTXTime = txTime;
}
TXPacket::~TXPacket ()
{
}
void TXPacket::reset()
{
mSize = 0;
mPosition = 0;
mChannel = CH_87;
mTXTime = 0;
memset(mPacket, 0, sizeof mPacket);
}
uint16_t TXPacket::size()
{
return mSize;
}
time_t TXPacket::txTime()
{
return mTXTime;
}
VHFChannel TXPacket::channel()
{
return mChannel;
}
void TXPacket::addBit(uint8_t bit)
{
ASSERT(mSize < MAX_AIS_TX_PACKET_SIZE);
uint16_t index = mSize / 8;
uint8_t offset = mSize % 8;
if ( bit )
mPacket[index] |= ( 1 << offset );
++mSize;
}
void TXPacket::pad()
{
uint16_t rem = 8 - mSize % 8;
for ( uint16_t i = 0; i < rem; ++i )
addBit(0);
}
bool TXPacket::eof()
{
if ( mSize == 0 )
return true;
return mPosition > mSize - 1;
}
uint8_t TXPacket::nextBit()
{
ASSERT(mPosition < mSize);
uint16_t index = mPosition / 8;
uint8_t offset = mPosition % 8;
++mPosition;
return (mPacket[index] & ( 1 << offset )) != 0;
}
///////////////////////////////////////////////////////////////////////////////
//
// TXPacketPool
//
///////////////////////////////////////////////////////////////////////////////
TXPacketPool &TXPacketPool::instance()
{
static TXPacketPool __instance;
return __instance;
}
void TXPacketPool::init()
{
mPool = new ObjectPool<TXPacket>(4);
}
TXPacket *TXPacketPool::newTXPacket(VHFChannel channel, time_t txTime)
{
TXPacket *p = mPool->get();
if ( !p )
return p;
p->reset();
p->configure(channel, txTime);
return p;
}
void TXPacketPool::deleteTXPacket(TXPacket* p)
{
ASSERT(p);
mPool->put(p);
}

61
src/TXPacket.hpp Normal file
View File

@ -0,0 +1,61 @@
/*
* TXPacket.hpp
*
* Created on: Dec 12, 2015
* Author: peter
*/
#ifndef TXPACKET_HPP_
#define TXPACKET_HPP_
#include <inttypes.h>
#include <time.h>
#include "globals.h"
#include "ObjectPool.hpp"
#include "AISChannels.h"
class TXPacket
{
public:
friend class TXPacketPool;
TXPacket ();
void addBit(uint8_t bit);
void pad();
uint16_t size();
// Iterator pattern for transmitting bit-by-bit
bool eof();
uint8_t nextBit();
VHFChannel channel();
time_t txTime();
private:
~TXPacket ();
void configure(VHFChannel channel, time_t txTime);
void reset();
private:
uint8_t mPacket[MAX_AIS_TX_PACKET_SIZE/8+1];
uint16_t mSize;
uint16_t mPosition;
VHFChannel mChannel;
time_t mTXTime;
};
class TXPacketPool
{
public:
static TXPacketPool &instance();
void init();
TXPacket *newTXPacket(VHFChannel channel, time_t txTime);
void deleteTXPacket(TXPacket*);
private:
ObjectPool<TXPacket> *mPool;
};
#endif /* TXPACKET_HPP_ */

164
src/TXPowerSettings.h Normal file
View File

@ -0,0 +1,164 @@
/*
* power.h
*
* Created on: May 8, 2016
* Author: peter
*/
#ifndef TXPOWERSETTINGS_H_
#define TXPOWERSETTINGS_H_
// Define if board uses the Skyworks 66100 front end module
#define USING_FEM
#ifdef USING_FEM
#define MAX_TX_LEVEL 27;
#define MIN_TX_LEVEL -27;
#else
#define MAX_TX_LEVEL 20;
#define MIN_TX_LEVEL -27;
#endif
#include <inttypes.h>
/*
* Table settings derived from Silabs AN 900. Enumeration is for convenience and type safety. PWR_PXX = +XXdBm, PWR_MXX = -XXdBm
*/
typedef enum {
#ifdef USING_FEM
PWR_P27 = 0,
PWR_P26,
PWR_P25,
PWR_P24,
PWR_P23,
PWR_P22,
PWR_P21,
PWR_P20,
#else
PWR_P20 = 0,
#endif
PWR_P19,
PWR_P18,
PWR_P17,
PWR_P16,
PWR_P15,
PWR_P14,
PWR_P13,
PWR_P12,
PWR_P11,
PWR_P10,
PWR_P09,
PWR_P08,
PWR_P07,
PWR_P06,
PWR_P05,
PWR_P04,
PWR_P03,
PWR_P02,
PWR_P01,
PWR_P00,
PWR_M01,
PWR_M02,
PWR_M03,
PWR_M04,
PWR_M05,
PWR_M06,
PWR_M07,
PWR_M08,
PWR_M09,
PWR_M10,
PWR_M11,
PWR_M12,
PWR_M13,
PWR_M14,
PWR_M15,
PWR_M16,
PWR_M17,
PWR_M18,
PWR_M19,
PWR_M20,
PWR_M21,
PWR_M22,
PWR_M23,
PWR_M24,
PWR_M25,
PWR_M26,
PWR_M27
}
tx_power_level;
typedef struct {
tx_power_level level; // For convenience
uint8_t pa_mode; // PA Mode
uint8_t pa_level; // PA power level (native parameter)
uint8_t pa_bias_clkduty; // PA bias clock duty
uint8_t bypass; // Desired state of BYP pin on Skyworks 66100 FEM
}
pa_params;
static const pa_params POWER_TABLE[] = {
#ifdef USING_FEM
{PWR_P27, 0x09, 0x11, 0x11, 0x01},
{PWR_P26, 0x09, 0x0d, 0x10, 0x01},
{PWR_P25, 0x09, 0x0d, 0x0d, 0x01},
{PWR_P24, 0x09, 0x0a, 0x0f, 0x01},
{PWR_P23, 0x09, 0x07, 0x15, 0x01},
{PWR_P22, 0x09, 0x09, 0x0e, 0x01},
{PWR_P21, 0x09, 0x09, 0x0d, 0x01},
#endif
{PWR_P20, 0x08, 0x5f, 0x00, 0x00},
{PWR_P19, 0x08, 0x3d, 0x00, 0x00},
{PWR_P18, 0x08, 0x32, 0x00, 0x00},
{PWR_P17, 0x08, 0x2b, 0x00, 0x00},
{PWR_P16, 0x08, 0x25, 0x00, 0x00},
{PWR_P15, 0x08, 0x21, 0x00, 0x00},
{PWR_P14, 0x08, 0x1d, 0x00, 0x00},
{PWR_P13, 0x08, 0x19, 0x00, 0x00},
{PWR_P12, 0x08, 0x16, 0x00, 0x00},
{PWR_P11, 0x08, 0x14, 0x00, 0x00},
{PWR_P10, 0x08, 0x12, 0x00, 0x00},
{PWR_P09, 0x08, 0x10, 0x00, 0x00},
{PWR_P08, 0x08, 0x0e, 0x00, 0x00},
{PWR_P07, 0x08, 0x14, 0xc0, 0x00},
{PWR_P06, 0x08, 0x11, 0xc0, 0x00},
{PWR_P05, 0x09, 0x25, 0x25, 0x00},
{PWR_P04, 0x09, 0x23, 0x23, 0x00},
{PWR_P03, 0x09, 0x21, 0x21, 0x00},
{PWR_P02, 0x09, 0x1f, 0x1f, 0x00},
{PWR_P01, 0x09, 0x1d, 0x1d, 0x00},
{PWR_P00, 0x09, 0x1c, 0x1b, 0x00},
{PWR_M01, 0x09, 0x1a, 0x1a, 0x00},
{PWR_M02, 0x09, 0x19, 0x18, 0x00},
{PWR_M03, 0x09, 0x18, 0x16, 0x00},
{PWR_M04, 0x09, 0x16, 0x16, 0x00},
{PWR_M05, 0x09, 0x14, 0x15, 0x00},
{PWR_M06, 0x09, 0x14, 0x13, 0x00},
{PWR_M07, 0x09, 0x12, 0x13, 0x00},
{PWR_M08, 0x09, 0x11, 0x12, 0x00},
{PWR_M09, 0x09, 0x11, 0x10, 0x00},
{PWR_M10, 0x09, 0x0f, 0x10, 0x00},
{PWR_M11, 0x09, 0x0f, 0x0e, 0x00},
{PWR_M12, 0x09, 0x0e, 0x0d, 0x00},
{PWR_M13, 0x09, 0x0d, 0x0d, 0x00},
{PWR_M14, 0x09, 0x0c, 0x0c, 0x00},
{PWR_M15, 0x09, 0x0b, 0x0c, 0x00},
{PWR_M16, 0x09, 0x0b, 0x0b, 0x00},
{PWR_M17, 0x09, 0x09, 0x0c, 0x00},
{PWR_M18, 0x09, 0x08, 0x0c, 0x00},
{PWR_M19, 0x09, 0x08, 0x0b, 0x00},
{PWR_M20, 0x09, 0x07, 0x0b, 0x00},
{PWR_M21, 0x09, 0x07, 0x0a, 0x00},
{PWR_M22, 0x09, 0x07, 0x09, 0x00},
{PWR_M23, 0x09, 0x07, 0x08, 0x00},
{PWR_M24, 0x09, 0x07, 0x07, 0x00},
{PWR_M25, 0x09, 0x07, 0x06, 0x00},
{PWR_M26, 0x09, 0x05, 0x08, 0x00},
{PWR_M27, 0x09, 0x05, 0x07, 0x00}
};
#endif /* TXPOWERSETTINGS_H_ */

153
src/TXScheduler.cpp Normal file
View File

@ -0,0 +1,153 @@
/*
* TXScheduler.cpp
*
* Created on: Dec 12, 2015
* Author: peter
*/
#include "TXScheduler.hpp"
#include "EventQueue.hpp"
#include "AISMessages.hpp"
#include "TXPacket.hpp"
#include <vector>
#include <string>
#include <sstream>
//#include <diag/Trace.h>
#include <stdlib.h>
#include "RadioManager.hpp"
#include "ChannelManager.hpp"
#include "printf2.h"
using namespace std;
TXScheduler::TXScheduler ()
{
EventQueue::instance().addObserver(this, GPS_FIX_EVENT | CLOCK_EVENT);
mPositionReportChannel = CH_87;
mStaticDataChannel = CH_87;
mUTC = 0;
mTesting = false;
EEPROM::instance().readStationData(mStationData);
printf2("Read station data from EEPROM:\r\n");
printf2("MMSI: %d\r\n", mStationData.mmsi);
printf2("CS: %s\r\n", mStationData.callsign);
printf2("Name: %s\r\n", mStationData.name);
}
TXScheduler::~TXScheduler ()
{
}
void TXScheduler::startTXTesting()
{
mTesting = true;
}
void TXScheduler::processEvent(Event *event)
{
//printf2("-> TXScheduler::processEvent()\r\n");
#ifndef ENABLE_TX
return;
#endif
switch(event->type()) {
case GPS_FIX_EVENT: {
if ( mTesting )
return;
//if ( Radio::instance().isCalibratingRSSI() )
// return;
GPSFIXEvent *gfe = static_cast<GPSFIXEvent*> (event);
//printf2("UTC: %d\r\n", mUTC);
// We do not schedule transmissions if the ChannelManager is not sure what channels are in use yet
if ( !ChannelManager::instance().channelsDetermined() )
return;
// TODO: This is UGLY. Stop using modulus and start counting from previous timestamps
// A class B only transmits when its internal GPS is working, so we tie these to GPS updates.
if ( RadioManager::instance().initialized() && mUTC && (mUTC % DEFAULT_TX_INTERVAL) == 0) {
TXPacket *p1 = TXPacketPool::instance().newTXPacket(mPositionReportChannel, mUTC);
if ( !p1 ) {
printf2("Unable to allocate TX packet for message 18, will try again later\r\n");
break;
}
AISMessage18 msg;
msg.latitude = gfe->mLat;
msg.longitude = gfe->mLng;
msg.sog = gfe->mSpeed;
msg.cog = gfe->mCOG;
msg.utc = gfe->mUTC;
msg.encode (*p1);
RadioManager::instance ().scheduleTransmission (p1);
// Our next position report should be on the other channel
mPositionReportChannel = RadioManager::instance().alternateChannel(mPositionReportChannel);
}
if ( RadioManager::instance().initialized() && mUTC && (mUTC % MSG_24_TX_INTERVAL) == 0 ) {
TXPacket *p2 = TXPacketPool::instance().newTXPacket(mStaticDataChannel, mUTC+2);
if ( !p2 ) {
printf2("Unable to allocate TX packet for 24A\r\n");
break;
}
AISMessage24A msg2;
msg2.encode(*p2);
RadioManager::instance().scheduleTransmission(p2);
TXPacket *p3 = TXPacketPool::instance().newTXPacket(mStaticDataChannel, mUTC+7);
if ( !p3 ) {
printf2("Unable to allocate TX packet for 24B\r\n");
break;
}
AISMessage24B msg3;
msg3.encode(*p3);
RadioManager::instance().scheduleTransmission(p3);
// Our next static data report should be on the other channel
mStaticDataChannel = RadioManager::instance().alternateChannel(mStaticDataChannel);
}
break;
}
case CLOCK_EVENT: {
// This is reliable and independent of GPS update frequency which could change to something other than 1Hz
ClockEvent *c = static_cast<ClockEvent*>(event);
mUTC = c->mTime;
if ( RadioManager::instance().initialized() && mTesting && mUTC % 1 == 0 ) {
scheduleTestPacket();
printf2("Scheduled test packet\r\n");
}
break;
}
default:
break;
}
//printf2("<- TXScheduler::processEvent()\r\n");
}
void TXScheduler::scheduleTestPacket()
{
/*
TXPacket *p = TXPacketPool::instance().newTXPacket(AIS_CHANNELS[rand() % 2 + 18].vhf, mUTC);
if ( !p )
return;
for ( int i = 0; i < MAX_AIS_TX_PACKET_SIZE; ++i ) {
p->addBit(rand() % 2);
}
RadioManager::instance().scheduleTransmission(p);
*/
}

37
src/TXScheduler.hpp Normal file
View File

@ -0,0 +1,37 @@
/*
* TXScheduler.hpp
*
* Created on: Dec 12, 2015
* Author: peter
*/
#ifndef TXSCHEDULER_HPP_
#define TXSCHEDULER_HPP_
#include "Events.hpp"
#include <time.h>
#include "ObjectPool.hpp"
#include "AISChannels.h"
#include "EEPROM.hpp"
class TXScheduler : public EventConsumer
{
public:
TXScheduler ();
virtual
~TXScheduler ();
void processEvent(Event *event);
void startTXTesting();
private:
void scheduleTestPacket();
private:
VHFChannel mPositionReportChannel;
VHFChannel mStaticDataChannel;
time_t mUTC;
bool mTesting;
StationData mStationData;
};
#endif /* TXSCHEDULER_HPP_ */

232
src/Transceiver.cpp Normal file
View File

@ -0,0 +1,232 @@
/*
* Transceiver.cpp
*
* Created on: May 21, 2016
* Author: peter
*/
#include "Transceiver.hpp"
#include "NoiseFloorDetector.hpp"
#include "LEDManager.hpp"
#include "EventQueue.hpp"
#include "Events.hpp"
#include "EZRadioPRO.h"
#include "AISChannels.h"
Transceiver::Transceiver(SPI_TypeDef *spi, GPIO_TypeDef *sdnPort, uint16_t sdnPin, GPIO_TypeDef *csPort, uint16_t csPin, GPIO_TypeDef *gpio1Port, uint16_t gpio1Pin,
GPIO_TypeDef *gpio3Port, uint16_t gpio3Pin, GPIO_TypeDef *ctxPort, uint16_t ctxPin, GPIO_TypeDef *bypPort, uint16_t bypPin)
: Receiver(spi, sdnPort, sdnPin, csPort, csPin, gpio1Port, gpio1Pin, gpio3Port, gpio3Pin)
{
mTXPacket = NULL;
mCTXPort = ctxPort;
mCTXPin = ctxPin;
mBYPPort = bypPort;
mBYPPin = bypPin;
}
void Transceiver::configure()
{
Receiver::configure();
// Anything transmitter specific goes here
SET_PROPERTY_PARAMS p;
p.Group = 0x20;
p.NumProperties = 1;
p.StartProperty = 0x00;
p.Data[0] = 0x20 | 0x08 | 0x03; // Synchronous direct mode from GPIO 1 with 2GFSK modulation
sendCmd(SET_PROPERTY, &p, 4, NULL, 0);
#ifdef USE_BT_04
/*
* Set the TX filter coefficients for a BT of 0.4 as per ITU spec for AIS
* http://community.silabs.com/t5/Wireless/si4463-GMSK-spectrum-spread/m-p/160063/highlight/false#M9438
*/
uint8_t data[] = { 0x52, 0x4f, 0x45, 0x37, 0x28, 0x1a, 0x10, 0x09, 0x04 };
p.Group = 0x22;
p.NumProperties = 9;
p.StartProperty = 0x0f;
memcpy(p.Data, data, 9);
sendCmd(SET_PROPERTY, &p, 12, NULL, 0);
#endif
}
void Transceiver::transmitCW(VHFChannel channel)
{
startReceiving(channel);
configureForTX(TX_POWER_LEVEL);
SET_PROPERTY_PARAMS p;
p.Group = 0x20;
p.NumProperties = 1;
p.StartProperty = 0x00;
p.Data[0] = 0x08;
sendCmd (SET_PROPERTY, &p, 4, NULL, 0);
TX_OPTIONS options;
options.channel = AIS_CHANNELS[channel].ordinal;
options.condition = 8 << 4;
options.tx_len = 0;
options.tx_delay = 0;
options.repeats = 0;
sendCmd (START_TX, &options, sizeof options, NULL, 0);
CHIP_STATUS_REPLY chip_status;
sendCmd (GET_CHIP_STATUS, NULL, 0, &chip_status, sizeof chip_status);
if (chip_status.Current & 0x08) {
printf2 ("Error starting TX:\r\n");
printf2 ("%.8x %.8x %.8x\r\n", chip_status.Pending,
chip_status.Current, chip_status.Error);
}
else {
printf2 ("Radio transmitting carrier on channel %d (%.3fMHz)\r\n", AIS_CHANNELS[channel].itu, AIS_CHANNELS[channel].frequency);
}
}
void Transceiver::configureForTX(tx_power_level powerLevel)
{
/*
* Configure MCU pin for RFIC GPIO1 as output
*/
GPIO_InitTypeDef gpio;
gpio.GPIO_Pin = mGPIO1Pin;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Speed = GPIO_Speed_Level_1;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(mGPIO1P, &gpio);
/*
* Configure radio GPIOs for TX:
* GPIO 0: Don't care
* GPIO 1: INPUT of TX bits
* GPIO 2: Don't care
* GPIO 3: RX_TX_DATA_CLK
* NIRQ : SYNC_WORD_DETECT
*/
GPIO_PIN_CFG_PARAMS gpiocfg;
gpiocfg.GPIO0 = 0x00; // No change
gpiocfg.GPIO1 = 0x04; // Input
gpiocfg.GPIO2 = 0x00; // No change
gpiocfg.GPIO3 = 0x1F; // RX/TX data clock
gpiocfg.NIRQ = 0x1A; // Sync word detect
gpiocfg.SDO = 0x00; // No change
gpiocfg.GENCFG = 0x00; // No change
sendCmd(GPIO_PIN_CFG, &gpiocfg, sizeof gpiocfg, &gpiocfg, sizeof gpiocfg);
const pa_params &pwr = POWER_TABLE[powerLevel];
SET_PROPERTY_PARAMS p;
p.Group = 0x22;
p.NumProperties = 3;
p.StartProperty = 0x00;
p.Data[0] = pwr.pa_mode;
p.Data[1] = pwr.pa_level;
p.Data[2] = pwr.pa_bias_clkduty;
sendCmd(SET_PROPERTY, &p, 6, NULL, 0);
// BYP setting is in table
if ( pwr.bypass )
GPIO_SetBits(mBYPPort, mBYPPin);
else
GPIO_ResetBits(mBYPPort, mBYPPin);
// CTX goes high
GPIO_SetBits(mCTXPort, mCTXPin);
}
void Transceiver::assignTXPacket(TXPacket *p)
{
ASSERT(!mTXPacket);
mTXPacket = p;
}
TXPacket* Transceiver::assignedTXPacket()
{
return mTXPacket;
}
void Transceiver::onBitClock()
{
if ( gRadioState == RADIO_RECEIVING ) {
Receiver::onBitClock();
// If we have an assigned packet and we're on the correct channel, at the right bit of the time slot,
// and the RSSI is within 6dB of the noise floor for this channel, then fire!!!
if ( mSlotBitNumber == CCA_SLOT_BIT+1 && mTXPacket && mTXPacket->channel() == mChannel && mRXPacket->rssi() < NoiseFloorDetector::instance().getNoiseFloor(mChannel) + 12 ) {
startTransmitting();
}
}
else {
if ( mTXPacket->eof() ) {
LEDManager::instance().blink(LEDManager::BLUE_LED);
startReceiving(mChannel);
printf2("Transmitted %d bit packet on channel %d\r\n", mTXPacket->size(), AIS_CHANNELS[mChannel].itu);
TXPacketPool::instance().deleteTXPacket(mTXPacket);
mTXPacket = NULL;
gRadioState = RADIO_RECEIVING;
}
else {
uint8_t bit = mTXPacket->nextBit();
if ( bit )
GPIO_SetBits(mGPIO1P, mGPIO1Pin);
else
GPIO_ResetBits(mGPIO1P, mGPIO1Pin);
}
}
}
void Transceiver::timeSlotStarted(uint32_t slot)
{
Receiver::timeSlotStarted(slot);
// Switch channel if we have a transmission scheduled and we're not on the right channel
if ( gRadioState == RADIO_RECEIVING && mTXPacket && mTXPacket->channel() != mChannel )
startReceiving(mTXPacket->channel());
}
void Transceiver::startTransmitting()
{
// Configure the RFIC GPIOs for transmission
// Configure the pin for GPIO 1 as output
// Set TX power level
// Start transmitting
gRadioState = RADIO_TRANSMITTING;
configureForTX(TX_POWER_LEVEL);
//ASSERT(false);
TX_OPTIONS options;
options.channel = AIS_CHANNELS[mChannel].ordinal;
options.condition = 0;
options.tx_len = 0;
options.tx_delay = 0;
options.repeats = 0;
sendCmd(START_TX, &options, sizeof options, NULL, 0);
/*
* Check if something went wrong
*/
CHIP_STATUS_REPLY chip_status;
sendCmd(GET_CHIP_STATUS, NULL, 0, &chip_status, sizeof chip_status);
if ( chip_status.Current & 0x08 ) {
printf2("Error starting TX: %.8x %.8x %.8x\r\n", chip_status.Pending, chip_status.Current, chip_status.Error);
gRadioState = RADIO_RECEIVING;
startReceiving(mChannel);
}
}
void Transceiver::startReceiving(VHFChannel channel)
{
// Make sure the FEM is in RX mode - CTX goes low
GPIO_ResetBits(mCTXPort, mCTXPin);
Receiver::startReceiving(channel);
}

52
src/Transceiver.hpp Normal file
View File

@ -0,0 +1,52 @@
/*
* Transceiver.hpp
*
* Created on: May 21, 2016
* Author: peter
*/
#ifndef TRANSCEIVER_HPP_
#define TRANSCEIVER_HPP_
#include "Receiver.hpp"
#include "TXPacket.hpp"
class Transceiver : public Receiver
{
public:
Transceiver(SPI_TypeDef *spi,
GPIO_TypeDef *sdnPort,
uint16_t sdnPin,
GPIO_TypeDef *csPort,
uint16_t csPin,
GPIO_TypeDef *gpio1Port,
uint16_t gpio1Pin,
GPIO_TypeDef *gpio3Port,
uint16_t gpio3Pin,
GPIO_TypeDef *ctxPort,
uint16_t ctxPin,
GPIO_TypeDef *bypPort,
uint16_t bypPin);
void onBitClock();
void timeSlotStarted(uint32_t slot);
void assignTXPacket(TXPacket *p);
TXPacket *assignedTXPacket();
void startReceiving(VHFChannel channel);
void transmitCW(VHFChannel channel);
protected:
void configure();
private:
void startTransmitting();
void configureForTX(tx_power_level pwr);
private:
TXPacket *mTXPacket;
GPIO_TypeDef *mCTXPort;
uint16_t mCTXPin;
GPIO_TypeDef *mBYPPort;
uint16_t mBYPPin;
};
#endif /* TRANSCEIVER_HPP_ */

257
src/Utils.cpp Normal file
View File

@ -0,0 +1,257 @@
#include "Utils.hpp"
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <sstream>
#include <vector>
#include <limits>
#include <cmath>
#include <errno.h>
#include <cassert>
#include <sstream>
#include <iomanip>
#include "MetricUnits.hpp"
#include "stm32f30x.h"
static bool __LITTLE_ENDIAN = false;
static uint32_t __junk = 0;
static const uint16_t CRC16_XMODEM_TABLE[] =
{ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108,
0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231,
0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339,
0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462,
0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a,
0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653,
0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b,
0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4,
0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc,
0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5,
0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd,
0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6,
0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae,
0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97,
0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f,
0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188,
0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080,
0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9,
0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1,
0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea,
0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2,
0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db,
0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3,
0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c,
0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844,
0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d,
0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75,
0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e,
0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26,
0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f,
0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17,
0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 };
class EndianessCheck
{
public:
EndianessCheck()
{
uint32_t v = 1;
uint8_t *b = (uint8_t*) &v;
__LITTLE_ENDIAN = *b == 0x01;
}
};
EndianessCheck __checkendianess;
using namespace std;
void Utils::makeLowercase(string &s)
{
std::transform(s.begin(), s.end(), s.begin(), static_cast<int (*)(int)>(tolower));
}
void Utils::makeUppercase(string &s)
{
std::transform(s.begin(), s.end(), s.begin(), static_cast<int (*)(int)>(toupper));
}
void Utils::trim(string &str)
{
static string whitespace(" \t\f\v\n\r");
string::size_type pos = str.find_last_not_of(whitespace);
if ( pos != string::npos ) {
str.erase(pos + 1);
pos = str.find_first_not_of(whitespace);
if ( pos != string::npos )
str.erase(0, pos);
}
else
str.erase(str.begin(), str.end());
}
string Utils::toString(int i)
{
ostringstream o;
o << i;
return o.str();
}
string Utils::toString(unsigned i)
{
ostringstream o;
o << i;
return o.str();
}
string Utils::toString(double d)
{
ostringstream o;
o << fixed << d;
return o.str();
}
string Utils::toString(long long l)
{
ostringstream o;
o << l;
return o.str();
}
int Utils::toInt(const std::string &s)
{
if ( s.empty() )
return 0;
return atoi(s.c_str());
}
double Utils::toDouble(const std::string &s)
{
if ( s.empty() )
return 0.0;
return atof(s.c_str());
}
long long Utils::toInt64(const std::string &s)
{
if ( s.empty() )
return 0;
return atoll(s.c_str());
}
double Utils::latitudeFromNMEA(const string &decimal, const string &hemisphere)
{
// Latitude always starts with 4 integers: 2 for degrees, 2 for minutes . N decimal minutes
string degStr = decimal.substr(0, 2);
string decStr = decimal.substr(2);
double deg = Utils::toDouble(degStr);
double min = Utils::toDouble(decStr);
return (hemisphere == "N" ? 1 : -1) * (deg + min / 60.0f);
}
double Utils::longitudeFromNMEA(const string &decimal, const string &hemisphere)
{
// Longitude always starts with 5 integers: 3 for degrees, 2 for minutes . N decimal minutes
string degStr = decimal.substr(0, 3);
string decStr = decimal.substr(3);
double deg = Utils::toDouble(degStr);
double min = Utils::toDouble(decStr);
return (hemisphere == "E" ? 1 : -1) * (deg + min / 60.0f);
}
void Utils::delay(uint32_t ticks)
{
while (ticks--)
__junk <<= 2;
}
uint16_t Utils::reverseBits(uint16_t crc)
{
uint16_t result = 0;
for ( size_t i = 0; i < 16; ++i ) {
result <<= 1;
result |= ((crc & (1 << i)) >> i);
}
return result;
}
uint16_t Utils::crc16(uint8_t *bytes, uint16_t length)
{
uint16_t crc = 0xffff;
for ( uint16_t b = 0; b < length; ++b ) {
crc = ((crc << 8) & 0xff00) ^ CRC16_XMODEM_TABLE[((crc >> 8) & 0xff) ^ bytes[b]];
}
return Utils::reverseBits(~crc);
}
void Utils::tokenize(const string &str, char delim, vector<string> &result)
{
if ( str.empty() )
return;
string token;
result.clear();
for ( unsigned i = 0; i < str.length(); ++i )
{
if ( str[i] == delim )
{
result.push_back(token);
token.erase();
}
else
token += str[i];
}
result.push_back(token);
}
uint32_t Utils::coordinateToUINT32(double value)
{
uint32_t val = fabs(value) * 600000;
if ( value < 0.0 )
val = ~val + 1;
return val;
}
double Utils::coordinateFromUINT32(uint32_t value, uint8_t numBits)
{
if ( value & (1 << (numBits - 1)) ) {
value = ~value;
for ( int i = numBits - 1; i < 32; ++i )
value &= ~(1 << i);
return (double) value / -600000.0f;
}
else {
return (double) value / 600000.0f;
}
}
double arcInRadians(double lat1, double lon1, double lat2, double lon2)
{
double dLat = (lat2 - lat1) * DEG_TO_RAD;
double dLon = (lon2 - lon1) * DEG_TO_RAD;
double lat1Rad = lat1 * DEG_TO_RAD;
double lat2Rad = lat2 * DEG_TO_RAD;
double a = sin(dLat/2.0) * sin(dLat/2.0) + sin(dLon/2.0) * sin(dLon/2) * cos(lat1Rad) * cos(lat2Rad);
double radians = 2 * asin(min(1.0, sqrt(a)));
return radians;
}
double Utils::haversineDistance(double lat1, double lon1, double lat2, double lon2)
{
return EARTH_RADIUS_IN_METERS * arcInRadians(lat1, lon1, lat2, lon2);
}
bool Utils::inISR()
{
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk );
}

46
src/Utils.hpp Normal file
View File

@ -0,0 +1,46 @@
#ifndef __UTILS_H__
#define __UTILS_H__
#include <string>
#include <vector>
#include <inttypes.h>
using namespace std;
class Utils
{
public:
static void delay(uint32_t ticks);
static void makeLowercase(std::string &);
static void makeUppercase(std::string &);
static void trim(std::string &s);
static void tokenize(const string &str, char delim, vector<string> &result);
static std::string toString(int);
static std::string toString(unsigned);
static std::string toString(double);
static std::string toString(long long);
static int toInt(const std::string &);
static long long toInt64(const std::string &);
static double toDouble(const std::string &);
static double latitudeFromNMEA(const string &decimal, const string &hemisphere);
static double longitudeFromNMEA(const string &decimal, const string &hemisphere);
static double haversineDistance(double lat1, double lon1, double lat2, double lon2);
static uint16_t crc16(uint8_t* data, uint16_t len);
static uint16_t reverseBits(uint16_t data);
static uint32_t coordinateToUINT32(double value);
static double coordinateFromUINT32(uint32_t aisCoordinate, uint8_t numBits);
static bool inISR();
};
#endif
/*
Local Variables: ***
mode: c++ ***
End: ***
*/

22
src/_assert.h Normal file
View File

@ -0,0 +1,22 @@
/*
* _assert.h
*
* Created on: May 28, 2016
* Author: peter
*/
#ifndef ASSERT_H_
#define ASSERT_H_
#include "globals.h"
#include <cassert>
#include "printf2.h"
#ifdef DEV_MODE
#define ASSERT(b) {if (!(b)) {printf2_now("\r\nAssertion failed at %s:%d\r\n", __FILE__, __LINE__); while(1);}}
#else
#define ASSERT(b) assert(b);
#endif
#endif /* ASSERT_H_ */

50
src/_write.c Normal file
View File

@ -0,0 +1,50 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// Do not include on semihosting and when freestanding
#if !defined(OS_USE_SEMIHOSTING) && !(__STDC_HOSTED__ == 0)
// ----------------------------------------------------------------------------
#include <errno.h>
#include "diag/Trace.h"
// ----------------------------------------------------------------------------
// When using retargetted configurations, the standard write() system call,
// after a long way inside newlib, finally calls this implementation function.
// Based on the file descriptor, it can send arrays of characters to
// different physical devices.
// Currently only the output and error file descriptors are tested,
// and the characters are forwarded to the trace device, mainly
// for demonstration purposes. Adjust it for your specific needs.
// For freestanding applications this file is not used and can be safely
// ignored.
ssize_t
_write (int fd, const char* buf, size_t nbyte);
ssize_t
_write (int fd __attribute__((unused)), const char* buf __attribute__((unused)),
size_t nbyte __attribute__((unused)))
{
#if defined(TRACE)
// STDOUT and STDERR are routed to the trace device
if (fd == 1 || fd == 2)
{
return trace_write (buf, nbyte);
}
#endif // TRACE
errno = ENOSYS;
return -1;
}
// ----------------------------------------------------------------------------
#endif // !defined(OS_USE_SEMIHOSTING) && !(__STDC_HOSTED__ == 0)

104
src/globals.h Normal file
View File

@ -0,0 +1,104 @@
/*
* defines.h
*
* Created on: Dec 12, 2015
* Author: peter
*/
#ifndef GLOBALS_H_
#define GLOBALS_H_
#include "radio_config.h"
#include "TXPowerSettings.h"
#define MODEL "SEAWAIS_02"
#define REVISION "0.5.1"
/*
* If this is defined, the device transmits low-power carrier at a nominal frequency of 162.075Mhz,
* two channels above AIS. This is meant to be used for crystal calibration only
*/
//#define CALIBRATION_MODE 1
// Undefine to disable transmission
#define ENABLE_TX 1
#ifdef ENABLE_TX
//#define TX_TEST_MODE
#endif
#ifdef CALIBRATION_MODE
#define TX_POWER_LEVEL PWR_M27
#else
#ifdef TX_TEST_MODE
#define TX_POWER_LEVEL PWR_P16
#else
#define TX_POWER_LEVEL PWR_M10
#endif
#endif
#define ENABLE_TERMINAL
#define OUTPUT_GPS_NMEA
#define ENABLE_PRINTF2
// Some AIS messages can occupy 5 time slots (5x256 = 1280). We call it quits at 2 slots.
#define MAX_AIS_RX_PACKET_SIZE 512
#ifdef TX_TEST_MODE
// For testing, it's necessary to transmit longer packets for a basic RTL-SDR receiver to not "miss" them.
#define MAX_AIS_TX_PACKET_SIZE 1280
#else
// As a class B transponder, we never transmit anything bigger than 256 bits
#define MAX_AIS_TX_PACKET_SIZE 300
#endif
// Maximum allowed backlog in TX queue
#define MAX_TX_PACKETS_IN_QUEUE 4
// Define this to set BT=0.4 for GMSK (as per ITU spec for AIS). Default is 0.5
#define USE_BT_04
// Default interval for message 18 (position report)
#define DEFAULT_TX_INTERVAL 30
// Default interval for message 24 A&B (static data report)
#define MSG_24_TX_INTERVAL 180
// Maximum number of seconds to spend in CCA mode before giving up transmission of current packet (must be less than DEFAULT_TX_INTERVAL)
#define MAX_CCA_TIME 20
#define CCA_SLOT_BIT 8
// Extra debugging using halting assertions
#define DEV_MODE 1
/*
* Ideally, these should come from some non-volatile storage on board, but for now
* we just define them here.
*
* NOTE: It is against US Coast Guard regulations to transmit AIS messages with an invalid MMSI. Consider yourself warned.
* That said, just about everyone developing AIS equipment does this at some point, typically in lab environments.
*
* Also, manufacturers of AIS transmitters must program the MMSI, station name and other metadata on behalf of
* their customers prior to shipping to a US address, as users are prohibited from altering those.
*
* Of course, regulations were written at a time when none would design and build their own AIS equipment in
* an open-source fashion, so they are (as usual) at least a decade behind the technology curve.
*/
#define STATION_MMSI 987654321
#define STATION_NAME "TEST STATION 01"
#define STATION_CALLSIGN "N0NNNN"
#endif /* GLOBALS_H_ */

148
src/main.cpp Normal file
View File

@ -0,0 +1,148 @@
//
// This file is part of the GNU ARM Eclipse distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
#include "printf2.h"
#include "GPS.hpp"
#include "RadioManager.hpp"
#include "EventQueue.hpp"
#include "LEDManager.hpp"
#include "TXPacket.hpp"
#include "RXPacketProcessor.hpp"
#include "TXScheduler.hpp"
#include "Utils.hpp"
#include "system_stm32f30x.h"
#include "stm32f30x.h"
#include "DataTerminal.hpp"
#include "TXScheduler.hpp"
#include "DebugPrinter.hpp"
#include "EEPROM.hpp"
// ----------------------------------------------------------------------------
//
// Standalone STM32F3 empty sample (trace via DEBUG).
//
// Trace support is enabled by adding the TRACE macro definition.
// By default the trace messages are forwarded to the DEBUG output,
// but can be rerouted to any device or completely suppressed, by
// changing the definitions required in system/src/diag/trace_impl.c
// (currently OS_USE_TRACE_ITM, OS_USE_TRACE_SEMIHOSTING_DEBUG/_STDOUT).
//
// ----- main() ---------------------------------------------------------------
// Sample pragmas to cope with warnings. Please note the related line at
// the end of this function, used to pop the compiler diagnostics status.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wmissing-declarations"
#pragma GCC diagnostic ignored "-Wreturn-type"
/*
* DO NOT FORGET to modify this function when changing GPIO pins elsewhere in code.
*/
void configureUnusedPins();
int
main(int argc, char* argv[])
{
// At this stage the system clock should have already been configured
// at high speed.
printf2_Init(230400);
EEPROM::instance().init();
/*
struct StationData __d;
__d.mmsi = 987654321;
__d.len = 0;
__d.beam = 0;
strcpy(__d.callsign, "0N0000");
strcpy(__d.name, "TEST STATION 01");
EEPROM::instance().writeStationData(__d);
*/
EventQueue::instance().init();
EventPool::instance().init();
TXPacketPool::instance().init();
RXPacketPool::instance().init();
LEDManager::instance().clear();
TXScheduler txScheduler;
DebugPrinter __db;
#ifdef ENABLE_TERMINAL
DataTerminal::instance().init();
#endif
#if defined CALIBRATION_MODE
RadioManager::instance().init();
RadioManager::instance().transmitCW(CH_86);
#elif defined TX_TEST_MODE
Radio::instance().init();
GPS::instance().init();
Radio::instance().start();
Radio::instance().startReceiving(4);
txScheduler.startTXTesting();
#else
RXPacketProcessor packetProcessor;
RadioManager::instance().init();
GPS::instance().init();
RadioManager::instance().start();
#endif
configureUnusedPins();
// Dispatch events issued by ISRs
printf2("Starting main event loop\r\n");
while (true) {
EventQueue::instance().dispatch();
}
// If execution jumps here, something is seriously fucked up!!!
assert(false);
}
void configureUnusedPins()
{
// ST Micro recommends configuring all unused GPIOs as low outputs
GPIO_InitTypeDef gpio;
// Port A pins
uint32_t pins = GPIO_Pin_15 | GPIO_Pin_11 | GPIO_Pin_12;
gpio.GPIO_Pin = pins;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_Speed = GPIO_Speed_Level_1;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio);
GPIO_ResetBits(GPIOA, pins);
// Port B pins
pins = GPIO_Pin_0 | GPIO_Pin_5;
gpio.GPIO_Pin = pins;
GPIO_Init(GPIOB, &gpio);
GPIO_ResetBits(GPIOB, pins);
// Port C pins
pins = GPIO_Pin_14 | GPIO_Pin_15;
gpio.GPIO_Pin = pins;
GPIO_Init(GPIOC, &gpio);
GPIO_ResetBits(GPIOC, pins);
}
#pragma GCC diagnostic pop
// ----------------------------------------------------------------------------

100
src/printf2.cpp Normal file
View File

@ -0,0 +1,100 @@
/*
* printf2.c
*
* Created on: Mar 1, 2016
* Author: peter
*/
#include "stm32f30x.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "Events.hpp"
#include "Utils.hpp"
#include "EventQueue.hpp"
#include <diag/Trace.h>
void printf2_Init(int baudrate)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_7);
USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
}
void USART_putc(USART_TypeDef* USARTx, char c)
{
while (!(USARTx->ISR & 0x00000040))
;
USART_SendData(USARTx, c);
}
void USART_puts(USART_TypeDef* USARTx, const char *s)
{
for ( int i = 0; s[i] != 0; ++i )
USART_putc(USARTx, s[i]);
}
static char __buffer[256];
void printf2_now(const char *format, ...)
{
va_list list;
va_start(list, format);
vsnprintf(__buffer, 255, format, list);
va_end(list);
USART_puts(USART2, __buffer);
}
#ifdef ENABLE_PRINTF2
void printf2(const char *format, ...)
{
if ( Utils::inISR() ) {
DebugEvent *e = static_cast<DebugEvent*>(EventPool::instance().newEvent(DEBUG_EVENT));
if ( e == NULL )
return;
va_list list;
va_start(list, format);
vsnprintf(e->mBuffer, 255, format, list);
va_end(list);
EventQueue::instance().push(e);
}
else {
va_list list;
va_start(list, format);
vsnprintf(__buffer, 255, format, list);
va_end(list);
USART_puts(USART2, __buffer);
}
}
#else
void printf2(const char *format, ...)
{
va_list list;
va_start(list, format);
vsnprintf(__buffer, 255, format, list);
va_end(list);
trace_printf(__buffer);
}
#endif

20
src/printf2.h Normal file
View File

@ -0,0 +1,20 @@
/*
* printf2.h
*
* Created on: Mar 1, 2016
* Author: peter
*/
#ifndef PRINTF2_H_
#define PRINTF2_H_
void printf2_Init(int baudrate);
// printf2 automatically determines ISR vs thread mode and schedules or prints immediately depending
void printf2(const char *format, ...);
// printf2_now outputs to UART immediately, disregarding ISR vs thread mode
void printf2_now(const char *format, ...);
#endif /* PRINTF2_H_ */

14
src/radio_config.h Normal file
View File

@ -0,0 +1,14 @@
/*
* radio_config.h
*
* Created on: Dec 6, 2015
* Author: peter
*/
#ifndef RADIO_CONFIG_STUB_H_
#define RADIO_CONFIG_STUB_H_
#include "radio_config_ph_all_channels.h"
#endif /* RADIO_CONFIG_H_ */

1095
src/radio_config_ph.h Normal file

File diff suppressed because it is too large Load Diff

1090
src/radio_config_ph2.h Normal file

File diff suppressed because it is too large Load Diff

1088
src/radio_config_ph3.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

934
src/radio_config_rev2.h Normal file
View File

@ -0,0 +1,934 @@
/*! @file radio_config.h
* @brief This file contains the automatically generated
* configurations.
*
* @n WDS GUI Version: 3.2.9.0
* @n Device: Si4463 Rev.: C2
*
* @b COPYRIGHT
* @n Silicon Laboratories Confidential
* @n Copyright 2015 Silicon Laboratories, Inc.
* @n http://www.silabs.com
*/
#ifndef RADIO_CONFIG_H_
#define RADIO_CONFIG_H_
// USER DEFINED PARAMETERS
// Define your own parameters here
// INPUT DATA
/*
// Crys_freq(Hz): 30000000 Crys_tol(ppm): 15 IF_mode: 2 High_perf_Ch_Fil: 1 OSRtune: 0 Ch_Fil_Bw_AFC: 0 ANT_DIV: 0 PM_pattern: 15
// MOD_type: 3 Rsymb(sps): 9600 Fdev(Hz): 2400 RXBW(Hz): 150000 Manchester: 0 AFC_en: 0 Rsymb_error: 0.1 Chip-Version: 2
// RF Freq.(MHz): 161.975 API_TC: 29 fhst: 25000 inputBW: 0 BERT: 0 RAW_dout: 0 D_source: 1 Hi_pfm_div: 1
// API_ARR_Det_en: 0 Fdev_error: 0 API_ETSI: 0
//
// # RX IF frequency is -468750 Hz
// # WB filter 3 (BW = 23.15 kHz); NB-filter 3 (BW = 23.15 kHz)
//
// Modulation index: 0.5
*/
// CONFIGURATION PARAMETERS
#define RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ 30000000L
#define RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER 0x00
#define RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH 0x00
#define RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP 0x03
#define RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET 0xF000
#include "si446x_patch.h"
// CONFIGURATION COMMANDS
/*
// Command: RF_POWER_UP
// Description: Command to power-up the device and select the operational mode and functionality.
*/
#define RF_POWER_UP 0x02, 0x81, 0x00, 0x01, 0xC9, 0xC3, 0x80
/*
// Command: RF_GPIO_PIN_CFG
// Description: Configures the GPIO pins.
*/
#define RF_GPIO_PIN_CFG 0x13, 0x03, 0x14, 0x02, 0x11, 0x1B, 0x00, 0x00
/*
// Set properties: RF_GLOBAL_XO_TUNE_1
// Number of properties: 1
// Group ID: 0x00
// Start ID: 0x00
// Default values: 0x40,
// Descriptions:
// GLOBAL_XO_TUNE - Configure the internal capacitor frequency tuning bank for the crystal oscillator.
*/
#define RF_GLOBAL_XO_TUNE_1 0x11, 0x00, 0x01, 0x00, 0x30
/*
// Set properties: RF_GLOBAL_CONFIG_1
// Number of properties: 1
// Group ID: 0x00
// Start ID: 0x03
// Default values: 0x20,
// Descriptions:
// GLOBAL_CONFIG - Global configuration settings.
*/
#define RF_GLOBAL_CONFIG_1 0x11, 0x00, 0x01, 0x03, 0x20
/*
// Set properties: RF_PREAMBLE_CONFIG_1
// Number of properties: 1
// Group ID: 0x10
// Start ID: 0x04
// Default values: 0x21,
// Descriptions:
// PREAMBLE_CONFIG - General configuration bits for the Preamble field.
*/
#define RF_PREAMBLE_CONFIG_1 0x11, 0x10, 0x01, 0x04, 0x21
/*
// Set properties: RF_MODEM_MOD_TYPE_12
// Number of properties: 12
// Group ID: 0x20
// Start ID: 0x00
// Default values: 0x02, 0x80, 0x07, 0x0F, 0x42, 0x40, 0x01, 0xC9, 0xC3, 0x80, 0x00, 0x06,
// Descriptions:
// MODEM_MOD_TYPE - Selects the type of modulation. In TX mode, additionally selects the source of the modulation.
// MODEM_MAP_CONTROL - Controls polarity and mapping of transmit and receive bits.
// MODEM_DSM_CTRL - Miscellaneous control bits for the Delta-Sigma Modulator (DSM) in the PLL Synthesizer.
// MODEM_DATA_RATE_2 - Unsigned 24-bit value used to determine the TX data rate
// MODEM_DATA_RATE_1 - Unsigned 24-bit value used to determine the TX data rate
// MODEM_DATA_RATE_0 - Unsigned 24-bit value used to determine the TX data rate
// MODEM_TX_NCO_MODE_3 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
// MODEM_TX_NCO_MODE_2 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
// MODEM_TX_NCO_MODE_1 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
// MODEM_TX_NCO_MODE_0 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
// MODEM_FREQ_DEV_2 - 17-bit unsigned TX frequency deviation word.
// MODEM_FREQ_DEV_1 - 17-bit unsigned TX frequency deviation word.
*/
#define RF_MODEM_MOD_TYPE_12 0x11, 0x20, 0x0C, 0x00, 0x0B, 0x00, 0x07, 0x02, 0x71, 0x00, 0x05, 0xC9, 0xC3, 0x80, 0x00, 0x00
/*
// Set properties: RF_MODEM_FREQ_DEV_0_1
// Number of properties: 1
// Group ID: 0x20
// Start ID: 0x0C
// Default values: 0xD3,
// Descriptions:
// MODEM_FREQ_DEV_0 - 17-bit unsigned TX frequency deviation word.
*/
#define RF_MODEM_FREQ_DEV_0_1 0x11, 0x20, 0x01, 0x0C, 0xD2
/*
// Set properties: RF_MODEM_TX_RAMP_DELAY_12
// Number of properties: 12
// Group ID: 0x20
// Start ID: 0x18
// Default values: 0x01, 0x00, 0x08, 0x03, 0xC0, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x4B,
// Descriptions:
// MODEM_TX_RAMP_DELAY - TX ramp-down delay setting.
// MODEM_MDM_CTRL - MDM control.
// MODEM_IF_CONTROL - Selects Fixed-IF, Scaled-IF, or Zero-IF mode of RX Modem operation.
// MODEM_IF_FREQ_2 - the IF frequency setting (an 18-bit signed number).
// MODEM_IF_FREQ_1 - the IF frequency setting (an 18-bit signed number).
// MODEM_IF_FREQ_0 - the IF frequency setting (an 18-bit signed number).
// MODEM_DECIMATION_CFG1 - Specifies three decimator ratios for the Cascaded Integrator Comb (CIC) filter.
// MODEM_DECIMATION_CFG0 - Specifies miscellaneous parameters and decimator ratios for the Cascaded Integrator Comb (CIC) filter.
// MODEM_DECIMATION_CFG2 - Specifies miscellaneous decimator filter selections.
// MODEM_IFPKD_THRESHOLDS -
// MODEM_BCR_OSR_1 - RX BCR/Slicer oversampling rate (12-bit unsigned number).
// MODEM_BCR_OSR_0 - RX BCR/Slicer oversampling rate (12-bit unsigned number).
*/
//#define RF_MODEM_TX_RAMP_DELAY_12 0x11, 0x20, 0x0C, 0x18, 0x01, 0x00, 0x08, 0x02, 0x80, 0x00, 0xB0, 0x10, 0x0C, 0xE8, 0x00, 0x4E
#define RF_MODEM_TX_RAMP_DELAY_12 0x11, 0x20, 0x0C, 0x18, 0x01, 0x00, 0x08, 0x02, 0x80, 0x00, 0xB0, 0x11, 0x0C, 0xE8, 0x00, 0x4E
/*
// Set properties: RF_MODEM_BCR_NCO_OFFSET_2_12
// Number of properties: 12
// Group ID: 0x20
// Start ID: 0x24
// Default values: 0x06, 0xD3, 0xA0, 0x06, 0xD3, 0x02, 0xC0, 0x00, 0x00, 0x23, 0x83, 0x69,
// Descriptions:
// MODEM_BCR_NCO_OFFSET_2 - RX BCR NCO offset value (an unsigned 22-bit number).
// MODEM_BCR_NCO_OFFSET_1 - RX BCR NCO offset value (an unsigned 22-bit number).
// MODEM_BCR_NCO_OFFSET_0 - RX BCR NCO offset value (an unsigned 22-bit number).
// MODEM_BCR_GAIN_1 - The unsigned 11-bit RX BCR loop gain value.
// MODEM_BCR_GAIN_0 - The unsigned 11-bit RX BCR loop gain value.
// MODEM_BCR_GEAR - RX BCR loop gear control.
// MODEM_BCR_MISC1 - Miscellaneous control bits for the RX BCR loop.
// MODEM_BCR_MISC0 - Miscellaneous RX BCR loop controls.
// MODEM_AFC_GEAR - RX AFC loop gear control.
// MODEM_AFC_WAIT - RX AFC loop wait time control.
// MODEM_AFC_GAIN_1 - Sets the gain of the PLL-based AFC acquisition loop, and provides miscellaneous control bits for AFC functionality.
// MODEM_AFC_GAIN_0 - Sets the gain of the PLL-based AFC acquisition loop, and provides miscellaneous control bits for AFC functionality.
*/
//#define RF_MODEM_BCR_NCO_OFFSET_2_12 0x11, 0x20, 0x0C, 0x24, 0x06, 0x8D, 0xB9, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x12, 0x80, 0x69
#define RF_MODEM_BCR_NCO_OFFSET_2_12 0x11, 0x20, 0x0C, 0x24, 0x06, 0x8D, 0xB9, 0x06, 0xD3, 0x02, 0x10, 0x00, 0x00, 0x12, 0x80, 0x69
/*
// Set properties: RF_MODEM_AFC_LIMITER_1_3
// Number of properties: 3
// Group ID: 0x20
// Start ID: 0x30
// Default values: 0x00, 0x40, 0xA0,
// Descriptions:
// MODEM_AFC_LIMITER_1 - Set the AFC limiter value.
// MODEM_AFC_LIMITER_0 - Set the AFC limiter value.
// MODEM_AFC_MISC - Specifies miscellaneous AFC control bits.
*/
#define RF_MODEM_AFC_LIMITER_1_3 0x11, 0x20, 0x03, 0x30, 0x01, 0x5C, 0xA0
/*
// Set properties: RF_MODEM_AGC_CONTROL_1
// Number of properties: 1
// Group ID: 0x20
// Start ID: 0x35
// Default values: 0xE0,
// Descriptions:
// MODEM_AGC_CONTROL - Miscellaneous control bits for the Automatic Gain Control (AGC) function in the RX Chain.
*/
#define RF_MODEM_AGC_CONTROL_1 0x11, 0x20, 0x01, 0x35, 0xE0
/*
// Set properties: RF_MODEM_AGC_WINDOW_SIZE_12
// Number of properties: 12
// Group ID: 0x20
// Start ID: 0x38
// Default values: 0x11, 0x10, 0x10, 0x0B, 0x1C, 0x40, 0x00, 0x00, 0x2B, 0x0C, 0xA4, 0x03,
// Descriptions:
// MODEM_AGC_WINDOW_SIZE - Specifies the size of the measurement and settling windows for the AGC algorithm.
// MODEM_AGC_RFPD_DECAY - Sets the decay time of the RF peak detectors.
// MODEM_AGC_IFPD_DECAY - Sets the decay time of the IF peak detectors.
// MODEM_FSK4_GAIN1 - Specifies the gain factor of the secondary branch in 4(G)FSK ISI-suppression.
// MODEM_FSK4_GAIN0 - Specifies the gain factor of the primary branch in 4(G)FSK ISI-suppression.
// MODEM_FSK4_TH1 - 16 bit 4(G)FSK slicer threshold.
// MODEM_FSK4_TH0 - 16 bit 4(G)FSK slicer threshold.
// MODEM_FSK4_MAP - 4(G)FSK symbol mapping code.
// MODEM_OOK_PDTC - Configures the attack and decay times of the OOK Peak Detector.
// MODEM_OOK_BLOPK - Configures the slicing reference level of the OOK Peak Detector.
// MODEM_OOK_CNT1 - OOK control.
// MODEM_OOK_MISC - Selects the detector(s) used for demodulation of an OOK signal, or for demodulation of a (G)FSK signal when using the asynchronous demodulator.
*/
#define RF_MODEM_AGC_WINDOW_SIZE_12 0x11, 0x20, 0x0C, 0x38, 0x11, 0x11, 0x11, 0x80, 0x1A, 0x20, 0x00, 0x00, 0x28, 0x0C, 0xA4, 0x23
/*
// Set properties: RF_MODEM_RAW_CONTROL_5
// Number of properties: 5
// Group ID: 0x20
// Start ID: 0x45
// Default values: 0x02, 0x00, 0xA3, 0x02, 0x80,
// Descriptions:
// MODEM_RAW_CONTROL - Defines gain and enable controls for raw / nonstandard mode.
// MODEM_RAW_EYE_1 - 11 bit eye-open detector threshold.
// MODEM_RAW_EYE_0 - 11 bit eye-open detector threshold.
// MODEM_ANT_DIV_MODE - Antenna diversity mode settings.
// MODEM_ANT_DIV_CONTROL - Specifies controls for the Antenna Diversity algorithm.
*/
#define RF_MODEM_RAW_CONTROL_5 0x11, 0x20, 0x05, 0x45, 0x03, 0x00, 0x85, 0x02, 0x00
/*
// Set properties: RF_MODEM_RSSI_JUMP_THRESH_4
// Number of properties: 4
// Group ID: 0x20
// Start ID: 0x4B
// Default values: 0x0C, 0x01, 0x00, 0x40,
// Descriptions:
// MODEM_RSSI_JUMP_THRESH - Configures the RSSI Jump Detection threshold.
// MODEM_RSSI_CONTROL - Control of the averaging modes and latching time for reporting RSSI value(s).
// MODEM_RSSI_CONTROL2 - RSSI Jump Detection control.
// MODEM_RSSI_COMP - RSSI compensation value.
*/
#define RF_MODEM_RSSI_JUMP_THRESH_4 0x11, 0x20, 0x04, 0x4B, 0x06, 0x09, 0x14, 0x40
/*
// Set properties: RF_MODEM_RAW_SEARCH2_2
// Number of properties: 2
// Group ID: 0x20
// Start ID: 0x50
// Default values: 0x00, 0x08,
// Descriptions:
// MODEM_RAW_SEARCH2 - Defines and controls the search period length for the Moving Average and Min-Max detectors.
// MODEM_CLKGEN_BAND - Select PLL Synthesizer output divider ratio as a function of frequency band.
*/
#define RF_MODEM_RAW_SEARCH2_2 0x11, 0x20, 0x02, 0x50, 0x94, 0x0D
/*
// Set properties: RF_MODEM_SPIKE_DET_2
// Number of properties: 2
// Group ID: 0x20
// Start ID: 0x54
// Default values: 0x00, 0x00,
// Descriptions:
// MODEM_SPIKE_DET - Configures the threshold for (G)FSK Spike Detection.
// MODEM_ONE_SHOT_AFC - Configures parameters for th e One Shot AFC function and for BCR timing/acquisition.
*/
#define RF_MODEM_SPIKE_DET_2 0x11, 0x20, 0x02, 0x54, 0x03, 0x07
/*
// Set properties: RF_MODEM_RSSI_MUTE_1
// Number of properties: 1
// Group ID: 0x20
// Start ID: 0x57
// Default values: 0x00,
// Descriptions:
// MODEM_RSSI_MUTE - Configures muting of the RSSI to avoid false RSSI interrupts.
*/
#define RF_MODEM_RSSI_MUTE_1 0x11, 0x20, 0x01, 0x57, 0x00
/*
// Set properties: RF_MODEM_DSA_CTRL1_5
// Number of properties: 5
// Group ID: 0x20
// Start ID: 0x5B
// Default values: 0x00, 0x00, 0x00, 0x00, 0x00,
// Descriptions:
// MODEM_DSA_CTRL1 - Configures parameters for the Signal Arrival Detection circuit block and algorithm.
// MODEM_DSA_CTRL2 - Configures parameters for the Signal Arrival Detection circuit block and algorithm.
// MODEM_DSA_QUAL - Configures parameters for the Eye Opening qualification m ethod of the Signal Arrival Detection algorithm.
// MODEM_DSA_RSSI - Signal Arrival Detect RSSI Qualifier Config
// MODEM_DSA_MISC - Miscellaneous detection of signal arrival bits.
*/
#define RF_MODEM_DSA_CTRL1_5 0x11, 0x20, 0x05, 0x5B, 0x40, 0x04, 0x04, 0x78, 0x20
/*
// Set properties: RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12
// Number of properties: 12
// Group ID: 0x21
// Start ID: 0x00
// Default values: 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01,
// Descriptions:
// MODEM_CHFLT_RX1_CHFLT_COE13_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE12_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE11_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE10_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE9_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE8_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE7_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE6_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE5_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE4_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE3_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE2_7_0 - Filter coefficients for the first set of RX filter coefficients.
*/
#define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12 0x11, 0x21, 0x0C, 0x00, 0x7E, 0x64, 0x1B, 0xBA, 0x58, 0x0B, 0xDD, 0xCE, 0xD6, 0xE6, 0xF6, 0x00
/*
// Set properties: RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12
// Number of properties: 12
// Group ID: 0x21
// Start ID: 0x0C
// Default values: 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F, 0xFF, 0xC4, 0x30, 0x7F, 0xF5, 0xB5,
// Descriptions:
// MODEM_CHFLT_RX1_CHFLT_COE1_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE0_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COEM0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COEM1 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COEM2 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COEM3 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE13_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE12_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE11_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE10_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE9_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE8_7_0 - Filter coefficients for the second set of RX filter coefficients.
*/
#define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12 0x11, 0x21, 0x0C, 0x0C, 0x03, 0x03, 0x15, 0xF0, 0x3F, 0x00, 0x7E, 0x64, 0x1B, 0xBA, 0x58, 0x0B
/*
// Set properties: RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12
// Number of properties: 12
// Group ID: 0x21
// Start ID: 0x18
// Default values: 0xB8, 0xDE, 0x05, 0x17, 0x16, 0x0C, 0x03, 0x00, 0x15, 0xFF, 0x00, 0x00,
// Descriptions:
// MODEM_CHFLT_RX2_CHFLT_COE7_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE6_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE5_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE4_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE3_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE2_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE1_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE0_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COEM0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COEM1 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COEM2 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COEM3 - Filter coefficients for the second set of RX filter coefficients.
*/
#define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12 0x11, 0x21, 0x0C, 0x18, 0xDD, 0xCE, 0xD6, 0xE6, 0xF6, 0x00, 0x03, 0x03, 0x15, 0xF0, 0x3F, 0x00
/*
// Set properties: RF_PA_TC_1
// Number of properties: 1
// Group ID: 0x22
// Start ID: 0x03
// Default values: 0x5D,
// Descriptions:
// PA_TC - Configuration of PA ramping parameters.
*/
#define RF_PA_TC_1 0x11, 0x22, 0x01, 0x03, 0x1D
/*
// Set properties: RF_SYNTH_PFDCP_CPFF_7
// Number of properties: 7
// Group ID: 0x23
// Start ID: 0x00
// Default values: 0x2C, 0x0E, 0x0B, 0x04, 0x0C, 0x73, 0x03,
// Descriptions:
// SYNTH_PFDCP_CPFF - Feed forward charge pump current selection.
// SYNTH_PFDCP_CPINT - Integration charge pump current selection.
// SYNTH_VCO_KV - Gain scaling factors (Kv) for the VCO tuning varactors on both the integrated-path and feed forward path.
// SYNTH_LPFILT3 - Value of resistor R2 in feed-forward path of loop filter.
// SYNTH_LPFILT2 - Value of capacitor C2 in feed-forward path of loop filter.
// SYNTH_LPFILT1 - Value of capacitors C1 and C3 in feed-forward path of loop filter.
// SYNTH_LPFILT0 - Bias current of the active amplifier in the feed-forward loop filter.
*/
#define RF_SYNTH_PFDCP_CPFF_7 0x11, 0x23, 0x07, 0x00, 0x2C, 0x0E, 0x0B, 0x04, 0x0C, 0x73, 0x03
/*
// Set properties: RF_FREQ_CONTROL_INTE_8
// Number of properties: 8
// Group ID: 0x40
// Start ID: 0x00
// Default values: 0x3C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF,
// Descriptions:
// FREQ_CONTROL_INTE - Frac-N PLL Synthesizer integer divide number.
// FREQ_CONTROL_FRAC_2 - Frac-N PLL fraction number.
// FREQ_CONTROL_FRAC_1 - Frac-N PLL fraction number.
// FREQ_CONTROL_FRAC_0 - Frac-N PLL fraction number.
// FREQ_CONTROL_CHANNEL_STEP_SIZE_1 - EZ Frequency Programming channel step size.
// FREQ_CONTROL_CHANNEL_STEP_SIZE_0 - EZ Frequency Programming channel step size.
// FREQ_CONTROL_W_SIZE - Set window gating period (in number of crystal reference clock cycles) for counting VCO frequency during calibration.
// FREQ_CONTROL_VCOCNT_RX_ADJ - Adjust target count for VCO calibration in RX mode.
*/
#define RF_FREQ_CONTROL_INTE_8 0x11, 0x40, 0x08, 0x00, 0x3B, 0x0B, 0x00, 0x00, 0x14, 0x7B, 0x20, 0xFA
/*
// Command: RF_START_RX
// Description: Switches to RX state and starts reception of a packet.
*/
#define RF_START_RX 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
/*
// Command: RF_IRCAL
// Description: Image rejection calibration.
*/
#define RF_IRCAL 0x17, 0x56, 0x10, 0xCA, 0xF0
/*
// Command: RF_IRCAL_1
// Description: Image rejection calibration.
*/
#define RF_IRCAL_1 0x17, 0x13, 0x10, 0xCA, 0xF0
/*
// Set properties: RF_GLOBAL_CLK_CFG_1
// Number of properties: 1
// Group ID: 0x00
// Start ID: 0x01
// Default values: 0x00,
// Descriptions:
// GLOBAL_CLK_CFG - Clock configuration options.
*/
#define RF_GLOBAL_CLK_CFG_1 0x11, 0x00, 0x01, 0x01, 0x00
/*
// Set properties: RF_GLOBAL_CONFIG_1_1
// Number of properties: 1
// Group ID: 0x00
// Start ID: 0x03
// Default values: 0x20,
// Descriptions:
// GLOBAL_CONFIG - Global configuration settings.
*/
#define RF_GLOBAL_CONFIG_1_1 0x11, 0x00, 0x01, 0x03, 0x20
/*
// Set properties: RF_INT_CTL_ENABLE_1
// Number of properties: 1
// Group ID: 0x01
// Start ID: 0x00
// Default values: 0x04,
// Descriptions:
// INT_CTL_ENABLE - This property provides for global enabling of the three interrupt groups (Chip, Modem and Packet Handler) in order to generate HW interrupts at the NIRQ pin.
*/
#define RF_INT_CTL_ENABLE_1 0x11, 0x01, 0x01, 0x00, 0x00
/*
// Set properties: RF_FRR_CTL_A_MODE_4
// Number of properties: 4
// Group ID: 0x02
// Start ID: 0x00
// Default values: 0x01, 0x02, 0x09, 0x00,
// Descriptions:
// FRR_CTL_A_MODE - Fast Response Register A Configuration.
// FRR_CTL_B_MODE - Fast Response Register B Configuration.
// FRR_CTL_C_MODE - Fast Response Register C Configuration.
// FRR_CTL_D_MODE - Fast Response Register D Configuration.
*/
#define RF_FRR_CTL_A_MODE_4 0x11, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00
/*
// Set properties: RF_PREAMBLE_CONFIG_STD_1_1
// Number of properties: 1
// Group ID: 0x10
// Start ID: 0x01
// Default values: 0x14,
// Descriptions:
// PREAMBLE_CONFIG_STD_1 - Configuration of reception of a packet with a Standard Preamble pattern.
*/
#define RF_PREAMBLE_CONFIG_STD_1_1 0x11, 0x10, 0x01, 0x01, 0x14
/*
// Set properties: RF_PKT_CONFIG1_1
// Number of properties: 1
// Group ID: 0x12
// Start ID: 0x06
// Default values: 0x00,
// Descriptions:
// PKT_CONFIG1 - General configuration bits for transmission or reception of a packet.
*/
#define RF_PKT_CONFIG1_1 0x11, 0x12, 0x01, 0x06, 0x40
/*
// Set properties: RF_MODEM_MOD_TYPE_12_1
// Number of properties: 12
// Group ID: 0x20
// Start ID: 0x00
// Default values: 0x02, 0x80, 0x07, 0x0F, 0x42, 0x40, 0x01, 0xC9, 0xC3, 0x80, 0x00, 0x06,
// Descriptions:
// MODEM_MOD_TYPE - Selects the type of modulation. In TX mode, additionally selects the source of the modulation.
// MODEM_MAP_CONTROL - Controls polarity and mapping of transmit and receive bits.
// MODEM_DSM_CTRL - Miscellaneous control bits for the Delta-Sigma Modulator (DSM) in the PLL Synthesizer.
// MODEM_DATA_RATE_2 - Unsigned 24-bit value used to determine the TX data rate
// MODEM_DATA_RATE_1 - Unsigned 24-bit value used to determine the TX data rate
// MODEM_DATA_RATE_0 - Unsigned 24-bit value used to determine the TX data rate
// MODEM_TX_NCO_MODE_3 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
// MODEM_TX_NCO_MODE_2 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
// MODEM_TX_NCO_MODE_1 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
// MODEM_TX_NCO_MODE_0 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
// MODEM_FREQ_DEV_2 - 17-bit unsigned TX frequency deviation word.
// MODEM_FREQ_DEV_1 - 17-bit unsigned TX frequency deviation word.
*/
#define RF_MODEM_MOD_TYPE_12_1 0x11, 0x20, 0x0C, 0x00, 0x0B, 0x00, 0x07, 0x05, 0xDC, 0x00, 0x05, 0xC9, 0xC3, 0x80, 0x00, 0x01
/*
// Set properties: RF_MODEM_FREQ_DEV_0_1_1
// Number of properties: 1
// Group ID: 0x20
// Start ID: 0x0C
// Default values: 0xD3,
// Descriptions:
// MODEM_FREQ_DEV_0 - 17-bit unsigned TX frequency deviation word.
*/
#define RF_MODEM_FREQ_DEV_0_1_1 0x11, 0x20, 0x01, 0x0C, 0xF7
/*
// Set properties: RF_MODEM_TX_RAMP_DELAY_12_1
// Number of properties: 12
// Group ID: 0x20
// Start ID: 0x18
// Default values: 0x01, 0x00, 0x08, 0x03, 0xC0, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x4B,
// Descriptions:
// MODEM_TX_RAMP_DELAY - TX ramp-down delay setting.
// MODEM_MDM_CTRL - MDM control.
// MODEM_IF_CONTROL - Selects Fixed-IF, Scaled-IF, or Zero-IF mode of RX Modem operation.
// MODEM_IF_FREQ_2 - the IF frequency setting (an 18-bit signed number).
// MODEM_IF_FREQ_1 - the IF frequency setting (an 18-bit signed number).
// MODEM_IF_FREQ_0 - the IF frequency setting (an 18-bit signed number).
// MODEM_DECIMATION_CFG1 - Specifies three decimator ratios for the Cascaded Integrator Comb (CIC) filter.
// MODEM_DECIMATION_CFG0 - Specifies miscellaneous parameters and decimator ratios for the Cascaded Integrator Comb (CIC) filter.
// MODEM_DECIMATION_CFG2 - Specifies miscellaneous decimator filter selections.
// MODEM_IFPKD_THRESHOLDS -
// MODEM_BCR_OSR_1 - RX BCR/Slicer oversampling rate (12-bit unsigned number).
// MODEM_BCR_OSR_0 - RX BCR/Slicer oversampling rate (12-bit unsigned number).
*/
#define RF_MODEM_TX_RAMP_DELAY_12_1 0x11, 0x20, 0x0C, 0x18, 0x01, 0x80, 0x08, 0x02, 0x80, 0x00, 0x70, 0x20, 0x00, 0xE8, 0x00, 0x62
/*
// Set properties: RF_MODEM_BCR_NCO_OFFSET_2_12_1
// Number of properties: 12
// Group ID: 0x20
// Start ID: 0x24
// Default values: 0x06, 0xD3, 0xA0, 0x06, 0xD3, 0x02, 0xC0, 0x00, 0x00, 0x23, 0x83, 0x69,
// Descriptions:
// MODEM_BCR_NCO_OFFSET_2 - RX BCR NCO offset value (an unsigned 22-bit number).
// MODEM_BCR_NCO_OFFSET_1 - RX BCR NCO offset value (an unsigned 22-bit number).
// MODEM_BCR_NCO_OFFSET_0 - RX BCR NCO offset value (an unsigned 22-bit number).
// MODEM_BCR_GAIN_1 - The unsigned 11-bit RX BCR loop gain value.
// MODEM_BCR_GAIN_0 - The unsigned 11-bit RX BCR loop gain value.
// MODEM_BCR_GEAR - RX BCR loop gear control.
// MODEM_BCR_MISC1 - Miscellaneous control bits for the RX BCR loop.
// MODEM_BCR_MISC0 - Miscellaneous RX BCR loop controls.
// MODEM_AFC_GEAR - RX AFC loop gear control.
// MODEM_AFC_WAIT - RX AFC loop wait time control.
// MODEM_AFC_GAIN_1 - Sets the gain of the PLL-based AFC acquisition loop, and provides miscellaneous control bits for AFC functionality.
// MODEM_AFC_GAIN_0 - Sets the gain of the PLL-based AFC acquisition loop, and provides miscellaneous control bits for AFC functionality.
*/
#define RF_MODEM_BCR_NCO_OFFSET_2_12_1 0x11, 0x20, 0x0C, 0x24, 0x05, 0x3E, 0x2D, 0x02, 0x9D, 0x00, 0xC2, 0x00, 0x54, 0x62, 0x81, 0x01
/*
// Set properties: RF_MODEM_AFC_LIMITER_1_3_1
// Number of properties: 3
// Group ID: 0x20
// Start ID: 0x30
// Default values: 0x00, 0x40, 0xA0,
// Descriptions:
// MODEM_AFC_LIMITER_1 - Set the AFC limiter value.
// MODEM_AFC_LIMITER_0 - Set the AFC limiter value.
// MODEM_AFC_MISC - Specifies miscellaneous AFC control bits.
*/
#define RF_MODEM_AFC_LIMITER_1_3_1 0x11, 0x20, 0x03, 0x30, 0x02, 0x13, 0x80
/*
// Set properties: RF_MODEM_AGC_CONTROL_1_1
// Number of properties: 1
// Group ID: 0x20
// Start ID: 0x35
// Default values: 0xE0,
// Descriptions:
// MODEM_AGC_CONTROL - Miscellaneous control bits for the Automatic Gain Control (AGC) function in the RX Chain.
*/
#define RF_MODEM_AGC_CONTROL_1_1 0x11, 0x20, 0x01, 0x35, 0xE0
/*
// Set properties: RF_MODEM_AGC_WINDOW_SIZE_12_1
// Number of properties: 12
// Group ID: 0x20
// Start ID: 0x38
// Default values: 0x11, 0x10, 0x10, 0x0B, 0x1C, 0x40, 0x00, 0x00, 0x2B, 0x0C, 0xA4, 0x03,
// Descriptions:
// MODEM_AGC_WINDOW_SIZE - Specifies the size of the measurement and settling windows for the AGC algorithm.
// MODEM_AGC_RFPD_DECAY - Sets the decay time of the RF peak detectors.
// MODEM_AGC_IFPD_DECAY - Sets the decay time of the IF peak detectors.
// MODEM_FSK4_GAIN1 - Specifies the gain factor of the secondary branch in 4(G)FSK ISI-suppression.
// MODEM_FSK4_GAIN0 - Specifies the gain factor of the primary branch in 4(G)FSK ISI-suppression.
// MODEM_FSK4_TH1 - 16 bit 4(G)FSK slicer threshold.
// MODEM_FSK4_TH0 - 16 bit 4(G)FSK slicer threshold.
// MODEM_FSK4_MAP - 4(G)FSK symbol mapping code.
// MODEM_OOK_PDTC - Configures the attack and decay times of the OOK Peak Detector.
// MODEM_OOK_BLOPK - Configures the slicing reference level of the OOK Peak Detector.
// MODEM_OOK_CNT1 - OOK control.
// MODEM_OOK_MISC - Selects the detector(s) used for demodulation of an OOK signal, or for demodulation of a (G)FSK signal when using the asynchronous demodulator.
*/
#define RF_MODEM_AGC_WINDOW_SIZE_12_1 0x11, 0x20, 0x0C, 0x38, 0x11, 0x15, 0x15, 0x80, 0x1A, 0x20, 0x00, 0x00, 0x28, 0x0C, 0x84, 0x23
/*
// Set properties: RF_MODEM_RAW_CONTROL_8
// Number of properties: 8
// Group ID: 0x20
// Start ID: 0x45
// Default values: 0x02, 0x00, 0xA3, 0x02, 0x80, 0xFF, 0x0C, 0x01,
// Descriptions:
// MODEM_RAW_CONTROL - Defines gain and enable controls for raw / nonstandard mode.
// MODEM_RAW_EYE_1 - 11 bit eye-open detector threshold.
// MODEM_RAW_EYE_0 - 11 bit eye-open detector threshold.
// MODEM_ANT_DIV_MODE - Antenna diversity mode settings.
// MODEM_ANT_DIV_CONTROL - Specifies controls for the Antenna Diversity algorithm.
// MODEM_RSSI_THRESH - Configures the RSSI threshold.
// MODEM_RSSI_JUMP_THRESH - Configures the RSSI Jump Detection threshold.
// MODEM_RSSI_CONTROL - Control of the averaging modes and latching time for reporting RSSI value(s).
*/
#define RF_MODEM_RAW_CONTROL_8 0x11, 0x20, 0x08, 0x45, 0x8F, 0x00, 0x6A, 0x02, 0x00, 0x40, 0x06, 0x00
/*
// Set properties: RF_MODEM_RSSI_CONTROL_3
// Number of properties: 3
// Group ID: 0x20
// Start ID: 0x4C
// Default values: 0x01, 0x00, 0x40,
// Descriptions:
// MODEM_RSSI_CONTROL - Control of the averaging modes and latching time for reporting RSSI value(s).
// MODEM_RSSI_CONTROL2 - RSSI Jump Detection control.
// MODEM_RSSI_COMP - RSSI compensation value.
*/
#define RF_MODEM_RSSI_CONTROL_3 0x11, 0x20, 0x03, 0x4C, 0x09, 0x1C, 0x40
/*
// Set properties: RF_MODEM_RAW_SEARCH2_2_1
// Number of properties: 2
// Group ID: 0x20
// Start ID: 0x50
// Default values: 0x00, 0x08,
// Descriptions:
// MODEM_RAW_SEARCH2 - Defines and controls the search period length for the Moving Average and Min-Max detectors.
// MODEM_CLKGEN_BAND - Select PLL Synthesizer output divider ratio as a function of frequency band.
*/
#define RF_MODEM_RAW_SEARCH2_2_1 0x11, 0x20, 0x02, 0x50, 0x94, 0x0D
/*
// Set properties: RF_MODEM_SPIKE_DET_2_1
// Number of properties: 2
// Group ID: 0x20
// Start ID: 0x54
// Default values: 0x00, 0x00,
// Descriptions:
// MODEM_SPIKE_DET - Configures the threshold for (G)FSK Spike Detection.
// MODEM_ONE_SHOT_AFC - Configures parameters for th e One Shot AFC function and for BCR timing/acquisition.
*/
#define RF_MODEM_SPIKE_DET_2_1 0x11, 0x20, 0x02, 0x54, 0x03, 0x07
/*
// Set properties: RF_MODEM_RSSI_MUTE_1_1
// Number of properties: 1
// Group ID: 0x20
// Start ID: 0x57
// Default values: 0x00,
// Descriptions:
// MODEM_RSSI_MUTE - Configures muting of the RSSI to avoid false RSSI interrupts.
*/
#define RF_MODEM_RSSI_MUTE_1_1 0x11, 0x20, 0x01, 0x57, 0x00
/*
// Set properties: RF_MODEM_DSA_CTRL1_5_1
// Number of properties: 5
// Group ID: 0x20
// Start ID: 0x5B
// Default values: 0x00, 0x00, 0x00, 0x00, 0x00,
// Descriptions:
// MODEM_DSA_CTRL1 - Configures parameters for the Signal Arrival Detection circuit block and algorithm.
// MODEM_DSA_CTRL2 - Configures parameters for the Signal Arrival Detection circuit block and algorithm.
// MODEM_DSA_QUAL - Configures parameters for the Eye Opening qualification method of the Signal Arrival Detection algorithm.
// MODEM_DSA_RSSI - Signal Arrival Detect RSSI Qualifier Config
// MODEM_DSA_MISC - Miscellaneous detection of signal arrival bits.
*/
//#define RF_MODEM_DSA_CTRL1_5_1 0x11, 0x20, 0x05, 0x5B, 0x42, 0x04, 0x04, 0x78, 0x20
#define RF_MODEM_DSA_CTRL1_5_1 0x11, 0x20, 0x05, 0x5B, 0xA2, 0x24, 0x04, 0x30, 0x20
/*
// Set properties: RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1
// Number of properties: 12
// Group ID: 0x21
// Start ID: 0x00
// Default values: 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01,
// Descriptions:
// MODEM_CHFLT_RX1_CHFLT_COE13_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE12_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE11_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE10_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE9_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE8_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE7_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE6_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE5_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE4_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE3_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE2_7_0 - Filter coefficients for the first set of RX filter coefficients.
*/
//#define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 0x11, 0x21, 0x0C, 0x00, 0xCC, 0xA1, 0x30, 0xA0, 0x21, 0xD1, 0xB9, 0xC9, 0xEA, 0x05, 0x12, 0x11
#define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 0x11, 0x21, 0x0C, 0x00, 0xFF, 0xC4, 0x30, 0x7F, 0xF5, 0xB5, 0xB8, 0xDE, 0x05, 0x17, 0x16, 0x0C
/*
// Set properties: RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1
// Number of properties: 12
// Group ID: 0x21
// Start ID: 0x0C
// Default values: 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F, 0xFF, 0xC4, 0x30, 0x7F, 0xF5, 0xB5,
// Descriptions:
// MODEM_CHFLT_RX1_CHFLT_COE1_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COE0_7_0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COEM0 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COEM1 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COEM2 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX1_CHFLT_COEM3 - Filter coefficients for the first set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE13_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE12_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE11_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE10_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE9_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE8_7_0 - Filter coefficients for the second set of RX filter coefficients.
*/
//#define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 0x11, 0x21, 0x0C, 0x0C, 0x0A, 0x04, 0x15, 0xFC, 0x03, 0x00, 0xCC, 0xA1, 0x30, 0xA0, 0x21, 0xD1
#define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 0x11, 0x21, 0x0C, 0x0C, 0x03, 0x00, 0x15, 0xFF, 0x00, 0x00, 0xFF, 0xC4, 0x30, 0x7F, 0xF5, 0xB5
/*
// Set properties: RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1
// Number of properties: 12
// Group ID: 0x21
// Start ID: 0x18
// Default values: 0xB8, 0xDE, 0x05, 0x17, 0x16, 0x0C, 0x03, 0x00, 0x15, 0xFF, 0x00, 0x00,
// Descriptions:
// MODEM_CHFLT_RX2_CHFLT_COE7_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE6_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE5_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE4_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE3_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE2_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE1_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COE0_7_0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COEM0 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COEM1 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COEM2 - Filter coefficients for the second set of RX filter coefficients.
// MODEM_CHFLT_RX2_CHFLT_COEM3 - Filter coefficients for the second set of RX filter coefficients.
*/
//#define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 0x11, 0x21, 0x0C, 0x18, 0xB9, 0xC9, 0xEA, 0x05, 0x12, 0x11, 0x0A, 0x04, 0x15, 0xFC, 0x03, 0x00
#define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 0x11, 0x21, 0x0C, 0x18, 0xB8, 0xDE, 0x05, 0x17, 0x16, 0x0C, 0x03, 0x00, 0x15, 0xFF, 0x00, 0x00
/*
// Set properties: RF_PA_TC_1_1
// Number of properties: 1
// Group ID: 0x22
// Start ID: 0x03
// Default values: 0x5D,
// Descriptions:
// PA_TC - Configuration of PA ramping parameters.
*/
#define RF_PA_TC_1_1 0x11, 0x22, 0x01, 0x03, 0x1D
/*
// Set properties: RF_SYNTH_PFDCP_CPFF_7_1
// Number of properties: 7
// Group ID: 0x23
// Start ID: 0x00
// Default values: 0x2C, 0x0E, 0x0B, 0x04, 0x0C, 0x73, 0x03,
// Descriptions:
// SYNTH_PFDCP_CPFF - Feed forward charge pump current selection.
// SYNTH_PFDCP_CPINT - Integration charge pump current selection.
// SYNTH_VCO_KV - Gain scaling factors (Kv) for the VCO tuning varactors on both the integrated-path and feed forward path.
// SYNTH_LPFILT3 - Value of resistor R2 in feed-forward path of loop filter.
// SYNTH_LPFILT2 - Value of capacitor C2 in feed-forward path of loop filter.
// SYNTH_LPFILT1 - Value of capacitors C1 and C3 in feed-forward path of loop filter.
// SYNTH_LPFILT0 - Bias current of the active amplifier in the feed-forward loop filter.
*/
#define RF_SYNTH_PFDCP_CPFF_7_1 0x11, 0x23, 0x07, 0x00, 0x2C, 0x0E, 0x0B, 0x04, 0x0C, 0x73, 0x03
/*
// Set properties: RF_FREQ_CONTROL_INTE_8_1
// Number of properties: 8
// Group ID: 0x40
// Start ID: 0x00
// Default values: 0x3C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF,
// Descriptions:
// FREQ_CONTROL_INTE - Frac-N PLL Synthesizer integer divide number.
// FREQ_CONTROL_FRAC_2 - Frac-N PLL fraction number.
// FREQ_CONTROL_FRAC_1 - Frac-N PLL fraction number.
// FREQ_CONTROL_FRAC_0 - Frac-N PLL fraction number.
// FREQ_CONTROL_CHANNEL_STEP_SIZE_1 - EZ Frequency Programming channel step size.
// FREQ_CONTROL_CHANNEL_STEP_SIZE_0 - EZ Frequency Programming channel step size.
// FREQ_CONTROL_W_SIZE - Set window gating period (in number of crystal reference clock cycles) for counting VCO frequency during calibration.
// FREQ_CONTROL_VCOCNT_RX_ADJ - Adjust target count for VCO calibration in RX mode.
*/
#define RF_FREQ_CONTROL_INTE_8_1 0x11, 0x40, 0x08, 0x00, 0x3F, 0x0E, 0x51, 0xEB, 0x14, 0x7B, 0x20, 0xFA
// AUTOMATICALLY GENERATED CODE!
// DO NOT EDIT/MODIFY BELOW THIS LINE!
// --------------------------------------------
#ifndef FIRMWARE_LOAD_COMPILE
#define RADIO_CONFIGURATION_DATA_ARRAY { \
SI446X_PATCH_CMDS, \
0x07, RF_POWER_UP, \
0x08, RF_GPIO_PIN_CFG, \
0x05, RF_GLOBAL_XO_TUNE_1, \
0x05, RF_GLOBAL_CONFIG_1, \
0x05, RF_PREAMBLE_CONFIG_1, \
0x10, RF_MODEM_MOD_TYPE_12, \
0x05, RF_MODEM_FREQ_DEV_0_1, \
0x10, RF_MODEM_TX_RAMP_DELAY_12, \
0x10, RF_MODEM_BCR_NCO_OFFSET_2_12, \
0x07, RF_MODEM_AFC_LIMITER_1_3, \
0x05, RF_MODEM_AGC_CONTROL_1, \
0x10, RF_MODEM_AGC_WINDOW_SIZE_12, \
0x09, RF_MODEM_RAW_CONTROL_5, \
0x08, RF_MODEM_RSSI_JUMP_THRESH_4, \
0x06, RF_MODEM_RAW_SEARCH2_2, \
0x06, RF_MODEM_SPIKE_DET_2, \
0x05, RF_MODEM_RSSI_MUTE_1, \
0x09, RF_MODEM_DSA_CTRL1_5, \
0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12, \
0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12, \
0x10, RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12, \
0x05, RF_PA_TC_1, \
0x0B, RF_SYNTH_PFDCP_CPFF_7, \
0x0C, RF_FREQ_CONTROL_INTE_8, \
0x08, RF_START_RX, \
0x05, RF_IRCAL, \
0x05, RF_IRCAL_1, \
0x05, RF_GLOBAL_CLK_CFG_1, \
0x05, RF_GLOBAL_CONFIG_1_1, \
0x05, RF_INT_CTL_ENABLE_1, \
0x08, RF_FRR_CTL_A_MODE_4, \
0x05, RF_PREAMBLE_CONFIG_STD_1_1, \
0x05, RF_PKT_CONFIG1_1, \
0x10, RF_MODEM_MOD_TYPE_12_1, \
0x05, RF_MODEM_FREQ_DEV_0_1_1, \
0x10, RF_MODEM_TX_RAMP_DELAY_12_1, \
0x10, RF_MODEM_BCR_NCO_OFFSET_2_12_1, \
0x07, RF_MODEM_AFC_LIMITER_1_3_1, \
0x05, RF_MODEM_AGC_CONTROL_1_1, \
0x10, RF_MODEM_AGC_WINDOW_SIZE_12_1, \
0x0C, RF_MODEM_RAW_CONTROL_8, \
0x07, RF_MODEM_RSSI_CONTROL_3, \
0x06, RF_MODEM_RAW_SEARCH2_2_1, \
0x06, RF_MODEM_SPIKE_DET_2_1, \
0x05, RF_MODEM_RSSI_MUTE_1_1, \
0x09, RF_MODEM_DSA_CTRL1_5_1, \
0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1, \
0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1, \
0x10, RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1, \
0x05, RF_PA_TC_1_1, \
0x0B, RF_SYNTH_PFDCP_CPFF_7_1, \
0x0C, RF_FREQ_CONTROL_INTE_8_1, \
0x00 \
}
#else
#define RADIO_CONFIGURATION_DATA_ARRAY { 0 }
#endif
// DEFAULT VALUES FOR CONFIGURATION PARAMETERS
#define RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ_DEFAULT 30000000L
#define RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER_DEFAULT 0x00
#define RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH_DEFAULT 0x10
#define RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP_DEFAULT 0x01
#define RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET_DEFAULT 0x1000
#define RADIO_CONFIGURATION_DATA_RADIO_PATCH_INCLUDED 0x00
#define RADIO_CONFIGURATION_DATA_RADIO_PATCH_SIZE 0x00
#define RADIO_CONFIGURATION_DATA_RADIO_PATCH { }
#ifndef RADIO_CONFIGURATION_DATA_ARRAY
#error "This property must be defined!"
#endif
#ifndef RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ
#define RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ_DEFAULT
#endif
#ifndef RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER
#define RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER_DEFAULT
#endif
#ifndef RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH
#define RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH_DEFAULT
#endif
#ifndef RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP
#define RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP_DEFAULT
#endif
#ifndef RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET
#define RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET_DEFAULT
#endif
#define RADIO_CONFIGURATION_DATA { \
Radio_Configuration_Data_Array, \
RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER, \
RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH, \
RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP, \
RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET \
}
#endif /* RADIO_CONFIG_H_ */

72
src/si446x_patch.h Normal file
View File

@ -0,0 +1,72 @@
// COPYRIGHT=2014 Silicon Laboratories, Inc.
// GENERATED=16:43 October 16 2014
// ROMID=0x06
// FUNCTION=TEST
// MAJOR=0
// MINOR=0
// BUILD=0
// PATCHID=0x311A
// REQUIRES=NONE
// SIZE=448
// CRCT=0x714b
#define SI446X_PATCH_ROMID 00
#define SI446X_PATCH_ID 00
#define SI446X_PATCH_CMDS \
0x08,0x04,0x21,0x71,0x4B,0x00,0x00,0xBA,0x9E, \
0x08,0x05,0x48,0x23,0x2E,0x2B,0x90,0xB1,0x4E, \
0x08,0xEA,0x3F,0xB9,0xE8,0x8B,0xA9,0xCA,0xD6, \
0x08,0x05,0xD2,0xE5,0xBE,0xD1,0x27,0x55,0x82, \
0x08,0xE5,0x56,0x2A,0x3B,0x76,0x76,0x96,0x48, \
0x08,0x05,0x8E,0x26,0xD8,0x5D,0x01,0xA7,0x88, \
0x08,0xE2,0x89,0xCC,0x63,0x79,0x95,0x00,0x4B, \
0x08,0x05,0xE0,0x75,0xCD,0xA4,0xB9,0x46,0xBC, \
0x08,0xEA,0xD3,0x37,0xD2,0x9A,0x89,0x82,0xEA, \
0x08,0x05,0x0C,0xAE,0x4C,0xF5,0xF6,0x3C,0xB3, \
0x08,0xE9,0xA7,0x70,0xDF,0xF1,0x14,0x4F,0x04, \
0x08,0x05,0xFE,0x5B,0xDF,0x47,0x0A,0x7C,0x5B, \
0x08,0xE2,0xFB,0x3E,0x21,0xA2,0x1B,0xAA,0x93, \
0x08,0x05,0xBF,0xFD,0xAB,0x69,0x6C,0xA8,0x5A, \
0x08,0xE2,0x66,0xB7,0x2E,0x2C,0x45,0x2D,0xFB, \
0x08,0x05,0x0D,0x55,0xBD,0xC2,0x37,0x00,0x72, \
0x08,0xE2,0xFF,0x57,0x4D,0x7C,0x6C,0x00,0x2C, \
0x08,0x05,0x9E,0xF2,0x46,0xFD,0xD3,0x16,0x1B, \
0x08,0xEA,0x16,0x7F,0x67,0x4D,0xE5,0xE2,0xC8, \
0x08,0x05,0x37,0x33,0x1C,0xFA,0xBB,0xEE,0xEF, \
0x08,0xEA,0x00,0x5F,0xBE,0xA4,0xFC,0xBF,0xC1, \
0x08,0x05,0x95,0x12,0x2F,0x0A,0xCF,0x55,0x8C, \
0x08,0xE7,0x70,0xC2,0xD4,0xF0,0x81,0x95,0xC8, \
0x08,0xE7,0x72,0x00,0xF9,0x8D,0x15,0x01,0xA3, \
0x08,0xE7,0x18,0xE5,0x6C,0x51,0x1F,0x86,0x9F, \
0x08,0xE7,0xDD,0x37,0x59,0x4B,0xAD,0xB0,0x9C, \
0x08,0xE7,0xC8,0xE8,0x84,0xCD,0x55,0x41,0x83, \
0x08,0xEF,0x4F,0x8E,0x38,0xCB,0x37,0x02,0x87, \
0x08,0xE7,0xF5,0x00,0x88,0x4C,0x09,0x65,0xCE, \
0x08,0xEF,0xDD,0xBC,0x65,0x62,0xAC,0x75,0x62, \
0x08,0xE7,0xC0,0xF1,0x5D,0x98,0xB0,0xDD,0x43, \
0x08,0xE7,0x19,0xB4,0xF8,0x9F,0x6D,0x8C,0xCB, \
0x08,0xE1,0xDE,0x63,0xC2,0x32,0xC6,0xE4,0x2F, \
0x08,0x05,0xF4,0x33,0xB7,0x2E,0x72,0x9A,0xF9, \
0x08,0xE7,0x65,0xD9,0x38,0xB8,0xFE,0x31,0x16, \
0x08,0xE7,0xF3,0x06,0x2D,0xF5,0xFE,0x0C,0x38, \
0x08,0xE7,0x70,0x4F,0xE7,0x49,0xB4,0x58,0x39, \
0x08,0xEF,0xF1,0x46,0xA9,0x23,0x38,0x64,0xC0, \
0x08,0xE7,0x09,0x4E,0x04,0xD3,0x46,0x15,0x02, \
0x08,0xEF,0x8D,0xC7,0x20,0xC3,0x90,0x87,0x4D, \
0x08,0xEF,0x00,0xAB,0x7F,0x27,0x02,0xC6,0xA0, \
0x08,0xE7,0x23,0xA6,0xA6,0xA4,0x27,0x11,0x7D, \
0x08,0xEF,0xB3,0xF1,0x9E,0x6A,0xB3,0x19,0xAF, \
0x08,0xE7,0xAB,0xF5,0x15,0x78,0x5E,0x48,0xF8, \
0x08,0xEF,0x5B,0xB1,0x2E,0xAF,0x2A,0xFF,0x16, \
0x08,0xE7,0x30,0x62,0x5C,0x82,0x7A,0x3F,0x83, \
0x08,0xEF,0x91,0xA7,0xD3,0x1B,0x64,0x85,0xBE, \
0x08,0xE7,0x4D,0x81,0x94,0xE4,0xAA,0xE8,0xDB, \
0x08,0xEF,0xA0,0xCC,0x4A,0x23,0xA5,0x7E,0x36, \
0x08,0xEF,0x0C,0x72,0x4C,0xFB,0x26,0x5A,0xEC, \
0x08,0xEF,0x0E,0x42,0xFA,0xAF,0x49,0xA0,0xA8, \
0x08,0xE7,0x6D,0x12,0xDF,0x2B,0x0C,0x61,0x58, \
0x08,0xEA,0xB6,0x9B,0xDE,0x81,0xB9,0xFF,0xFF, \
0x08,0x05,0x04,0xEB,0xD8,0x12,0xD6,0x8D,0xE0, \
0x08,0xEC,0x29,0x66,0x4B,0xDE,0xB7,0xDE,0x36, \
0x08,0x05,0x0D,0x28,0xB9,0x0A,0x89,0x31,0x1A

View File

@ -0,0 +1,120 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
#ifndef ARM_SEMIHOSTING_H_
#define ARM_SEMIHOSTING_H_
// ----------------------------------------------------------------------------
// Semihosting operations.
enum OperationNumber
{
// Regular operations
SEMIHOSTING_EnterSVC = 0x17,
SEMIHOSTING_ReportException = 0x18,
SEMIHOSTING_SYS_CLOSE = 0x02,
SEMIHOSTING_SYS_CLOCK = 0x10,
SEMIHOSTING_SYS_ELAPSED = 0x30,
SEMIHOSTING_SYS_ERRNO = 0x13,
SEMIHOSTING_SYS_FLEN = 0x0C,
SEMIHOSTING_SYS_GET_CMDLINE = 0x15,
SEMIHOSTING_SYS_HEAPINFO = 0x16,
SEMIHOSTING_SYS_ISERROR = 0x08,
SEMIHOSTING_SYS_ISTTY = 0x09,
SEMIHOSTING_SYS_OPEN = 0x01,
SEMIHOSTING_SYS_READ = 0x06,
SEMIHOSTING_SYS_READC = 0x07,
SEMIHOSTING_SYS_REMOVE = 0x0E,
SEMIHOSTING_SYS_RENAME = 0x0F,
SEMIHOSTING_SYS_SEEK = 0x0A,
SEMIHOSTING_SYS_SYSTEM = 0x12,
SEMIHOSTING_SYS_TICKFREQ = 0x31,
SEMIHOSTING_SYS_TIME = 0x11,
SEMIHOSTING_SYS_TMPNAM = 0x0D,
SEMIHOSTING_SYS_WRITE = 0x05,
SEMIHOSTING_SYS_WRITEC = 0x03,
SEMIHOSTING_SYS_WRITE0 = 0x04,
// Codes returned by SEMIHOSTING_ReportException
ADP_Stopped_ApplicationExit = ((2 << 16) + 38),
ADP_Stopped_RunTimeError = ((2 << 16) + 35),
};
// ----------------------------------------------------------------------------
// SWI numbers and reason codes for RDI (Angel) monitors.
#define AngelSWI_ARM 0x123456
#ifdef __thumb__
#define AngelSWI 0xAB
#else
#define AngelSWI AngelSWI_ARM
#endif
// For thumb only architectures use the BKPT instruction instead of SWI.
#if defined(__ARM_ARCH_7M__) \
|| defined(__ARM_ARCH_7EM__) \
|| defined(__ARM_ARCH_6M__)
#define AngelSWIInsn "bkpt"
#define AngelSWIAsm bkpt
#else
#define AngelSWIInsn "swi"
#define AngelSWIAsm swi
#endif
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
// Testing the local semihosting handler cannot use another BKPT, since this
// configuration cannot trigger HaedFault exceptions while the debugger is
// connected, so we use an illegal op code, that will trigger an
// UsageFault exception.
#define AngelSWITestFault "setend be"
#define AngelSWITestFaultOpCode (0xB658)
#endif
static inline int
__attribute__ ((always_inline))
call_host (int reason, void* arg)
{
int value;
asm volatile (
" mov r0, %[rsn] \n"
" mov r1, %[arg] \n"
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
" " AngelSWITestFault " \n"
#else
" " AngelSWIInsn " %[swi] \n"
#endif
" mov %[val], r0"
: [val] "=r" (value) /* Outputs */
: [rsn] "r" (reason), [arg] "r" (arg), [swi] "i" (AngelSWI) /* Inputs */
: "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
// Clobbers r0 and r1, and lr if in supervisor mode
);
// Accordingly to page 13-77 of ARM DUI 0040D other registers
// can also be clobbered. Some memory positions may also be
// changed by a system call, so they should not be kept in
// registers. Note: we are assuming the manual is right and
// Angel is respecting the APCS.
return value;
}
// ----------------------------------------------------------------------------
// Function used in _exit() to return the status code as Angel exception.
static inline void
__attribute__ ((always_inline,noreturn))
report_exception (int reason)
{
call_host (SEMIHOSTING_ReportException, (void*) reason);
for (;;)
;
}
// ----------------------------------------------------------------------------
#endif // ARM_SEMIHOSTING_H_

View File

@ -0,0 +1,7 @@
The stm32f30x.h and system_stm32f30x.h files are from stsw-stm32108.zip,
the folder:
STM32F30x_DSP_StdPeriph_Lib_V1.0.0/Libraries/CMSIS/Device/ST/STM32F30x/Include
The cmsis_device.h is added for convenience.

View File

@ -0,0 +1,136 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
*
* $Date: 19. October 2015
* $Revision: V.1.4.5 a
*
* Project: CMSIS DSP Library
* Title: arm_common_tables.h
*
* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of ARM LIMITED nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* -------------------------------------------------------------------- */
#ifndef _ARM_COMMON_TABLES_H
#define _ARM_COMMON_TABLES_H
#include "arm_math.h"
extern const uint16_t armBitRevTable[1024];
extern const q15_t armRecipTableQ15[64];
extern const q31_t armRecipTableQ31[64];
/* extern const q31_t realCoefAQ31[1024]; */
/* extern const q31_t realCoefBQ31[1024]; */
extern const float32_t twiddleCoef_16[32];
extern const float32_t twiddleCoef_32[64];
extern const float32_t twiddleCoef_64[128];
extern const float32_t twiddleCoef_128[256];
extern const float32_t twiddleCoef_256[512];
extern const float32_t twiddleCoef_512[1024];
extern const float32_t twiddleCoef_1024[2048];
extern const float32_t twiddleCoef_2048[4096];
extern const float32_t twiddleCoef_4096[8192];
#define twiddleCoef twiddleCoef_4096
extern const q31_t twiddleCoef_16_q31[24];
extern const q31_t twiddleCoef_32_q31[48];
extern const q31_t twiddleCoef_64_q31[96];
extern const q31_t twiddleCoef_128_q31[192];
extern const q31_t twiddleCoef_256_q31[384];
extern const q31_t twiddleCoef_512_q31[768];
extern const q31_t twiddleCoef_1024_q31[1536];
extern const q31_t twiddleCoef_2048_q31[3072];
extern const q31_t twiddleCoef_4096_q31[6144];
extern const q15_t twiddleCoef_16_q15[24];
extern const q15_t twiddleCoef_32_q15[48];
extern const q15_t twiddleCoef_64_q15[96];
extern const q15_t twiddleCoef_128_q15[192];
extern const q15_t twiddleCoef_256_q15[384];
extern const q15_t twiddleCoef_512_q15[768];
extern const q15_t twiddleCoef_1024_q15[1536];
extern const q15_t twiddleCoef_2048_q15[3072];
extern const q15_t twiddleCoef_4096_q15[6144];
extern const float32_t twiddleCoef_rfft_32[32];
extern const float32_t twiddleCoef_rfft_64[64];
extern const float32_t twiddleCoef_rfft_128[128];
extern const float32_t twiddleCoef_rfft_256[256];
extern const float32_t twiddleCoef_rfft_512[512];
extern const float32_t twiddleCoef_rfft_1024[1024];
extern const float32_t twiddleCoef_rfft_2048[2048];
extern const float32_t twiddleCoef_rfft_4096[4096];
/* floating-point bit reversal tables */
#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 )
#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 )
#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 )
#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
/* fixed-point bit reversal tables */
#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 )
#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 )
#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 )
#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
/* Tables for Fast Math Sine and Cosine */
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
#endif /* ARM_COMMON_TABLES_H */

View File

@ -0,0 +1,79 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
*
* $Date: 19. March 2015
* $Revision: V.1.4.5
*
* Project: CMSIS DSP Library
* Title: arm_const_structs.h
*
* Description: This file has constant structs that are initialized for
* user convenience. For example, some can be given as
* arguments to the arm_cfft_f32() function.
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of ARM LIMITED nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* -------------------------------------------------------------------- */
#ifndef _ARM_CONST_STRUCTS_H
#define _ARM_CONST_STRUCTS_H
#include "arm_math.h"
#include "arm_common_tables.h"
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,734 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS Cortex-M Core Function/Instruction Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#ifndef __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
/**
\brief Enable FIQ
\details 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
\details 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
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
/**
\brief Get FPSCR
\details 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 == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details 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 == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details 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
\details 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
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details 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() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Reverse byte order (32 bit)
\details 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)
\details Reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order in signed short value
\details Reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return(result);
}
#endif
/**
\brief Count leading zeros
\details 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
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details 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
\details 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 Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#endif /* (__CORTEX_M >= 0x04) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
#ifndef STM32F3_CMSIS_DEVICE_H_
#define STM32F3_CMSIS_DEVICE_H_
#if defined(STM32F30X)
#include "stm32f30x.h"
#elif defined(STM32F37X)
#include "stm32f37x.h"
#else
#error "No CMSIS header file"
#endif
#endif // STM32F3_CMSIS_DEVICE_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,811 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
// [ILG]
#if defined ( __GNUC__ )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex_M0
@{
*/
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
#define __STATIC_INLINE static inline
#else
#error Unknown compiler
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "core_cmInstr.h" /* Core Instruction Access */
#include "core_cmFunc.h" /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0_REV
#define __CM0_REV 0x0000U
#warning "__CM0_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex_M0 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Get Pending Interrupt
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) < 0)
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_DEPENDANT */
// [ILG]
#if defined ( __GNUC__ )
#pragma GCC diagnostic pop
#endif
#endif /* __CMSIS_GENERIC */

View File

@ -0,0 +1,927 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_H_GENERIC
// [ILG]
#if defined ( __GNUC__ )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex-M0+
@{
*/
/* CMSIS CM0+ definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
__CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
#define __STATIC_INLINE static inline
#else
#error Unknown compiler
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "core_cmInstr.h" /* Core Instruction Access */
#include "core_cmFunc.h" /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000U
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0U
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0U
#warning "__VTOR_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex-M0+ */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
#if (__VTOR_PRESENT == 1U)
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
#if (__VTOR_PRESENT == 1U)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
#endif
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1U)
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/**
\brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register Definitions */
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register Definitions */
#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register Definitions */
#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register Definitions */
#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register Definitions */
#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M0+ header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0+ Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1U)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Get Pending Interrupt
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) < 0)
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
// [ILG]
#if defined ( __GNUC__ )
#pragma GCC diagnostic pop
#endif
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@ -0,0 +1,87 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@ -0,0 +1,96 @@
/**************************************************************************//**
* @file core_cmSimd.h
* @brief CMSIS Cortex-M SIMD Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMSIMD_H
#define __CORE_CMSIMD_H
#ifdef __cplusplus
extern "C" {
#endif
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CMSIMD_H */

View File

@ -0,0 +1,926 @@
/**************************************************************************//**
* @file core_sc000.h
* @brief CMSIS SC000 Core Peripheral Access Layer Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_SC000_H_GENERIC
#define __CORE_SC000_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup SC000
@{
*/
/* CMSIS SC000 definitions */
#define __SC000_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
#define __SC000_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \
__SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_SC (000U) /*!< Cortex secure core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
#define __STATIC_INLINE static inline
#else
#error Unknown compiler
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "core_cmInstr.h" /* Core Instruction Access */
#include "core_cmFunc.h" /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_SC000_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_SC000_H_DEPENDANT
#define __CORE_SC000_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __SC000_REV
#define __SC000_REV 0x0000U
#warning "__SC000_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0U
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group SC000 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED0[1U];
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
uint32_t RESERVED1[154U];
__IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
\brief Type definitions for the System Control and ID Register not in the SCB
@{
*/
/**
\brief Structure type to access the System Control and ID Register not in the SCB.
*/
typedef struct
{
uint32_t RESERVED0[2U];
__IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
} SCnSCB_Type;
/* Auxiliary Control Register Definitions */
#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
/*@} end of group CMSIS_SCnotSCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1U)
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/**
\brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register Definitions */
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register Definitions */
#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register Definitions */
#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register Definitions */
#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register Definitions */
#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the SC000 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of SC000 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1U)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Get Pending Interrupt
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) < 0)
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_SC000_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,105 @@
/**
******************************************************************************
* @file system_stm32f30x.h
* @author MCD Application Team
* @version V1.0.0
* @date 04-September-2012
* @brief CMSIS Cortex-M4 Device System Source File for STM32F30x devices.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f30x_system
* @{
*/
/**
* @brief Define to prevent recursive inclusion
*/
#ifndef __SYSTEM_STM32F30X_H
#define __SYSTEM_STM32F30X_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup STM32F30x_System_Includes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F30x_System_Exported_types
* @{
*/
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* @}
*/
/** @addtogroup STM32F30x_System_Exported_Constants
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F30x_System_Exported_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F30x_System_Exported_Functions
* @{
*/
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*__SYSTEM_STM32F30X_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,94 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
#ifndef CORTEXM_EXCEPTION_HANDLERS_H_
#define CORTEXM_EXCEPTION_HANDLERS_H_
#include <stdint.h>
#if defined(DEBUG)
#define __DEBUG_BKPT() asm volatile ("bkpt 0")
#endif
// ----------------------------------------------------------------------------
#if defined(__cplusplus)
extern "C"
{
#endif
// External references to cortexm_handlers.c
extern void
Reset_Handler (void);
extern void
NMI_Handler (void);
extern void
HardFault_Handler (void);
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
extern void
MemManage_Handler (void);
extern void
BusFault_Handler (void);
extern void
UsageFault_Handler (void);
extern void
DebugMon_Handler (void);
#endif
extern void
SVC_Handler (void);
extern void
PendSV_Handler (void);
extern void
SysTick_Handler (void);
// Exception Stack Frame of the Cortex-M3 or Cortex-M4 processor.
typedef struct
{
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t psr;
#if defined(__ARM_ARCH_7EM__)
uint32_t s[16];
#endif
} ExceptionStackFrame;
#if defined(TRACE)
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
void
dumpExceptionStack (ExceptionStackFrame* frame, uint32_t cfsr, uint32_t mmfar,
uint32_t bfar, uint32_t lr);
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#if defined(__ARM_ARCH_6M__)
void
dumpExceptionStack (ExceptionStackFrame* frame, uint32_t lr);
#endif // defined(__ARM_ARCH_6M__)
#endif // defined(TRACE)
void
HardFault_Handler_C (ExceptionStackFrame* frame, uint32_t lr);
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
void
UsageFault_Handler_C (ExceptionStackFrame* frame, uint32_t lr);
void
BusFault_Handler_C (ExceptionStackFrame* frame, uint32_t lr);
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#if defined(__cplusplus)
}
#endif
// ----------------------------------------------------------------------------
#endif // CORTEXM_EXCEPTION_HANDLERS_H_

146
system/include/diag/Trace.h Normal file
View File

@ -0,0 +1,146 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
#ifndef DIAG_TRACE_H_
#define DIAG_TRACE_H_
// ----------------------------------------------------------------------------
#include <unistd.h>
// ----------------------------------------------------------------------------
// The trace device is an independent output channel, intended for debug
// purposes.
//
// The API is simple, and mimics the standard output calls:
// - trace_printf()
// - trace_puts()
// - trace_putchar();
//
// The implementation is done in
// - trace_write()
//
// Trace support is enabled by adding the TRACE definition.
// By default the trace messages are forwarded to the ITM output,
// but can be rerouted via any device or completely suppressed by
// changing the definitions required in system/src/diag/trace_impl.c
// (currently OS_USE_TRACE_ITM, OS_USE_TRACE_SEMIHOSTING_DEBUG/_STDOUT).
//
// When TRACE is not defined, all functions are inlined to empty bodies.
// This has the advantage that the trace call do not need to be conditionally
// compiled with #ifdef TRACE/#endif
#if defined(TRACE)
#if defined(__cplusplus)
extern "C"
{
#endif
void
trace_initialize(void);
// Implementation dependent
ssize_t
trace_write(const char* buf, size_t nbyte);
// ----- Portable -----
int
trace_printf(const char* format, ...);
int
trace_puts(const char *s);
int
trace_putchar(int c);
void
trace_dump_args(int argc, char* argv[]);
#if defined(__cplusplus)
}
#endif
#else // !defined(TRACE)
#if defined(__cplusplus)
extern "C"
{
#endif
inline void
trace_initialize(void);
// Implementation dependent
inline ssize_t
trace_write(const char* buf, size_t nbyte);
inline int
trace_printf(const char* format, ...);
inline int
trace_puts(const char *s);
inline int
trace_putchar(int c);
inline void
trace_dump_args(int argc, char* argv[]);
#if defined(__cplusplus)
}
#endif
inline void
__attribute__((always_inline))
trace_initialize(void)
{
}
// Empty definitions when trace is not defined
inline ssize_t
__attribute__((always_inline))
trace_write(const char* buf __attribute__((unused)),
size_t nbyte __attribute__((unused)))
{
return 0;
}
inline int
__attribute__((always_inline))
trace_printf(const char* format __attribute__((unused)), ...)
{
return 0;
}
inline int
__attribute__((always_inline))
trace_puts(const char *s __attribute__((unused)))
{
return 0;
}
inline int
__attribute__((always_inline))
trace_putchar(int c)
{
return c;
}
inline void
__attribute__((always_inline))
trace_dump_args(int argc __attribute__((unused)),
char* argv[] __attribute__((unused)))
{
}
#endif // defined(TRACE)
// ----------------------------------------------------------------------------
#endif // DIAG_TRACE_H_

View File

@ -0,0 +1,4 @@
These files are from stsw-stm32108.zip, the folder:
STM32F30x_DSP_StdPeriph_Lib_V1.0.0/Libraries/STM32F30x_StdPeriph_Driver/inc

View File

@ -0,0 +1,831 @@
/**
******************************************************************************
* @file stm32f30x_adc.h
* @author MCD Application Team
* @version V1.0.1
* @date 23-October-2012
* @brief This file contains all the functions prototypes for the ADC firmware
* library.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F30x_ADC_H
#define __STM32F30x_ADC_H
// [ILG]
#if defined ( __GNUC__ )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpadded"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f30x.h"
/** @addtogroup STM32F30x_StdPeriph_Driver
* @{
*/
/** @addtogroup ADC
* @{
*/
/* Exported types ------------------------------------------------------------*/
/**
* @brief ADC Init structure definition
*/
typedef struct
{
uint32_t ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in
Continuous or Single mode.
This parameter can be set to ENABLE or DISABLE. */
uint32_t ADC_Resolution; /*!< Configures the ADC resolution.
This parameter can be a value of @ref ADC_resolution */
uint32_t ADC_ExternalTrigConvEvent; /*!< Defines the external trigger used to start the analog
to digital conversion of regular channels. This parameter
can be a value of @ref ADC_external_trigger_sources_for_regular_channels_conversion */
uint32_t ADC_ExternalTrigEventEdge; /*!< Select the external trigger edge and enable the trigger of a regular group.
This parameter can be a value of
@ref ADC_external_trigger_edge_for_regular_channels_conversion */
uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right.
This parameter can be a value of @ref ADC_data_align */
uint32_t ADC_OverrunMode; /*!< Specifies the way data overrun are managed.
This parameter can be set to ENABLE or DISABLE. */
uint32_t ADC_AutoInjMode; /*!< Enable/disable automatic injected group conversion after
regular group conversion.
This parameter can be set to ENABLE or DISABLE. */
uint8_t ADC_NbrOfRegChannel; /*!< Specifies the number of ADC channels that will be converted
using the sequencer for regular channel group.
This parameter must range from 1 to 16. */
}ADC_InitTypeDef;
/**
* @}
*/
/**
* @brief ADC Init structure definition
*/
typedef struct
{
uint32_t ADC_ExternalTrigInjecConvEvent; /*!< Defines the external trigger used to start the analog
to digital conversion of injected channels. This parameter
can be a value of @ref ADC_external_trigger_sources_for_Injected_channels_conversion */
uint32_t ADC_ExternalTrigInjecEventEdge; /*!< Select the external trigger edge and enable the trigger of an injected group.
This parameter can be a value of
@ref ADC_external_trigger_edge_for_Injected_channels_conversion */
uint8_t ADC_NbrOfInjecChannel; /*!< Specifies the number of ADC channels that will be converted
using the sequencer for injected channel group.
This parameter must range from 1 to 4. */
uint32_t ADC_InjecSequence1;
uint32_t ADC_InjecSequence2;
uint32_t ADC_InjecSequence3;
uint32_t ADC_InjecSequence4;
}ADC_InjectedInitTypeDef;
/**
* @}
*/
typedef struct
{
uint32_t ADC_Mode; /*!< Configures the ADC to operate in
independent or multi mode.
This parameter can be a value of @ref ADC_mode */
uint32_t ADC_Clock; /*!< Select the clock of the ADC. The clock is common for both master
and slave ADCs.
This parameter can be a value of @ref ADC_Clock */
uint32_t ADC_DMAAccessMode; /*!< Configures the Direct memory access mode for multi ADC mode.
This parameter can be a value of
@ref ADC_Direct_memory_access_mode_for_multi_mode */
uint32_t ADC_DMAMode; /*!< Configures the DMA mode for ADC.
This parameter can be a value of @ref ADC_DMA_Mode_definition */
uint8_t ADC_TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases.
This parameter can be a value between 0x0 and 0xF */
}ADC_CommonInitTypeDef;
/* Exported constants --------------------------------------------------------*/
/** @defgroup ADC_Exported_Constants
* @{
*/
#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \
((PERIPH) == ADC2) || \
((PERIPH) == ADC3) || \
((PERIPH) == ADC4))
#define IS_ADC_DMA_PERIPH(PERIPH) (((PERIPH) == ADC1) || \
((PERIPH) == ADC2) || \
((PERIPH) == ADC3) || \
((PERIPH) == ADC4))
/** @defgroup ADC_ContinuousConvMode
* @{
*/
#define ADC_ContinuousConvMode_Enable ((uint32_t)0x00002000) /*!< ADC continuous conversion mode enable */
#define ADC_ContinuousConvMode_Disable ((uint32_t)0x00000000) /*!< ADC continuous conversion mode disable */
#define IS_ADC_CONVMODE(MODE) (((MODE) == ADC_ContinuousConvMode_Enable) || \
((MODE) == ADC_ContinuousConvMode_Disable))
/**
* @}
*/
/** @defgroup ADC_OverunMode
* @{
*/
#define ADC_OverrunMode_Enable ((uint32_t)0x00001000) /*!< ADC Overrun Mode enable */
#define ADC_OverrunMode_Disable ((uint32_t)0x00000000) /*!< ADC Overrun Mode disable */
#define IS_ADC_OVRUNMODE(MODE) (((MODE) == ADC_OverrunMode_Enable) || \
((MODE) == ADC_OverrunMode_Disable))
/**
* @}
*/
/** @defgroup ADC_AutoInjecMode
* @{
*/
#define ADC_AutoInjec_Enable ((uint32_t)0x02000000) /*!< ADC Auto injected Mode enable */
#define ADC_AutoInjec_Disable ((uint32_t)0x00000000) /*!< ADC Auto injected Mode disable */
#define IS_ADC_AUTOINJECMODE(MODE) (((MODE) == ADC_AutoInjec_Enable) || \
((MODE) == ADC_AutoInjec_Disable))
/**
* @}
*/
/** @defgroup ADC_resolution
* @{
*/
#define ADC_Resolution_12b ((uint32_t)0x00000000) /*!< ADC 12-bit resolution */
#define ADC_Resolution_10b ((uint32_t)0x00000008) /*!< ADC 10-bit resolution */
#define ADC_Resolution_8b ((uint32_t)0x00000010) /*!< ADC 8-bit resolution */
#define ADC_Resolution_6b ((uint32_t)0x00000018) /*!< ADC 6-bit resolution */
#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \
((RESOLUTION) == ADC_Resolution_10b) || \
((RESOLUTION) == ADC_Resolution_8b) || \
((RESOLUTION) == ADC_Resolution_6b))
/**
* @}
*/
/** @defgroup ADC_external_trigger_edge_for_regular_channels_conversion
* @{
*/
#define ADC_ExternalTrigEventEdge_None ((uint16_t)0x0000) /*!< ADC No external trigger for regular conversion */
#define ADC_ExternalTrigEventEdge_RisingEdge ((uint16_t)0x0400) /*!< ADC external trigger rising edge for regular conversion */
#define ADC_ExternalTrigEventEdge_FallingEdge ((uint16_t)0x0800) /*!< ADC ADC external trigger falling edge for regular conversion */
#define ADC_ExternalTrigEventEdge_BothEdge ((uint16_t)0x0C00) /*!< ADC ADC external trigger both edges for regular conversion */
#define IS_EXTERNALTRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigEventEdge_None) || \
((EDGE) == ADC_ExternalTrigEventEdge_RisingEdge) || \
((EDGE) == ADC_ExternalTrigEventEdge_FallingEdge) || \
((EDGE) == ADC_ExternalTrigEventEdge_BothEdge))
/**
* @}
*/
/** @defgroup ADC_external_trigger_edge_for_Injected_channels_conversion
* @{
*/
#define ADC_ExternalTrigInjecEventEdge_None ((uint16_t)0x0000) /*!< ADC No external trigger for regular conversion */
#define ADC_ExternalTrigInjecEventEdge_RisingEdge ((uint16_t)0x0040) /*!< ADC external trigger rising edge for injected conversion */
#define ADC_ExternalTrigInjecEventEdge_FallingEdge ((uint16_t)0x0080) /*!< ADC external trigger falling edge for injected conversion */
#define ADC_ExternalTrigInjecEventEdge_BothEdge ((uint16_t)0x00C0) /*!< ADC external trigger both edges for injected conversion */
#define IS_EXTERNALTRIGINJ_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigInjecEventEdge_None) || \
((EDGE) == ADC_ExternalTrigInjecEventEdge_RisingEdge) || \
((EDGE) == ADC_ExternalTrigInjecEventEdge_FallingEdge) || \
((EDGE) == ADC_ExternalTrigInjecEventEdge_BothEdge))
/** @defgroup ADC_external_trigger_sources_for_regular_channels_conversion
* @{
*/
#define ADC_ExternalTrigConvEvent_0 ((uint16_t)0x0000) /*!< ADC external trigger event 0 */
#define ADC_ExternalTrigConvEvent_1 ((uint16_t)0x0040) /*!< ADC external trigger event 1 */
#define ADC_ExternalTrigConvEvent_2 ((uint16_t)0x0080) /*!< ADC external trigger event 2 */
#define ADC_ExternalTrigConvEvent_3 ((uint16_t)0x00C0) /*!< ADC external trigger event 3 */
#define ADC_ExternalTrigConvEvent_4 ((uint16_t)0x0100) /*!< ADC external trigger event 4 */
#define ADC_ExternalTrigConvEvent_5 ((uint16_t)0x0140) /*!< ADC external trigger event 5 */
#define ADC_ExternalTrigConvEvent_6 ((uint16_t)0x0180) /*!< ADC external trigger event 6 */
#define ADC_ExternalTrigConvEvent_7 ((uint16_t)0x01C0) /*!< ADC external trigger event 7 */
#define ADC_ExternalTrigConvEvent_8 ((uint16_t)0x0200) /*!< ADC external trigger event 8 */
#define ADC_ExternalTrigConvEvent_9 ((uint16_t)0x0240) /*!< ADC external trigger event 9 */
#define ADC_ExternalTrigConvEvent_10 ((uint16_t)0x0280) /*!< ADC external trigger event 10 */
#define ADC_ExternalTrigConvEvent_11 ((uint16_t)0x02C0) /*!< ADC external trigger event 11 */
#define ADC_ExternalTrigConvEvent_12 ((uint16_t)0x0300) /*!< ADC external trigger event 12 */
#define ADC_ExternalTrigConvEvent_13 ((uint16_t)0x0340) /*!< ADC external trigger event 13 */
#define ADC_ExternalTrigConvEvent_14 ((uint16_t)0x0380) /*!< ADC external trigger event 14 */
#define ADC_ExternalTrigConvEvent_15 ((uint16_t)0x03C0) /*!< ADC external trigger event 15 */
#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConvEvent_0) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_1) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_2) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_3) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_4) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_5) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_6) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_7) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_8) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_9) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_10) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_11) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_12) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_13) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_14) || \
((REGTRIG) == ADC_ExternalTrigConvEvent_15))
/**
* @}
*/
/** @defgroup ADC_external_trigger_sources_for_Injected_channels_conversion
* @{
*/
#define ADC_ExternalTrigInjecConvEvent_0 ((uint16_t)0x0000) /*!< ADC external trigger for injected conversion event 0 */
#define ADC_ExternalTrigInjecConvEvent_1 ((uint16_t)0x0004) /*!< ADC external trigger for injected conversion event 1 */
#define ADC_ExternalTrigInjecConvEvent_2 ((uint16_t)0x0008) /*!< ADC external trigger for injected conversion event 2 */
#define ADC_ExternalTrigInjecConvEvent_3 ((uint16_t)0x000C) /*!< ADC external trigger for injected conversion event 3 */
#define ADC_ExternalTrigInjecConvEvent_4 ((uint16_t)0x0010) /*!< ADC external trigger for injected conversion event 4 */
#define ADC_ExternalTrigInjecConvEvent_5 ((uint16_t)0x0014) /*!< ADC external trigger for injected conversion event 5 */
#define ADC_ExternalTrigInjecConvEvent_6 ((uint16_t)0x0018) /*!< ADC external trigger for injected conversion event 6 */
#define ADC_ExternalTrigInjecConvEvent_7 ((uint16_t)0x001C) /*!< ADC external trigger for injected conversion event 7 */
#define ADC_ExternalTrigInjecConvEvent_8 ((uint16_t)0x0020) /*!< ADC external trigger for injected conversion event 8 */
#define ADC_ExternalTrigInjecConvEvent_9 ((uint16_t)0x0024) /*!< ADC external trigger for injected conversion event 9 */
#define ADC_ExternalTrigInjecConvEvent_10 ((uint16_t)0x0028) /*!< ADC external trigger for injected conversion event 10 */
#define ADC_ExternalTrigInjecConvEvent_11 ((uint16_t)0x002C) /*!< ADC external trigger for injected conversion event 11 */
#define ADC_ExternalTrigInjecConvEvent_12 ((uint16_t)0x0030) /*!< ADC external trigger for injected conversion event 12 */
#define ADC_ExternalTrigInjecConvEvent_13 ((uint16_t)0x0034) /*!< ADC external trigger for injected conversion event 13 */
#define ADC_ExternalTrigInjecConvEvent_14 ((uint16_t)0x0038) /*!< ADC external trigger for injected conversion event 14 */
#define ADC_ExternalTrigInjecConvEvent_15 ((uint16_t)0x003C) /*!< ADC external trigger for injected conversion event 15 */
#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConvEvent_0) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_1) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_2) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_3) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_4) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_5) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_6) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_7) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_8) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_9) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_10) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_11) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_12) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_13) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_14) || \
((INJTRIG) == ADC_ExternalTrigInjecConvEvent_15))
/**
* @}
*/
/** @defgroup ADC_data_align
* @{
*/
#define ADC_DataAlign_Right ((uint32_t)0x00000000) /*!< ADC Data alignment right */
#define ADC_DataAlign_Left ((uint32_t)0x00000020) /*!< ADC Data alignment left */
#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \
((ALIGN) == ADC_DataAlign_Left))
/**
* @}
*/
/** @defgroup ADC_channels
* @{
*/
#define ADC_Channel_1 ((uint8_t)0x01) /*!< ADC Channel 1 */
#define ADC_Channel_2 ((uint8_t)0x02) /*!< ADC Channel 2 */
#define ADC_Channel_3 ((uint8_t)0x03) /*!< ADC Channel 3 */
#define ADC_Channel_4 ((uint8_t)0x04) /*!< ADC Channel 4 */
#define ADC_Channel_5 ((uint8_t)0x05) /*!< ADC Channel 5 */
#define ADC_Channel_6 ((uint8_t)0x06) /*!< ADC Channel 6 */
#define ADC_Channel_7 ((uint8_t)0x07) /*!< ADC Channel 7 */
#define ADC_Channel_8 ((uint8_t)0x08) /*!< ADC Channel 8 */
#define ADC_Channel_9 ((uint8_t)0x09) /*!< ADC Channel 9 */
#define ADC_Channel_10 ((uint8_t)0x0A) /*!< ADC Channel 10 */
#define ADC_Channel_11 ((uint8_t)0x0B) /*!< ADC Channel 11 */
#define ADC_Channel_12 ((uint8_t)0x0C) /*!< ADC Channel 12 */
#define ADC_Channel_13 ((uint8_t)0x0D) /*!< ADC Channel 13 */
#define ADC_Channel_14 ((uint8_t)0x0E) /*!< ADC Channel 14 */
#define ADC_Channel_15 ((uint8_t)0x0F) /*!< ADC Channel 15 */
#define ADC_Channel_16 ((uint8_t)0x10) /*!< ADC Channel 16 */
#define ADC_Channel_17 ((uint8_t)0x11) /*!< ADC Channel 17 */
#define ADC_Channel_18 ((uint8_t)0x12) /*!< ADC Channel 18 */
#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16)
#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_18)
#define ADC_Channel_Vbat ((uint8_t)ADC_Channel_17)
#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_1) || \
((CHANNEL) == ADC_Channel_2) || \
((CHANNEL) == ADC_Channel_3) || \
((CHANNEL) == ADC_Channel_4) || \
((CHANNEL) == ADC_Channel_5) || \
((CHANNEL) == ADC_Channel_6) || \
((CHANNEL) == ADC_Channel_7) || \
((CHANNEL) == ADC_Channel_8) || \
((CHANNEL) == ADC_Channel_9) || \
((CHANNEL) == ADC_Channel_10) || \
((CHANNEL) == ADC_Channel_11) || \
((CHANNEL) == ADC_Channel_12) || \
((CHANNEL) == ADC_Channel_13) || \
((CHANNEL) == ADC_Channel_14) || \
((CHANNEL) == ADC_Channel_15) || \
((CHANNEL) == ADC_Channel_16) || \
((CHANNEL) == ADC_Channel_17) || \
((CHANNEL) == ADC_Channel_18))
#define IS_ADC_DIFFCHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_1) || \
((CHANNEL) == ADC_Channel_2) || \
((CHANNEL) == ADC_Channel_3) || \
((CHANNEL) == ADC_Channel_4) || \
((CHANNEL) == ADC_Channel_5) || \
((CHANNEL) == ADC_Channel_6) || \
((CHANNEL) == ADC_Channel_7) || \
((CHANNEL) == ADC_Channel_8) || \
((CHANNEL) == ADC_Channel_9) || \
((CHANNEL) == ADC_Channel_10) || \
((CHANNEL) == ADC_Channel_11) || \
((CHANNEL) == ADC_Channel_12) || \
((CHANNEL) == ADC_Channel_13) || \
((CHANNEL) == ADC_Channel_14))
/**
* @}
*/
/** @defgroup ADC_mode
* @{
*/
#define ADC_Mode_Independent ((uint32_t)0x00000000) /*!< ADC independent mode */
#define ADC_Mode_CombRegSimulInjSimul ((uint32_t)0x00000001) /*!< ADC multi ADC mode: Combined Regular simultaneous injected simultaneous mode */
#define ADC_Mode_CombRegSimulAltTrig ((uint32_t)0x00000002) /*!< ADC multi ADC mode: Combined Regular simultaneous Alternate trigger mode */
#define ADC_Mode_InjSimul ((uint32_t)0x00000005) /*!< ADC multi ADC mode: Injected simultaneous mode */
#define ADC_Mode_RegSimul ((uint32_t)0x00000006) /*!< ADC multi ADC mode: Regular simultaneous mode */
#define ADC_Mode_Interleave ((uint32_t)0x00000007) /*!< ADC multi ADC mode: Interleave mode */
#define ADC_Mode_AltTrig ((uint32_t)0x00000009) /*!< ADC multi ADC mode: Alternate Trigger mode */
#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \
((MODE) == ADC_Mode_CombRegSimulInjSimul) || \
((MODE) == ADC_Mode_CombRegSimulAltTrig) || \
((MODE) == ADC_Mode_InjSimul) || \
((MODE) == ADC_Mode_RegSimul) || \
((MODE) == ADC_Mode_Interleave) || \
((MODE) == ADC_Mode_AltTrig))
/**
* @}
*/
/** @defgroup ADC_Clock
* @{
*/
#define ADC_Clock_AsynClkMode ((uint32_t)0x00000000) /*!< ADC Asynchronous clock mode */
#define ADC_Clock_SynClkModeDiv1 ((uint32_t)0x00010000) /*!< Synchronous clock mode divided by 1 */
#define ADC_Clock_SynClkModeDiv2 ((uint32_t)0x00020000) /*!< Synchronous clock mode divided by 2 */
#define ADC_Clock_SynClkModeDiv4 ((uint32_t)0x00030000) /*!< Synchronous clock mode divided by 4 */
#define IS_ADC_CLOCKMODE(CLOCK) (((CLOCK) == ADC_Clock_AsynClkMode) ||\
((CLOCK) == ADC_Clock_SynClkModeDiv1) ||\
((CLOCK) == ADC_Clock_SynClkModeDiv2)||\
((CLOCK) == ADC_Clock_SynClkModeDiv4))
/**
* @}
*/
/** @defgroup ADC_Direct_memory_access_mode_for_multi_mode
* @{
*/
#define ADC_DMAAccessMode_Disabled ((uint32_t)0x00000000) /*!< DMA mode disabled */
#define ADC_DMAAccessMode_1 ((uint32_t)0x00008000) /*!< DMA mode enabled for 12 and 10-bit resolution (6 bit) */
#define ADC_DMAAccessMode_2 ((uint32_t)0x0000C000) /*!< DMA mode enabled for 8 and 6-bit resolution (8bit) */
#define IS_ADC_DMA_ACCESS_MODE(MODE) (((MODE) == ADC_DMAAccessMode_Disabled) || \
((MODE) == ADC_DMAAccessMode_1) || \
((MODE) == ADC_DMAAccessMode_2))
/**
* @}
*/
/** @defgroup ADC_sampling_time
* @{
*/
#define ADC_SampleTime_1Cycles5 ((uint8_t)0x00) /*!< ADC sampling time 1.5 cycle */
#define ADC_SampleTime_2Cycles5 ((uint8_t)0x01) /*!< ADC sampling time 2.5 cycles */
#define ADC_SampleTime_4Cycles5 ((uint8_t)0x02) /*!< ADC sampling time 4.5 cycles */
#define ADC_SampleTime_7Cycles5 ((uint8_t)0x03) /*!< ADC sampling time 7.5 cycles */
#define ADC_SampleTime_19Cycles5 ((uint8_t)0x04) /*!< ADC sampling time 19.5 cycles */
#define ADC_SampleTime_61Cycles5 ((uint8_t)0x05) /*!< ADC sampling time 61.5 cycles */
#define ADC_SampleTime_181Cycles5 ((uint8_t)0x06) /*!< ADC sampling time 181.5 cycles */
#define ADC_SampleTime_601Cycles5 ((uint8_t)0x07) /*!< ADC sampling time 601.5 cycles */
#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_1Cycles5) || \
((TIME) == ADC_SampleTime_2Cycles5) || \
((TIME) == ADC_SampleTime_4Cycles5) || \
((TIME) == ADC_SampleTime_7Cycles5) || \
((TIME) == ADC_SampleTime_19Cycles5) || \
((TIME) == ADC_SampleTime_61Cycles5) || \
((TIME) == ADC_SampleTime_181Cycles5) || \
((TIME) == ADC_SampleTime_601Cycles5))
/**
* @}
*/
/** @defgroup ADC_injected_Channel_selection
* @{
*/
#define ADC_InjectedChannel_1 ADC_Channel_1 /*!< ADC Injected channel 1 */
#define ADC_InjectedChannel_2 ADC_Channel_2 /*!< ADC Injected channel 2 */
#define ADC_InjectedChannel_3 ADC_Channel_3 /*!< ADC Injected channel 3 */
#define ADC_InjectedChannel_4 ADC_Channel_4 /*!< ADC Injected channel 4 */
#define ADC_InjectedChannel_5 ADC_Channel_5 /*!< ADC Injected channel 5 */
#define ADC_InjectedChannel_6 ADC_Channel_6 /*!< ADC Injected channel 6 */
#define ADC_InjectedChannel_7 ADC_Channel_7 /*!< ADC Injected channel 7 */
#define ADC_InjectedChannel_8 ADC_Channel_8 /*!< ADC Injected channel 8 */
#define ADC_InjectedChannel_9 ADC_Channel_9 /*!< ADC Injected channel 9 */
#define ADC_InjectedChannel_10 ADC_Channel_10 /*!< ADC Injected channel 10 */
#define ADC_InjectedChannel_11 ADC_Channel_11 /*!< ADC Injected channel 11 */
#define ADC_InjectedChannel_12 ADC_Channel_12 /*!< ADC Injected channel 12 */
#define ADC_InjectedChannel_13 ADC_Channel_13 /*!< ADC Injected channel 13 */
#define ADC_InjectedChannel_14 ADC_Channel_14 /*!< ADC Injected channel 14 */
#define ADC_InjectedChannel_15 ADC_Channel_15 /*!< ADC Injected channel 15 */
#define ADC_InjectedChannel_16 ADC_Channel_16 /*!< ADC Injected channel 16 */
#define ADC_InjectedChannel_17 ADC_Channel_17 /*!< ADC Injected channel 17 */
#define ADC_InjectedChannel_18 ADC_Channel_18 /*!< ADC Injected channel 18 */
#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \
((CHANNEL) == ADC_InjectedChannel_2) || \
((CHANNEL) == ADC_InjectedChannel_3) || \
((CHANNEL) == ADC_InjectedChannel_4) ||\
((CHANNEL) == ADC_InjectedChannel_5) ||\
((CHANNEL) == ADC_InjectedChannel_6) ||\
((CHANNEL) == ADC_InjectedChannel_7) ||\
((CHANNEL) == ADC_InjectedChannel_8) ||\
((CHANNEL) == ADC_InjectedChannel_9) ||\
((CHANNEL) == ADC_InjectedChannel_10) ||\
((CHANNEL) == ADC_InjectedChannel_11) ||\
((CHANNEL) == ADC_InjectedChannel_12) ||\
((CHANNEL) == ADC_InjectedChannel_13) ||\
((CHANNEL) == ADC_InjectedChannel_14) ||\
((CHANNEL) == ADC_InjectedChannel_15) ||\
((CHANNEL) == ADC_InjectedChannel_16) ||\
((CHANNEL) == ADC_InjectedChannel_17) ||\
((CHANNEL) == ADC_InjectedChannel_18))
/**
* @}
*/
/** @defgroup ADC_injected_Sequence_selection
* @{
*/
#define ADC_InjectedSequence_1 ADC_Channel_1 /*!< ADC Injected sequence 1 */
#define ADC_InjectedSequence_2 ADC_Channel_2 /*!< ADC Injected sequence 2 */
#define ADC_InjectedSequence_3 ADC_Channel_3 /*!< ADC Injected sequence 3 */
#define ADC_InjectedSequence_4 ADC_Channel_4 /*!< ADC Injected sequence 4 */
#define IS_ADC_INJECTED_SEQUENCE(SEQUENCE) (((SEQUENCE) == ADC_InjectedSequence_1) || \
((SEQUENCE) == ADC_InjectedSequence_2) || \
((SEQUENCE) == ADC_InjectedSequence_3) || \
((SEQUENCE) == ADC_InjectedSequence_4))
/**
* @}
*/
/** @defgroup ADC_analog_watchdog_selection
* @{
*/
#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00C00000) /*!< ADC Analog watchdog single regular mode */
#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x01400000) /*!< ADC Analog watchdog single injected mode */
#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x01C00000) /*!< ADC Analog watchdog single regular or injected mode */
#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000) /*!< ADC Analog watchdog all regular mode */
#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x01000000) /*!< ADC Analog watchdog all injected mode */
#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x01800000) /*!< ADC Analog watchdog all regular and all injected mode */
#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000) /*!< ADC Analog watchdog off */
#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \
((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \
((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \
((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \
((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \
((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \
((WATCHDOG) == ADC_AnalogWatchdog_None))
/**
* @}
*/
/** @defgroup ADC_Calibration_Mode_definition
* @{
*/
#define ADC_CalibrationMode_Single ((uint32_t)0x00000000) /*!< ADC Calibration for single ended channel */
#define ADC_CalibrationMode_Differential ((uint32_t)0x40000000) /*!< ADC Calibration for differential channel */
#define IS_ADC_CALIBRATION_MODE(MODE) (((MODE) == ADC_CalibrationMode_Single) ||((MODE) == ADC_CalibrationMode_Differential))
/**
* @}
*/
/** @defgroup ADC_DMA_Mode_definition
* @{
*/
#define ADC_DMAMode_OneShot ((uint32_t)0x00000000) /*!< ADC DMA Oneshot mode */
#define ADC_DMAMode_Circular ((uint32_t)0x00000002) /*!< ADC DMA circular mode */
#define IS_ADC_DMA_MODE(MODE) (((MODE) == ADC_DMAMode_OneShot) || ((MODE) == ADC_DMAMode_Circular))
/**
* @}
*/
/** @defgroup ADC_interrupts_definition
* @{
*/
#define ADC_IT_RDY ((uint16_t)0x0001) /*!< ADC Ready (ADRDY) interrupt source */
#define ADC_IT_EOSMP ((uint16_t)0x0002) /*!< ADC End of Sampling interrupt source */
#define ADC_IT_EOC ((uint16_t)0x0004) /*!< ADC End of Regular Conversion interrupt source */
#define ADC_IT_EOS ((uint16_t)0x0008) /*!< ADC End of Regular sequence of Conversions interrupt source */
#define ADC_IT_OVR ((uint16_t)0x0010) /*!< ADC overrun interrupt source */
#define ADC_IT_JEOC ((uint16_t)0x0020) /*!< ADC End of Injected Conversion interrupt source */
#define ADC_IT_JEOS ((uint16_t)0x0040) /*!< ADC End of Injected sequence of Conversions interrupt source */
#define ADC_IT_AWD1 ((uint16_t)0x0080) /*!< ADC Analog watchdog 1 interrupt source */
#define ADC_IT_AWD2 ((uint16_t)0x0100) /*!< ADC Analog watchdog 2 interrupt source */
#define ADC_IT_AWD3 ((uint16_t)0x0200) /*!< ADC Analog watchdog 3 interrupt source */
#define ADC_IT_JQOVF ((uint16_t)0x0400) /*!< ADC Injected Context Queue Overflow interrupt source */
#define IS_ADC_IT(IT) ((((IT) & (uint16_t)0xF800) == 0x0000) && ((IT) != 0x0000))
#define IS_ADC_GET_IT(IT) (((IT) == ADC_IT_RDY) || ((IT) == ADC_IT_EOSMP) || \
((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_EOS) || \
((IT) == ADC_IT_OVR) || ((IT) == ADC_IT_EOS) || \
((IT) == ADC_IT_JEOS) || ((IT) == ADC_IT_AWD1) || \
((IT) == ADC_IT_AWD2) || ((IT) == ADC_IT_AWD3) || \
((IT) == ADC_IT_JQOVF))
/**
* @}
*/
/** @defgroup ADC_flags_definition
* @{
*/
#define ADC_FLAG_RDY ((uint16_t)0x0001) /*!< ADC Ready (ADRDY) flag */
#define ADC_FLAG_EOSMP ((uint16_t)0x0002) /*!< ADC End of Sampling flag */
#define ADC_FLAG_EOC ((uint16_t)0x0004) /*!< ADC End of Regular Conversion flag */
#define ADC_FLAG_EOS ((uint16_t)0x0008) /*!< ADC End of Regular sequence of Conversions flag */
#define ADC_FLAG_OVR ((uint16_t)0x0010) /*!< ADC overrun flag */
#define ADC_FLAG_JEOC ((uint16_t)0x0020) /*!< ADC End of Injected Conversion flag */
#define ADC_FLAG_JEOS ((uint16_t)0x0040) /*!< ADC End of Injected sequence of Conversions flag */
#define ADC_FLAG_AWD1 ((uint16_t)0x0080) /*!< ADC Analog watchdog 1 flag */
#define ADC_FLAG_AWD2 ((uint16_t)0x0100) /*!< ADC Analog watchdog 2 flag */
#define ADC_FLAG_AWD3 ((uint16_t)0x0200) /*!< ADC Analog watchdog 3 flag */
#define ADC_FLAG_JQOVF ((uint16_t)0x0400) /*!< ADC Injected Context Queue Overflow flag */
#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xF800) == 0x0000) && ((FLAG) != 0x0000))
#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_RDY) || ((FLAG) == ADC_FLAG_EOSMP) || \
((FLAG) == ADC_FLAG_EOC) || ((FLAG) == ADC_FLAG_EOS) || \
((FLAG) == ADC_FLAG_OVR) || ((FLAG) == ADC_FLAG_JEOC) || \
((FLAG) == ADC_FLAG_JEOS) || ((FLAG) == ADC_FLAG_AWD1) || \
((FLAG) == ADC_FLAG_AWD2) || ((FLAG) == ADC_FLAG_AWD3) || \
((FLAG) == ADC_FLAG_JQOVF))
/**
* @}
*/
/** @defgroup ADC_Common_flags_definition
* @{
*/
#define ADC_FLAG_MSTRDY ((uint32_t)0x00000001) /*!< ADC Master Ready (ADRDY) flag */
#define ADC_FLAG_MSTEOSMP ((uint32_t)0x00000002) /*!< ADC Master End of Sampling flag */
#define ADC_FLAG_MSTEOC ((uint32_t)0x00000004) /*!< ADC Master End of Regular Conversion flag */
#define ADC_FLAG_MSTEOS ((uint32_t)0x00000008) /*!< ADC Master End of Regular sequence of Conversions flag */
#define ADC_FLAG_MSTOVR ((uint32_t)0x00000010) /*!< ADC Master overrun flag */
#define ADC_FLAG_MSTJEOC ((uint32_t)0x00000020) /*!< ADC Master End of Injected Conversion flag */
#define ADC_FLAG_MSTJEOS ((uint32_t)0x00000040) /*!< ADC Master End of Injected sequence of Conversions flag */
#define ADC_FLAG_MSTAWD1 ((uint32_t)0x00000080) /*!< ADC Master Analog watchdog 1 flag */
#define ADC_FLAG_MSTAWD2 ((uint32_t)0x00000100) /*!< ADC Master Analog watchdog 2 flag */
#define ADC_FLAG_MSTAWD3 ((uint32_t)0x00000200) /*!< ADC Master Analog watchdog 3 flag */
#define ADC_FLAG_MSTJQOVF ((uint32_t)0x00000400) /*!< ADC Master Injected Context Queue Overflow flag */
#define ADC_FLAG_SLVRDY ((uint32_t)0x00010000) /*!< ADC Slave Ready (ADRDY) flag */
#define ADC_FLAG_SLVEOSMP ((uint32_t)0x00020000) /*!< ADC Slave End of Sampling flag */
#define ADC_FLAG_SLVEOC ((uint32_t)0x00040000) /*!< ADC Slave End of Regular Conversion flag */
#define ADC_FLAG_SLVEOS ((uint32_t)0x00080000) /*!< ADC Slave End of Regular sequence of Conversions flag */
#define ADC_FLAG_SLVOVR ((uint32_t)0x00100000) /*!< ADC Slave overrun flag */
#define ADC_FLAG_SLVJEOC ((uint32_t)0x00200000) /*!< ADC Slave End of Injected Conversion flag */
#define ADC_FLAG_SLVJEOS ((uint32_t)0x00400000) /*!< ADC Slave End of Injected sequence of Conversions flag */
#define ADC_FLAG_SLVAWD1 ((uint32_t)0x00800000) /*!< ADC Slave Analog watchdog 1 flag */
#define ADC_FLAG_SLVAWD2 ((uint32_t)0x01000000) /*!< ADC Slave Analog watchdog 2 flag */
#define ADC_FLAG_SLVAWD3 ((uint32_t)0x02000000) /*!< ADC Slave Analog watchdog 3 flag */
#define ADC_FLAG_SLVJQOVF ((uint32_t)0x04000000) /*!< ADC Slave Injected Context Queue Overflow flag */
#define IS_ADC_CLEAR_COMMONFLAG(FLAG) ((((FLAG) & (uint32_t)0xF800F800) == 0x0000) && ((FLAG) != 0x00000000))
#define IS_ADC_GET_COMMONFLAG(FLAG) (((FLAG) == ADC_FLAG_MSTRDY) || ((FLAG) == ADC_FLAG_MSTEOSMP) || \
((FLAG) == ADC_FLAG_MSTEOC) || ((FLAG) == ADC_FLAG_MSTEOS) || \
((FLAG) == ADC_FLAG_MSTOVR) || ((FLAG) == ADC_FLAG_MSTEOS) || \
((FLAG) == ADC_FLAG_MSTJEOS) || ((FLAG) == ADC_FLAG_MSTAWD1) || \
((FLAG) == ADC_FLAG_MSTAWD2) || ((FLAG) == ADC_FLAG_MSTAWD3) || \
((FLAG) == ADC_FLAG_MSTJQOVF) || \
((FLAG) == ADC_FLAG_SLVRDY) || ((FLAG) == ADC_FLAG_SLVEOSMP) || \
((FLAG) == ADC_FLAG_SLVEOC) || ((FLAG) == ADC_FLAG_SLVEOS) || \
((FLAG) == ADC_FLAG_SLVOVR) || ((FLAG) == ADC_FLAG_SLVEOS) || \
((FLAG) == ADC_FLAG_SLVJEOS) || ((FLAG) == ADC_FLAG_SLVAWD1) || \
((FLAG) == ADC_FLAG_SLVAWD2) || ((FLAG) == ADC_FLAG_SLVAWD3) || \
((FLAG) == ADC_FLAG_SLVJQOVF))
/**
* @}
*/
/** @defgroup ADC_thresholds
* @{
*/
#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF)
/**
* @}
*/
/** @defgroup ADC_injected_offset
* @{
*/
#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF)
/**
* @}
*/
/** @defgroup ADC_injected_length
* @{
*/
#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4))
/**
* @}
*/
/** @defgroup ADC_regular_length
* @{
*/
#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10))
/**
* @}
*/
/** @defgroup ADC_regular_discontinuous_mode_number
* @{
*/
#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8))
/**
* @}
*/
/** @defgroup ADC_two_sampling_delay_number
* @{
*/
#define IS_ADC_TWOSAMPLING_DELAY(DELAY) (((DELAY) <= 0xF))
/**
* @}
*/
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* Function used to set the ADC configuration to the default reset state *****/
void ADC_DeInit(ADC_TypeDef* ADCx);
/* Initialization and Configuration functions *********************************/
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);
void ADC_InjectedInit(ADC_TypeDef* ADCx, ADC_InjectedInitTypeDef* ADC_InjectedInitStruct);
void ADC_InjectedStructInit(ADC_InjectedInitTypeDef* ADC_InjectedInitStruct);
void ADC_CommonInit(ADC_TypeDef* ADCx, ADC_CommonInitTypeDef* ADC_CommonInitStruct);
void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_StartCalibration(ADC_TypeDef* ADCx);
uint32_t ADC_GetCalibrationValue(ADC_TypeDef* ADCx);
void ADC_SetCalibrationValue(ADC_TypeDef* ADCx, uint32_t ADC_Calibration);
void ADC_SelectCalibrationMode(ADC_TypeDef* ADCx, uint32_t ADC_CalibrationMode);
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);
void ADC_DisableCmd(ADC_TypeDef* ADCx);
FlagStatus ADC_GetDisableCmdStatus(ADC_TypeDef* ADCx);
void ADC_VoltageRegulatorCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SelectDifferentialMode(ADC_TypeDef* ADCx, uint8_t ADC_Channel, FunctionalState NewState);
void ADC_SelectQueueOfContextMode(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_AutoDelayCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
/* Analog Watchdog configuration functions ************************************/
void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);
void ADC_AnalogWatchdog1ThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);
void ADC_AnalogWatchdog2ThresholdsConfig(ADC_TypeDef* ADCx, uint8_t HighThreshold, uint8_t LowThreshold);
void ADC_AnalogWatchdog3ThresholdsConfig(ADC_TypeDef* ADCx, uint8_t HighThreshold, uint8_t LowThreshold);
void ADC_AnalogWatchdog1SingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);
void ADC_AnalogWatchdog2SingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);
void ADC_AnalogWatchdog3SingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);
/* Temperature Sensor, Vrefint and Vbat management function */
void ADC_TempSensorCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_VrefintCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_VbatCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
/* Channels Configuration functions ***********************************/
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_RegularChannelSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t SequencerLength);
void ADC_ExternalTriggerConfig(ADC_TypeDef* ADCx, uint16_t ADC_ExternalTrigConvEvent, uint16_t ADC_ExternalTrigEventEdge);
void ADC_StartConversion(ADC_TypeDef* ADCx);
FlagStatus ADC_GetStartConversionStatus(ADC_TypeDef* ADCx);
void ADC_StopConversion(ADC_TypeDef* ADCx);
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
uint32_t ADC_GetDualModeConversionValue(ADC_TypeDef* ADCx);
void ADC_SetChannelOffset1(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint16_t Offset);
void ADC_SetChannelOffset2(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint16_t Offset);
void ADC_SetChannelOffset3(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint16_t Offset);
void ADC_SetChannelOffset4(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint16_t Offset);
void ADC_ChannelOffset1Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ChannelOffset2Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ChannelOffset3Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ChannelOffset4Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
/* Regular Channels DMA Configuration functions *******************************/
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_DMAConfig(ADC_TypeDef* ADCx, uint32_t ADC_DMAMode);
/* Injected channels Configuration functions **********************************/
void ADC_InjectedChannelSampleTimeConfig(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint8_t ADC_SampleTime);
void ADC_StartInjectedConversion(ADC_TypeDef* ADCx);
FlagStatus ADC_GetStartInjectedConversionStatus(ADC_TypeDef* ADCx);
void ADC_StopInjectedConversion(ADC_TypeDef* ADCx);
void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);
/* ADC Dual Modes Configuration functions *************************************/
FlagStatus ADC_GetCommonFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG);
void ADC_ClearCommonFlag(ADC_TypeDef* ADCx, uint32_t ADC_FLAG);
/* Interrupts and flags management functions **********************************/
void ADC_ITConfig(ADC_TypeDef* ADCx, uint32_t ADC_IT, FunctionalState NewState);
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG);
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint32_t ADC_FLAG);
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint32_t ADC_IT);
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint32_t ADC_IT);
#ifdef __cplusplus
}
#endif
// [ILG]
#if defined ( __GNUC__ )
#pragma GCC diagnostic pop
#endif
#endif /*__STM32F30x_ADC_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,654 @@
/**
******************************************************************************
* @file stm32f30x_can.h
* @author MCD Application Team
* @version V1.0.1
* @date 23-October-2012
* @brief This file contains all the functions prototypes for the CAN firmware
* library.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F30x_CAN_H
#define __STM32F30x_CAN_H
// [ILG]
#if defined ( __GNUC__ )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpadded"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f30x.h"
/** @addtogroup STM32F30x_StdPeriph_Driver
* @{
*/
/** @addtogroup CAN
* @{
*/
/* Exported types ------------------------------------------------------------*/
#define IS_CAN_ALL_PERIPH(PERIPH) (((PERIPH) == CAN1))
/**
* @brief CAN init structure definition
*/
typedef struct
{
uint16_t CAN_Prescaler; /*!< Specifies the length of a time quantum.
It ranges from 1 to 1024. */
uint8_t CAN_Mode; /*!< Specifies the CAN operating mode.
This parameter can be a value of @ref CAN_operating_mode */
uint8_t CAN_SJW; /*!< Specifies the maximum number of time quanta
the CAN hardware is allowed to lengthen or
shorten a bit to perform resynchronization.
This parameter can be a value of @ref CAN_synchronisation_jump_width */
uint8_t CAN_BS1; /*!< Specifies the number of time quanta in Bit
Segment 1. This parameter can be a value of
@ref CAN_time_quantum_in_bit_segment_1 */
uint8_t CAN_BS2; /*!< Specifies the number of time quanta in Bit Segment 2.
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
FunctionalState CAN_TTCM; /*!< Enable or disable the time triggered communication mode.
This parameter can be set either to ENABLE or DISABLE. */
FunctionalState CAN_ABOM; /*!< Enable or disable the automatic bus-off management.
This parameter can be set either to ENABLE or DISABLE. */
FunctionalState CAN_AWUM; /*!< Enable or disable the automatic wake-up mode.
This parameter can be set either to ENABLE or DISABLE. */
FunctionalState CAN_NART; /*!< Enable or disable the non-automatic retransmission mode.
This parameter can be set either to ENABLE or DISABLE. */
FunctionalState CAN_RFLM; /*!< Enable or disable the Receive FIFO Locked mode.
This parameter can be set either to ENABLE or DISABLE. */
FunctionalState CAN_TXFP; /*!< Enable or disable the transmit FIFO priority.
This parameter can be set either to ENABLE or DISABLE. */
} CAN_InitTypeDef;
/**
* @brief CAN filter init structure definition
*/
typedef struct
{
uint16_t CAN_FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
configuration, first one for a 16-bit configuration).
This parameter can be a value between 0x0000 and 0xFFFF */
uint16_t CAN_FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
configuration, second one for a 16-bit configuration).
This parameter can be a value between 0x0000 and 0xFFFF */
uint16_t CAN_FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
according to the mode (MSBs for a 32-bit configuration,
first one for a 16-bit configuration).
This parameter can be a value between 0x0000 and 0xFFFF */
uint16_t CAN_FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
according to the mode (LSBs for a 32-bit configuration,
second one for a 16-bit configuration).
This parameter can be a value between 0x0000 and 0xFFFF */
uint16_t CAN_FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter.
This parameter can be a value of @ref CAN_filter_FIFO */
uint8_t CAN_FilterNumber; /*!< Specifies the filter which will be initialized. It ranges from 0 to 13. */
uint8_t CAN_FilterMode; /*!< Specifies the filter mode to be initialized.
This parameter can be a value of @ref CAN_filter_mode */
uint8_t CAN_FilterScale; /*!< Specifies the filter scale.
This parameter can be a value of @ref CAN_filter_scale */
FunctionalState CAN_FilterActivation; /*!< Enable or disable the filter.
This parameter can be set either to ENABLE or DISABLE. */
} CAN_FilterInitTypeDef;
/**
* @brief CAN Tx message structure definition
*/
typedef struct
{
uint32_t StdId; /*!< Specifies the standard identifier.
This parameter can be a value between 0 to 0x7FF. */
uint32_t ExtId; /*!< Specifies the extended identifier.
This parameter can be a value between 0 to 0x1FFFFFFF. */
uint8_t IDE; /*!< Specifies the type of identifier for the message that
will be transmitted. This parameter can be a value
of @ref CAN_identifier_type */
uint8_t RTR; /*!< Specifies the type of frame for the message that will
be transmitted. This parameter can be a value of
@ref CAN_remote_transmission_request */
uint8_t DLC; /*!< Specifies the length of the frame that will be
transmitted. This parameter can be a value between
0 to 8 */
uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0
to 0xFF. */
} CanTxMsg;
/**
* @brief CAN Rx message structure definition
*/
typedef struct
{
uint32_t StdId; /*!< Specifies the standard identifier.
This parameter can be a value between 0 to 0x7FF. */
uint32_t ExtId; /*!< Specifies the extended identifier.
This parameter can be a value between 0 to 0x1FFFFFFF. */
uint8_t IDE; /*!< Specifies the type of identifier for the message that
will be received. This parameter can be a value of
@ref CAN_identifier_type */
uint8_t RTR; /*!< Specifies the type of frame for the received message.
This parameter can be a value of
@ref CAN_remote_transmission_request */
uint8_t DLC; /*!< Specifies the length of the frame that will be received.
This parameter can be a value between 0 to 8 */
uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to
0xFF. */
uint8_t FMI; /*!< Specifies the index of the filter the message stored in
the mailbox passes through. This parameter can be a
value between 0 to 0xFF */
} CanRxMsg;
/* Exported constants --------------------------------------------------------*/
/** @defgroup CAN_Exported_Constants
* @{
*/
/** @defgroup CAN_InitStatus
* @{
*/
#define CAN_InitStatus_Failed ((uint8_t)0x00) /*!< CAN initialization failed */
#define CAN_InitStatus_Success ((uint8_t)0x01) /*!< CAN initialization OK */
/* Legacy defines */
#define CANINITFAILED CAN_InitStatus_Failed
#define CANINITOK CAN_InitStatus_Success
/**
* @}
*/
/** @defgroup CAN_operating_mode
* @{
*/
#define CAN_Mode_Normal ((uint8_t)0x00) /*!< normal mode */
#define CAN_Mode_LoopBack ((uint8_t)0x01) /*!< loopback mode */
#define CAN_Mode_Silent ((uint8_t)0x02) /*!< silent mode */
#define CAN_Mode_Silent_LoopBack ((uint8_t)0x03) /*!< loopback combined with silent mode */
#define IS_CAN_MODE(MODE) (((MODE) == CAN_Mode_Normal) || \
((MODE) == CAN_Mode_LoopBack)|| \
((MODE) == CAN_Mode_Silent) || \
((MODE) == CAN_Mode_Silent_LoopBack))
/**
* @}
*/
/**
* @defgroup CAN_operating_mode
* @{
*/
#define CAN_OperatingMode_Initialization ((uint8_t)0x00) /*!< Initialization mode */
#define CAN_OperatingMode_Normal ((uint8_t)0x01) /*!< Normal mode */
#define CAN_OperatingMode_Sleep ((uint8_t)0x02) /*!< sleep mode */
#define IS_CAN_OPERATING_MODE(MODE) (((MODE) == CAN_OperatingMode_Initialization) ||\
((MODE) == CAN_OperatingMode_Normal)|| \
((MODE) == CAN_OperatingMode_Sleep))
/**
* @}
*/
/**
* @defgroup CAN_operating_mode_status
* @{
*/
#define CAN_ModeStatus_Failed ((uint8_t)0x00) /*!< CAN entering the specific mode failed */
#define CAN_ModeStatus_Success ((uint8_t)!CAN_ModeStatus_Failed) /*!< CAN entering the specific mode Succeed */
/**
* @}
*/
/** @defgroup CAN_synchronisation_jump_width
* @{
*/
#define CAN_SJW_1tq ((uint8_t)0x00) /*!< 1 time quantum */
#define CAN_SJW_2tq ((uint8_t)0x01) /*!< 2 time quantum */
#define CAN_SJW_3tq ((uint8_t)0x02) /*!< 3 time quantum */
#define CAN_SJW_4tq ((uint8_t)0x03) /*!< 4 time quantum */
#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1tq) || ((SJW) == CAN_SJW_2tq)|| \
((SJW) == CAN_SJW_3tq) || ((SJW) == CAN_SJW_4tq))
/**
* @}
*/
/** @defgroup CAN_time_quantum_in_bit_segment_1
* @{
*/
#define CAN_BS1_1tq ((uint8_t)0x00) /*!< 1 time quantum */
#define CAN_BS1_2tq ((uint8_t)0x01) /*!< 2 time quantum */
#define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */
#define CAN_BS1_4tq ((uint8_t)0x03) /*!< 4 time quantum */
#define CAN_BS1_5tq ((uint8_t)0x04) /*!< 5 time quantum */
#define CAN_BS1_6tq ((uint8_t)0x05) /*!< 6 time quantum */
#define CAN_BS1_7tq ((uint8_t)0x06) /*!< 7 time quantum */
#define CAN_BS1_8tq ((uint8_t)0x07) /*!< 8 time quantum */
#define CAN_BS1_9tq ((uint8_t)0x08) /*!< 9 time quantum */
#define CAN_BS1_10tq ((uint8_t)0x09) /*!< 10 time quantum */
#define CAN_BS1_11tq ((uint8_t)0x0A) /*!< 11 time quantum */
#define CAN_BS1_12tq ((uint8_t)0x0B) /*!< 12 time quantum */
#define CAN_BS1_13tq ((uint8_t)0x0C) /*!< 13 time quantum */
#define CAN_BS1_14tq ((uint8_t)0x0D) /*!< 14 time quantum */
#define CAN_BS1_15tq ((uint8_t)0x0E) /*!< 15 time quantum */
#define CAN_BS1_16tq ((uint8_t)0x0F) /*!< 16 time quantum */
#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16tq)
/**
* @}
*/
/** @defgroup CAN_time_quantum_in_bit_segment_2
* @{
*/
#define CAN_BS2_1tq ((uint8_t)0x00) /*!< 1 time quantum */
#define CAN_BS2_2tq ((uint8_t)0x01) /*!< 2 time quantum */
#define CAN_BS2_3tq ((uint8_t)0x02) /*!< 3 time quantum */
#define CAN_BS2_4tq ((uint8_t)0x03) /*!< 4 time quantum */
#define CAN_BS2_5tq ((uint8_t)0x04) /*!< 5 time quantum */
#define CAN_BS2_6tq ((uint8_t)0x05) /*!< 6 time quantum */
#define CAN_BS2_7tq ((uint8_t)0x06) /*!< 7 time quantum */
#define CAN_BS2_8tq ((uint8_t)0x07) /*!< 8 time quantum */
#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8tq)
/**
* @}
*/
/** @defgroup CAN_clock_prescaler
* @{
*/
#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1) && ((PRESCALER) <= 1024))
/**
* @}
*/
/** @defgroup CAN_filter_number
* @{
*/
#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27)
/**
* @}
*/
/** @defgroup CAN_filter_mode
* @{
*/
#define CAN_FilterMode_IdMask ((uint8_t)0x00) /*!< identifier/mask mode */
#define CAN_FilterMode_IdList ((uint8_t)0x01) /*!< identifier list mode */
#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FilterMode_IdMask) || \
((MODE) == CAN_FilterMode_IdList))
/**
* @}
*/
/** @defgroup CAN_filter_scale
* @{
*/
#define CAN_FilterScale_16bit ((uint8_t)0x00) /*!< Two 16-bit filters */
#define CAN_FilterScale_32bit ((uint8_t)0x01) /*!< One 32-bit filter */
#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FilterScale_16bit) || \
((SCALE) == CAN_FilterScale_32bit))
/**
* @}
*/
/** @defgroup CAN_filter_FIFO
* @{
*/
#define CAN_Filter_FIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */
#define CAN_Filter_FIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */
#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FilterFIFO0) || \
((FIFO) == CAN_FilterFIFO1))
/* Legacy defines */
#define CAN_FilterFIFO0 CAN_Filter_FIFO0
#define CAN_FilterFIFO1 CAN_Filter_FIFO1
/**
* @}
*/
/** @defgroup CAN_Start_bank_filter_for_slave_CAN
* @{
*/
#define IS_CAN_BANKNUMBER(BANKNUMBER) (((BANKNUMBER) >= 1) && ((BANKNUMBER) <= 27))
/**
* @}
*/
/** @defgroup CAN_Tx
* @{
*/
#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02))
#define IS_CAN_STDID(STDID) ((STDID) <= ((uint32_t)0x7FF))
#define IS_CAN_EXTID(EXTID) ((EXTID) <= ((uint32_t)0x1FFFFFFF))
#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08))
/**
* @}
*/
/** @defgroup CAN_identifier_type
* @{
*/
#define CAN_Id_Standard ((uint32_t)0x00000000) /*!< Standard Id */
#define CAN_Id_Extended ((uint32_t)0x00000004) /*!< Extended Id */
#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_Id_Standard) || \
((IDTYPE) == CAN_Id_Extended))
/* Legacy defines */
#define CAN_ID_STD CAN_Id_Standard
#define CAN_ID_EXT CAN_Id_Extended
/**
* @}
*/
/** @defgroup CAN_remote_transmission_request
* @{
*/
#define CAN_RTR_Data ((uint32_t)0x00000000) /*!< Data frame */
#define CAN_RTR_Remote ((uint32_t)0x00000002) /*!< Remote frame */
#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_Data) || ((RTR) == CAN_RTR_Remote))
/* Legacy defines */
#define CAN_RTR_DATA CAN_RTR_Data
#define CAN_RTR_REMOTE CAN_RTR_Remote
/**
* @}
*/
/** @defgroup CAN_transmit_constants
* @{
*/
#define CAN_TxStatus_Failed ((uint8_t)0x00)/*!< CAN transmission failed */
#define CAN_TxStatus_Ok ((uint8_t)0x01) /*!< CAN transmission succeeded */
#define CAN_TxStatus_Pending ((uint8_t)0x02) /*!< CAN transmission pending */
#define CAN_TxStatus_NoMailBox ((uint8_t)0x04) /*!< CAN cell did not provide
an empty mailbox */
/* Legacy defines */
#define CANTXFAILED CAN_TxStatus_Failed
#define CANTXOK CAN_TxStatus_Ok
#define CANTXPENDING CAN_TxStatus_Pending
#define CAN_NO_MB CAN_TxStatus_NoMailBox
/**
* @}
*/
/** @defgroup CAN_receive_FIFO_number_constants
* @{
*/
#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO 0 used to receive */
#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO 1 used to receive */
#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1))
/**
* @}
*/
/** @defgroup CAN_sleep_constants
* @{
*/
#define CAN_Sleep_Failed ((uint8_t)0x00) /*!< CAN did not enter the sleep mode */
#define CAN_Sleep_Ok ((uint8_t)0x01) /*!< CAN entered the sleep mode */
/* Legacy defines */
#define CANSLEEPFAILED CAN_Sleep_Failed
#define CANSLEEPOK CAN_Sleep_Ok
/**
* @}
*/
/** @defgroup CAN_wake_up_constants
* @{
*/
#define CAN_WakeUp_Failed ((uint8_t)0x00) /*!< CAN did not leave the sleep mode */
#define CAN_WakeUp_Ok ((uint8_t)0x01) /*!< CAN leaved the sleep mode */
/* Legacy defines */
#define CANWAKEUPFAILED CAN_WakeUp_Failed
#define CANWAKEUPOK CAN_WakeUp_Ok
/**
* @}
*/
/**
* @defgroup CAN_Error_Code_constants
* @{
*/
#define CAN_ErrorCode_NoErr ((uint8_t)0x00) /*!< No Error */
#define CAN_ErrorCode_StuffErr ((uint8_t)0x10) /*!< Stuff Error */
#define CAN_ErrorCode_FormErr ((uint8_t)0x20) /*!< Form Error */
#define CAN_ErrorCode_ACKErr ((uint8_t)0x30) /*!< Acknowledgment Error */
#define CAN_ErrorCode_BitRecessiveErr ((uint8_t)0x40) /*!< Bit Recessive Error */
#define CAN_ErrorCode_BitDominantErr ((uint8_t)0x50) /*!< Bit Dominant Error */
#define CAN_ErrorCode_CRCErr ((uint8_t)0x60) /*!< CRC Error */
#define CAN_ErrorCode_SoftwareSetErr ((uint8_t)0x70) /*!< Software Set Error */
/**
* @}
*/
/** @defgroup CAN_flags
* @{
*/
/* If the flag is 0x3XXXXXXX, it means that it can be used with CAN_GetFlagStatus()
and CAN_ClearFlag() functions. */
/* If the flag is 0x1XXXXXXX, it means that it can only be used with
CAN_GetFlagStatus() function. */
/* Transmit Flags */
#define CAN_FLAG_RQCP0 ((uint32_t)0x38000001) /*!< Request MailBox0 Flag */
#define CAN_FLAG_RQCP1 ((uint32_t)0x38000100) /*!< Request MailBox1 Flag */
#define CAN_FLAG_RQCP2 ((uint32_t)0x38010000) /*!< Request MailBox2 Flag */
/* Receive Flags */
#define CAN_FLAG_FMP0 ((uint32_t)0x12000003) /*!< FIFO 0 Message Pending Flag */
#define CAN_FLAG_FF0 ((uint32_t)0x32000008) /*!< FIFO 0 Full Flag */
#define CAN_FLAG_FOV0 ((uint32_t)0x32000010) /*!< FIFO 0 Overrun Flag */
#define CAN_FLAG_FMP1 ((uint32_t)0x14000003) /*!< FIFO 1 Message Pending Flag */
#define CAN_FLAG_FF1 ((uint32_t)0x34000008) /*!< FIFO 1 Full Flag */
#define CAN_FLAG_FOV1 ((uint32_t)0x34000010) /*!< FIFO 1 Overrun Flag */
/* Operating Mode Flags */
#define CAN_FLAG_WKU ((uint32_t)0x31000008) /*!< Wake up Flag */
#define CAN_FLAG_SLAK ((uint32_t)0x31000012) /*!< Sleep acknowledge Flag */
/* @note When SLAK interrupt is disabled (SLKIE=0), no polling on SLAKI is possible.
In this case the SLAK bit can be polled.*/
/* Error Flags */
#define CAN_FLAG_EWG ((uint32_t)0x10F00001) /*!< Error Warning Flag */
#define CAN_FLAG_EPV ((uint32_t)0x10F00002) /*!< Error Passive Flag */
#define CAN_FLAG_BOF ((uint32_t)0x10F00004) /*!< Bus-Off Flag */
#define CAN_FLAG_LEC ((uint32_t)0x30F00070) /*!< Last error code Flag */
#define IS_CAN_GET_FLAG(FLAG) (((FLAG) == CAN_FLAG_LEC) || ((FLAG) == CAN_FLAG_BOF) || \
((FLAG) == CAN_FLAG_EPV) || ((FLAG) == CAN_FLAG_EWG) || \
((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_FOV0) || \
((FLAG) == CAN_FLAG_FF0) || ((FLAG) == CAN_FLAG_FMP0) || \
((FLAG) == CAN_FLAG_FOV1) || ((FLAG) == CAN_FLAG_FF1) || \
((FLAG) == CAN_FLAG_FMP1) || ((FLAG) == CAN_FLAG_RQCP2) || \
((FLAG) == CAN_FLAG_RQCP1)|| ((FLAG) == CAN_FLAG_RQCP0) || \
((FLAG) == CAN_FLAG_SLAK ))
#define IS_CAN_CLEAR_FLAG(FLAG)(((FLAG) == CAN_FLAG_LEC) || ((FLAG) == CAN_FLAG_RQCP2) || \
((FLAG) == CAN_FLAG_RQCP1) || ((FLAG) == CAN_FLAG_RQCP0) || \
((FLAG) == CAN_FLAG_FF0) || ((FLAG) == CAN_FLAG_FOV0) ||\
((FLAG) == CAN_FLAG_FF1) || ((FLAG) == CAN_FLAG_FOV1) || \
((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_SLAK))
/**
* @}
*/
/** @defgroup CAN_interrupts
* @{
*/
#define CAN_IT_TME ((uint32_t)0x00000001) /*!< Transmit mailbox empty Interrupt*/
/* Receive Interrupts */
#define CAN_IT_FMP0 ((uint32_t)0x00000002) /*!< FIFO 0 message pending Interrupt*/
#define CAN_IT_FF0 ((uint32_t)0x00000004) /*!< FIFO 0 full Interrupt*/
#define CAN_IT_FOV0 ((uint32_t)0x00000008) /*!< FIFO 0 overrun Interrupt*/
#define CAN_IT_FMP1 ((uint32_t)0x00000010) /*!< FIFO 1 message pending Interrupt*/
#define CAN_IT_FF1 ((uint32_t)0x00000020) /*!< FIFO 1 full Interrupt*/
#define CAN_IT_FOV1 ((uint32_t)0x00000040) /*!< FIFO 1 overrun Interrupt*/
/* Operating Mode Interrupts */
#define CAN_IT_WKU ((uint32_t)0x00010000) /*!< Wake-up Interrupt*/
#define CAN_IT_SLK ((uint32_t)0x00020000) /*!< Sleep acknowledge Interrupt*/
/* Error Interrupts */
#define CAN_IT_EWG ((uint32_t)0x00000100) /*!< Error warning Interrupt*/
#define CAN_IT_EPV ((uint32_t)0x00000200) /*!< Error passive Interrupt*/
#define CAN_IT_BOF ((uint32_t)0x00000400) /*!< Bus-off Interrupt*/
#define CAN_IT_LEC ((uint32_t)0x00000800) /*!< Last error code Interrupt*/
#define CAN_IT_ERR ((uint32_t)0x00008000) /*!< Error Interrupt*/
/* Flags named as Interrupts : kept only for FW compatibility */
#define CAN_IT_RQCP0 CAN_IT_TME
#define CAN_IT_RQCP1 CAN_IT_TME
#define CAN_IT_RQCP2 CAN_IT_TME
#define IS_CAN_IT(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP0) ||\
((IT) == CAN_IT_FF0) || ((IT) == CAN_IT_FOV0) ||\
((IT) == CAN_IT_FMP1) || ((IT) == CAN_IT_FF1) ||\
((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG) ||\
((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\
((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\
((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK))
#define IS_CAN_CLEAR_IT(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FF0) ||\
((IT) == CAN_IT_FOV0)|| ((IT) == CAN_IT_FF1) ||\
((IT) == CAN_IT_FOV1)|| ((IT) == CAN_IT_EWG) ||\
((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\
((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\
((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK))
/**
* @}
*/
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* Function used to set the CAN configuration to the default reset state *****/
void CAN_DeInit(CAN_TypeDef* CANx);
/* Initialization and Configuration functions *********************************/
uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct);
void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);
void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct);
void CAN_SlaveStartBank(uint8_t CAN_BankNumber);
void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState);
void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState);
/* CAN Frames Transmission functions ******************************************/
uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);
uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox);
void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox);
/* CAN Frames Reception functions *********************************************/
void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage);
void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber);
uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber);
/* Operation modes functions **************************************************/
uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
uint8_t CAN_Sleep(CAN_TypeDef* CANx);
uint8_t CAN_WakeUp(CAN_TypeDef* CANx);
/* CAN Bus Error management functions *****************************************/
uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx);
uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx);
uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx);
/* Interrupts and flags management functions **********************************/
void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState);
FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT);
void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT);
#ifdef __cplusplus
}
#endif
// [ILG]
#if defined ( __GNUC__ )
#pragma GCC diagnostic pop
#endif
#endif /* __STM32F30x_CAN_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Some files were not shown because too many files have changed in this diff Show More