When #WisBlock transmits #LoRa Packets ... Our #BL602 LoRa Receiver hangs! ... Let's find out why 🤔
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
Something spooky about #BL602 GPIO Interrupts 🤔 ... Let's disconnect #LoRa SX1276 pins DIO1 to DIO3 ... And connect DIO0 to my fav Blue LED (GPIO 11)
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora
#PineCone #BL602 Blue LED switches off ... When #WisBlock transmits a #LoRa Packet ... So DIO0 Packet Received works! Why does the GPIO Interrupt hang? 🤔
https://github.com/lupyuen/bl_iot_sdk/tree/lorarecv/customer_app/sdk_app_lora
#BL602 GPIO Interrupt triggered OK when #LoRa Packet received yay! ... But why does it work now? 🤔
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
NimBLE Porting Layer builds OK on #RISCV #BL602 #FreeRTOS yay! ... Let's call these Event Queue functions to process our received #LoRa Packets
https://lupyuen.github.io/pinetime-rust-mynewt/articles/dfu#nimble-event-queue-functions
Shall we teach #BL602 Multitasking with NimBLE Porting Layer? 1️⃣ Looks easier than FreeRTOS 2️⃣ It's portable to FreeRTOS, Mynewt, NuttX and RIOT OS 🤔
#LoRa Packet goes from #WisBlock Transmitter ... To #BL602 SX1276 Interrupt Handler ... To #FreeRTOS Task yay! Now we read the received LoRa Packet from SX1276 over SPI
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
Aha! #BL602 hits a #RISCV Exception ... When processing the received #LoRa Packet! Let's follow these steps to troubleshoot...
https://lupyuen.github.io/articles/i2c#appendix-how-to-troubleshoot-risc-v-exceptions
Our #BL602 Build, Flash and Run Firmware script generates the #RISCV Disassembly ... Let's track down the address of the RISC-V Exception
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/run.sh
Oops the Program Counter for our #RISCV Exception is null ... So there must be a missing Callback Function somewhere in our #LoRa #BL602 Firmware 🤔
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
#BL602 #LoRa Exception happened because we passed a pointer to a stack object ... Which gets used by the Interrupt Handler 😲 ... This works OK in the original Mynewt code, but not for BL602
https://gist.github.com/lupyuen/1539f9dd52e9a83d4fbe7724481112bf
For #BL602 we fix this exception by copying the object ... Instead of storing a pointer to the object
#BL602 now displays the #LoRa Packet received from #WisBlock yay!
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
Mystery #BL602 GPIO Function ... What does it do? Will it fix our problem with triggering multiple GPIO Interrupts? 🤔
#BL602 Reference Manual mentions "GPIO_INT_CLR" but the address is undefined in the doc ... Methinks a chunk of addresses are missing from the doc 🤔
https://github.com/bouffalolab/bl_docs/tree/main/BL602_RM/en
Searching GitHub for "GPIO_INT_CLR" shows ultraembedded RISC-V SoC ... Coincidence? 🤔
https://github.com/search?l=Markdown&q=GPIO_INT_CLR&type=Code
Ah my folly ways ... Multiple #BL602 GPIO Interrupts can't be registered like this ... Lemme fix this 🪠
Let's handle #BL602 GPIO Interrupts the smarter way ... By iterating thru the Interrupt Events created with the NimBLE Porting Layer
Reconnected #PineCone #BL602 @PINE64 ... To #LoRa SX1276 pins DIO0 to DIO3 ... For testing our GPIO interrupt handler
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/sx1276.h
Enabled #BL602 GPIO Interrupt Handler for #LoRa SX1276 ... And BL602 hits a #RISCV Exception ... At an invalid Program Address 🤔
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
Let's disable #LoRa Channel Activity Detection for now ... #BL602 receives first LoRa Packet ... But not the second packet 🤔
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
Can #BL602 show the Stack Trace for this #RISCV Exception? ... Let's find out 🤔
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
#BL602 shows Stack Trace when CONFIG_ENABLE_FP=1 ... But the addresses don't make sense ... They belong to the code that's dumping the Stack Trace 🤔
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/proj_config.mk#L40-L42
Let's dump the #BL602 Stack with this function ... And figure out why our Exception Stack Trace doesn't look right
Here are the #BL602 Stacks for the Foreground RTOS Task, Background Task and Exception Handler ... Let's see what's wrong with the Exception Stack
Complete #BL602 Stack Data for the Exception is here
https://gist.github.com/lupyuen/5ddbcdd1054c775521291c3d114f6cee
Below the #BL602 Exception Handler Stack ... Is another Stack! ... Does this Stack contain the Stack Trace that we need? 🤔
https://gist.github.com/lupyuen/5ddbcdd1054c775521291c3d114f6cee
Quiz: What's wrong with this C code? 🤔 ... I'm soooo upset I missed this simple bug 🙄
https://github.com/apache/mynewt-core/blob/master/apps/loraping/src/main.c#L215-L233
Answer: "radio_events" contains Undefined Fields ... Because it was allocated on the Stack! Lesson Learnt: ALWAYS Init Stack Variables! 🙏
https://github.com/apache/mynewt-core/blob/master/apps/loraping/src/main.c#L215-L233
Back to our #BL602 Stack Trace ... Yep the Correct Stack Trace is indeed lurking behind our (unhelpful) Exception Stack Trace ... How shall we show the Correct Stack Trace beyond the Emptiness? 🤔
https://gist.github.com/lupyuen/5ddbcdd1054c775521291c3d114f6cee
Let's do #BL602 #LoRa Receive Timeout with these Callout Functions from the NimBLE Porting Layer
https://lupyuen.github.io/pinetime-rust-mynewt/articles/dfu#nimble-callout-functions
#BL602 receives 4 #LoRa Packets by executing 458 SPI requests ... Great load test for SPI 👍
https://github.com/lupyuen/bl_iot_sdk/blob/lorarecv/customer_app/sdk_app_lora/sdk_app_lora/demo.c
@lupyuen wow, that is some crappy implementation by the sound of it! Honestly I am surprised, usually the low-level uC people (the ones working with assembly and C) tend to do a way better job than that.
@freemo Haha ahem ... I ported this LoRa driver from Mynewt OS. The driver was designed for platforms without DMA.
Since we support DMA on BL602, we can do better ... But the driver needs to be redesigned.
@lupyuen
What hw part is being talked to over said dma? Does order of dma reads matter? Can you cache requests issue dma read burst and send result asynchronously etc or per queue keeping order? We had similar problem in nokia on radiomodules i think. Dont remember exact solution though.
@PawelK I ported the driver from Mynewt OS to BL602.
Since I don't have the time to redesign the driver and do a thorough regression test ... We'll have to live with this inefficiency for now.
@lupyuen yeesh!
@lupyuen
Yes uninit vars suck. Llvm/clang autowarns or can error on this. Has great static checker too and plenty of warnings etc.
@lupyuen
Use before def/partial def only.
Oops #BL602 needs us to "make clean ; make" to fix up the Stack Frame Pointers ... Now BL602 Stack Trace points to the "ebreak" instruction ... Which belongs to the #RISCV Exception Handler 🙄
https://github.com/lupyuen/bl_iot_sdk/releases/tag/v7.0.1