This commit is contained in:
Kamil Trzciński 2025-12-21 15:43:38 -05:00 committed by GitHub
commit 8b3029dc56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 123 additions and 16 deletions

View file

@ -296,10 +296,16 @@ can_init(void)
gpio_peripheral(GPIO_Rx, CAN_FUNCTION_Rx, 1);
gpio_peripheral(GPIO_Tx, CAN_FUNCTION_Tx, 0);
canhw_start(CONFIG_CANBUS_FREQUENCY);
}
DECL_INIT(can_init);
void
canhw_start(uint32_t canbus_frequency)
{
uint32_t pclock = get_pclock_frequency(CANx_GCLK_ID);
uint32_t btr = compute_btr(pclock, CONFIG_CANBUS_FREQUENCY);
uint32_t btr = compute_btr(pclock, canbus_frequency);
/*##-1- Configure the CAN #######################################*/
@ -349,4 +355,11 @@ can_init(void)
CANx->MCAN_ILE = MCAN_ILE_EINT0;
CANx->MCAN_IE = MCAN_IE_RF0NE | FDCAN_IE_TC | MCAN_IE_PEDE | MCAN_IE_PEAE;
}
DECL_INIT(can_init);
void
canhw_stop(void)
{
NVIC_DisableIRQ(CANx_IRQn);
CANx->MCAN_ILE &= ~MCAN_ILE_EINT0;
CANx->MCAN_IE &= ~(MCAN_IE_RF0NE | FDCAN_IE_TC);
}

View file

@ -311,10 +311,16 @@ can_init(void)
gpio_peripheral(GPIO_Rx, CAN_FUNCTION, 1);
gpio_peripheral(GPIO_Tx, CAN_FUNCTION, 0);
canhw_start(CONFIG_CANBUS_FREQUENCY);
}
DECL_INIT(can_init);
void
canhw_start(uint32_t canbus_frequency)
{
uint32_t pclock = get_pclock_frequency(CANx_GCLK_ID);
uint32_t btr = compute_btr(pclock, CONFIG_CANBUS_FREQUENCY);
uint32_t btr = compute_btr(pclock, canbus_frequency);
/*##-1- Configure the CAN #######################################*/
@ -356,4 +362,11 @@ can_init(void)
CANx->ILE.reg = CAN_ILE_EINT0;
CANx->IE.reg = CAN_IE_RF0NE | FDCAN_IE_TC | CAN_IE_PEDE | CAN_IE_PEAE;
}
DECL_INIT(can_init);
void
canhw_stop(void)
{
NVIC_DisableIRQ(CANx_IRQn);
CANx->ILE.reg &= ~CAN_ILE_EINT0;
CANx->IE.reg &= ~(CAN_IE_RF0NE | FDCAN_IE_TC);
}

View file

@ -28,6 +28,8 @@ enum {
};
// callbacks provided by board specific code
void canhw_start(uint32_t frequency);
void canhw_stop(void);
int canhw_send(struct canbus_msg *msg);
void canhw_set_filter(uint32_t id);
void canhw_get_status(struct canbus_status *status);

View file

@ -43,6 +43,11 @@ enum gs_usb_breq {
GS_USB_BREQ_BT_CONST_EXT,
};
enum gs_can_mode {
GS_CAN_MODE_RESET = 0,
GS_CAN_MODE_START
};
struct gs_host_config {
uint32_t byte_order;
} __packed;
@ -134,6 +139,8 @@ enum {
HS_TX_LOCAL = 4,
};
uint32_t canbus_frequency = CONFIG_CANBUS_FREQUENCY;
// Send a message to the Linux host
static int
send_frame(struct canbus_msg *msg)
@ -551,6 +558,7 @@ enum {
static void *usb_xfer_data;
static uint8_t usb_xfer_size, usb_xfer_flags;
static void (*usb_xfer_complete)();
// Set the USB "stall" condition
static void
@ -562,7 +570,8 @@ usb_do_stall(void)
// Transfer data on the usb endpoint 0
static void
usb_do_xfer(void *data, uint_fast8_t size, uint_fast8_t flags)
usb_do_xfer2(void *data, uint_fast8_t size, uint_fast8_t flags
, void (*complete)())
{
for (;;) {
uint_fast8_t xs = size;
@ -590,7 +599,11 @@ usb_do_xfer(void *data, uint_fast8_t size, uint_fast8_t flags)
// Must send zero-length-packet
continue;
usb_xfer_flags = 0;
usb_xfer_complete = NULL;
usb_notify_ep0();
if (complete) {
complete();
}
return;
}
continue;
@ -600,6 +613,7 @@ usb_do_xfer(void *data, uint_fast8_t size, uint_fast8_t flags)
usb_xfer_data = data;
usb_xfer_size = size;
usb_xfer_flags = flags;
usb_xfer_complete = complete;
return;
}
// Error
@ -608,6 +622,12 @@ usb_do_xfer(void *data, uint_fast8_t size, uint_fast8_t flags)
}
}
static void
usb_do_xfer(void *data, uint_fast8_t size, uint_fast8_t flags)
{
usb_do_xfer2(data, size, flags, NULL);
}
static void
usb_req_get_descriptor(struct usb_ctrlrequest *req)
{
@ -709,20 +729,37 @@ gs_breq_bt_const(struct usb_ctrlrequest *req)
struct gs_device_bittiming device_bittiming;
static void
gs_breq_bittiming_complete(void)
{
uint32_t bit_time = 1 + device_bittiming.prop_seg +
device_bittiming.phase_seg1 + device_bittiming.phase_seg2;
canbus_frequency = bt_const.fclk_can / (device_bittiming.brp * bit_time);
}
static void
gs_breq_bittiming(struct usb_ctrlrequest *req)
{
// Bit timing is ignored for now
usb_do_xfer(&device_bittiming, sizeof(device_bittiming), UX_READ);
usb_do_xfer2(&device_bittiming, sizeof(device_bittiming), UX_READ
, gs_breq_bittiming_complete);
}
struct gs_device_mode device_mode;
static void
gs_breq_mode_complete(void)
{
if (device_mode.mode == GS_CAN_MODE_START)
canhw_start(canbus_frequency);
else if (device_mode.mode == GS_CAN_MODE_RESET)
canhw_stop();
}
static void
gs_breq_mode(struct usb_ctrlrequest *req)
{
// Mode is ignored for now
usb_do_xfer(&device_mode, sizeof(device_mode), UX_READ);
usb_do_xfer2(&device_mode, sizeof(device_mode), UX_READ
, gs_breq_mode_complete);
}
static void
@ -769,7 +806,8 @@ usb_ep0_task(void)
if (!sched_check_wake(&usb_ep0_wake))
return;
if (usb_xfer_flags)
usb_do_xfer(usb_xfer_data, usb_xfer_size, usb_xfer_flags);
usb_do_xfer2(usb_xfer_data, usb_xfer_size, usb_xfer_flags
, usb_xfer_complete);
else
usb_state_ready();
}

View file

@ -83,13 +83,25 @@ can_init(void)
// Setup canbus
can2040_setup(&cbus, 0);
can2040_callback_config(&cbus, can2040_cb);
canhw_start(CONFIG_CANBUS_FREQUENCY);
}
DECL_INIT(can_init);
void
canhw_start(uint32_t canbus_frequency)
{
// Enable irqs
armcm_enable_irq(PIOx_IRQHandler, PIO0_IRQ_0_IRQn, 1);
// Start canbus
uint32_t pclk = get_pclock_frequency(RESETS_RESET_PIO0_RESET);
can2040_start(&cbus, pclk, CONFIG_CANBUS_FREQUENCY
can2040_start(&cbus, pclk, canbus_frequency
, CONFIG_RPXXXX_CANBUS_GPIO_RX, CONFIG_RPXXXX_CANBUS_GPIO_TX);
}
DECL_INIT(can_init);
void
canhw_stop(void)
{
can2040_stop(&cbus);
NVIC_DisableIRQ(PIO0_IRQ_0_IRQn);
}

View file

@ -300,10 +300,16 @@ can_init(void)
gpio_peripheral(GPIO_Rx, CAN_FUNCTION, 1);
gpio_peripheral(GPIO_Tx, CAN_FUNCTION, 0);
canhw_start(CONFIG_CANBUS_FREQUENCY);
}
DECL_INIT(can_init);
void
canhw_start(uint32_t canbus_frequency)
{
uint32_t pclock = get_pclock_frequency((uint32_t)SOC_CAN);
uint32_t btr = compute_btr(pclock, CONFIG_CANBUS_FREQUENCY);
uint32_t btr = compute_btr(pclock, canbus_frequency);
/*##-1- Configure the CAN #######################################*/
@ -335,4 +341,14 @@ can_init(void)
armcm_enable_irq(CAN_IRQHandler, CAN_SCE_IRQn, 0);
SOC_CAN->IER = CAN_IER_FMPIE0 | CAN_IER_ERRIE | CAN_IER_LECIE;
}
DECL_INIT(can_init);
void
canhw_stop(void)
{
NVIC_DisableIRQ(CAN_RX0_IRQn);
if (CAN_RX0_IRQn != CAN_RX1_IRQn)
NVIC_DisableIRQ(CAN_RX1_IRQn);
if (CAN_RX0_IRQn != CAN_TX_IRQn)
NVIC_DisableIRQ(CAN_TX_IRQn);
SOC_CAN->IER &= ~CAN_IER_FMPIE0;
}

View file

@ -324,10 +324,16 @@ can_init(void)
gpio_peripheral(GPIO_Rx, CAN_FUNCTION, 1);
gpio_peripheral(GPIO_Tx, CAN_FUNCTION, 0);
canhw_start(CONFIG_CANBUS_FREQUENCY);
}
DECL_INIT(can_init);
void
canhw_start(uint32_t canbus_frequency)
{
uint32_t pclock = get_pclock_frequency((uint32_t)SOC_CAN);
uint32_t btr = compute_btr(pclock, CONFIG_CANBUS_FREQUENCY);
uint32_t btr = compute_btr(pclock, canbus_frequency);
/*##-1- Configure the CAN #######################################*/
@ -371,4 +377,11 @@ can_init(void)
SOC_CAN->ILE = FDCAN_ILE_EINT0;
SOC_CAN->IE = FDCAN_IE_RF0NE | FDCAN_IE_TC | FDCAN_IE_PEDE | FDCAN_IE_PEAE;
}
DECL_INIT(can_init);
void
canhw_stop(void)
{
NVIC_DisableIRQ(CAN_IT0_IRQn);
SOC_CAN->ILE &= ~FDCAN_ILE_EINT0;
SOC_CAN->IE &= ~(FDCAN_IE_RF0NE | FDCAN_IE_TC);
}