Main sPrinter Control Software

This document provides information about the control software of the sPrinter rover, developed by students of the Faculty of Electrical Engineering and Information Technology STU in Bratislava.

While it was previously developed in ac6 System Workbench, we decided to transfer to regain control over our toolchain and transfer to non-managed environment. We currently use cmake and compile with arm-none-eabi-gcc with newlib and c++17.

We generate the initialization via STM CubeMX, and use CLion as our IDE.

Debugging is done via the open source Open OCD debugger. It's pretty cool.

Fuck Eclipse dude, seriously.

General Information

This chapter contains general information of the project.

MCU And Board

The board used is Nucleo F446ZE, with STM32F446ZET MCU.

Board Mechanical Drawing in mil

Board Mechanical Drawing in mil

Board Pin Mapping

Board Pin Mapping

MCU Features and Peripherals

MCU Features and Peripherals

Pin Mapping

This is the current pin mapping of the main sPrinter MCU.

PinNameModePeripheralFunction
PA0SRV1_POSPWM2TIM2_CH1Servo 1 position
PA1SRV2_POSPWM2TIM2_CH1Servo 2 position
PA8USB_SOFSOFUSB_OTG_FSUSB start of signal
PA9LOG_TXTXUSART1Log serial transmit
PA10LOG_RXRXUSART1Log serial receive
PA11USB_DMDMUSB_OTG_FSUSB data minus
PA12USB_DPDPUSB_OTG_FSUSB data plus
PA13TMSSWDIOSYS_JTMSJTag test mode select
PA14TCKSWCLKSYS_JTCKJTag clock
PB0LED_GREENOUT_PPGPIOGreen LED
PB7LED_BLUEOUT_PPGPIOBlue LED
PB10STEP1_DIROUT_PPGPIOStepper 1 direction
PB11STEP2_DIROUT_PPGPIOStepper 2 direction
PB14LED_REDOUT_PPGPIORed LED
PC0SUN_ADC1IN10ADC1Suntracker analog in
PC1SUN_ADC2IN11ADC1Suntracker analog in
PC2SUN_ADC3IN12ADC1Suntracker analog in
PC3SUN_ADC4IN13ADC1Suntracker analog in
PC4SUN_ADC5IN14ADC1Suntracker analog in
PC6ENG4_SPDPWM2TIM8_CH1Engine 4 speed
PC7ENG3_SPDPWM2TIM8_CH2Engine 3 speed
PC8ENG2_SPDPWM2TIM8_CH3Engine 2 speed
PC9ENG1_SPDPWM2TIM8_CH4Engine 1 speed
PC13USER_BTNEXTI10_RTGPIOUser button interrupt
PC14OSC32_INOSC32_INRCCOscillator input
PC15OSC32_OUTOSC32_OUTRCCOscillator output
PD0STEP1_ENOUT_PPGPIOStepper 1 enable
PD1STEP2_ENOUT_PPGPIOStepper 2 enable
PD5RF_TXTXUSART2RF module transmit
PD6RF_RXRXUSART2RF module receive
PD8STLK_TXTXUSART3STLink transmit
PD9STLK_RXRXUSART3STLink receive
PD12ENG5_SPDPWM2TIM4_CH1Engine 5 speed
PD13ENG6_SPDPWM2TIM4_CH2Engine 6 speed
PD14ENG7_SPDPWM2TIM4_CH3Engine 7 speed
PE2ENC3_EIEXTI2_RFTGPIOEncoder 3 interrupt
PE3ENC4_EIEXTI3_RFTGPIOEncoder 4 interrupt
PE4ENC5_EIEXTI4_RFTGPIOEncoder 5 interrupt
PE5ENC6_EIEXTI5_RFTGPIOEncoder 6 interrupt
PE7ENG1_DIROUT_PPGPIOEngine 1 direction
PE8ENG2_DIROUT_PPGPIOEngine 2 direction
PE9ENG3_DIROUT_PPGPIOEngine 3 direction
PE10ENG4_DIROUT_PPGPIOEngine 4 direction
PE11ENG5_DIROUT_PPGPIOEngine 5 direction
PE12ENG6_DIROUT_PPGPIOEngine 6 direction
PE14ENG7_DIROUT_PPGPIOEngine 7 direction
PG0ENC1_EIEXTI0_RFTGPIOEncoder 1 interrupt
PG1ENC2_EIEXTI1_RFTGPIOEncoder 2 interrupt
PG2STEP1_CTLOUT_PPGPIOStepper 1 control
PG3STEP2_CTLOUT_PPGPIOStepper 2 control
PG6USB_PWROUT_PPGPIOUSB power switch on
PG7USB_OCINGPIOUSB over current
PH0MCOOSC_INRCCOscillator input
PH1OSC_OUTOSC_OUTRCCOscillator output

Core Library

The core library is the fundamental library containing basis of the system, the scheduler, time manipulation and logging.

Core Library - Logging Functionality

Headers

  • core/log.h Contains the

    • template<typename ... Args> void log(Args ... args) function, which allows logging any implemented type into the default log USART.
  • core/fatal.h Contains the unrecoverable

    • template<typename ... Args> void fatal(Args ... args) function, which freezes the system along with reporting.

Extending the Logger

If you want to be able to log a special non-trivial type T, you need to provide a void logImpl::log(T) function for it.

If you want the logging system to know your type, you must include your logImpl function declaration before you include the log header.

Example Usage

Log Example

#include <core/log.h>

void printFoo(uint32_t x, const char *y)
{
    log("The x is: ", x, ", and the y is: \"", y, "\"\n");
}

Fatal Example

#include <core/fatal.h>

void printBar(uint32_t *x)
{
    if(!x)
        fatal("Oh no, nullptr dereference in printBar! - x = ", uintptr_t(x), "\n");

    log("The *x is: ", *x, "\n"); 
}

Extending the Logger Example

// Foo.h
struct Foo {
    uint32_t x;
    uint16_t ys[8];
};

namespace logImpl { void log(const Foo &foo); }

// Foo.cpp
#include "Foo.h"
#include <core/log.h>

namespace logImpl {
    void log(const Foo &foo)
    {
        log("Foo { x: ", foo.x, ", ys: [ ");
        for(const auto &y: foo.ys)
            log(y, " ");
        log("] }");
    }
}

Scheduler

Time