mirror of
https://github.com/andreili/katapult.git
synced 2025-08-23 19:34:06 +02:00
canbus: Resync canbus code with upstream Klipper code
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
e3e72b8642
commit
2b22438c01
@ -4,19 +4,23 @@
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include "canbus.h" // canbus_send
|
||||
#include "canserial.h" // canserial_send
|
||||
#include "autoconf.h" // CONFIG_CANBUS_FREQUENCY
|
||||
#include "canbus.h" // canhw_send
|
||||
#include "canserial.h" // canserial_notify_tx
|
||||
#include "command.h" // DECL_CONSTANT
|
||||
|
||||
DECL_CONSTANT("CANBUS_FREQUENCY", CONFIG_CANBUS_FREQUENCY);
|
||||
|
||||
int
|
||||
canserial_send(struct canbus_msg *msg)
|
||||
canbus_send(struct canbus_msg *msg)
|
||||
{
|
||||
return canbus_send(msg);
|
||||
return canhw_send(msg);
|
||||
}
|
||||
|
||||
void
|
||||
canserial_set_filter(uint32_t id)
|
||||
canbus_set_filter(uint32_t id)
|
||||
{
|
||||
canbus_set_filter(id);
|
||||
canhw_set_filter(id);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -18,10 +18,12 @@ struct canbus_msg {
|
||||
#define CANMSG_DATA_LEN(msg) ((msg)->dlc > 8 ? 8 : (msg)->dlc)
|
||||
|
||||
// callbacks provided by board specific code
|
||||
int canbus_send(struct canbus_msg *msg);
|
||||
void canbus_set_filter(uint32_t id);
|
||||
int canhw_send(struct canbus_msg *msg);
|
||||
void canhw_set_filter(uint32_t id);
|
||||
|
||||
// canbus.c
|
||||
int canbus_send(struct canbus_msg *msg);
|
||||
void canbus_set_filter(uint32_t id);
|
||||
void canbus_notify_tx(void);
|
||||
void canbus_process_data(struct canbus_msg *msg);
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "board/io.h" // readb
|
||||
#include "board/irq.h" // irq_save
|
||||
#include "board/misc.h" // console_sendf
|
||||
#include "canbus.h" // canbus_set_uuid
|
||||
#include "canbus.h" // canbus_send
|
||||
#include "canserial.h" // canserial_notify_tx
|
||||
#include "command.h" // DECL_CONSTANT
|
||||
#include "fasthash.h" // fasthash64
|
||||
@ -68,7 +68,7 @@ canserial_tx_task(void)
|
||||
break;
|
||||
msg.dlc = now;
|
||||
memcpy(msg.data, &CanData.transmit_buf[tpos], now);
|
||||
int ret = canserial_send(&msg);
|
||||
int ret = canbus_send(&msg);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
tpos += now;
|
||||
@ -153,7 +153,7 @@ can_process_query_unassigned(struct canbus_msg *msg)
|
||||
send.data[7] = CANBUS_CMD_SET_CANBOOT_NODEID;
|
||||
// Send with retry
|
||||
for (;;) {
|
||||
int ret = canserial_send(&send);
|
||||
int ret = canbus_send(&send);
|
||||
if (ret >= 0)
|
||||
return;
|
||||
}
|
||||
@ -170,7 +170,7 @@ static void
|
||||
can_id_conflict(void)
|
||||
{
|
||||
CanData.assigned_id = 0;
|
||||
canserial_set_filter(CanData.assigned_id);
|
||||
canbus_set_filter(CanData.assigned_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -182,7 +182,7 @@ can_process_set_canboot_nodeid(struct canbus_msg *msg)
|
||||
if (can_check_uuid(msg)) {
|
||||
if (newid != CanData.assigned_id) {
|
||||
CanData.assigned_id = newid;
|
||||
canserial_set_filter(CanData.assigned_id);
|
||||
canbus_set_filter(CanData.assigned_id);
|
||||
}
|
||||
} else if (newid == CanData.assigned_id) {
|
||||
can_id_conflict();
|
||||
|
@ -6,13 +6,9 @@
|
||||
#define CANBUS_ID_ADMIN 0x3f0
|
||||
#define CANBUS_ID_ADMIN_RESP 0x3f1
|
||||
|
||||
// callbacks provided by board specific code
|
||||
struct canbus_msg;
|
||||
int canserial_send(struct canbus_msg *msg);
|
||||
void canserial_set_filter(uint32_t id);
|
||||
|
||||
// canserial.c
|
||||
void canserial_notify_tx(void);
|
||||
struct canbus_msg;
|
||||
int canserial_process_data(struct canbus_msg *msg);
|
||||
void canserial_set_uuid(uint8_t *raw_uuid, uint32_t raw_uuid_len);
|
||||
|
||||
|
@ -26,7 +26,7 @@ static struct can2040 cbus;
|
||||
|
||||
// Transmit a packet
|
||||
int
|
||||
canbus_send(struct canbus_msg *msg)
|
||||
canhw_send(struct canbus_msg *msg)
|
||||
{
|
||||
int ret = can2040_transmit(&cbus, (void*)msg);
|
||||
if (ret < 0)
|
||||
@ -36,7 +36,7 @@ canbus_send(struct canbus_msg *msg)
|
||||
|
||||
// Setup the receive packet filter
|
||||
void
|
||||
canbus_set_filter(uint32_t id)
|
||||
canhw_set_filter(uint32_t id)
|
||||
{
|
||||
// Filter not implemented (and not necessary)
|
||||
}
|
||||
|
@ -92,7 +92,7 @@
|
||||
|
||||
// Transmit a packet
|
||||
int
|
||||
canbus_send(struct canbus_msg *msg)
|
||||
canhw_send(struct canbus_msg *msg)
|
||||
{
|
||||
uint32_t tsr = SOC_CAN->TSR;
|
||||
if (!(tsr & (CAN_TSR_TME0|CAN_TSR_TME1|CAN_TSR_TME2))) {
|
||||
@ -129,7 +129,7 @@ canbus_send(struct canbus_msg *msg)
|
||||
|
||||
// Setup the receive packet filter
|
||||
void
|
||||
canbus_set_filter(uint32_t id)
|
||||
canhw_set_filter(uint32_t id)
|
||||
{
|
||||
/* Select the start slave bank */
|
||||
SOC_CAN->FMR |= CAN_FMR_FINIT;
|
||||
@ -268,7 +268,7 @@ can_init(void)
|
||||
;
|
||||
|
||||
/*##-2- Configure the CAN Filter #######################################*/
|
||||
canbus_set_filter(0);
|
||||
canhw_set_filter(0);
|
||||
|
||||
/*##-3- Configure Interrupts #################################*/
|
||||
armcm_enable_irq(CAN_IRQHandler, CAN_RX0_IRQn, 0);
|
||||
|
@ -1,84 +1,107 @@
|
||||
// Serial over CAN emulation for STM32 boards.
|
||||
// FDCAN support on stm32 chips
|
||||
//
|
||||
// Copyright (C) 2021-2022 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2019 Eug Krashtan <eug.krashtan@gmail.com>
|
||||
// Copyright (C) 2020 Pontus Borg <glpontus@gmail.com>
|
||||
// Copyright (C) 2021 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <string.h> // memcpy
|
||||
#include "autoconf.h" // CONFIG_MACH_STM32F1
|
||||
#include "board/irq.h" // irq_disable
|
||||
#include "command.h" // DECL_CONSTANT_STR
|
||||
#include "generic/armcm_boot.h" // armcm_enable_irq
|
||||
#include "generic/canbus.h" // canbus_notify_tx
|
||||
#include "generic/canserial.h" // CANBUS_ID_ADMIN
|
||||
#include "generic/serial_irq.h" // serial_rx_byte
|
||||
#include "internal.h" // enable_pclock
|
||||
#include "sched.h" // DECL_INIT
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t id_section;
|
||||
__IO uint32_t dlc_section;
|
||||
__IO uint32_t data[64 / 4];
|
||||
}FDCAN_FIFO_TypeDef;
|
||||
|
||||
#define FDCAN_XTD (1<<30)
|
||||
#define FDCAN_RTR (1<<29)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t FLS[28]; // Filter list standard
|
||||
__IO uint32_t FLE[16]; // Filter list extended
|
||||
FDCAN_FIFO_TypeDef RXF0[3];
|
||||
FDCAN_FIFO_TypeDef RXF1[3];
|
||||
__IO uint32_t TEF[6]; // Tx event FIFO
|
||||
FDCAN_FIFO_TypeDef TXFIFO[3];
|
||||
}FDCAN_MSG_RAM_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FDCAN_MSG_RAM_TypeDef fdcan1;
|
||||
FDCAN_MSG_RAM_TypeDef fdcan2;
|
||||
}FDCAN_RAM_TypeDef;
|
||||
|
||||
FDCAN_RAM_TypeDef *fdcan_ram = (FDCAN_RAM_TypeDef *)(SRAMCAN_BASE);
|
||||
|
||||
#define FDCAN_IE_TC (FDCAN_IE_TCE | FDCAN_IE_TCFE | FDCAN_IE_TFEE)
|
||||
/****************************************************************
|
||||
* Pin configuration
|
||||
****************************************************************/
|
||||
|
||||
#if CONFIG_STM32_CANBUS_PA11_PA12
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PA12");
|
||||
#define GPIO_Rx GPIO('A', 11)
|
||||
#define GPIO_Tx GPIO('A', 12)
|
||||
#elif CONFIG_STM32_CANBUS_PA11_PB9
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PB9");
|
||||
#define GPIO_Rx GPIO('A', 11)
|
||||
#define GPIO_Tx GPIO('B', 9)
|
||||
#elif CONFIG_STM32_CANBUS_PB8_PB9
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB8,PB9");
|
||||
#define GPIO_Rx GPIO('B', 8)
|
||||
#define GPIO_Tx GPIO('B', 9)
|
||||
#elif CONFIG_STM32_CANBUS_PD0_PD1
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PD0,PD1");
|
||||
#define GPIO_Rx GPIO('D', 0)
|
||||
#define GPIO_Tx GPIO('D', 1)
|
||||
#elif CONFIG_STM32_CANBUS_PD12_PD13
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PD12,PD13");
|
||||
#define GPIO_Rx GPIO('D', 12)
|
||||
#define GPIO_Tx GPIO('D', 13)
|
||||
#elif CONFIG_STM32_CANBUS_PB0_PB1
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB0,PB1");
|
||||
#define GPIO_Rx GPIO('B', 0)
|
||||
#define GPIO_Tx GPIO('B', 1)
|
||||
#elif CONFIG_STM32_CANBUS_PC2_PC3
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PC2,PC3");
|
||||
#define GPIO_Rx GPIO('C', 2)
|
||||
#define GPIO_Tx GPIO('C', 3)
|
||||
#endif
|
||||
|
||||
#if !CONFIG_STM32_CANBUS_PB0_PB1
|
||||
#if !(CONFIG_STM32_CANBUS_PB0_PB1 || CONFIG_STM32_CANBUS_PC2_PC3)
|
||||
#define SOC_CAN FDCAN1
|
||||
#define MSG_RAM fdcan_ram->fdcan1
|
||||
#define MSG_RAM (((struct fdcan_ram_layout*)SRAMCAN_BASE)->fdcan1)
|
||||
#else
|
||||
#define SOC_CAN FDCAN2
|
||||
#define MSG_RAM fdcan_ram->fdcan2
|
||||
#define MSG_RAM (((struct fdcan_ram_layout*)SRAMCAN_BASE)->fdcan2)
|
||||
#endif
|
||||
|
||||
#define CAN_IT0_IRQn TIM16_FDCAN_IT0_IRQn
|
||||
#define CAN_FUNCTION GPIO_FUNCTION(3) // Alternative function mapping number
|
||||
|
||||
#ifndef SOC_CAN
|
||||
#error No known CAN device for configured MCU
|
||||
#if CONFIG_MACH_STM32G0
|
||||
#define CAN_IT0_IRQn TIM16_FDCAN_IT0_IRQn
|
||||
#define CAN_FUNCTION GPIO_FUNCTION(3) // Alternative function mapping number
|
||||
#elif CONFIG_MACH_STM32H7 || CONFIG_MACH_STM32G4
|
||||
#define CAN_IT0_IRQn FDCAN1_IT0_IRQn
|
||||
#define CAN_FUNCTION GPIO_FUNCTION(9) // Alternative function mapping number
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Message ram layout
|
||||
****************************************************************/
|
||||
|
||||
struct fdcan_fifo {
|
||||
uint32_t id_section;
|
||||
uint32_t dlc_section;
|
||||
uint32_t data[64 / 4];
|
||||
};
|
||||
|
||||
#define FDCAN_XTD (1<<30)
|
||||
#define FDCAN_RTR (1<<29)
|
||||
|
||||
struct fdcan_msg_ram {
|
||||
uint32_t FLS[28]; // Filter list standard
|
||||
uint32_t FLE[16]; // Filter list extended
|
||||
struct fdcan_fifo RXF0[3];
|
||||
struct fdcan_fifo RXF1[3];
|
||||
uint32_t TEF[6]; // Tx event FIFO
|
||||
struct fdcan_fifo TXFIFO[3];
|
||||
};
|
||||
|
||||
struct fdcan_ram_layout {
|
||||
struct fdcan_msg_ram fdcan1;
|
||||
struct fdcan_msg_ram fdcan2;
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* CANbus code
|
||||
****************************************************************/
|
||||
|
||||
#define FDCAN_IE_TC (FDCAN_IE_TCE | FDCAN_IE_TCFE | FDCAN_IE_TFEE)
|
||||
|
||||
// Transmit a packet
|
||||
int
|
||||
canbus_send(struct canbus_msg *msg)
|
||||
canhw_send(struct canbus_msg *msg)
|
||||
{
|
||||
uint32_t txfqs = SOC_CAN->TXFQS;
|
||||
if (txfqs & FDCAN_TXFQS_TFQF)
|
||||
@ -86,7 +109,7 @@ canbus_send(struct canbus_msg *msg)
|
||||
return -1;
|
||||
|
||||
uint32_t w_index = ((txfqs & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
|
||||
FDCAN_FIFO_TypeDef *txfifo = &MSG_RAM.TXFIFO[w_index];
|
||||
struct fdcan_fifo *txfifo = &MSG_RAM.TXFIFO[w_index];
|
||||
uint32_t ids;
|
||||
if (msg->id & CANMSG_ID_EFF)
|
||||
ids = (msg->id & 0x1fffffff) | FDCAN_XTD;
|
||||
@ -97,6 +120,7 @@ canbus_send(struct canbus_msg *msg)
|
||||
txfifo->dlc_section = (msg->dlc & 0x0f) << 16;
|
||||
txfifo->data[0] = msg->data32[0];
|
||||
txfifo->data[1] = msg->data32[1];
|
||||
barrier();
|
||||
SOC_CAN->TXBAR = ((uint32_t)1 << w_index);
|
||||
return CANMSG_DATA_LEN(msg);
|
||||
}
|
||||
@ -112,7 +136,7 @@ can_filter(uint32_t index, uint32_t id)
|
||||
|
||||
// Setup the receive packet filter
|
||||
void
|
||||
canbus_set_filter(uint32_t id)
|
||||
canhw_set_filter(uint32_t id)
|
||||
{
|
||||
if (!CONFIG_CANBUS_FILTER)
|
||||
return;
|
||||
@ -128,10 +152,18 @@ canbus_set_filter(uint32_t id)
|
||||
can_filter(0, CANBUS_ID_ADMIN);
|
||||
can_filter(1, id);
|
||||
can_filter(2, id + 1);
|
||||
|
||||
#if CONFIG_MACH_STM32G0
|
||||
SOC_CAN->RXGFC = ((id ? 3 : 1) << FDCAN_RXGFC_LSS_Pos
|
||||
| 0x02 << FDCAN_RXGFC_ANFS_Pos);
|
||||
#elif CONFIG_MACH_STM32H7 || CONFIG_MAC_STM32G4
|
||||
uint32_t flssa = (uint32_t)MSG_RAM.FLS - SRAMCAN_BASE;
|
||||
SOC_CAN->SIDFC = flssa | ((id ? 3 : 1) << FDCAN_SIDFC_LSS_Pos);
|
||||
SOC_CAN->GFC = 0x02 << FDCAN_GFC_ANFS_Pos;
|
||||
#endif
|
||||
|
||||
/* Leave the initialisation mode for the filter */
|
||||
barrier();
|
||||
SOC_CAN->CCCR &= ~FDCAN_CCCR_CCE;
|
||||
SOC_CAN->CCCR &= ~FDCAN_CCCR_INIT;
|
||||
}
|
||||
@ -149,7 +181,7 @@ CAN_IRQHandler(void)
|
||||
if (rxf0s & FDCAN_RXF0S_F0FL) {
|
||||
// Read and ack data packet
|
||||
uint32_t idx = (rxf0s & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos;
|
||||
FDCAN_FIFO_TypeDef *rxf0 = &MSG_RAM.RXF0[idx];
|
||||
struct fdcan_fifo *rxf0 = &MSG_RAM.RXF0[idx];
|
||||
uint32_t ids = rxf0->id_section;
|
||||
struct canbus_msg msg;
|
||||
if (ids & FDCAN_XTD)
|
||||
@ -160,6 +192,7 @@ CAN_IRQHandler(void)
|
||||
msg.dlc = (rxf0->dlc_section >> 16) & 0x0f;
|
||||
msg.data32[0] = rxf0->data[0];
|
||||
msg.data32[1] = rxf0->data[1];
|
||||
barrier();
|
||||
SOC_CAN->RXF0A = idx;
|
||||
|
||||
// Process packet
|
||||
@ -251,15 +284,25 @@ can_init(void)
|
||||
|
||||
SOC_CAN->NBTP = btr;
|
||||
|
||||
#if CONFIG_MACH_STM32H7 || CONFIG_MAC_STM32G4
|
||||
/* Setup message RAM addresses */
|
||||
uint32_t f0sa = (uint32_t)MSG_RAM.RXF0 - SRAMCAN_BASE;
|
||||
SOC_CAN->RXF0C = f0sa | (ARRAY_SIZE(MSG_RAM.RXF0) << FDCAN_RXF0C_F0S_Pos);
|
||||
SOC_CAN->RXESC = (7 << FDCAN_RXESC_F1DS_Pos) | (7 << FDCAN_RXESC_F0DS_Pos);
|
||||
uint32_t tbsa = (uint32_t)MSG_RAM.TXFIFO - SRAMCAN_BASE;
|
||||
SOC_CAN->TXBC = tbsa | (ARRAY_SIZE(MSG_RAM.TXFIFO) << FDCAN_TXBC_TFQS_Pos);
|
||||
SOC_CAN->TXESC = 7 << FDCAN_TXESC_TBDS_Pos;
|
||||
#endif
|
||||
|
||||
/* Leave the initialisation mode */
|
||||
SOC_CAN->CCCR &= ~FDCAN_CCCR_CCE;
|
||||
SOC_CAN->CCCR &= ~FDCAN_CCCR_INIT;
|
||||
|
||||
/*##-2- Configure the CAN Filter #######################################*/
|
||||
canbus_set_filter(0);
|
||||
canhw_set_filter(0);
|
||||
|
||||
/*##-3- Configure Interrupts #################################*/
|
||||
armcm_enable_irq(CAN_IRQHandler, CAN_IT0_IRQn, 0);
|
||||
armcm_enable_irq(CAN_IRQHandler, CAN_IT0_IRQn, 1);
|
||||
SOC_CAN->ILE = FDCAN_ILE_EINT0;
|
||||
SOC_CAN->IE = FDCAN_IE_RF0NE | FDCAN_IE_TC;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user