mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-12-24 08:38:34 -07:00
add SLCAN
Signed-off-by: Findlay Feng <i@fengch.me>
This commit is contained in:
parent
8c7693c048
commit
d86f28d2ed
4 changed files with 547 additions and 16 deletions
|
|
@ -50,7 +50,7 @@ source "src/simulator/Kconfig"
|
|||
config SERIAL
|
||||
bool
|
||||
config SERIAL_BAUD
|
||||
depends on SERIAL
|
||||
depends on SERIAL || SERIAL_CANBUS
|
||||
int "Baud rate for serial port" if LOW_LEVEL_OPTIONS
|
||||
default 250000
|
||||
help
|
||||
|
|
@ -261,9 +261,11 @@ endmenu
|
|||
# Generic configuration options for CANbus
|
||||
config CANSERIAL
|
||||
bool
|
||||
config SERIAL_CANBUS
|
||||
bool
|
||||
config CANBUS
|
||||
bool
|
||||
default y if CANSERIAL || USBCANBUS
|
||||
default y if CANSERIAL || USBCANBUS || SERIAL_CANBUS
|
||||
config CANBUS_FREQUENCY
|
||||
int "CAN bus speed" if LOW_LEVEL_OPTIONS && CANBUS
|
||||
default 1000000
|
||||
|
|
|
|||
410
src/generic/slcan.c
Normal file
410
src/generic/slcan.c
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
// Support for Linux "slcan" CANbus adapter emulation
|
||||
//
|
||||
// Copyright (C) 2025 Findlay Feng <i@fengch.me>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include "autoconf.h"
|
||||
#include "board/irq.h"
|
||||
#include "canbus.h"
|
||||
#include "canserial.h"
|
||||
#include "command.h"
|
||||
#include "sched.h"
|
||||
#include "serial_irq.h"
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
DECL_CONSTANT("CANBUS_FREQUENCY", CONFIG_CANBUS_FREQUENCY);
|
||||
|
||||
#define SLCAN_RX_BUFF_SIZE 128
|
||||
#define SLCAN_RX_BUFF_MAKS 127
|
||||
|
||||
#define SLCAN_TX_QUEUE_SIZE 16
|
||||
#define SLCAN_TX_QUEUE_MAKS 15
|
||||
|
||||
// CAN2.0A
|
||||
#define SLCAN_MTU (sizeof("t11181122334455667788EA5F\r") + 1)
|
||||
|
||||
// CAN2.0B
|
||||
// #define SLCAN_MTU (sizeof("T1111222281122334455667788EA5F\r") + 1)
|
||||
|
||||
union slcan_frame
|
||||
{
|
||||
struct
|
||||
{
|
||||
char cmd;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
char id[3];
|
||||
char dcl;
|
||||
char data[16];
|
||||
char timestamp[4];
|
||||
} __packed;
|
||||
char cmd_data[SLCAN_MTU - 1];
|
||||
};
|
||||
} __packed;
|
||||
char buff[SLCAN_MTU];
|
||||
};
|
||||
|
||||
static struct slcan_data
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t count;
|
||||
char buff[SLCAN_RX_BUFF_SIZE];
|
||||
} rx;
|
||||
|
||||
struct
|
||||
{
|
||||
char *head;
|
||||
uint32_t offset;
|
||||
uint32_t count;
|
||||
uint32_t working;
|
||||
union slcan_frame queue[SLCAN_TX_QUEUE_SIZE];
|
||||
} tx;
|
||||
|
||||
uint32_t assigned_id;
|
||||
} slcan = {0};
|
||||
|
||||
static inline uint8_t hex2int(char c)
|
||||
{
|
||||
uint8_t ret = c - '0';
|
||||
|
||||
if (ret < 10)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return (c - 'A' + 10) & 0xf;
|
||||
}
|
||||
|
||||
static inline char int2hex(uint8_t i)
|
||||
{
|
||||
i &= 0xf;
|
||||
|
||||
return i + (i < 10 ? '0' : 'A' - 10);
|
||||
}
|
||||
|
||||
static int get_canbus_msg_for_slcan_frame(struct canbus_msg *msg,
|
||||
union slcan_frame const *slcan_f)
|
||||
{
|
||||
msg->id = hex2int(slcan_f->id[0]) << 8 | hex2int(slcan_f->id[1]) << 4 |
|
||||
hex2int(slcan_f->id[2]);
|
||||
msg->dlc = hex2int(slcan_f->dcl);
|
||||
|
||||
if (msg->dlc > 8)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
char const *data = slcan_f->data;
|
||||
for (int i = 0; i < msg->dlc; i++)
|
||||
{
|
||||
uint8_t tmp = hex2int(*(data++)) << 4;
|
||||
msg->data[i] = tmp | hex2int(*(data++));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_slcan_frame_for_canbus_msg(union slcan_frame *slcan_f,
|
||||
struct canbus_msg const *msg)
|
||||
{
|
||||
uint32_t id = msg->id;
|
||||
slcan_f->id[0] = int2hex(id >> 8);
|
||||
slcan_f->id[1] = int2hex(id >> 4);
|
||||
slcan_f->id[2] = int2hex(id);
|
||||
|
||||
uint8_t dlc = msg->dlc;
|
||||
if (dlc > 8)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
slcan_f->cmd = 't';
|
||||
slcan_f->dcl = int2hex(dlc);
|
||||
|
||||
char *data = slcan_f->data;
|
||||
for (int i = 0; i < dlc; i++)
|
||||
{
|
||||
uint8_t tmp = msg->data[i];
|
||||
*(data++) = int2hex(tmp >> 4);
|
||||
*(data++) = int2hex(tmp);
|
||||
}
|
||||
|
||||
*(data++) = '\r';
|
||||
*data = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void serial_rx_byte(uint_fast8_t data)
|
||||
{
|
||||
uint32_t count = slcan.rx.count;
|
||||
if (count - slcan.rx.offset >= SLCAN_RX_BUFF_SIZE)
|
||||
{
|
||||
// todo_error();
|
||||
return;
|
||||
}
|
||||
|
||||
slcan.rx.buff[(count++) & SLCAN_RX_BUFF_MAKS] = data;
|
||||
slcan.rx.count = count;
|
||||
|
||||
if (data == '\r')
|
||||
{
|
||||
sched_wake_tasks();
|
||||
}
|
||||
}
|
||||
|
||||
int serial_get_tx_byte(uint8_t *pdata)
|
||||
{
|
||||
char *head = slcan.tx.head;
|
||||
char c = head == NULL ? '\0' : *head;
|
||||
|
||||
while (c == '\0')
|
||||
{
|
||||
uint32_t offset = slcan.tx.offset;
|
||||
if (offset == slcan.tx.count)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
head = slcan.tx.queue[(offset++) & SLCAN_TX_QUEUE_MAKS].buff;
|
||||
slcan.tx.offset = offset;
|
||||
slcan.tx.head = head;
|
||||
|
||||
c = *head;
|
||||
}
|
||||
|
||||
*pdata = c;
|
||||
slcan.tx.head = head + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _slcan_send(int *format(union slcan_frame *slcan_frame,
|
||||
char const *data),
|
||||
char const *data)
|
||||
{
|
||||
uint32_t working;
|
||||
|
||||
irq_disable();
|
||||
if ((slcan.tx.count - (slcan.tx.offset + slcan.tx.working)) >=
|
||||
SLCAN_TX_QUEUE_SIZE)
|
||||
{
|
||||
irq_enable();
|
||||
return -1;
|
||||
}
|
||||
|
||||
working = slcan.tx.working++;
|
||||
irq_enable();
|
||||
|
||||
uint32_t count = slcan.tx.count + working;
|
||||
|
||||
union slcan_frame *f = &slcan.tx.queue[count & SLCAN_TX_QUEUE_MAKS];
|
||||
|
||||
int ret = 0;
|
||||
if (format(f, data))
|
||||
{
|
||||
*f->buff = '\0';
|
||||
ret = -2;
|
||||
};
|
||||
|
||||
irq_disable();
|
||||
|
||||
if (working == 0)
|
||||
{
|
||||
slcan.tx.count += slcan.tx.working;
|
||||
slcan.tx.working = 0;
|
||||
serial_enable_tx_irq();
|
||||
}
|
||||
|
||||
irq_enable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int slcan_frame_fill(union slcan_frame *dest_frame,
|
||||
union slcan_frame const *src_frame)
|
||||
{
|
||||
strncpy((char *)dest_frame, (char const *)src_frame,
|
||||
sizeof(union slcan_frame));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define slcan_send(c, f) \
|
||||
_slcan_send((int *(*)(union slcan_frame *, const char *))(c), \
|
||||
(char const *)(f))
|
||||
|
||||
static int slcan_send_frame(union slcan_frame const *f)
|
||||
{
|
||||
return slcan_send(slcan_frame_fill, f);
|
||||
}
|
||||
|
||||
static int slcan_send_msg(struct canbus_msg const *msg)
|
||||
{
|
||||
return slcan_send(get_slcan_frame_for_canbus_msg, msg);
|
||||
}
|
||||
|
||||
static const uint32_t slcan_bitrate_const[] = {
|
||||
10000, 20000, 50000, 100000, 125000, 250000, 500000, 800000, 1000000};
|
||||
|
||||
#define ERROR ((union slcan_frame const *)"\a")
|
||||
#define OK ((union slcan_frame const *)"\r")
|
||||
|
||||
static int frame_dump(union slcan_frame const *f)
|
||||
{
|
||||
switch (f->cmd)
|
||||
{
|
||||
case 'C':
|
||||
case 'O':
|
||||
slcan_send_frame(OK);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
uint8_t index = f->cmd_data[0] - '0';
|
||||
|
||||
if (index > 8)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
uint32_t s = slcan_bitrate_const[index];
|
||||
|
||||
if (s != CONFIG_CANBUS_FREQUENCY)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
slcan_send_frame(OK);
|
||||
|
||||
break;
|
||||
|
||||
case 't':
|
||||
struct canbus_msg msg;
|
||||
if (get_canbus_msg_for_slcan_frame(&msg, f) != 0)
|
||||
{
|
||||
goto error;
|
||||
};
|
||||
|
||||
uint32_t id = msg.id;
|
||||
if (id == slcan.assigned_id)
|
||||
{
|
||||
canserial_process_data(&msg);
|
||||
slcan_send_frame(OK);
|
||||
break;
|
||||
}
|
||||
|
||||
if (canhw_send(&msg) < 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
slcan_send_frame(OK);
|
||||
if (id == CANBUS_ID_ADMIN)
|
||||
{
|
||||
canserial_process_data(&msg);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
error:
|
||||
slcan_send_frame(ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static union slcan_frame slcan_tmp = {0};
|
||||
static char *next = slcan_tmp.buff;
|
||||
static int sync_next = 0;
|
||||
void slcan_task(void)
|
||||
{
|
||||
while (slcan.rx.offset != slcan.rx.count)
|
||||
{
|
||||
|
||||
uint32_t offset = slcan.rx.offset;
|
||||
|
||||
char c = slcan.rx.buff[offset++ & SLCAN_RX_BUFF_MAKS];
|
||||
|
||||
if (sync_next)
|
||||
{
|
||||
if (c == '\r')
|
||||
{
|
||||
sync_next = 0;
|
||||
}
|
||||
|
||||
goto next_char;
|
||||
}
|
||||
|
||||
if (c == '\r')
|
||||
{
|
||||
if (next < slcan_tmp.data)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
int dlc = hex2int(slcan_tmp.dcl);
|
||||
|
||||
if (dlc > 8 || next < &slcan_tmp.data[dlc << 1])
|
||||
{
|
||||
goto next_frame;
|
||||
}
|
||||
|
||||
*next = c;
|
||||
*(next + 1) = '\0';
|
||||
|
||||
if (frame_dump(&slcan_tmp) == -2)
|
||||
{
|
||||
sched_wake_tasks();
|
||||
return;
|
||||
}
|
||||
|
||||
goto next_frame;
|
||||
}
|
||||
|
||||
if (!isprint(c))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (next - slcan_tmp.buff >= sizeof(slcan_tmp))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
*(next++) = c;
|
||||
|
||||
next_char:
|
||||
slcan.rx.offset = offset;
|
||||
continue;
|
||||
error:
|
||||
sync_next = 1;
|
||||
next_frame:
|
||||
slcan.rx.offset = offset;
|
||||
next = slcan_tmp.buff;
|
||||
}
|
||||
}
|
||||
|
||||
DECL_TASK(slcan_task);
|
||||
|
||||
int canbus_send(struct canbus_msg *msg)
|
||||
{
|
||||
if (slcan_send_msg(msg))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return msg->dlc;
|
||||
}
|
||||
|
||||
void canbus_set_filter(uint32_t id) { slcan.assigned_id = id; }
|
||||
|
||||
void canbus_notify_tx(void) { sched_wake_tasks(); }
|
||||
|
||||
void canbus_process_data(struct canbus_msg *msg) { slcan_send_msg(msg); }
|
||||
|
|
@ -168,6 +168,10 @@ config HAVE_STM32_USBCANBUS
|
|||
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
|
||||
depends on !MACH_STM32F1
|
||||
default y
|
||||
config HAVE_STM32_SLCAN
|
||||
bool
|
||||
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
|
||||
default y
|
||||
|
||||
config MCU
|
||||
string
|
||||
|
|
@ -397,50 +401,133 @@ choice
|
|||
bool "USB (on PB14/PB15)"
|
||||
depends on MACH_STM32H743 || MACH_STM32H750
|
||||
select USBSERIAL
|
||||
config STM32_SERIAL_USART1
|
||||
config STM32_DIRECT_SERIAL_USART1
|
||||
bool "Serial (on USART1 PA10/PA9)"
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART1_ALT_PB7_PB6
|
||||
select STM32_SERIAL_USART1
|
||||
config STM32_DIRECT_SERIAL_USART1_ALT_PB7_PB6
|
||||
bool "Serial (on USART1 PB7/PB6)" if LOW_LEVEL_OPTIONS
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART2
|
||||
select STM32_SERIAL_USART1_ALT_PB7_PB6
|
||||
config STM32_DIRECT_SERIAL_USART2
|
||||
bool "Serial (on USART2 PA3/PA2)" if LOW_LEVEL_OPTIONS
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART2_ALT_PA15_PA14
|
||||
select STM32_SERIAL_USART2
|
||||
config STM32_DIRECT_SERIAL_USART2_ALT_PA15_PA14
|
||||
bool "Serial (on USART2 PA15/PA14)" if LOW_LEVEL_OPTIONS && (MACH_STM32F0 || MACH_STM32G4)
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART2_ALT_PB4_PB3
|
||||
select STM32_SERIAL_USART2_ALT_PA15_PA14
|
||||
config STM32_DIRECT_SERIAL_USART2_ALT_PB4_PB3
|
||||
bool "Serial (on USART2 PB4/PB3)" if LOW_LEVEL_OPTIONS && MACH_STM32G4
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART2_ALT_PD6_PD5
|
||||
select STM32_SERIAL_USART2_ALT_PB4_PB3
|
||||
config STM32_DIRECT_SERIAL_USART2_ALT_PD6_PD5
|
||||
bool "Serial (on USART2 PD6/PD5)" if LOW_LEVEL_OPTIONS && !MACH_STM32F0
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART3
|
||||
select STM32_SERIAL_USART2_ALT_PD6_PD5
|
||||
config STM32_DIRECT_SERIAL_USART3
|
||||
bool "Serial (on USART3 PB11/PB10)" if LOW_LEVEL_OPTIONS
|
||||
depends on !MACH_STM32F0 && !MACH_STM32F401
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART3_ALT_PD9_PD8
|
||||
select STM32_SERIAL_USART3
|
||||
config STM32_DIRECT_SERIAL_USART3_ALT_PD9_PD8
|
||||
bool "Serial (on USART3 PD9/PD8)" if LOW_LEVEL_OPTIONS
|
||||
depends on !MACH_STM32F0 && !MACH_STM32F401
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART3_ALT_PC11_PC10
|
||||
select STM32_SERIAL_USART3_ALT_PD9_PD8
|
||||
config STM32_DIRECT_SERIAL_USART3_ALT_PC11_PC10
|
||||
bool "Serial (on USART3 PC11/PC10)" if LOW_LEVEL_OPTIONS
|
||||
depends on MACH_STM32G474
|
||||
select SERIAL
|
||||
config STM32_SERIAL_UART4
|
||||
select STM32_SERIAL_USART3_ALT_PC11_PC10
|
||||
config STM32_DIRECT_SERIAL_UART4
|
||||
bool "Serial (on UART4 PA0/PA1)"
|
||||
depends on MACH_STM32H7
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART5
|
||||
select STM32_SERIAL_UART4
|
||||
config STM32_DIRECT_SERIAL_USART5
|
||||
bool "Serial (on USART5 PD2/PD3)" if LOW_LEVEL_OPTIONS
|
||||
depends on MACH_STM32G0Bx
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART6
|
||||
select STM32_SERIAL_USART5
|
||||
config STM32_DIRECT_SERIAL_USART6
|
||||
bool "Serial (on USART6 PA12/PA11)" if LOW_LEVEL_OPTIONS && MACH_STM32F401
|
||||
select SERIAL
|
||||
config STM32_SERIAL_USART6_ALT_PC7_PC6
|
||||
select STM32_SERIAL_USART6
|
||||
config STM32_DIRECT_SERIAL_USART6_ALT_PC7_PC6
|
||||
bool "Serial (on USART6 PC7/PC6)" if LOW_LEVEL_OPTIONS && MACH_STM32F401
|
||||
select SERIAL
|
||||
select STM32_SERIAL_USART6_ALT_PC7_PC6
|
||||
config STM32_SLCAN_USART1
|
||||
bool "SLCAN bus bridge (Serial on USART1 PA10/PA9)"
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART1
|
||||
config STM32_SLCAN_USART1_ALT_PB7_PB6
|
||||
bool "SLCAN bus bridge (Serial on USART1 PB7/PB6)" if LOW_LEVEL_OPTIONS
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART1_ALT_PB7_PB6
|
||||
config STM32_SLCAN_USART2
|
||||
bool "SLCAN bus bridge (Serial on USART2 PA3/PA2)" if LOW_LEVEL_OPTIONS
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART2
|
||||
config STM32_SLCAN_USART2_ALT_PA15_PA14
|
||||
bool "SLCAN bus bridge (Serial on USART2 PA15/PA14)" if LOW_LEVEL_OPTIONS && (MACH_STM32F0 || MACH_STM32G4)
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART2_ALT_PA15_PA14
|
||||
config STM32_SLCAN_USART2_ALT_PB4_PB3
|
||||
bool "SLCAN bus bridge (Serial on USART2 PB4/PB3)" if LOW_LEVEL_OPTIONS && MACH_STM32G4
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART2_ALT_PB4_PB3
|
||||
config STM32_SLCAN_USART2_ALT_PD6_PD5
|
||||
bool "SLCAN bus bridge (Serial on USART2 PD6/PD5)" if LOW_LEVEL_OPTIONS && !MACH_STM32F0
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART2_ALT_PD6_PD5
|
||||
config STM32_SLCAN_USART3
|
||||
bool "SLCAN bus bridge (Serial on USART3 PB11/PB10)" if LOW_LEVEL_OPTIONS
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
depends on !MACH_STM32F0 && !MACH_STM32F401
|
||||
select STM32_SERIAL_USART3
|
||||
config STM32_SLCAN_USART3_ALT_PD9_PD8
|
||||
bool "SLCAN bus bridge (Serial on USART3 PD9/PD8)" if LOW_LEVEL_OPTIONS
|
||||
depends on HAVE_STM32_SLCAN
|
||||
depends on !MACH_STM32F0 && !MACH_STM32F401
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART3_ALT_PD9_PD8
|
||||
config STM32_SLCAN_USART3_ALT_PC11_PC10
|
||||
bool "SLCAN bus bridge (Serial on USART3 PC11/PC10)" if LOW_LEVEL_OPTIONS
|
||||
depends on HAVE_STM32_SLCAN
|
||||
depends on MACH_STM32G474
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART3_ALT_PC11_PC10
|
||||
config STM32_SLCAN_UART4
|
||||
bool "SLCAN bus bridge (Serial on UART4 PA0/PA1)"
|
||||
depends on HAVE_STM32_SLCAN
|
||||
depends on MACH_STM32H7
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_UART4
|
||||
config STM32_SLCAN_USART5
|
||||
bool "SLCAN bus bridge (Serial on USART5 PD2/PD3)" if LOW_LEVEL_OPTIONS
|
||||
depends on HAVE_STM32_SLCAN
|
||||
depends on MACH_STM32G0Bx
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART5
|
||||
config STM32_SLCAN_USART6
|
||||
bool "SLCAN bus bridge (Serial on USART6 PA12/PA11)" if LOW_LEVEL_OPTIONS && MACH_STM32F401
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART6
|
||||
config STM32_SLCAN_USART6_ALT_PC7_PC6
|
||||
bool "SLCAN bus bridge (Serial on USART6 PC7/PC6)" if LOW_LEVEL_OPTIONS && MACH_STM32F401
|
||||
depends on HAVE_STM32_SLCAN
|
||||
select SERIAL_CANBUS
|
||||
select STM32_SERIAL_USART6_ALT_PC7_PC6
|
||||
config STM32_CANBUS_PA11_PA12
|
||||
bool "CAN bus (on PA11/PA12)"
|
||||
depends on HAVE_STM32_CANBUS || HAVE_STM32_FDCANBUS
|
||||
|
|
@ -495,7 +582,7 @@ choice
|
|||
select USBCANBUS
|
||||
endchoice
|
||||
choice
|
||||
prompt "CAN bus interface" if USBCANBUS
|
||||
prompt "CAN bus interface" if USBCANBUS || SERIAL_CANBUS
|
||||
config STM32_CMENU_CANBUS_PB8_PB9
|
||||
bool "CAN bus (on PB8/PB9)"
|
||||
config STM32_CMENU_CANBUS_PI9_PH13
|
||||
|
|
@ -524,6 +611,37 @@ choice
|
|||
depends on HAVE_STM32_FDCANBUS
|
||||
endchoice
|
||||
|
||||
config STM32_SERIAL_USART1
|
||||
bool
|
||||
config STM32_SERIAL_USART1_ALT_PB7_PB6
|
||||
bool
|
||||
config STM32_SERIAL_USART2
|
||||
bool
|
||||
config STM32_SERIAL_USART2_ALT_PA15_PA14
|
||||
bool
|
||||
config STM32_SERIAL_USART2_ALT_PB4_PB3
|
||||
bool
|
||||
config STM32_SERIAL_USART2_ALT_PD6_PD5
|
||||
bool
|
||||
config STM32_SERIAL_USART3
|
||||
bool
|
||||
depends on !MACH_STM32F0 && !MACH_STM32F401
|
||||
config STM32_SERIAL_USART3_ALT_PD9_PD8
|
||||
bool
|
||||
depends on !MACH_STM32F0 && !MACH_STM32F401
|
||||
config STM32_SERIAL_USART3_ALT_PC11_PC10
|
||||
bool
|
||||
depends on MACH_STM32G474
|
||||
config STM32_SERIAL_UART4
|
||||
bool
|
||||
depends on MACH_STM32H7
|
||||
config STM32_SERIAL_USART5
|
||||
bool
|
||||
depends on MACH_STM32G0Bx
|
||||
config STM32_SERIAL_USART6
|
||||
bool
|
||||
config STM32_SERIAL_USART6_ALT_PC7_PC6
|
||||
bool
|
||||
|
||||
config STM32_CANBUS_PB8_PB9
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ src-$(CONFIG_USBSERIAL) += $(usb-src-y) stm32/chipid.c generic/usb_cdc.c
|
|||
canbus-src-y := generic/canserial.c ../lib/fast-hash/fasthash.c
|
||||
canbus-src-$(CONFIG_HAVE_STM32_CANBUS) += stm32/can.c
|
||||
canbus-src-$(CONFIG_HAVE_STM32_FDCANBUS) += stm32/fdcan.c
|
||||
src-$(CONFIG_SERIAL_CANBUS) += $(serial-src-y) $(canbus-src-y) generic/slcan.c stm32/chipid.c
|
||||
src-$(CONFIG_CANSERIAL) += $(canbus-src-y) generic/canbus.c stm32/chipid.c
|
||||
src-$(CONFIG_USBCANBUS) += $(usb-src-y) $(canbus-src-y)
|
||||
src-$(CONFIG_USBCANBUS) += stm32/chipid.c generic/usb_canbus.c
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue