diff --git a/src/shared/radio/CC3135/CC3135.cpp b/src/shared/radio/CC3135/CC3135.cpp index d3ff6ffd6b1118d4fef7a003c3cb93fbbe4f0885..761607147cd4f89f9782431447816f62d769379b 100644 --- a/src/shared/radio/CC3135/CC3135.cpp +++ b/src/shared/radio/CC3135/CC3135.cpp @@ -25,28 +25,39 @@ #include <kernel/scheduler/scheduler.h> #include <utils/Debug.h> -#define TRY(expr) \ - do \ - { \ - Boardcore::CC3135::Error result = (expr); \ - if (result != Boardcore::CC3135::Error::NO_ERROR) \ - { \ - TRACE("[cc3135] NWP error@ %s\n", __FUNCTION__); \ - return result; \ - } \ +#define TRY(expr) \ + do \ + { \ + Boardcore::CC3135::Error result = (expr); \ + if (result != Boardcore::CC3135::Error::NO_ERROR) \ + { \ + TRACE("[cc3135] Error: %s @ %s:%d\n", \ + Boardcore::CC3135::errorToStr(result), __FUNCTION__, \ + __LINE__); \ + return result; \ + } \ } while (0) using namespace Boardcore::CC3135Defs; using namespace miosix; +constexpr uint8_t TEST_CHANNEL = 6; + namespace Boardcore { -CC3135::CC3135(std::unique_ptr<ICC3135Iface> &&iface) : iface(std::move(iface)) +CC3135::CC3135(std::unique_ptr<ICC3135Iface> &&iface) + : iface(std::move(iface)), sd(-1) { irq_wait_thread = thread; } +CC3135::~CC3135() +{ + socketClose(sd); + sd = -1; +} + CC3135::Error CC3135::init(bool wait_for_init) { if (wait_for_init) @@ -66,16 +77,76 @@ CC3135::Error CC3135::init(bool wait_for_init) // Start internal thread this->start(); + // Setup transceiver mode + TRY(setupTransceiver()); + TRY(startRecv()); + + return Error::NO_ERROR; +} + +CC3135::Error CC3135::prepareForReset() +{ + // We need the device in station mode + TRY(wlanSetMode(ROLE_STA)); + + return Error::NO_ERROR; +} + +CC3135::Error CC3135::startRecv() { return socketRecv(sd, Buffer::null(), 0); } + +CC3135::Error CC3135::dummyRecv() { return socketRecv(sd, Buffer::null(), 0); } + +CC3135::Error CC3135::dummySend() +{ + struct Packet + { + uint32_t a = 0xdeadbabe; + uint32_t b = 0xdeadbeef; + uint32_t c = 0xbabebabe; + }; + + Packet packet; + + uint16_t flags = + makeWlanRawRfTxParams(TEST_CHANNEL, RATE_1M, 0, PREAMBLE_LONG); + TRY(socketSend2(sd, Buffer::from(&packet), flags)); + + return Error::NO_ERROR; +} + +CC3135::Error CC3135::setupTransceiver() +{ + // TODO: This should really set the device in the correct mode and re-init + + // Reset connection policies + TRY(wlanPolicySet(WLAN_POLICY_CONNECTION, 0, Buffer::null())); + + Error result = wlanDisconnect(); + + // Check for not errors and continue + if (result != Error::NO_ERROR && result != Error::WLAN_ALREADY_DISCONNECTED) + return result; + + // Open transceiver socket + // with respect of IEE802.11 medium access policies + TRY(socketOpen(AF_RF, SOCK_RAW, TEST_CHANNEL, sd)); + TRACE("[cc3135] Socket opened: %d\n", sd); + + // As a sanity check, verify the socket type + if (sdGetType(sd) != SdType::RAW_TRANSCEIVER) + return Error::GENERIC_ERROR; + return Error::NO_ERROR; } CC3135::Error CC3135::getVersion(DeviceVersion &version) { version = {}; - return devigeGet(1, 12, Buffer::from<DeviceVersion>(&version)); + return devigeGet(DEVICE_GENERAL, DEVICE_GENERAL_VERSION, + Buffer::from<DeviceVersion>(&version)); } -CC3135::Error CC3135::devigeGet(uint8_t set_id, uint8_t option, Buffer result) +CC3135::Error CC3135::devigeGet(uint8_t set_id, uint8_t option, Buffer value) { DeviceSetGet tx_command = {}; tx_command.device_set_id = set_id; @@ -83,31 +154,107 @@ CC3135::Error CC3135::devigeGet(uint8_t set_id, uint8_t option, Buffer result) DeviceSetGet rx_command = {}; - return inoutPacketSync(OPCODE_DEVICE_DEVICEGET, Buffer::from(&tx_command), - Buffer::null(), OPCODE_DEVICE_DEVICEGETRESPONSE, - Buffer::from(&rx_command), result); + TRY(inoutPacketSync(OPCODE_DEVICE_DEVICEGET, Buffer::from(&tx_command), + Buffer::null(), OPCODE_DEVICE_DEVICEGETRESPONSE, + Buffer::from(&rx_command), value)); + + return errorFromStatus(rx_command.status); } -CC3135::Error CC3135::dummyDeviceRead() +CC3135::Error CC3135::wlanSetMode(CC3135Defs::Mode mode) { - ResponseHeader header; - TRY(readHeader(&header)); + WlanSetMode tx_command = {}; + tx_command.mode = mode; - defaultPacketHandler(header); + BasicResponse rx_command = {}; - return Error::NO_ERROR; + TRY(inoutPacketSync(OPCODE_WLAN_SET_MODE, Buffer::from(&tx_command), + Buffer::null(), OPCODE_WLAN_SET_MODE_RESPONSE, + Buffer::from(&rx_command), Buffer::null())); + + return errorFromStatus(rx_command.status); } -CC3135::Error CC3135::setMode(CC3135Defs::Mode mode) +CC3135::Error CC3135::wlanPolicySet(uint8_t type, uint8_t option, Buffer value) { - WlanSetMode tx_command = {}; - tx_command.mode = mode; + WlanPolicySetGet tx_command = {}; + tx_command.policy_type = type; + tx_command.policy_option = option; + tx_command.policy_option_len = value.len; BasicResponse rx_command = {}; - return inoutPacketSync(OPCODE_WLAN_SET_MODE, Buffer::from(&tx_command), - Buffer::null(), OPCODE_WLAN_SET_MODE_RESPONSE, - Buffer::from(&rx_command), Buffer::null()); + TRY(inoutPacketSync(OPCODE_WLAN_POLICYSETCOMMAND, Buffer::from(&tx_command), + value, OPCODE_WLAN_POLICYSETRESPONSE, + Buffer::from(&rx_command), Buffer::null())); + + return errorFromStatus(rx_command.status); +} + +CC3135::Error CC3135::wlanDisconnect() +{ + BasicResponse rx_command = {}; + + TRY(inoutPacketSync(OPCODE_WLAN_WLANDISCONNECTCOMMAND, Buffer::null(), + Buffer::null(), OPCODE_WLAN_WLANDISCONNECTRESPONSE, + Buffer::from(&rx_command), Buffer::null())); + + return errorFromStatus(rx_command.status); +} + +CC3135::Error CC3135::socketOpen(uint8_t domain, uint8_t type, uint8_t protocol, + Sd &sd) +{ + SocketCommand tx_command = {}; + tx_command.domain = domain; + tx_command.type = type; + tx_command.protocol = protocol; + + SocketResponse rx_command = {}; + + TRY(inoutPacketSync(OPCODE_SOCKET_SOCKET, Buffer::from(&tx_command), + Buffer::null(), OPCODE_SOCKET_SOCKETRESPONSE, + Buffer::from(&rx_command), Buffer::null())); + + sd = rx_command.sd; + return errorFromStatus(rx_command.status_or_len); +} + +CC3135::Error CC3135::socketClose(Sd sd) +{ + CloseCommand tx_command = {}; + tx_command.sd = sd; + + SocketResponse rx_command = {}; + + TRY(inoutPacketSync(OPCODE_SOCKET_CLOSE, Buffer::from(&tx_command), + Buffer::null(), OPCODE_SOCKET_CLOSERESPONSE, + Buffer::from(&rx_command), Buffer::null())); + + return errorFromStatus(rx_command.status_or_len); +} + +CC3135::Error CC3135::socketRecv(Sd sd, Buffer buffer, uint16_t flags) +{ + SendRecvCommand tx_command = {}; + tx_command.sd = sd; + tx_command.status_or_len = 300; + tx_command.family_and_flags = flags & 0x0f; + + return writePacketSync(OPCODE_SOCKET_RECV, Buffer::from(&tx_command), + Buffer::null()); +} + +CC3135::Error CC3135::socketSend2(Sd sd, Buffer buffer, uint16_t flags) +{ + SendRecvCommand2 tx_command = {}; + tx_command.sd = sd; + tx_command.status_or_len = buffer.len; + tx_command.family_and_flags = flags & 0x0f; + tx_command.flags = flags; + + return writePacketSync(OPCODE_SOCKET_SEND, Buffer::from(&tx_command), + buffer); } void CC3135::handleIrq() @@ -162,24 +309,6 @@ void CC3135::restoreDefaultServiceThread() } } -void CC3135::defaultPacketHandler(CC3135Defs::ResponseHeader header) -{ - TRACE( - "[cc3135] Received packet:\n" - "- Opcode: %s (%4x)\n" - "- Status: %u\n" - "- Socket tx failures: %u\n" - "- Socket non blocking: %u\n", - opToStr(header.inner.opcode), header.inner.opcode, header.dev_status, - header.socket_tx_failure, header.socket_non_blocking); - - size_t len = header.inner.len; - - // Dummy read rest of the data - if (len > 0) - dummyRead(len); -} - void CC3135::run() { // TODO: Implement a way to stop this thread @@ -188,22 +317,83 @@ void CC3135::run() waitForIrq(); // Thread::sleep(500); + ResponseHeader header; { // Lock the device interface Lock<FastMutex> iface_lock(iface_mutex); - ResponseHeader header; Error result = readHeader(&header); if (result != Error::NO_ERROR) { - TRACE("[cc3135] NWP error!\n"); + TRACE("[cc3135] Error: %s\n", errorToStr(result)); + continue; } - else + + defaultPacketHandler(header); + } + } +} + +void CC3135::defaultPacketHandler(CC3135Defs::ResponseHeader header) +{ + TRACE( + "[cc3135] Received packet:\n" + "- Opcode: %s (%4x)\n" + "- Status: %u\n" + "- Socket tx failures: %u\n" + "- Socket non blocking: %u\n", + opToStr(header.inner.opcode), header.inner.opcode, header.dev_status, + header.socket_tx_failure, header.socket_non_blocking); + + size_t len = alignSize(header.inner.len); + + switch (header.inner.opcode) + { + case OPCODE_SOCKET_RECVASYNCRESPONSE: + { + SocketResponse rx_command = {}; + + safeRead(len, Buffer::from(&rx_command)); + + // 8 byte proprietary header, format information? + uint64_t header2; + safeRead(len, Buffer::from(&header2)); + rx_command.status_or_len -= 8; + + /* + notprintf("Header: %8x\n", header2); + + if (rx_command.status_or_len >= 0) { - defaultPacketHandler(header); + notprintf("%d %d\n", len, rx_command.status_or_len); + + uint8_t response[len]; + safeRead(len, Buffer{response, len}); + + for (int i = 0; i < rx_command.status_or_len; i++) + { + notprintf("%2x ", response[i]); + } + notprintf("\n"); } + */ + + break; } + default: + if (len > 0) + { + dummyRead(len); + len = 0; + } + }; + + // Dummy read rest of the data + if (len > 0) + { + TRACE("[cc3135] %d bytes still in receive buffer!\n", len); + dummyRead(len); } } @@ -268,7 +458,7 @@ CC3135::Error CC3135::readPacket(OpCode opcode, CC3135::Buffer command, else { // Read the rest of the packet - size_t len = header.inner.len; + size_t len = alignSize(header.inner.len); safeRead(len, command); safeRead(len, payload); @@ -287,8 +477,8 @@ CC3135::Error CC3135::readPacket(OpCode opcode, CC3135::Buffer command, CC3135::Error CC3135::writePacket(OpCode opcode, CC3135::Buffer command, CC3135::Buffer payload) { - RequestHeader header{opcode, - static_cast<uint16_t>(command.len + payload.len)}; + size_t len = alignSize(command.len + payload.len); + RequestHeader header{opcode, static_cast<uint16_t>(len)}; TRY(writeHeader(&header)); @@ -330,7 +520,7 @@ CC3135::Error CC3135::readHeader(ResponseHeader *header) while (true) { if ((getTick() - start) > TIMEOUT) - return Error::NWP_TIMEOUT; + return Error::SYNC_TIMEOUT; // Reads in SPI are always more than 4 bytes bool found = false; @@ -368,7 +558,7 @@ CC3135::Error CC3135::readHeader(ResponseHeader *header) while (n2hSyncPatternMatch(sync, tx_seq_num)) { if ((getTick() - start) > TIMEOUT) - return Error::NWP_TIMEOUT; + return Error::SYNC_TIMEOUT; memmove(&buf[0], &buf[4], 4); iface->read(&buf[4], 4); @@ -415,13 +605,8 @@ CC3135::Error CC3135::writeHeader(RequestHeader *header) void CC3135::dummyRead(size_t n) { // Avoid HUGE stack allocations - uint8_t dummy[256]; - - while (n > 0) - { - iface->read(dummy, std::min(n, sizeof(dummy))); - n -= std::min(n, sizeof(dummy)); - } + uint8_t dummy[n]; + iface->read(dummy, n); } void CC3135::safeRead(size_t &len, Buffer buffer) @@ -433,4 +618,38 @@ void CC3135::safeRead(size_t &len, Buffer buffer) } } +CC3135::Error CC3135::errorFromStatus(int16_t status) +{ + if (status >= 0) + { + return Error::NO_ERROR; + } + + TRACE("[cc3135] Non zero status: %d\n", status); + switch (status) + { + case -2071: + return Error::WLAN_ALREADY_DISCONNECTED; + default: + return Error::GENERIC_ERROR; + } +} + +const char *CC3135::errorToStr(Error error) +{ + switch (error) + { + case Error::NO_ERROR: + return "NO_ERROR"; + case Error::SYNC_TIMEOUT: + return "SYNC_TIMEOUT"; + case Error::GENERIC_ERROR: + return "GENERIC_ERROR"; + case Error::WLAN_ALREADY_DISCONNECTED: + return "WLAN_ALREADY_DISCONNECTED"; + default: + return "<unknown>"; + } +} + } // namespace Boardcore diff --git a/src/shared/radio/CC3135/CC3135.h b/src/shared/radio/CC3135/CC3135.h index 531c44a0e9cbdcdf8ad8b545ebe5dbac620c892d..d60104533039edb337d3a8ca5ca3bc4b0a09d52a 100644 --- a/src/shared/radio/CC3135/CC3135.h +++ b/src/shared/radio/CC3135/CC3135.h @@ -43,14 +43,18 @@ namespace Boardcore class CC3135 : ActiveObject { public: + constexpr static size_t MTU = 1536; + enum class Error { - NO_ERROR, //< No error occured. - NWP_TIMEOUT, //< The NWP did not respond. - NWP_STATUS_NON_ZERO, //< The NWD returned a non-zero status code. + NO_ERROR, //< No error occured. + SYNC_TIMEOUT, //< The NWP did not respond. + GENERIC_ERROR, //< Generic error class. + WLAN_ALREADY_DISCONNECTED, //< Wlan is already disconnected. }; explicit CC3135(std::unique_ptr<ICC3135Iface> &&iface); + ~CC3135(); CC3135::Error init(bool wait_for_init); @@ -58,7 +62,14 @@ public: CC3135::Error getVersion(CC3135Defs::DeviceVersion &version); - CC3135::Error setMode(CC3135Defs::Mode mode); + CC3135::Error startRecv(); + + CC3135::Error dummyRecv(); + CC3135::Error dummySend(); + + CC3135::Error prepareForReset(); + + static const char *errorToStr(Error error); private: //! Simple buffer for scatter/gather IO @@ -79,7 +90,7 @@ private: class ServiceThreadLock { public: - ServiceThreadLock(CC3135 *parent) : parent(parent) + explicit ServiceThreadLock(CC3135 *parent) : parent(parent) { parent->installAsServiceThread(); } @@ -90,15 +101,34 @@ private: CC3135 *parent; }; + CC3135::Error setupTransceiver(); + //! Function for servicing async messages. void run() override; void defaultPacketHandler(CC3135Defs::ResponseHeader header); - CC3135::Error devigeGet(uint8_t set_id, uint8_t option, Buffer result); + // Part of the device API + + CC3135::Error devigeGet(uint8_t set_id, uint8_t option, Buffer value); + + CC3135::Error wlanSetMode(CC3135Defs::Mode mode); + + CC3135::Error wlanPolicySet(uint8_t type, uint8_t option, Buffer value); - //! Read something from the device, to wake it up? - CC3135::Error dummyDeviceRead(); + CC3135::Error wlanDisconnect(); + + CC3135::Error socketOpen(uint8_t domain, uint8_t type, uint8_t protocol, + CC3135Defs::Sd &sd); + + CC3135::Error socketClose(CC3135Defs::Sd sd); + + CC3135::Error socketRecv(CC3135Defs::Sd sd, Buffer buffer, uint16_t flags); + + // CC3135::Error socketSend(CC3135Defs::Sd sd, Buffer buffer, uint8_t + // flags); + + CC3135::Error socketSend2(CC3135Defs::Sd sd, Buffer buffer, uint16_t flags); // Functions dedicated to interrupt servicing @@ -142,6 +172,8 @@ private: //! Safely read a buffer, does bound checking void safeRead(size_t &len, Buffer buffer); + static CC3135::Error errorFromStatus(int16_t status); + miosix::Thread *irq_wait_thread = nullptr; //< Thread waiting on IRQ size_t irq_count = 0; //< Number of interrupts @@ -149,6 +181,8 @@ private: std::unique_ptr<ICC3135Iface> iface; uint8_t tx_seq_num = 0; + + CC3135Defs::Sd sd; //< Socket descriptor }; } // namespace Boardcore diff --git a/src/shared/radio/CC3135/CC3135Defs.h b/src/shared/radio/CC3135/CC3135Defs.h index 06c2fd3eaa64f39c7f250a21465d1049bb07cfd7..0738afaa3a96e46ad38cd7c9b3b428a736ff1646 100644 --- a/src/shared/radio/CC3135/CC3135Defs.h +++ b/src/shared/radio/CC3135/CC3135Defs.h @@ -37,15 +37,6 @@ namespace Boardcore namespace CC3135Defs { -enum Mode : uint8_t -{ - ROLE_STA = 0, - ROLE_RESERVED = 1, - ROLE_AP = 2, - ROLE_P2P = 3, - ROLE_TAG = 4 -}; - //! Synchronous message mask. constexpr uint16_t OPCODE_SYNC = 1 << 10; @@ -53,26 +44,92 @@ constexpr uint16_t OPCODE_SYNC = 1 << 10; enum OpCode : uint16_t { OPCODE_DEVICE_INITCOMPLETE = 0x0008, + OPCODE_DEVICE_ABORT = 0x000C, OPCODE_DEVICE_DEVICEASYNCDUMMY = 0x0063, OPCODE_DEVICE_DEVICEGETRESPONSE = 0x0466, OPCODE_DEVICE_DEVICESETRESPONSE = 0x04B7, OPCODE_WLAN_PROVISIONING_STATUS_ASYNC_EVENT = 0x089A, //< ???? + OPCODE_WLAN_WLANDISCONNECTRESPONSE = 0x0C81, + OPCODE_WLAN_POLICYSETRESPONSE = 0x0C86, OPCODE_WLAN_SET_MODE_RESPONSE = 0x0CB4, + OPCODE_SOCKET_RECVASYNCRESPONSE = 0x100A, + OPCODE_SOCKET_SOCKETRESPONSE = 0x1401, + OPCODE_SOCKET_CLOSERESPONSE = 0x1402, OPCODE_NETAPP_IPACQUIRED = 0x1825, //< ???? OPCODE_DEVICE_DEVICEGET = 0x8466, OPCODE_DEVICE_DEVICESET = 0x84B7, + OPCODE_WLAN_POLICYSETCOMMAND = 0x8C86, + OPCODE_WLAN_WLANDISCONNECTCOMMAND = 0x8C81, OPCODE_WLAN_SET_MODE = 0x8CB4, + OPCODE_SOCKET_SOCKET = 0x9401, + OPCODE_SOCKET_CLOSE = 0x9402, + OPCODE_SOCKET_RECV = 0x940A, + OPCODE_SOCKET_SEND = 0x940C, }; //! Is this message synchronous? inline bool isSync(OpCode op) { return op & OPCODE_SYNC; } -struct SyncPattern +inline const char *opToStr(OpCode op) { - uint32_t long1; - uint16_t short1; - uint8_t byte1; - uint8_t byte2; + switch (op) + { + case OpCode::OPCODE_DEVICE_INITCOMPLETE: + return "OPCODE_DEVICE_INITCOMPLETE"; + case OpCode::OPCODE_DEVICE_ABORT: + return "OPCODE_DEVICE_ABORT"; + case OpCode::OPCODE_DEVICE_DEVICEASYNCDUMMY: + return "OPCODE_DEVICE_DEVICEASYNCDUMMY"; + case OpCode::OPCODE_DEVICE_DEVICEGETRESPONSE: + return "OPCODE_DEVICE_DEVICEGETRESPONSE"; + case OpCode::OPCODE_DEVICE_DEVICESETRESPONSE: + return "OPCODE_DEVICE_DEVICESETRESPONSE"; + case OpCode::OPCODE_NETAPP_IPACQUIRED: + return "OPCODE_NETAPP_IPACQUIRED"; + case OpCode::OPCODE_WLAN_PROVISIONING_STATUS_ASYNC_EVENT: + return "OPCODE_WLAN_PROVISIONING_STATUS_ASYNC_EVENT"; + case OpCode::OPCODE_WLAN_WLANDISCONNECTRESPONSE: + return "OPCODE_WLAN_WLANDISCONNECTRESPONSE"; + case OpCode::OPCODE_WLAN_POLICYSETRESPONSE: + return "OPCODE_WLAN_POLICYSETRESPONSE"; + case OpCode::OPCODE_WLAN_SET_MODE_RESPONSE: + return "OPCODE_WLAN_SET_MODE_RESPONSE"; + case OpCode::OPCODE_SOCKET_RECVASYNCRESPONSE: + return "OPCODE_SOCKET_RECVASYNCRESPONSE"; + case OpCode::OPCODE_SOCKET_SOCKETRESPONSE: + return "OPCODE_SOCKET_SOCKETRESPONSE"; + case OpCode::OPCODE_SOCKET_CLOSERESPONSE: + return "OPCODE_SOCKET_CLOSERESPONSE"; + case OpCode::OPCODE_DEVICE_DEVICEGET: + return "OPCODE_DEVICE_DEVICEGET"; + case OpCode::OPCODE_DEVICE_DEVICESET: + return "OPCODE_DEVICE_DEVICESET"; + case OpCode::OPCODE_WLAN_POLICYSETCOMMAND: + return "OPCODE_WLAN_POLICYSETCOMMAND"; + case OpCode::OPCODE_WLAN_WLANDISCONNECTCOMMAND: + return "OPCODE_WLAN_WLANDISCONNECTCOMMAND"; + case OpCode::OPCODE_WLAN_SET_MODE: + return "OPCODE_WLAN_SET_MODE"; + case OpCode::OPCODE_SOCKET_SOCKET: + return "OPCODE_SOCKET_SOCKET"; + case OpCode::OPCODE_SOCKET_CLOSE: + return "OPCODE_SOCKET_CLOSE"; + case OpCode::OPCODE_SOCKET_RECV: + return "OPCODE_SOCKET_RECV"; + case OpCode::OPCODE_SOCKET_SEND: + return "OPCODE_SOCKET_SEND"; + default: + return "<unknown>"; + } +} + +enum Mode : uint8_t +{ + ROLE_STA = 0, + ROLE_RESERVED = 1, + ROLE_AP = 2, + ROLE_P2P = 3, + ROLE_TAG = 4 }; struct DeviceVersion @@ -82,7 +139,7 @@ struct DeviceVersion uint8_t phy_version[4]; uint8_t nwp_version[4]; uint16_t rom_version; - uint16_t _pad; + uint8_t _pad[2]; }; struct GenericHeader @@ -124,12 +181,167 @@ struct DeviceSetGet uint16_t config_len; }; +constexpr uint16_t DEVICE_GENERAL = 1; +constexpr uint16_t DEVICE_GENERAL_VERSION = 12; + struct WlanSetMode { Mode mode; uint8_t _pad[3]; }; +struct WlanPolicySetGet +{ + uint8_t policy_type; + uint8_t _pad; + uint8_t policy_option; + uint8_t policy_option_len; +}; + +constexpr uint8_t WLAN_POLICY_CONNECTION = 16; + +/// Socket descriptor; +using Sd = uint8_t; + +enum class SdType +{ + RAW_TRANSCEIVER, + GENERIC +}; + +inline SdType sdGetType(Sd sd) +{ + if ((sd & 0xf0) == 0x80) + { + return SdType::RAW_TRANSCEIVER; + } + else + { + return SdType::GENERIC; + } +} + +struct SocketCommand +{ + uint8_t domain; + uint8_t type; + uint8_t protocol; + uint8_t padding; +}; + +constexpr uint8_t AF_INET = 2; +constexpr uint8_t AF_INET6 = 3; +constexpr uint8_t AF_RF = 6; + +constexpr uint8_t SOCK_STREAM = 1; +constexpr uint8_t SOCK_DGRAM = 2; +constexpr uint8_t SOCK_RAW = 3; +constexpr uint8_t SOCK_RX_MTR = 4; + +constexpr uint8_t IPPROTO_TCP = 6; +constexpr uint8_t IPPROTO_UDP = 17; + +struct CloseCommand +{ + Sd sd; + uint8_t _pad[3]; +}; + +struct SendRecvCommand +{ + uint16_t status_or_len; + Sd sd; + uint8_t family_and_flags; +}; + +struct SendRecvCommand2 +{ + uint16_t status_or_len; + Sd sd; + uint8_t family_and_flags; + uint16_t flags; + uint8_t _pad[2]; +}; + +struct SocketResponse +{ + int16_t status_or_len; + Sd sd; + uint8_t _pad; +}; + +enum Rate : uint16_t +{ + RATE_1M = 1, + RATE_2M = 2, + RATE_5_5M = 3, + RATE_11M = 4, + RATE_6M = 6, + RATE_9M = 7, + RATE_12M = 8, + RATE_18M = 9, + RATE_24M = 10, + RATE_36M = 11, + RATE_48M = 12, + RATE_54M = 13, + RATE_MCS_0 = 14, + RATE_MCS_1 = 15, + RATE_MCS_2 = 16, + RATE_MCS_3 = 17, + RATE_MCS_4 = 18, + RATE_MCS_5 = 19, + RATE_MCS_6 = 20, + RATE_MCS_7 = 21, +}; + +enum Preable : uint16_t +{ + PREAMBLE_LONG = 0, + PREAMBLE_SHORT = 1 +}; + +inline uint16_t makeWlanRawRfTxParams(uint8_t channel, Rate rate, uint8_t power, + Preable preamble) +{ + constexpr uint8_t MAX_2_4G_CHANNEL = 14; + constexpr uint8_t BAND_2_4G = 0; + constexpr uint8_t BAND_5_0G = 1; + + constexpr uint8_t CHANNEL_SHIFT = 0; + constexpr uint8_t BAND_SHIFT = 5; + constexpr uint8_t RATE_SHIFT = 6; + constexpr uint8_t POWER_SHIFT = 11; + constexpr uint8_t PREAMBLE_SHIFT = 15; + + constexpr uint8_t CHANNEL_5G_SHIFT = 12; + + if (channel <= MAX_2_4G_CHANNEL) + { + return ((channel << CHANNEL_SHIFT) | (BAND_2_4G << BAND_SHIFT) | + (rate << RATE_SHIFT) | (power << POWER_SHIFT) | + (preamble << PREAMBLE_SHIFT)); + } + else + { + uint8_t channel_lo = channel & 0x1f; + uint8_t channel_hi = (channel & 0xe0) >> 5; + + return ((channel_lo << CHANNEL_SHIFT) | (BAND_5_0G << BAND_SHIFT) | + (rate << RATE_SHIFT) | (channel_hi << CHANNEL_5G_SHIFT) | + (power << POWER_SHIFT) | (preamble << PREAMBLE_SHIFT)); + } +} + +// Stuff required for synchronization + +struct SyncPattern +{ + uint32_t long1; + uint16_t short1; + uint8_t byte1; + uint8_t byte2; +}; + constexpr SyncPattern H2N_SYNC_PATTERN = {0xBBDDEEFF, 0x4321, 0x34, 0x12}; constexpr SyncPattern H2N_CNYS_PATTERN = {0xBBDDEEFF, 0x8765, 0x78, 0x56}; @@ -151,35 +363,6 @@ inline bool n2hSyncPatternMatch(uint32_t sync, uint8_t seq_num) //! Align message size. inline size_t alignSize(size_t size) { return (size + 3) & (~3); } -inline const char *opToStr(OpCode op) -{ - switch (op) - { - case OpCode::OPCODE_DEVICE_INITCOMPLETE: - return "OPCODE_DEVICE_INITCOMPLETE"; - case OpCode::OPCODE_DEVICE_DEVICEASYNCDUMMY: - return "OPCODE_DEVICE_DEVICEASYNCDUMMY"; - case OpCode::OPCODE_DEVICE_DEVICEGETRESPONSE: - return "OPCODE_DEVICE_DEVICEGETRESPONSE"; - case OpCode::OPCODE_DEVICE_DEVICESETRESPONSE: - return "OPCODE_DEVICE_DEVICESETRESPONSE"; - case OpCode::OPCODE_NETAPP_IPACQUIRED: - return "OPCODE_NETAPP_IPACQUIRED"; - case OpCode::OPCODE_WLAN_PROVISIONING_STATUS_ASYNC_EVENT: - return "OPCODE_WLAN_PROVISIONING_STATUS_ASYNC_EVENT"; - case OpCode::OPCODE_WLAN_SET_MODE_RESPONSE: - return "OPCODE_WLAN_SET_MODE_RESPONSE"; - case OpCode::OPCODE_DEVICE_DEVICEGET: - return "OPCODE_DEVICE_DEVICEGET"; - case OpCode::OPCODE_DEVICE_DEVICESET: - return "OPCODE_DEVICE_DEVICESET"; - case OpCode::OPCODE_WLAN_SET_MODE: - return "OPCODE_WLAN_SET_MODE"; - default: - return "<unknown>"; - } -} - } // namespace CC3135Defs } // namespace Boardcore diff --git a/src/tests/drivers/CC3135/test-cc3135.cpp b/src/tests/drivers/CC3135/test-cc3135.cpp index f1c137c302572b74651f045f2f62e7278faff7ed..863a7862933d2f36fb4d2837d2c38e5d8e1790a7 100644 --- a/src/tests/drivers/CC3135/test-cc3135.cpp +++ b/src/tests/drivers/CC3135/test-cc3135.cpp @@ -86,7 +86,7 @@ using irq = Gpio<GPIOA_BASE, 4>; using hib = Gpio<GPIOA_BASE, 6>; #define CC3135_SPI SPI1 -// #define CC3135_HIB +#define CC3135_HIB #endif #endif @@ -178,6 +178,8 @@ int main() initBoard(); + // For some reason, putting this before SPI peripheral activation makes it + // more reliable #ifdef CC3135_HIB // Reset CC3135 hib::low(); @@ -190,7 +192,7 @@ int main() GpioPin cs_pin = cs::getPin(); SPIBusConfig config = {}; - config.clockDivider = SPI::ClockDivider::DIV_32; + config.clockDivider = SPI::ClockDivider::DIV_64; config.mode = SPI::Mode::MODE_0; config.bitOrder = SPI::BitOrder::MSB_FIRST; @@ -204,22 +206,18 @@ int main() printf("[cc3135] Initializing...\n"); cc3135 = new CC3135(std::move(iface)); - // cc3135->handleIrq(); - - if (cc3135->init(false) != CC3135::Error::NO_ERROR) + auto result = cc3135->init(true); + if (result != CC3135::Error::NO_ERROR) { - printf("[cc3135] Failed to start cc3135, retrying...\n"); - Thread::sleep(2000); - return 0; + printf("[cc3135] Failed to start cc3135 (error: %s), retrying...\n", + CC3135::errorToStr(result)); + Thread::sleep(4000); - // miosix::reboot(); + miosix::reboot(); } printf("[cc3135] Initialization complete!\n"); - // CHECK(cc3135->setMode(CC3135Defs::ROLE_STA)); - // Thread::sleep(500); - CC3135Defs::DeviceVersion version = {}; CHECK(cc3135->getVersion(version)); printf( @@ -235,7 +233,29 @@ int main() version.nwp_version[3], version.rom_version); while (true) - ; + { + cc3135->startRecv(); + Thread::sleep(1000); + printf("[cc3135] Looping\n"); + + cc3135->dummySend(); + + CHECK(cc3135->getVersion(version)); + printf( + "[cc3135] Chip Id: %lx\n" + "[cc3135] Fw version: %u.%u.%u.%u\n" + "[cc3135] Phy version: %u.%u.%u.%u\n" + "[cc3135] Nwp version: %u.%u.%u.%u\n" + "[cc3135] Rom version: %x\n", + version.chip_id, version.fw_version[0], version.fw_version[1], + version.fw_version[2], version.fw_version[3], + version.phy_version[0], version.phy_version[1], + version.phy_version[2], version.phy_version[3], + version.nwp_version[0], version.nwp_version[1], + version.nwp_version[2], version.nwp_version[3], + version.rom_version); + } + // Thread::sleep(3000); // miosix::reboot(); }