From a0c6601cda5d504abb5317f28c1df9a37c09c00a Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Mon, 6 Jul 2026 13:36:53 -0700 Subject: [PATCH] Unify Send/Read error enums --- src/avclan/avclan.h | 57 ++++++++++++++++++++++ src/avclan/avclan.hpp | 35 ------------- src/avclan/avclan_defs.h | 25 ---------- src/avclan/avclan_phy.h | 8 ++- src/avclan/bus.cc | 17 +------ src/avclan/bus.hpp | 2 +- src/avclan/cdchanger.hpp | 2 +- src/avclan/device.hpp | 2 +- src/avclan/target/avr-attiny3216/phy_avr.c | 10 ++-- 9 files changed, 73 insertions(+), 85 deletions(-) create mode 100644 src/avclan/avclan.h delete mode 100644 src/avclan/avclan.hpp diff --git a/src/avclan/avclan.h b/src/avclan/avclan.h new file mode 100644 index 0000000..572fa3a --- /dev/null +++ b/src/avclan/avclan.h @@ -0,0 +1,57 @@ +// Copyright (C) 2026 Allen Hill +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#ifdef __cplusplus + #include + #define AVCLAN_ENUM_CLASS enum class +#else + #include + #define AVCLAN_ENUM_CLASS enum +#endif + +#ifdef __cplusplus +namespace avclan::detail { +struct Error { +#endif + + // Error enums are ordered such that a lower numeric value corresponds to + // more progress/success before an error occured, with 0 being no errors + AVCLAN_ENUM_CLASS Read : uint8_t { + BAD_DATA_PARITY = 0x01, + BAD_LENGTH_RANGE, + BAD_LENGTH_PARITY, + BAD_PERIPHERAL_PARITY, + BAD_CONTROLLER_PARITY, + BAD_CONTROL_PARITY, + BAD_PARITY, // non-specific bad parity + STARTBIT_TOO_SHORT, + STARTBIT_TOO_LONG, + BAD_STARTBIT, +} +// #ifndef __cplusplus +// Read +// #endif +; + + AVCLAN_ENUM_CLASS Send : uint8_t { + NAK_DATA = 0x01, + NAK_MESSAGE_LENGTH, + NAK_CONTROL, + NAK_ADDRESS, + NAK, // non-specific NAK + BUSY, + MUTED, +} +// #ifndef __cplusplus +// Send +// #endif +; + +#ifdef __cplusplus +}; +} // namespace avclan::detail +#endif + +#undef AVCLAN_ENUM_CLASS diff --git a/src/avclan/avclan.hpp b/src/avclan/avclan.hpp deleted file mode 100644 index ce43014..0000000 --- a/src/avclan/avclan.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2026 Allen Hill -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include - -namespace avclan::detail { -struct Error { - // Error enums are ordered such that a lower numeric value corresponds to - // more progress/success before an error occured, with 0 being no errors - enum class Read : uint8_t { - BAD_DATA_PARITY = 0x01, - BAD_LENGTH_RANGE, - BAD_LENGTH_PARITY, - BAD_PERIPHERAL_PARITY, - BAD_CONTROLLER_PARITY, - BAD_CONTROL_PARITY, - BAD_PARITY, // non-specific bad parity - STARTBIT_TOO_SHORT, - STARTBIT_TOO_LONG, - BAD_STARTBIT, - }; - - enum class Send : uint8_t { - NAK_DATA = 0x01, - NAK_MESSAGE_LENGTH, - NAK_CONTROL, - NAK_ADDRESS, - NAK, // non-specific NAK - BUSY, - MUTED, - }; -}; -} // namespace avclan::detail diff --git a/src/avclan/avclan_defs.h b/src/avclan/avclan_defs.h index b279258..7de56b9 100644 --- a/src/avclan/avclan_defs.h +++ b/src/avclan/avclan_defs.h @@ -111,28 +111,3 @@ typedef enum avclan_bit : uint8_t { bit_one = 0x01, bit_start = 0x10 } avclan_bit_t; - -// Error enums are ordered such that a lower numeric value corresponds to more -// progress/success before an error occured, with 0 being no errors -typedef enum : uint8_t { - rNO_ERROR = 0x00, - rBAD_DATA_PARITY = 0x01, - rBAD_LENGTH_RANGE, - rBAD_LENGTH_PARITY, - rBAD_PERIPHERAL_PARITY, - rBAD_CONTROLLER_PARITY, - rBAD_CONTROL_PARITY, - rSTARTBIT_TOO_SHORT, - rSTARTBIT_TOO_LONG, - rLATCHED_COMPARATOR, -} avclan_readerr_t; - -typedef enum : uint8_t { - sNO_ERROR = 0x00, - sNAK_DATA = 0x01, - sNAK_MESSAGE_LENGTH, - sNAK_CONTROL, - sNAK_ADDRESS, - sBUSY, - sMUTED, -} avclan_senderr_t; diff --git a/src/avclan/avclan_phy.h b/src/avclan/avclan_phy.h index 02ee202..441f6f9 100644 --- a/src/avclan/avclan_phy.h +++ b/src/avclan/avclan_phy.h @@ -7,10 +7,14 @@ #include +#include "avclan.h" #include "avclan_defs.h" #ifdef __cplusplus +using Read = avclan::detail::Error::Read; extern "C" { +#else +typedef enum Read Read; #endif // One-time bring-up of the bus hardware. Leaves the bus idle and TX unmuted. @@ -33,10 +37,10 @@ void AVCLAN_startEvent(void); // Start-bit handling, factored out of read/sendframe so the framing layer holds // no bus-timing or hardware-recovery logic. // - AVCLAN_readstartbit waits for and validates an incoming start bit, doing -// any target-specific bus recovery; see avclan_readerr_t. +// any target-specific bus recovery; see avclan::detail::Error::Read. // - AVCLAN_sendstartbit acquires the bus and emits a start bit; returns false // if the bus was busy. -avclan_readerr_t AVCLAN_readstartbit(void); +Read AVCLAN_readstartbit(void); bool AVCLAN_sendstartbit(void); // Per-symbol I/O. The send* helpers return the even parity of the bits sent; diff --git a/src/avclan/bus.cc b/src/avclan/bus.cc index 7a117b4..f6e5ab0 100644 --- a/src/avclan/bus.cc +++ b/src/avclan/bus.cc @@ -30,7 +30,7 @@ */ #include "bus.hpp" -#include "avclan.hpp" +#include "avclan.h" #include "avclan_defs.h" #include "avclan_phy.h" // bridge until phy has been ported #include "com232.h" @@ -280,20 +280,7 @@ auto Bus::send(const Frame *out, Frame::Print print) -> Error::Send { Bus::Handle Bus::get() { return {}; }; bool Bus::Handle::sendstartbit() { return AVCLAN_sendstartbit(); }; -auto Bus::Handle::readstartbit() -> Read { - using enum Error::Read; - auto err = AVCLAN_readstartbit(); - if (err == rSTARTBIT_TOO_LONG) - return STARTBIT_TOO_LONG; - - if (err == rLATCHED_COMPARATOR) - return BAD_STARTBIT; - - if (err == rSTARTBIT_TOO_SHORT) - return STARTBIT_TOO_SHORT; - - return Read{0}; -}; +auto Bus::Handle::readstartbit() -> Read { return AVCLAN_readstartbit(); }; void Bus::Handle::send_ACK() { AVCLAN_sendbit_ACK(); }; uint8_t Bus::Handle::read_ACK() { return AVCLAN_readbit_ACK(); }; diff --git a/src/avclan/bus.hpp b/src/avclan/bus.hpp index 2043f99..f7888cf 100644 --- a/src/avclan/bus.hpp +++ b/src/avclan/bus.hpp @@ -50,7 +50,7 @@ #include #include -#include "avclan.hpp" +#include "avclan.h" #include "avclan_defs.h" #include "avclan_phy.h" // bridge until phy has been ported #include "frame.hpp" diff --git a/src/avclan/cdchanger.hpp b/src/avclan/cdchanger.hpp index de53afb..72ee47c 100644 --- a/src/avclan/cdchanger.hpp +++ b/src/avclan/cdchanger.hpp @@ -7,7 +7,7 @@ #include -#include "avclan.hpp" +#include "avclan.h" #include "avclan_defs.h" #include "frame.hpp" diff --git a/src/avclan/device.hpp b/src/avclan/device.hpp index e85f411..4c0f996 100644 --- a/src/avclan/device.hpp +++ b/src/avclan/device.hpp @@ -3,7 +3,7 @@ #pragma once -#include "avclan.hpp" +#include "avclan.h" #include "frame.hpp" #include diff --git a/src/avclan/target/avr-attiny3216/phy_avr.c b/src/avclan/target/avr-attiny3216/phy_avr.c index a858103..6d1523c 100644 --- a/src/avclan/target/avr-attiny3216/phy_avr.c +++ b/src/avclan/target/avr-attiny3216/phy_avr.c @@ -328,18 +328,18 @@ void AVCLAN_busInit() { // (AC2 latched high because the bus is actually floating) this kicks PA7 hard // high to unlatch the comparator. The framing layer maps the result to its own // error reporting; no printing happens here. -avclan_readerr_t AVCLAN_readstartbit() { +Read AVCLAN_readstartbit() { uint16_t startbitlen = TCB1.CNT = 0; while (!BUS_IS_IDLE) { startbitlen = TCB1.CNT; if (startbitlen > (uint16_t)AVCLAN_STARTBIT_LOGIC_0 * 1.2) { - avclan_readerr_t result = rSTARTBIT_TOO_LONG; + Read result = STARTBIT_TOO_LONG; while (!BUS_IS_IDLE) { // If bus is "driven" too long, assume the AC2 is latched (e.g. // because the bus is actually floating). Kick it if so. // This should prevent/resolve a flood of "STARTBIT_TOO_LONG" errors if (TCB1.CNT > (uint16_t)(AVCLAN_STARTBIT_LOGIC_0 * 3)) { - result = rLATCHED_COMPARATOR; + result = BAD_STARTBIT; PORTA.OUTSET = PIN7_bm; // preset high before enabling the driver PORTA.DIRSET = PIN7_bm; // drive (-) hard high TCB1.CNT = 0; @@ -363,9 +363,9 @@ avclan_readerr_t AVCLAN_readstartbit() { if (!BUS_IS_IDLE) TCB1.CNT = 0; } - return rSTARTBIT_TOO_SHORT; + return STARTBIT_TOO_SHORT; } - return rNO_ERROR; // that was a start bit + return (Read)0; // that was a start bit } // Acquire the bus and emit a start bit. Returns false if another device is