Giter Club home page Giter Club logo

budgetcan-fw's Introduction

Introduction:

Firmware to support gs_usb on most STM32 devices. The board specific code can be autogenerated by CubeMX and copied over to your own directory in the ./Portable directory.

The goal of this project was to create a stable foundation for gs_usb while allowing developers to create custom software to support their boards.

The core functionality is in the ./Core directory and all the custom code for each board is in the ./Portable directory.

Using this driver you can create your own custom boards while utilizing the gs_usb core.

Core functionality includes:

  • USB connectivity to the gs_usb driver as implemented in the Linux kernel (support is currently matching kernel 6.1rc1 but is backwards compatible with all pervious kernels that support gs_usb). This functionality is maintained as stable even as the developer creates custom code.
  • Support for bxCAN (STMF0, STMF4, etc.)
  • Support for FDCAN (STMG0, STMG4, STMH7, STML5, STMU5)
  • Support for LIN (using any UART available on the STM32)
  • Support for the custom code to take action on messages received on the bus or transmitted by the host. The developer can also inject messages onto the bus in an adhoc manner based on their own custom code (e.g. a GPIO triggers the transmission of a message on the CAN bus or triggers a message back to the host).

Since the core codebase uses FreeRTOS you can create your own tasks/timers/queues/etc as needed to develop custom features for your board.

I have included a few examples to be used as templates.



How to create your own board:

  1. Pick one of the examples that best matches your desired board. The only files that need to be hand modified are the board.c and board.h. Everything else will be copied from the CubeMX generated files.
  2. Create a project in CubeMX based on the chipset you are using and the GPIO and/or additional peripherals you plan on using.
  3. This is very important: You must ensure you select the following to ensure the files are generated correctly by CubeMX.
    • You select CAN and USB under the "Connectivity" heading on the left. You must also enable the NVIC for all CAN channels and the USB.
    • Enable FreeRTOS under the "Middlewares" heading and select any interface. This ensures that the correct NVIC priorities are set and code is not generated for the IRQs that FreeRTOS uses.
    • Enable TIM2 by changing Clock Source -> Internal Clock.
    • Under the "SYS" menu change the Timebase Source to TIM1.
    • Any other configuration (adding UARTs, I2C, etc.) is up to you. You will need to determine where to place the autogenerated code for those peripherals.
  4. In the project make sure you select Makefile in your toolchain selection then Generate Code.
  5. The following files need to be copied over to the Portable/Inc and Portable/Src directories:
    • To Inc (XX matches your chip family)
      • stm32XXxx_hal_conf.h
      • stm32XXxx_it.h
    • To Src (XX matches your chip family)
      • stm32XXxx_hal_msp.c
      • stm32XXxx_hal_timebase_tim.c
      • stm32XXxx_it.c
      • system_stm32XXxx.c
  6. Open the main.c in the autogenerated code:
    • Cut and paste the MX_GPIO_Init and SystemClock_Config functions into your board.c file (overwrite what's already in the template).
  7. Open the main.h in the autogenerated code:
    • Cut and paste the "#include "stm32XXxx_hal.h"" line and paste it into the board_hal_config.h in you board's "Inc" directory replacing what may already be in the template.
    • Cut and paste any of the GPIO defines and place them into your board.h.
  8. Copy the startup_stm32xxxxxxx.s file from the autogenerated ./Core/Startup directory into the root of your board directory, and add bl __initialize_hardware_early to Reset_Handler label.
  9. Copy the STM32xxxxxxx_FLASH.ld file from the root of the autogenerated code into the root of your board directory.
  10. Edit anything in the board.c, board.h that needs to be changed to match your board's configuration.
  11. Edit anything in the FreeRTOSConfig.h that you may need to tailor for your board.
  12. Edit the Makefile in your board's root directory to update the names of the startup and linker files you copied over. If your chipset doesn't match the template then you will need to update the chipset family ID on source and include files.
  13. Compile and fix stuff you didn't update correctly.

NOTE: in file board.h symbol BOARD_SYSMEM_RESET_VECTOR shall be configured to start of the bootloader in system memory. This value can be found in AN2606 per each MCU. For example STM32H74x is the value 0x1FF09800.



How to use the LIN driver:

https://www.csselectronics.com/pages/lin-bus-protocol-intro-basics

The LIN driver is configured using "pseudo" CAN messages sent from the host. Since LIN data can be up to 8-bytes long we need to split the configuration into two CAN messages to properly configure. As currently designed the LIN driver can operate in either Slave or Monitor mode depending on the configuration. With monitor mode the developer has the ability to assign a "gateway" CAN message that is sent from the device to the host which contains data received on LIN (up to a maximum of 6 data bytes with the current non-FD design).

By default there are 10 slots per channel in the schedule table for use in slave or monitor mode. A matching PID in slave mode will trigger the transmission of the data contained in that slot. A PID match in The configuration method uses CANIDs that are configurable by the developer to best fit their design and use cases. The example below uses the default CANDIDs used by the budgetcan_g0 firmware.

Slot table design:

CH # Index PID Len Data0 Data1 ... DataN
0x00 0x00 0x00 0x02 0xDE 0xAD ... 0x00
0x00 0x01 0x01 0x01 0xBE 0x00 ... 0x00
xxx xxx xxx xxx xxx xxx ... xxx

Loading the slot is a two message process. The first message sent is the data bytes you wish to be loaded into the slot. This data will be held in the buffer until a load command is issued. Therefore there are two messages: Command message and Data message.

The data message is simply a CAN frame with a DLC of 8 that contains the 8 bytes of data you wish to load into the table

The command message has the following structure:

  • Byte 0: Command type - 0 = Load slot, 1 = Reserved, 2 = Enable slot, 3 = Disable slot, 4 = Disable all slots, 5 = Erase all slots
  • Byte 1: Channel - 0-255 : Developer may chose to have multiple LIN channels. This value defines which channel the command will be carried out on.
  • Byte 2: Slot index - 0-255: By default there are 10 slots but a developer may choose to offer as many as 255. This value defines which slot the command will be carried out on.
  • Byte 3: Slot flags - Bit 0 - 1 = Slot is active, 0 = Slot is inactive : Bits 1-7 = Reserved
  • Byte 4: Slot action - Bits 0:1 - 00 = Slave mode, 01 = Monitor mode, 10 & 11 = Reserved, Bits 2-7 = Reserved
  • Byte 5: PID : The PID that triggers a match on this slot
  • Byte 6: Length : The amount of data that will be returned in slave mode (0-8)

The following is an example of setting up slot 0 on channel 0 to trigger a slave response on PID $02 with 4 bytes of data (0x00, 0x00, 0x60, 0x40)

Setting up the data portion of the slot:

CANID DLC B1 B2 B3 B4 B5 B6 B7 B8
0x1FFFFE81 0x08 0x00 0x00 0x60 0x40 0x00 0x00 0x00 0x00

Loading the slot table with the data provided above and immediately start responding:

CANID DLC Command Type Channel Index Flags Action ID PID Len xx
0x1FFFFE80 0x08 0x00 0x00 0x00 0x01 0x00 0x02 0x04 0x00

When the table is already loaded you can activate and inactivate that individual slot

The following is an example of setting a speicifc slot inactive (Channel 0, Index 2)

CANID DLC Command Type Channel Index Flags Action ID PID Len xx
0x1FFFFE80 0x08 0x00 0x00 0x02 0x00 0x00 0x00 0x00 0x00

The following is an example of setting a speicifc slot active (Channel 0, Index 2)

CANID DLC Command Type Channel Index Flags Action ID PID Len xx
0x1FFFFE80 0x08 0x00 0x00 0x02 0x01 0x00 0x00 0x00 0x00

Using these slot tables there are a variety of ways to carry out tasks on the LIN bus. If you wish to perform a slave action (e.g. simulate a switch press) you could quickly load new data into the table with the steps above and the next slave request will respond with the newly loaded data. Or you may chose to load all possible slave response scenarios into different slots and enable and disable those slots with a single command message. The driver is designed to be as flexible as possible to preform many different LIN tasks.

Currently the driver does not support master frames. I may be added at a later date depending on interest.

I may update the configuration system at a later date to use longer CANFD frame for loading the tables and sending monitor data.

budgetcan-fw's People

Contributors

ryedwards avatar darkmoon32 avatar

Stargazers

Muhammad Rafli Ardiansyah avatar  avatar Carl Treudler avatar maciekr1234 avatar  avatar Yuki Kusakabe avatar  avatar dokee avatar Jon Polom avatar Maksim avatar Peter "Shawty" Shaw avatar Just avatar James Attewell avatar  avatar Marek Słowiński avatar Chu Tiến Thịnh avatar Ryan Huber avatar bbsccc avatar Philippe Carpentier-Savard avatar  avatar Maksim Salau avatar  avatar Choryu Park avatar Albert avatar Lech Perczak avatar 陈江 avatar Skip Hansen avatar yangjing29 avatar David Cole avatar  avatar

Watchers

Marc Kleine-Budde avatar normaldotcom avatar  avatar  avatar

budgetcan-fw's Issues

Upper computer

Hello, which upper computer are you using? Thank you!

Unrecoverable Error from 2.5ms Dominant Pulse on Bus (canablev2 target)

First of all, thank you to all those have contributed to this project, I am a fan!

I am using the canablev2 firmware build of this project and while it initially appears to work great, I am seeing that when there is a long (~2.5ms) dominant pulse on the bus from an erroneous node, the firmware appears to be acting a bit strange.

Steps

  1. Plug in CANable V2 interface with budgetcan_fw loaded.

  2. Bring up interface:

    • sudo ip link set dev can0 type can bitrate 500000 fd on dbitrate 2000000
    • sudo ip link set dev can0 up
  3. Check interface status with: ip -details link show can0

    19: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 72 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
    link/can  promiscuity 0  allmulti 0 minmtu 0 maxmtu 0 
    can <FD> state ERROR-ACTIVE restart-ms 0 
          bitrate 500000 sample-point 0.875
          tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1 brp 10
          gs_usb: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..1024 brp_inc 1
          dbitrate 2000000 dsample-point 0.750
          dtq 25 dprop-seg 7 dphase-seg1 7 dphase-seg2 5 dsjw 2 dbrp 2
          gs_usb: dtseg1 1..16 dtseg2 1..8 dsjw 1..4 dbrp 1..1024 dbrp_inc 1
          clock 80000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 parentbus usb parentdev 3-2:1.0 
    
  4. Send frame repeatedly on bus:

    • watch -n 0.1 'cansend can0 123#0011223344556677'
  5. I confirm frames being send correctly with logic analyser on bus. (I am using another canablev2 to ACK the frames.)

  6. I use a erroneous node to produce a 2.5ms dominant pulse on the bus.

  7. Immediately after that the canablev2 fails to send any more frames, but the state show with ip -details link show can0 remains as state ERROR-ACTIVE.

  8. Checking the interface status with ip -details link show can0 shows no difference the above snippet.

  9. If I reset the interface using these commands, I get the error after the last one: RTNETLINK answers: No such device. I have confirmed that running these command before the issue has been seen works correctly - there is no error and the interface appears to work fine.

    • sudo ip link set dev can0 down
    • sudo ip link set dev can0 type can bitrate 500000 fd on dbitrate 2000000
    • sudo ip link set dev can0 up
  10. I have also tried resetting the USB device in software using what I believe us the same as USBDEVFS_RESET, it sends a further 10 frames before then failing to send anymore. After a further 10 cansend requests without any frames being sent, the command returns write: No buffer space available.

  11. If I reset the device by unplugging and re-plugging in, then the issue is fixed after bringing back up the interface, etc. (But comes back after the next erroneous 2.5ms pulse.)

How to compile and use this on Windows

Hi there, I was hapily playing with 500kbps CAN on my MCP2515 breakout board with arduino when in the middle the thing stopped receiving data, not sure what happened maybe my MCP2515 got friend, idk

since I don't have time to get another one to verify this (that I fried my MCP2515 not something on my CAN Network) , I searched for an alternative solution and remembered that I have one STM32H750B-DK laying around

I know the thing (STM32H750B-DK) has built in 2x CAN-FD transciever and found this FW

So whats the best and quickest way to compile this on windows (I do have STM32CubeIDE 1.4.0 installed, but didn't find any project for it here in this repo) just to see if STM32H750B-DK can receive my 500kbs can comunication then I fried my MCP2515 module

of course if you have any good CAN example for STM32H750B-DK that would also be great

Thanks for Anwsering and Best Regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.