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