I/O peripherals are semi-independent functional units attached to the CPU via internal buses. Peripherals are not standalone units, and often have dependencies on other parts of the MCU. For example, to use any peripheral, you must enable its clock source and enable the power on the bus. To use a particular peripheral “bare-metal”, you must perform all the necessary actions as described in the device’s reference manual.
A design goal of the JumpStart API is to eliminate some of tedium and perform all the low-level actions to make it simple to use a peripheral.
The following features and peripherals are supported. These are common to all ST Cortex-M MCU families, and these exist in advanced MCU devices from many/all vendors.
· Cortex core functions, such as SysTick timer and delay functions (which use the SysTick timer).
· Clock system: important for any MCU programs.
· GPIO: most Cortex-M MCUs have flexible GPIO peripherals that allow pins to be set as input, output, or some alternate functions such as ADC (Analog Digital Conversion), or pins for other subsystems (e.g. TX/RX pins for UART).
· ADC: Analog Digital Conversion for converting an analog input signal to digital values.
· Timers: they can be used for counting time, or in advanced cases, capture an input signal (and calculate its frequency), or generate output waveforms, and other functions.
· USART, a commonly used peripheral for basic I/O.
· I2C “Wires”. Most MCUs provide I2C pins. JSAPI calls them I2C “wires”.
· I2C objects. These are built on top of the I2C wires, as multiple I2C objects can sit on a single I2C bus.
· SPI objects. SPI is a synchronous protocol in a master/slave configuration.
· External input trigger (EXTI): detects input pin events.
· DMA Streams. Some basic DMA features are supported. The DMA Stream objects represent the hardware DMA peripherals.
NOTE: By necessity, the JumpStart API header and library files are series-specific, i.e. there is a jsapi.h for the STM32F0xx series, another one for the STM32F4xx series, etc. In the header files, extern objects representing the peripheral abstractions are declared, e.g.:
extern JSAPI_GPIO porta, portb, portc, portd, porte, portf;
However, the actual number of peripherals are device-dependent, and can differ even between the same device in a different packaging! You must refer to the device data sheet to see which ports are defined for a particular device and its applicable features. For example, consider this table for the STM32F030 devices: the number of GPIO ports are different depending on the device variants.
ST’s nomenclature is that the last two letters/digits specify the package, memory size, and peripheral variations.
JumpStart API is written in C++, using the C++ class features to implement the API functions as member functions (also called method functions, or just methods) of statically defined objects. For example:
extern JSAPI_GPIO porta; // declared in jsapi.h
porta.MakeInput(4); // make Pin 4 or PORTA into an input pin
For people who are more familiar with C than C++, even though JSAPI is written in C++, you can still write most of your project in C. In fact, you may isolate all the JumpStart API-related code in a single C++ file, and the rest of the program can be written in C. You can even write mostly in C in a C++ file.
References to JSAPI functions and objects must be made in C++ .cpp
files. These files must include the jsapi.h header file.
· You can define a C function in a C++ file by prefixing its declaration and definition with the keyword extern “C”:
extern “C” unsigned aCfunctionInCPPFile(void)
Such a function may
be called by other C functions just like other C functions.
For more information, see the “JumpStart C++ for Cortex User Guide”.
The simplest way to use JumpStart API is to use the Project Wizard within the CodeBlocks IDE to create a new JSAPI-enabled project.
Invoke File->New…Project…, then select ImageCraft JSAPI Templates.
After selecting ImageCraft JSAPI Templates and clicking “Go”, you can select one of the templates for the STM32Fxx series:
After you follow the instructions, the wizard generates all the files and build options necessary to use JumpStart API in your code.
If you want to add JumpStart API to an existing project, or just want to do things by hand, you need to:
Add the JSAPI include directory to your Project->Build
Options->Paths->Include Paths. The directory is in the
form of $(IMAGECRAFT_DIR)\include\JSAPI\ST\STM32<xx>
where <xx> denotes the MCU series such as F0, F4, etc.
Each of these directories have the file jsapi.h in it, specific to that MCU series.
· Add the JSAPI library archive file to your Project->Build Options->Compiler/Linker
You may add it in the “Linker
Libs” section, specifying the library name libjsapi-stm32<xx> where
<xx> is the MCU series such as F0, F4, etc.
You may also add it to the “Linker Options” as -ljsapi-stm32<xx>. With this method, you omit the lib prefix.
The actual file is
libjsapi-stm<xx>.a in the $(IMAGECRAFT_DIR)\lib\, which is
specified to the compiler as a default library search
Add #include <jsapi.h> to any C++ source files that use
· Add -D_ARMGNUCPP to Build options…->Compiler/Linker->Compiler Options, as C++ requires static constructors to be called, and this option turns on the call in the startup file.
· In the startup file, you need to make sure the interrupt vector entries are filled in with JumpStart API function entry references. See below.
Again, all of the above actions will be done for you automatically if you use the JSAPI template wizard to create your project.
You can use JumpStart API with non-JSAPI code; sometimes this is required if you need to use features of a peripheral not supported by JSAPI. JumpStart API only touches the I/O registers that it uses. For example, if you do not use JSAPI with ADC, then you are free to use any ADC features in your own code. Furthermore, JumpStart API uses the I/O registers in “obvious ways”. For example, you can use JumpStart API to initialize an SPI unit, and then augment it to work with DMA with your own code.
A number of JumpStart API functions make use of interrupt handlers. For example, when you use interrupt-driven UART I/O, or when you use the EXTI API, interrupt handlers are required. The beauty of JumpStart API is that it implements those necessary details for you.
However, users must ensure that the interrupt vector table, usually located in the startup file of the project, contains the correct entries for the handlers. If you start a new JumpStart API project with the JumpStart API project wizard, the correct startup file will be copied. If not using the wizard, then you should still create a simple test project with the project wizard, and copy the entries from that test project’s startup file.
In particular, the name for the JumpStart API SysTick handler is “SysTick_Handler”, which is the name used in most startup file examples. All other JumpStart API handlers have names prefixed with JSAPI_, e.g. JSAPI_TIM2_Handler for timer 2.
All the interrupt handler routines in JumpStart API are decorated with the “weak” attribute, and thus can be overridden in user code by functions with the same names. Email us atif you need to override.
Lastly, since JumpStart API is written in C++, you must ensure that the routine __libc_init_array is called in the startup file prior to the call to the main function. Again, this is done in the startup file created by the project wizard. To do this by hand, make sure your startup code contains a sequence similar to this:
Our goal is to make new releases of JumpStart API backward compatible with older releases so that your existing projects will continue to work. New API functions may use C++ function overloading for enhanced features without affecting existing code.
There may be instances where we add new interrupt handlers and thus additional interrupt entries will be added in the sample startup file. If you are upgrading an existing JumpStart API enabled project and use new features that may involve interrupt handling, it would be wise to create a new test project with the project wizard and check the new startup file against the one you are using to ensure that all JumpStart API interrupt handlers are properly referenced.