5#include "libxr_def.hpp"
6#include DEF2STR(LIBXR_CH32_CONFIG_FILE)
8namespace LibXR::CH32UsbCanShared
13using IrqFn = void (*)();
15inline std::atomic_bool usb_inited{
false};
16inline std::atomic_bool can1_inited{
false};
18static constexpr uint16_t USBD_PMA_BYTES_SOLO = 512;
19static constexpr uint16_t USBD_PMA_BYTES_WITHCAN = 384;
23#if defined(RCC_APB1Periph_USB)
24inline constexpr bool K_HAS_USB_DEV_FS =
true;
26inline constexpr bool K_HAS_USB_DEV_FS =
false;
30inline constexpr bool K_HAS_CAN1 =
true;
32inline constexpr bool K_HAS_CAN1 =
false;
36inline constexpr bool K_HAS_CAN2 =
true;
38inline constexpr bool K_HAS_CAN2 =
false;
41inline constexpr bool K_SINGLE_CAN1 = K_HAS_CAN1 && !K_HAS_CAN2;
42inline constexpr bool K_USB_CAN_SHARE = K_HAS_USB_DEV_FS && K_SINGLE_CAN1;
44inline constexpr bool usb_can_share_enabled() {
return K_USB_CAN_SHARE; }
46inline uint16_t usb_pma_limit_bytes()
48 if constexpr (!K_USB_CAN_SHARE)
50 return USBD_PMA_BYTES_SOLO;
53 return can1_inited.load(std::memory_order_acquire) ? USBD_PMA_BYTES_WITHCAN
54 : USBD_PMA_BYTES_SOLO;
57inline std::atomic<IrqFn> usb_irq_cb{
nullptr};
58inline std::atomic<IrqFn> can1_rx0_cb{
nullptr};
59inline std::atomic<IrqFn> can1_tx_cb{
nullptr};
61inline void register_usb_irq(IrqFn fn)
63 usb_irq_cb.store(fn, std::memory_order_release);
66inline void register_can1_rx0(IrqFn fn)
68 if constexpr (K_USB_CAN_SHARE)
70 can1_rx0_cb.store(fn, std::memory_order_release);
78inline void register_can1_tx(IrqFn fn)
80 if constexpr (K_USB_CAN_SHARE)
82 can1_tx_cb.store(fn, std::memory_order_release);
90inline bool can1_active()
92 if constexpr (!K_USB_CAN_SHARE)
96 return (can1_rx0_cb.load(std::memory_order_acquire) !=
nullptr) ||
97 (can1_tx_cb.load(std::memory_order_acquire) !=
nullptr);