init can bus

This commit is contained in:
Travis Shears 2025-09-06 21:25:11 +02:00
parent 9c3f8e0b3f
commit 6adf5dca28
5 changed files with 180 additions and 0 deletions

View file

@ -18,6 +18,8 @@ project(test C CXX ASM)
pico_sdk_init()
# == NODE 1 ==
# the executable
add_executable( node1 node1.c bme280.c pms5003.c )
pico_set_program_version(node1 "0.1")
@ -29,6 +31,8 @@ target_link_libraries( node1 pico_stdlib hardware_i2c)
# create map/bin/hex file etc.
pico_add_extra_outputs( node1 )
# == WIFI SCAN ==
add_executable(wifi_scan wifi_scan.c)
target_include_directories(wifi_scan PRIVATE
${CMAKE_CURRENT_LIST_DIR}
@ -42,6 +46,7 @@ target_link_libraries(wifi_scan
pico_add_extra_outputs(wifi_scan)
# == MQTT TEST ==
# Define the host name of the MQTT server in an environment variable or pass it to cmake,
# e.g. cmake -DMQTT_SERVER=myserver ..
@ -94,3 +99,11 @@ target_compile_definitions(${TARGET_NAME} PRIVATE
)
pico_add_extra_outputs(${TARGET_NAME})
# == CAN BUS SENDER TEST ==
add_executable( can_bus_sender_test can_bus_sender_test.c can_bus.c )
pico_set_program_version(can_bus_sender_test "0.1")
pico_set_program_name(can_bus_sender_test "Can Bus Sender Test")
target_link_libraries(can_bus_sender_test pico_stdlib hardware_spi)
pico_add_extra_outputs(can_bus_sender_test)

109
can_bus.c Normal file
View file

@ -0,0 +1,109 @@
#include "can_bus.h"
// https://docs.cirkitdesigner.com/component/a4fea22c-a62d-453b-8645-1c8efe324cbc/mcp2515
// https://learn.adafruit.com/adafruit-picowbell-can-bus-for-pico/overview
// Pico Lib: https://github.com/adamczykpiotr/pico-mcp2515
// Arduino Lib: https://github.com/autowp/arduino-mcp2515
// MCP2515 is the cheap aliexpress boards I have
// spi_inst_t* CHANNEL = spi0;
// uint32_t SPI_CLOCK = DEFAULT_SPI_CLOCK
//
//
// 10000000 //10Mhz
#define MCP_SPI_CLOCK 5000000 // 5Mhz
#define MCP_INSTRUCTION_RESET 0xC0
#define MCP_INSTRUCTION_WRITE 0x02
void mcp2515_init(mcp2515_config *config, uint8_t cs_pin, uint8_t tx_pin,
uint8_t rx_pin, uint8_t sck_pin, spi_inst_t *spi_inst) {
config->CHANNEL = spi_inst;
config->CS_PIN = cs_pin;
spi_init(config->CHANNEL, MCP_SPI_CLOCK);
gpio_set_function(rx_pin, GPIO_FUNC_SPI);
gpio_set_function(sck_pin, GPIO_FUNC_SPI);
gpio_set_function(tx_pin, GPIO_FUNC_SPI);
spi_set_format(config->CHANNEL, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
// Chip select is active-low, so we'll initialise it to a driven-high state
gpio_init(config->CS_PIN);
gpio_set_dir(config->CS_PIN, GPIO_OUT);
// gpio_put(cs_pin, 0);
}
static void mcp2515_start_spi(mcp2515_config *config) {
asm volatile("nop \n nop \n nop");
gpio_put(config->CS_PIN, 0);
asm volatile("nop \n nop \n nop");
}
static void mcp2515_end_spi(mcp2515_config *config) {
asm volatile("nop \n nop \n nop");
gpio_put(config->CS_PIN, 1);
asm volatile("nop \n nop \n nop");
}
static void mcp2515_set_registers(mcp2515_config *config, const uint8_t reg,
const uint8_t values[], const uint8_t n) {
mcp2515_start_spi(config);
uint8_t data[2] = {MCP_INSTRUCTION_WRITE, reg};
spi_write_blocking(config->CHANNEL, data, 2);
spi_write_blocking(config->CHANNEL, values, n);
mcp2515_end_spi(config);
}
enum MCP_ERROR mcp2515_reset(mcp2515_config *config) {
mcp2515_start_spi(config);
uint8_t instruction = MCP_INSTRUCTION_RESET;
spi_write_blocking(config->CHANNEL, &instruction, 1);
mcp2515_end_spi(config);
sleep_ms(10);
uint8_t zeros[14];
memset(zeros, 0, sizeof(zeros));
// setRegisters(MCP_TXB0CTRL, zeros, 14);
// setRegisters(MCP_TXB1CTRL, zeros, 14);
// setRegisters(MCP_TXB2CTRL, zeros, 14);
// setRegister(MCP_RXB0CTRL, 0);
// setRegister(MCP_RXB1CTRL, 0);
// setRegister(MCP_CANINTE,
// CANINTF_RX0IF | CANINTF_RX1IF | CANINTF_ERRIF | CANINTF_MERRF);
// receives all valid messages using either Standard or Extended Identifiers
// that meet filter criteria. RXF0 is applied for RXB0, RXF1 is applied for
// RXB1
// modifyRegister(MCP_RXB0CTRL,
// RXBnCTRL_RXM_MASK | RXB0CTRL_BUKT | RXB0CTRL_FILHIT_MASK,
// RXBnCTRL_RXM_STDEXT | RXB0CTRL_BUKT | RXB0CTRL_FILHIT);
// modifyRegister(MCP_RXB1CTRL, RXBnCTRL_RXM_MASK | RXB1CTRL_FILHIT_MASK,
// RXBnCTRL_RXM_STDEXT | RXB1CTRL_FILHIT);
// clear filters and masks
// do not filter any standard frames for RXF0 used by RXB0
// do not filter any extended frames for RXF1 used by RXB1
// RXF filters[] = {RXF0, RXF1, RXF2, RXF3, RXF4, RXF5};
// for (int i = 0; i < 6; i++) {
// bool ext = (i == 1);
// ERROR result = setFilter(filters[i], ext, 0);
// if (result != ERROR_OK) {
// return result;
// }
// }
// MASK masks[] = {MASK0, MASK1};
// for (int i = 0; i < 2; i++) {
// ERROR result = setFilterMask(masks[i], true, 0);
// if (result != ERROR_OK) {
// return result;
// }
// }
return ERROR_OK;
}
// mcp2515.setBitrate(CAN_125KBPS);
// mcp2515.setLoopbackMode();

38
can_bus.h Normal file
View file

@ -0,0 +1,38 @@
#include "boards/pico.h"
#include "hardware/spi.h"
#include "pico/stdlib.h"
#include "pico/time.h"
// 16MHz 125Kbps
#define MCP_CFG1 (0x03)
#define MCP_CFG2 (0xF0)
#define MCP_CFG3 (0x86)
typedef struct {
spi_inst_t *CHANNEL;
uint8_t CS_PIN;
// uint8_t TX_PIN;
// uint8_t RX_PIN;
// uint8_t SCK_PIN;
// uint32_t SPI_CLOCK;
} mcp2515_config;
struct can_frame {
uint32_t can_id; // 32 bit CAN_ID + EFF/RTR/ERR flags
char can_dlc; // frame payload length in byte (0 .. CAN_MAX_DLEN) */
char data[8]; // msg
};
enum MCP_ERROR {
ERROR_OK = 0,
ERROR_FAIL = 1,
ERROR_ALLTXBUSY = 2,
ERROR_FAILINIT = 3,
ERROR_FAILTX = 4,
ERROR_NOMSG = 5
};
void mcp2515_init(mcp2515_config *config, uint8_t cs_pin, uint8_t tx_pin,
uint8_t rx_pin, uint8_t sck_pin, spi_inst_t *spi_inst);
enum MCP_ERROR sendMessage(const struct can_frame *frame);
enum MPC_ERROR readMessage(struct can_frame *frame);

0
can_bus_reader_test.c Normal file
View file

20
can_bus_sender_test.c Normal file
View file

@ -0,0 +1,20 @@
#include "pico/stdlib.h"
#include <hardware/gpio.h>
#include <hardware/spi.h>
#include "can_bus.h"
static mcp2515_config can_bus_config;
int main() {
stdio_init_all();
// Setup BME280
mcp2515_init(&can_bus_config, 13, 11, 12, 10, spi1);
while (true) {
// TODO: send message
// mcp2515.reset();
sleep_ms(1000);
// tight_loop_contents();
}
}