15 , bus( config.channel,
25 (void)spi_init( config.channel,
28 spi_set_format( config.channel,
34 spi_set_slave( config.channel,
37 gpio_set_function(config.mosi, GPIO_FUNC_SPI);
38 gpio_set_function(config.miso, GPIO_FUNC_SPI);
39 gpio_set_function(config.sck, GPIO_FUNC_SPI);
42 gpio_set_dir(config.cs,
true);
43 gpio_put(config.cs,
true);
49 if (
const auto rxSize = rxNodes.size())
52 pinMode(config.interrupt, INPUT);
55 digitalPinToInterrupt(config.interrupt),
58 auto self = static_cast<CanBusSpi*>(p);
60 if (self->bus.readMessage(&msg) == MCP2515::ERROR_OK)
62 self->rxBuffer.push_back(msg);
69 constexpr size_t Mcp2515MaxFilterCount = 6;
70 if (rxSize <= Mcp2515MaxFilterCount)
72 bus.setFilterMask(MCP2515::MASK0,
false, 0x7FF);
73 bus.setFilterMask(MCP2515::MASK1,
false, 0x7FF);
75 constexpr MCP2515::RXF filters[] = { MCP2515::RXF0, MCP2515::RXF1, MCP2515::RXF2, MCP2515::RXF3, MCP2515::RXF4, MCP2515::RXF5 };
77 for (
size_t i = 0; i < Mcp2515MaxFilterCount; ++i)
80 bus.setFilter(filters[i],
false, rxNodes[i].
id);
82 bus.setFilter(filters[i],
false, 0x7FF);
87 bus.setBitrate(config.canBaudrate, config.mcpClock);
99 inline CanBusSpi::operator bool()
const
101 return not(txTimeout() or rxTimeout());
104 inline bool CanBusSpi::txTimeout()
const
107 return millis() - transmitMs >= config.transmitTimeout;
112 inline bool CanBusSpi::rxTimeout()
const
115 return millis() - receiveMs >= config.receiveTimeout;
124 if (txNodes.size() and millis() - transmitMs >= config.transmitInterval)
127 transmitMs = millis();
134 Serial.print(
"CanBusSpiPico\n");
136 for (
auto&& node : txNodes)
138 Serial.print(
"\tTX ");
140 Serial.printf(
"0x%03x ",
static_cast<int>(node.id));
142 Serial.printf(
"%2zu byte ", node.data.size());
144 Serial.print(node.data.size() > SingleFrameSize ?
"(multi frame) " :
"(single frame) ");
148 for (
const auto& data : node.data)
150 Serial.printf(
"%4d", data);
158 for (
auto&& rxNode : rxNodes)
160 Serial.print(
"\tRX ");
162 Serial.printf(
"0x%03x ",
static_cast<int>(rxNode.id));
164 Serial.printf(
"%2zu byte ", rxNode.data.size());
166 Serial.print(rxNode.data.size() > SingleFrameSize ?
"(multi frame) " :
"(single frame) ");
170 for (
const auto& data : rxNode.data)
172 Serial.printf(
"%4d", data);
186 auto it = std::find_if(txNodes.begin(), txNodes.end(), [
id](
const CanTxNode& tx)
187 { return tx.id == id; });
188 if (it == txNodes.end())
190 txNodes.push_back({ id, std::vector<uint8_t>(length), 0 });
191 return &txNodes.back();
204 std::vector<uint8_t>(length),
209 return &rxNodes.back();
212 inline void CanBusSpi::onReceive()
214 for (
auto&& msg : rxBuffer)
217 auto it = std::find_if(rxNodes.begin(), rxNodes.end(), [msg](
const CanRxNode& rx)
218 { return rx.id == msg.can_id; });
219 if (it == rxNodes.end())
229 if (it->data.size() > SingleFrameSize)
232 const auto index = std::ceil(
static_cast<double>(it->data.size()) / (SingleFrameSize - 1 )) - 1;
234 if (msg.data[0] == index)
245 receiveMs = it->transmitMs = millis();
250 inline void CanBusSpi::onTransmit()
252 for (
auto&& node : txNodes)
255 msg.can_id = node.id;
256 msg.can_dlc = SingleFrameSize;
262 bus.sendMessage(&msg);
263 delayMicroseconds(200);
266 node.transmitMs = millis();
CanTxNode * createTx(uint32_t id, size_t length) override
バスに送信ノードを追加
Definition CanBusSpiPico.hpp:184
void begin()
通信開始
Definition CanBusSpiPico.hpp:23
void show() const
バスの状態を表示する
Definition CanBusSpiPico.hpp:132
void update()
バス更新
Definition CanBusSpiPico.hpp:121
CanBusSpi(const Config &config)
コンストラクタ
Definition CanBusSpiPico.hpp:13
CanRxNode * createRx(uint32_t id, size_t length) override
バスに受信ノードを参加させる
Definition CanBusSpiPico.hpp:200
void end()
通信終了
Definition CanBusSpiPico.hpp:93
void Packetize(Udon::ArrayView< const uint8_t > &&input, Udon::ArrayView< uint8_t > &&output, size_t singlePacketSize, Function func)
バイト列を複数のパケット、単一のパケットにパケット化する
Definition CanUtility.hpp:24
void Unpacketize(Udon::ArrayView< const uint8_t > &&input, Udon::ArrayView< uint8_t > &&output, size_t singlePacketSize)
複数のパケット、単一のパケットからバイト列にアンパケット化する
Definition CanUtility.hpp:83
設定
Definition CanBusSpiPico.hpp:28
CAN受信ノード
Definition ICanBus.hpp:28
CAN送信ノード
Definition ICanBus.hpp:17