Arduino Core for STM32  1.0

Wirish STM32/Arduino Library

Main features:

  • Implementation of some Arduino like functions, to make programming easier.
  • Changing pin mode, interrupts, etc. in real timer, not just on startup as using .ioc file.

What not to do:

  • Never use attachInterrupt() for pins, that are connected on same EXTI line. More here attachInterrupt().
  • Never use delay() function, if you don't want to block whole code processing.
  • Try not to call function digitalWrite for pins that pin mode is INPUT or when interrupt is attached to this pins.

How to use:

  1. Check if libraries for your MCU are included in this file.
  2. Choose Interrupt GPIO handling mode and meet the requirements of each mode. See Interrupt GPIO handling modes.
Note
This code is only c++ compatible. If you want to use it, convert your project to c++.

Types of pin numbering

This library uses 3 types of pin numbering. They are:

  • Pin of port (PPin) - (GPIO_PIN_0, GPIO_PIN_1, ...)
    • This is how HAL library pin numbering style.
    • Methods, that use this numbering requires also GPIO port.
    • Those pins can be combined like this: GPIO_PIN_0 | GPIO_PIN_1
  • Arduino like pin number (Pin)
    • Every pin have unique pin number. You can also use PA00, PA01, PB05,... or PA0, PA1, PB2,...
  • INT pin number (INTPin)
    • Numbers from 0 to 15. It is number of pin of GPIOx port. E.g. PA05 -> 5, PC07 -> 7, ...
    • This numbering is usually used to mark EXTI NVIC lines (there are 16 lines, same as pin count on every GPIO port and every line is connected just to one pin of that port).

Interrupt GPIO handling modes:

Those modes can be set by defining: "#define W_INT_HANDLING_MODE <your_mode_number>" before including wirish.h. Default mode is "Just wirish".

  1. Just wirish (2)
    • Interrupt callback functions will be overridden by this library. In this mode, you can set pin as EXTI interrupt in .ioc file, but you can't enable NVIC EXTI lines, because it will cause compilation error (multiple definition of function). To set interrupt to some pin, you just have to call attachInterrupt() method, because interrupt is not set by .ioc file. You should to call it also when you marked pin as EXTI interrupt in .ioc file, because it will set this pin as interrupt, but no callback function at interrupt will be called.
    • You can also override HAL_GPIO_EXTI_Callback() and use it in another libraries. It will be also called when interrupt fires.
    • PROS:
      • Every one of 16 callback lines can handle its own callback function.
      • You can also override HAL_GPIO_EXTI_Callback() function.
      • You don't need to set pin in .ioc file as interrupt to use it as interrupt.
      • You can easily use GPIO interrupts in your library without setting something in .ioc file.
    • CONS:
      • Pin interrupt setting you see in .ioc file, may not be true, because it can be set by your code.
      • You can't enable EXTI line in .ioc file, it will cause compilation error.
      • You can setup interrupt only by using attachInterrupt() function.
      • Multiple pins on same EXTI line can be set as interrupt, but only last set callback function will be called when interrupt fires on some of those pins.
  2. Semi mode (1)
    • In this mode, you should to mark pin as interrupt and also enable NVIC EXTI line to use interrupts. In code, you should to call method attachInterrupt() to set callback function to that interrupt also when you set interrupt in .ioc file. If you don't want to use interrupt from startup, you should to call function detachInterrupt() or pinMode() after MX_GPIO_Init(). You shouldn't override HAL_GPIO_EXTI_Callback function, because it will be overridden by this library.
    • PROS:
      • Every one of 16 callback lines can handle its own callback function.
      • You can see in .ioc file, which pin is used as interrupt.
      • You can set whatever in .ioc file and no compilation error will be shown.
    • CONS:
      • You can setup interrupt callback only by using attachInterrupt() function (also when it is enabled by MX_GPIO_Init()).
      • Pin is after MX_GPIO_Init() set as interrupt. If you don't want to use just right after startup, you have to call detachInterrupt() or pinMode() after MX_GPIO_Init().
      • You can't override HAL_GPIO_EXTI_Callback() function, it will cause compilation error.
      • Only pins marked as interrupt in .ioc file can be used as interrupts, else your callback function will never be called.
  3. Just .ioc (0)
    • In this mode, you should to set interrupts for some pin just in .ioc file (mark pin as EXTI interrupt and enable NVIC EXTI line). Functions attachInterrupt() and detachInterrupt() will do nothing. You should to override HAL_GPIO_EXTI_Callback by yourself to call callback functions at interrupt.
    • PROS:
      • You can see in .ioc file, which pin is used as interrupt.
      • You can set whatever in .ioc file and no compilation error will be shown.
      • You can also override HAL_GPIO_EXTI_Callback() function or maybe you should to if you want to use interrupts.
    • CONS:
    • You cannot set or reset pin as interrupt in code (attachInterrupt and detachInterrupt will be disabled).
    • You have to write your own code to handle interrupts by overriding HAL_GPIO_EXTI_Callback() function.

How to add support for your MCU:

  1. Check if your MCU is not supported yet.
  2. Add elif macro to include part (#elif defined(YOUR_MCU) ...)
  3. Add HAL library (e.g. stm32f0xx_hal.h, stm32l0xx_hal.h, ...)
  4. Check if some functions or variables does not require specific code for your MCU.
    • Check those functions/variables at first: irqlines, getInterruptGPIOfromPin, isInterruptSetOnPin, getPinPullSetting, getPinSpeedSetting

Troubleshooting:

1. Compiler says, that a lot of HAL functions are not declared.

  • Check if you marked at least one pin as OUTPUT or INPUT in .ioc file, it can sometimes cause problems.
  • Check if HAL timer library for your MCU is included.

2. Interrupt callback function is never called function is never called.

  • Check pin, you have attached interrupt really exists.
  • Check if you have used Arduino like pin numbering when calling attachInterrupt function.
  • Check what interrupt GPIO handling mode you have set (look for macro: W_INT_HANDLING_MODE). Each mode have it's own requirements, that have to be done to use interrupts.
  • Check if you set callback function to attachInterrupt function parameter.
  • Check if you are not using interrupt pins with same EXTI line. More here attachInterrupt().
  • Check if MCU pin really works. For example, try blink led with this pin.

3. Value that returns digitalRead() function is not correct.

  • Check if you have set pin, you want to read state, to INPUT calling pinMode() function or if pin is marked as INPUT in .ioc file.
  • Check if you are using pullUp or pullDown resistors(internal or external). If not, and your pin is floating, it acts as antenna and it's state is unpredictable.
  • Check if MCU pin really works. For example, try blink led with this pin.

4. I called digitalWite or digitalToggle, but pin state was not changed.

  • Check if you have set pin, you want to read state, to OUTPUT calling pinMode() function or if pin is marked as OUTPUT in .ioc file.
  • Check if you have not attached interrupt to this pin.
  • Check if MCU pin really works. For example, try to use it as INPUT.

Credits

Author
Matej Fitoš
Date
Nov 20, 2020
See also
wirish.h
WiringPinMode

Examples

Wirish