Skip to content

Commit

Permalink
Merge branch 'candle-usb:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Huibean authored Dec 18, 2024
2 parents 4679cc4 + 4ae1a7c commit 9858827
Show file tree
Hide file tree
Showing 27 changed files with 1,075 additions and 395 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true

[*.yml]
indent_size = 2
indent_style = space

[lib/**]
indent_size = 2
indent_style = space
53 changes: 53 additions & 0 deletions .github/workflows/compile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: compile

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
release:
- "ubuntu:20.04"
- "ubuntu:22.04"
- "ubuntu:24.04"
- "ubuntu:rolling"
- "debian:oldstable-slim"
- "debian:stable-slim"
- "debian:testing-slim"
- "debian:unstable-slim"

steps:
- uses: actions/checkout@v4

- name: Prepare ${{ matrix.release }} container
run: |
podman version
podman run --name stable -di --userns=keep-id:uid=1000,gid=1000 -v "$PWD":/home -w /home ${{ matrix.release }} bash
podman exec -i stable uname -a
podman exec -i stable id
podman exec -i -u root stable apt update
podman exec -e DEBIAN_FRONTEND='noninteractive' -i -u root stable apt install -o APT::Install-Suggests=false -qy \
clang \
cmake \
gcc-arm-none-eabi \
git \
make
- name: Configure & Build with arm-none-eabi-gcc
env:
toolchain: arm-none-eabi-gcc
run: |
podman exec -i stable cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=cmake/${toolchain}.cmake -B build-${toolchain}
podman exec -i stable cmake --build build-${toolchain}
- name: Show logs
if: ${{ failure() }}
run: |
for log in build-*/CMakeFiles/{CMakeOutput.log,CMakeConfigureLog.yaml}; do \
if [ -e ${log} ]; then \
echo "---------------- ${log} ----------------"; \
cat ${log}; \
fi; \
done
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
name: Check C Styling
steps:
- name: Checkout this commit
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: uncrustify check
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.ccls-cache/
/.idea/
/.vscode/
/Debug/
Expand Down
34 changes: 18 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ add_link_options(

add_subdirectory(libs/STM32_HAL)
add_subdirectory(libs/STM32_USB_Device_Library)
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake )
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)


# Add a custom target that produces version.h, plus
Expand Down Expand Up @@ -110,19 +110,22 @@ find_package(DFUSuffix)

function(dfu_flash target)
if (DFU_SUFFIX_EXECUTABLE)
add_custom_command( TARGET ${target}
add_custom_command(TARGET ${target}
DEPENDS ${target}
BYPRODUCTS ${target}.dfu
COMMAND ${CMAKE_OBJCOPY} -O binary ${target} ${target}.dfu
COMMAND ${DFU_SUFFIX_EXECUTABLE} --add ${target}.dfu --vid 1d50 --pid 606f 1>/dev/null
COMMENT "create and sign dfu bin file: ${TGTNAME}_fw"
)

add_custom_target( flash-${target}
dfu-util -a 0 -R -s 0x08000000 -D ${target}.dfu
add_custom_target(flash-${target}
dfu-util -a 0 -s 0x08000000:leave -D ${target}.dfu
DEPENDS ${target}.dfu
)
else()
add_custom_target( flash-${target}
dfu-util -d 1d50:606f -a 0 -R -s 0x08000000 -D ${target}.bin
add_custom_target(flash-${target}
dfu-util -d 1d50:606f -a 0 -s 0x08000000:leave -D ${target}.bin
DEPENDS ${target}.bin
)
endif()
endfunction()
Expand All @@ -140,9 +143,9 @@ endfunction()
# at configure time.

function(populate_ldscript)
set(prefix LDV)
set(options)
set(oneValueArgs
set(prefix LDV)
set(options)
set(oneValueArgs
CPU_FAMILY
FLASH_START
FLASH_SIZE
Expand Down Expand Up @@ -192,23 +195,23 @@ populate_ldscript(CPU_FAMILY STM32F407XE
HEAP_SIZE 1k
)

populate_ldscript(CPU_FAMILY STM32G0B1XK
populate_ldscript(CPU_FAMILY STM32G0B1xx
FLASH_START 0x08000000
FLASH_SIZE 512k
FLASH_SIZE 128k
RAM_START 0x20000000
RAM_SIZE 144k
STACK_SIZE 2k
HEAP_SIZE 1k
)

######### commands for adding each target have a lot in common: make helper func.
# Split into two categories, F042-based and F072-based.
# one helper func per STM32 CPU family

function(add_target_common TGTNAME CPU_FAMILY)
add_executable(${TGTNAME}_fw ${SOURCE_FILES})
add_dependencies(${TGTNAME}_fw version_h)
target_include_directories(${TGTNAME}_fw PRIVATE include/ ${CMAKE_CURRENT_BINARY_DIR})
target_link_options(${TGTNAME}_fw PRIVATE -T ${CPU_FAMILY}_processed.ld)
target_link_options(${TGTNAME}_fw PRIVATE -T ${CPU_FAMILY}_processed.ld LINKER:-Map=${TGTNAME}_fw.map)
make_bin_file(${TGTNAME}_fw)
dfu_flash(${TGTNAME}_fw)
show_object_size(${TGTNAME}_fw)
Expand All @@ -232,7 +235,6 @@ function(add_f072_target TGTNAME)
target_sources(${TGTNAME}_fw PRIVATE "src/device/device_f0.c")
target_link_options(${TGTNAME}_fw BEFORE PRIVATE ${CPUFLAGS_F0})
target_link_libraries(${TGTNAME}_fw PRIVATE STM32_HAL_STM32F072xB STM32_USB_Device_Library_STM32F072xB)

endfunction()

function(add_f407_target TGTNAME)
Expand All @@ -246,12 +248,12 @@ function(add_f407_target TGTNAME)
endfunction()

function(add_g0b1_target TGTNAME)
add_target_common(${TGTNAME} STM32G0B1XK)
add_target_common(${TGTNAME} STM32G0B1xx)
target_compile_definitions(${TGTNAME}_fw PRIVATE BOARD_${TGTNAME} STM32G0)
target_compile_options(${TGTNAME}_fw BEFORE PRIVATE ${CPUFLAGS_G0})
target_sources(${TGTNAME}_fw PRIVATE "src/device/device_g0.c")
target_link_options(${TGTNAME}_fw BEFORE PRIVATE ${CPUFLAGS_G0})
target_link_libraries(${TGTNAME}_fw PRIVATE STM32_HAL_STM32G0B1xK STM32_USB_Device_Library_STM32G0B1xK)
target_link_libraries(${TGTNAME}_fw PRIVATE STM32_HAL_STM32G0B1xx STM32_USB_Device_Library_STM32G0B1xx)
endfunction()

########## generate list of targets.
Expand Down
36 changes: 19 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
[![Build](https://github.com/candle-usb/candleLight_fw/actions/workflows/ci.yml/badge.svg)](https://github.com/candle-usb/candleLight_fw/actions)

This is firmware for certain STM32F042x/STM32F072xB-based USB-CAN adapters, notably:
- candleLight: https://github.com/HubertD/candleLight (STM32F072xB)
- candleLight FD: https://linux-automation.com/en/products/candlelight-fd.html (STM32G0B1CBT)
- candleLight: https://www.linux-automation.com/en/products/candlelight.html (STM32F072xB)
- cantact: https://www.linklayer.com/tools (STM32F042C6)
- canable (cantact clone): http://canable.io/ (STM32F042C6)
- USB2CAN: https://github.com/roboterclubaachen/usb2can (STM32F042x6)
- CANAlyze: https://kkuchera.github.io/canalyze/ (STM32F042C6)
- VulCAN Gen1: https://shop.copperforge.cc/products/ac41 (STM32F042x6)
- Entreé: https://github.com/tuna-f1sh/entree (STM32F042x6)
- CANable-MKS: https://github.com/makerbase-mks/CANable-MKS (STM32F072xB)
- ConvertDevice-xCAN: https://github.com/ConvertDevice/xCAN (STM32F072xB)
- ConvertDevice-xCANFD: https://github.com/ConvertDevice/xCANFD (STM32G0B1CBT6)
- DSD TECH SH-C30A: https://www.deshide.com/product-details.html?pid=384242&_t=1671089557 (STM32F072xB)
- FYSETC UCAN: https://www.fysetc.com/products/fysetc-ucan-board-based-on-stm32f072-usb-to-can-adapter-support-with-canable-candlelight-klipper-firmware (STM32F072xB)
- candleLight: <https://github.com/HubertD/candleLight> (STM32F072xB)
- candleLight FD: <https://linux-automation.com/en/products/candlelight-fd.html> (STM32G0B1CBT)
- candleLight: <https://www.linux-automation.com/en/products/candlelight.html> (STM32F072xB)
- cantact: <https://www.linklayer.com/tools> (STM32F042C6)
- canable (cantact clone): <http://canable.io/> (STM32F042C6)
- USB2CAN: <https://github.com/roboterclubaachen/usb2can> (STM32F042x6)
- CANAlyze: <https://kkuchera.github.io/canalyze/> (STM32F042C6)
- VulCAN Gen1: <https://shop.copperforge.cc/products/ac41> (STM32F042x6)
- Entreé: <https://github.com/tuna-f1sh/entree> (STM32F042x6)
- CANable-MKS 1.0: <https://github.com/makerbase-mks/CANable-MKS> (STM32F072xB)
- ConvertDevice-xCAN: <https://github.com/ConvertDevice/xCAN> (STM32F072xB)
- ConvertDevice-xCANFD: <https://github.com/ConvertDevice/xCANFD> (STM32G0B1CBT6)
- DSD TECH SH-C30A: <https://www.deshide.com/product-details.html?pid=384242&_t=1671089557> (STM32F072xB)
- FYSETC UCAN: <https://www.fysetc.com/products/fysetc-ucan-board-based-on-stm32f072-usb-to-can-adapter-support-with-canable-candlelight-klipper-firmware> (STM32F072xB)

Of important note is that the common STM32F103 will NOT work with this firmware because its hardware cannot use both USB and CAN simultaneously.
Beware also the smaller packages in the F042 series which map a USB and CAN_TX signal on the same pin and are therefore unusable !
Expand All @@ -30,6 +30,10 @@ firmware. Support for these devices is discussed in
https://github.com/candle-usb/candleLight_fw/pull/139 and
https://github.com/candle-usb/candleLight_fw/pull/176.

STM32G431-based devices (e.g. CANable-MKS 2.0) are not yet supported.

Currently, the firmware sends back an echo frame to the host when the frame is written to the CAN peripheral, and not when the frame is actually sent successfully on the bus. This affects timestamps, one-shot mode, and other edge cases.

## Known issues

Be aware that there is a bug in the gs_usb module in linux<4.5 that can crash the kernel on device removal.
Expand Down Expand Up @@ -135,9 +139,7 @@ Name=cannette99
- We include both a `.editorconfig` and `uncrustify.cfg` which should help with whitespace.

Typical command to run uncrustify on all source files (ignoring HAL and third-party libs):
`uncrustify -c ./uncrustify.cfg --replace $(find include src -name "*.[ch]")`

Optionally append `--no-backup` to avoid creating .orig files.
`uncrustify -c ./uncrustify.cfg --replace --no-backup $(find include src -name "*.[ch]")`

### Profiling
Not great on cortex-M0 cores (F042, F072 targets etc) since they lack hardware support (ITM and SWO). However, it's possible to randomly sample the program counter and get some coarse profiling info.
Expand Down
17 changes: 8 additions & 9 deletions cmake/FindDFUSuffix.cmake
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# find and set DFU_SUFFIX_EXECUTABLE

find_program ( DFU_SUFFIX_EXECUTABLE
NAMES dfu-suffix
DOC "dfu-suffix executable"
)

mark_as_advanced ( DFU_SUFFIX_EXECUTABLE )

# find and set DFU_SUFFIX_EXECUTABLE

find_program(DFU_SUFFIX_EXECUTABLE
NAMES dfu-suffix
DOC "dfu-suffix executable"
)

mark_as_advanced(DFU_SUFFIX_EXECUTABLE)
8 changes: 8 additions & 0 deletions cmake/arm-none-eabi-clang.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET arm-none-eabi)

SET (CMAKE_C_COMPILER_WORKS 1)
SET (CMAKE_CXX_COMPILER_WORKS 1)
8 changes: 8 additions & 0 deletions cmake/arm-none-eabi-gcc.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_C_COMPILER_TARGET arm-none-eabi)

SET (CMAKE_C_COMPILER_WORKS 1)
SET (CMAKE_CXX_COMPILER_WORKS 1)
18 changes: 17 additions & 1 deletion include/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ THE SOFTWARE.
#include <stdint.h>
#include <stdbool.h>

#include "config.h"
#include "gs_usb.h"
#include "hal_include.h"
#include "led.h"
Expand All @@ -47,9 +48,24 @@ typedef struct {
} can_data_t;

extern const struct gs_device_bt_const CAN_btconst;
extern const struct gs_device_bt_const_extended CAN_btconst_ext;

void can_init(can_data_t *channel, CAN_TypeDef *instance);
bool can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing);
void can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing);

#ifdef CONFIG_CANFD
void can_set_data_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing);
#else
static inline bool can_set_data_bittiming(can_data_t *channel,
const struct gs_device_bittiming *timing)
{
(void)channel;
(void)timing;

return false;
}
#endif

void can_enable(can_data_t *channel, uint32_t mode);
void can_disable(can_data_t *channel);
bool can_is_enabled(can_data_t *channel);
Expand Down
1 change: 1 addition & 0 deletions include/can_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ THE SOFTWARE.
#include "can.h"
#include "usbd_gs_can.h"

bool can_check_bittiming_ok(const struct can_bittiming_const *btc, const struct gs_device_bittiming *timing);
void CAN_SendFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
void CAN_ReceiveFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
void CAN_HandleError(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
24 changes: 12 additions & 12 deletions include/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@
#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x))

#define WRITE_ONCE(x,v) \
do { \
barrier(); \
ACCESS_ONCE(x) = (v); \
barrier(); \
} while (0)
do { \
barrier(); \
ACCESS_ONCE(x) = (v); \
barrier(); \
} while (0)

#define READ_ONCE(x) \
({ \
({ \
__typeof(x) __var = ({ \
barrier(); \
ACCESS_ONCE(x); \
Expand All @@ -77,21 +77,21 @@
#define sizeof_field(_s, _m) sizeof(((_s *)0)->_m)

#define container_of(ptr, type, member) \
({ \
({ \
__typeof(((type *)0)->member) *_p = (ptr); \
(type *)((char *)_p - offsetof(type, member)); \
})

#define struct_size(ptr, field, num) \
(offsetof(__typeof(*(ptr)), field) + sizeof((ptr)->field[0]) * (num))
(offsetof(__typeof(*(ptr)), field) + sizeof((ptr)->field[0]) * (num))

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

#define DECLARE_FLEX_ARRAY(_t, _n) \
struct { \
struct { } __dummy_ ## _n; \
_t _n[0]; \
}
struct { \
struct { } __dummy_ ## _n; \
_t _n[0]; \
}

#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
Expand Down
Loading

0 comments on commit 9858827

Please sign in to comment.