[STM32F091] CANbus support

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
Folkert
Posts: 2
Joined: Sat Dec 28, 2019 3:57 pm

[STM32F091] CANbus support

Post by Folkert » Sat Dec 28, 2019 4:12 pm

Hi, I have been trying to get the CAN bus working on a NUCLEO_F091RC board with an STM32F091RC microcontroller.
I have added to the file micropython/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h the lines:

Code: Select all

//CAN (added)
#define MICROPY_HW_CAN1_TX (pin_B9)
#define MICROPY_HW_CAN1_RX (pin_B8)
And tried to compile. However, I get the following error when pin.c is compiled (compiler call included):

Code: Select all

arm-none-eabi-gcc -I. -I../.. -Ibuild-NUCLEO_F091RC -I../../lib/cmsis/inc -I../../lib/stm32lib/CMSIS/STM32F0xx/Include/ -I../../lib/stm32lib/STM32F0xx_HAL_Driver/Inc -Iusbdev/core/inc -Iusbdev/class/inc -Ilwip_inc -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib -DFFCONF_H=\"lib/oofatfs/ffconf.h\"  -DSTM32F091xC -mthumb -msoft-float -mtune=cortex-m0 -mcpu=cortex-m0 -Os -DNDEBUG -Iboards/NUCLEO_F091RC -DSTM32_HAL_H='<stm32f0xx_hal.h>' -DMICROPY_HW_VTOR=0x08000000 -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT -fsingle-precision-constant -Wdouble-promotion -fdata-sections -ffunction-sections -c -MD -o build-NUCLEO_F091RC/pin.o pin.c
In file included from ../../py/mpstate.h:35:0,
                 from ../../py/runtime.h:29,
                 from pin.c:31:
build-NUCLEO_F091RC/genhdr/pins_af_const.h:67:55: error: 'GPIO_AF4_CAN1' undeclared here (not in a function); did you mean 'GPIO_AF4_CAN'?
     { MP_ROM_QSTR(MP_QSTR_AF4_CAN1),       MP_ROM_INT(GPIO_AF4_CAN1) },
                                                       ^
../../py/obj.h:87:67: note: in definition of macro 'MP_OBJ_NEW_SMALL_INT'
 #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 1) | 1))
                                                                   ^~~~~~~~~
build-NUCLEO_F091RC/genhdr/pins_af_const.h:67:44: note: in expansion of macro 'MP_ROM_INT'
     { MP_ROM_QSTR(MP_QSTR_AF4_CAN1),       MP_ROM_INT(GPIO_AF4_CAN1) },
                                            ^~~~~~~~~~
So somehow, after all the pins and alternate functions are gathered and combined into the pins_af_const.h file, the definition for the CAN port is off.

Can it have something to do with the fact that the F0 has only one CAN port? Does pins.c somehow compare it to a different definition?

I have spent a lot of time debugging, looking around, etc. but to no avail.

Folkert
Posts: 2
Joined: Sat Dec 28, 2019 3:57 pm

Re: [STM32F091] CANbus support

Post by Folkert » Sat Dec 28, 2019 4:58 pm

Note that I have also tried to define the CAN pins in the board as (so without the 1):

Code: Select all

#define MICROPY_HW_CAN_TX (pin_B9)
#define MICROPY_HW_CAN_RX (pin_B8)
This required the following change to micropython/ports/stm32/mpconfigboard_common.h (added extra IF clause twice)

Code: Select all

// Enable CAN if there are any peripherals defined
#if defined(MICROPY_HW_CAN1_TX) || defined(MICROPY_HW_CAN2_TX) || defined(MICROPY_HW_CAN3_TX) || defined(MICROPY_HW_CAN_TX)
#define MICROPY_HW_ENABLE_CAN (1)

(...)

#if defined(MICROPY_HW_CAN3_TX)
#define MICROPY_HW_MAX_CAN (3)
#elif defined(MICROPY_HW_CAN2_TX)
#define MICROPY_HW_MAX_CAN (2)
#elif defined(MICROPY_HW_CAN1_TX) || defined(MICROPY_HW_CAN_TX)
#define MICROPY_HW_MAX_CAN (1)
#endif
And subsequently in micropython/ports/stm32/can.h these additions (because the CAN port is named differently and the interrupt handler turned out to be called differently):

Code: Select all

#define CAN1_RX0_IRQn CEC_CAN_IRQn
#define CAN1_RX1_IRQn CEC_CAN_IRQn
#define CAN1_SCE_IRQn CEC_CAN_IRQn

#define CAN1 CAN
And lastly I had to compile with the -Werror option off as it throws some additional errors. Then it compiled and the CAN class shows in the pyb module, but it does not work :(. It seems that CAN on the M0 is quite a bit different still...:

Code: Select all

>>> import pyb
>>> help(pyb)
object <module 'pyb'> is of type module
  __name__ -- pyb
  fault_debug -- <function>
  repl_info -- <function>
  wfi -- <function>
  disable_irq -- <function>
  enable_irq -- <function>
  main -- <function>
  repl_uart -- <function>
  country -- <function>
  dht_readinto -- <function>
  Timer -- <class 'Timer'>
  RTC -- <class 'RTC'>
  Pin -- <class 'Pin'>
  ExtInt -- <class 'ExtInt'>
  Switch -- <class 'Switch'>
  LED -- <class 'LED'>
  SPI -- <class 'SPI'>
  UART -- <class 'UART'>
  CAN -- <class 'CAN'>
  ADC -- <class 'ADC'>
  ADCAll -- <class 'ADCAll'>
  DAC -- <class 'DAC'>
>>> from pyb import CAN
>>> can = CAN(1, CAN.LOOPBACK)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: CAN(1) doesn't exist

Post Reply