diff --git a/CMakeLists.txt b/CMakeLists.txt index 695de2782e4e94ce13bc2a1e0431abc0c91ace0f..d70fbc3c48b5e3ca54af2595c87b40109d83a6a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -280,7 +280,7 @@ add_executable(test-sx1278-serial sbs_target(test-sx1278-serial stm32f429zi_stm32f4discovery) add_executable(test-cc3135 src/tests/drivers/CC3135/test-cc3135.cpp) -sbs_target(test-cc3135 stm32f407vg_stm32f4discovery) +sbs_target(test-cc3135 stm32f429zi_stm32f4discovery) add_executable(test-cc3135-gs src/tests/drivers/CC3135/test-cc3135.cpp) sbs_target(test-cc3135-gs stm32f429zi_skyward_ground_station) diff --git a/src/shared/radio/CC3135/CC3135.cpp b/src/shared/radio/CC3135/CC3135.cpp index 3e01fe5759c58b913be28826da2ddb0028aad5b0..5124be5ee064891a1cdb787e8da6e88bab6bd167 100644 --- a/src/shared/radio/CC3135/CC3135.cpp +++ b/src/shared/radio/CC3135/CC3135.cpp @@ -38,20 +38,37 @@ CC3135::CC3135(std::unique_ptr<ICC3135Iface> &&iface) : iface(std::move(iface)) irq_wait_thread = thread; } -CC3135Defs::DeviceVersion CC3135::getVersion() +DeviceVersion CC3135::getVersion() +{ + DeviceVersion result = {}; + + devigeGet(1, 12, Buffer::from(&result)); + return result; +} + +void CC3135::devigeGet(uint8_t set_id, uint8_t option, Buffer result) { DeviceSetGet tx_command = {}; - tx_command.device_set_id = 1; // Device get general - tx_command.option = 12; // Device get general version + tx_command.device_set_id = set_id; + tx_command.option = option; - DeviceSetGet rx_command = {}; - DeviceVersion rx_payload = {}; + DeviceSetGet rx_command = {}; inoutPacketSync(OPCODE_DEVICE_DEVICEGET, Buffer::from(&tx_command), Buffer::null(), OPCODE_DEVICE_DEVICEGETRESPONSE, - Buffer::from(&rx_command), Buffer::from(&rx_payload)); + Buffer::from(&rx_command), result); +} + +void CC3135::setMode(CC3135Defs::Mode mode) +{ + WlanSetMode tx_command = {}; + tx_command.mode = mode; - return rx_payload; + BasicResponse rx_command = {}; + + inoutPacketSync(OPCODE_WLAN_SET_MODE, Buffer::from(&tx_command), + Buffer::null(), OPCODE_WLAN_SET_MODE_RESPONSE, + Buffer::from(&rx_command), Buffer::null()); } void CC3135::handleIrq() @@ -117,9 +134,32 @@ void CC3135::defaultPacketHandler(CC3135Defs::ResponseHeader header) opToStr(header.inner.opcode), header.inner.opcode, header.dev_status, header.socket_tx_failure, header.socket_non_blocking); + size_t len = header.inner.len; + + switch (header.inner.opcode) + { + case OPCODE_DEVICE_INITCOMPLETE: + { + DeviceInitInfo result = {}; + safeRead(len, Buffer::from(&result)); + + TRACE( + "[cc3135] Init completen:\n" + "- Status: %8x\n" + "- Chip Id: %lx\n" + "- More Data: %8x\n", + result.status, result.chip_id, result.more_data); + break; + } + + default: + break; + } + // Dummy read rest of the data // TODO: Add async commands - dummyRead(header.inner.len); + if (len > 0) + dummyRead(len); } void CC3135::run() @@ -129,6 +169,7 @@ void CC3135::run() while (true) { waitForIrq(); + // Thread::sleep(500); { // Lock the device interface @@ -186,6 +227,7 @@ void CC3135::readPacket(OpCode opcode, CC3135::Buffer command, while (true) { waitForIrq(); + // Thread::sleep(500); // Locking the interface is not needed @@ -201,13 +243,10 @@ void CC3135::readPacket(OpCode opcode, CC3135::Buffer command, // Read the rest of the packet size_t len = header.inner.len; - iface->read(command.ptr, std::min(len, command.len)); - len -= std::min(len, command.len); + safeRead(len, command); + safeRead(len, payload); - iface->read(payload.ptr, std::min(len, payload.len)); - len -= std::min(len, payload.len); - - // Read tail of remanining data + // Read tail of remaining data if (len > 0) dummyRead(len); @@ -224,8 +263,11 @@ void CC3135::writePacket(OpCode opcode, CC3135::Buffer command, writeHeader(&header); - iface->write(command.ptr, command.len); - iface->write(payload.ptr, payload.len); + if (command.len > 0) + iface->write(command.ptr, command.len); + + if (payload.len > 0) + iface->write(payload.ptr, payload.len); } void CC3135::readHeader(ResponseHeader *header) @@ -288,14 +330,15 @@ void CC3135::readHeader(ResponseHeader *header) } // 4. Scan for double syncs - /*uint32_t sync; + uint32_t sync; memcpy(&sync, &buf[0], 4); - while(n2hSyncPatternMatch(sync, tx_seq_num)) { + while (n2hSyncPatternMatch(sync, tx_seq_num)) + { memmove(&buf[0], &buf[4], 4); iface->read(&buf[4], 4); memcpy(&sync, &buf[0], 4); - }*/ + } tx_seq_num++; @@ -335,4 +378,13 @@ void CC3135::dummyRead(size_t n) iface->read(dummy, n); } +void CC3135::safeRead(size_t &len, Buffer buffer) +{ + if (buffer.len > 0) + { + iface->read(buffer.ptr, std::min(len, buffer.len)); + len -= std::min(len, buffer.len); + } +} + } // namespace Boardcore diff --git a/src/shared/radio/CC3135/CC3135.h b/src/shared/radio/CC3135/CC3135.h index 1925d1959733613d7c4c5b145e8e174c77e6df2d..31d18cdaa3b486aee8fac758837a7da1bde890db 100644 --- a/src/shared/radio/CC3135/CC3135.h +++ b/src/shared/radio/CC3135/CC3135.h @@ -49,6 +49,8 @@ public: CC3135Defs::DeviceVersion getVersion(); + void setMode(CC3135Defs::Mode mode); + private: //! Simple buffer for scatter/gather IO struct Buffer @@ -70,6 +72,8 @@ private: void defaultPacketHandler(CC3135Defs::ResponseHeader header); + void devigeGet(uint8_t set_id, uint8_t option, Buffer result); + // Functions dedicated to interrupt servicing //! Wait for an incoming interrupt (only callable in service thread). @@ -88,7 +92,7 @@ private: //! Read packet in input, with proper synchronization. void readPacketSync(CC3135Defs::OpCode opcode, Buffer command, Buffer payload); - //! Write a apcket in output, with proper synchronization. + //! Write a packet in output, with proper synchronization. void writePacketSync(CC3135Defs::OpCode opcode, Buffer command, Buffer payload); @@ -106,6 +110,9 @@ private: //! Read dummy n bytes. void dummyRead(size_t n); + //! Safely read a buffer, does bound checking + void safeRead(size_t &len, Buffer buffer); + miosix::Thread *irq_wait_thread = nullptr; //< Thread waiting on IRQ size_t irq_count = 0; //< Number of interrupts diff --git a/src/shared/radio/CC3135/CC3135Defs.h b/src/shared/radio/CC3135/CC3135Defs.h index affcb713ae3ebad92bdb2e4d2d3edbe9bdab0a5a..06c2fd3eaa64f39c7f250a21465d1049bb07cfd7 100644 --- a/src/shared/radio/CC3135/CC3135Defs.h +++ b/src/shared/radio/CC3135/CC3135Defs.h @@ -37,6 +37,15 @@ 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; @@ -48,9 +57,11 @@ enum OpCode : uint16_t OPCODE_DEVICE_DEVICEGETRESPONSE = 0x0466, OPCODE_DEVICE_DEVICESETRESPONSE = 0x04B7, OPCODE_WLAN_PROVISIONING_STATUS_ASYNC_EVENT = 0x089A, //< ???? + OPCODE_WLAN_SET_MODE_RESPONSE = 0x0CB4, OPCODE_NETAPP_IPACQUIRED = 0x1825, //< ???? OPCODE_DEVICE_DEVICEGET = 0x8466, OPCODE_DEVICE_DEVICESET = 0x84B7, + OPCODE_WLAN_SET_MODE = 0x8CB4, }; //! Is this message synchronous? @@ -92,6 +103,19 @@ struct ResponseHeader typedef GenericHeader RequestHeader; +struct BasicResponse +{ + int16_t status; + uint16_t sender; +}; + +struct DeviceInitInfo +{ + int32_t status; + int32_t chip_id; + int32_t more_data; +}; + struct DeviceSetGet { uint16_t status; @@ -100,6 +124,12 @@ struct DeviceSetGet uint16_t config_len; }; +struct WlanSetMode +{ + Mode mode; + uint8_t _pad[3]; +}; + constexpr SyncPattern H2N_SYNC_PATTERN = {0xBBDDEEFF, 0x4321, 0x34, 0x12}; constexpr SyncPattern H2N_CNYS_PATTERN = {0xBBDDEEFF, 0x8765, 0x78, 0x56}; @@ -137,10 +167,14 @@ inline const char *opToStr(OpCode op) 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>"; } diff --git a/src/tests/drivers/CC3135/test-cc3135.cpp b/src/tests/drivers/CC3135/test-cc3135.cpp index a1979a396659f2ea773ce5b3579cbd1ae9e8cd55..47e575d3c4bce62e6f42dadd116e4bd3c9a8a6a4 100644 --- a/src/tests/drivers/CC3135/test-cc3135.cpp +++ b/src/tests/drivers/CC3135/test-cc3135.cpp @@ -85,7 +85,7 @@ using hib = Gpio<GPIOA_BASE, 6>; CC3135 *cc3135 = nullptr; -volatile size_t IRQ_COUNT = 0; +volatile unsigned int IRQ_COUNT = 0; #if defined _BOARD_STM32F429ZI_SKYWARD_GS void __attribute__((used)) EXTI5_IRQHandlerImpl() @@ -159,7 +159,7 @@ int main() { if (last != IRQ_COUNT) { - printf("[cc3135] IRQ: %zu\n", IRQ_COUNT); + printf("[cc3135] IRQ: %u\n", IRQ_COUNT); last = IRQ_COUNT; } @@ -175,7 +175,7 @@ int main() GpioPin cs_pin = cs::getPin(); SPIBusConfig config = {}; - config.clockDivider = SPI::ClockDivider::DIV_128; + config.clockDivider = SPI::ClockDivider::DIV_64; config.mode = SPI::Mode::MODE_0; config.bitOrder = SPI::BitOrder::MSB_FIRST; @@ -193,11 +193,13 @@ int main() #ifdef CC3135_HIB // Reset CC3135 hib::low(); - Thread::sleep(10); + Thread::sleep(100); hib::high(); #endif - Thread::sleep(3000); + Thread::sleep(500); + // cc3135->setMode(CC3135Defs::ROLE_AP); + // Thread::sleep(500); auto version = cc3135->getVersion(); printf(