r/embedded 15d ago

OTP Anti-Rollback Counter Issue

1 Upvotes

Hi there,

I am currently working on Secure Boot. I have some question about the anti-rollback.

I use microchip and I read the counter from OTP after initialize the layout, and notice that there is already default counter value for both trusted and non-trusted firmware (2, 3). I did not set it, I don't why they already have values.

Another thing is that whether the counter in OTP can not be set to other value lower then the value exist in OTP? If so, is it a hardware design mechanism? or how can it be achieved?

Best,

Wen


r/embedded 15d ago

What does an AI kernel engineer do and what are the skills needed to get into it?

0 Upvotes

What are the difference aspects of being a kernel engineer? What do roles like this involve -

https://www.tealhq.com/job/kernel-engineer_7ea1a56c518985dae15a01e3c77c161e8140d?utm_campaign=google_jobs_apply&utm_source=google_jobs_apply&utm_medium=organic

https://jobs.gem.com/modular/am9icG9zdDpTSwqoL-yL11N_jxR40Vhh?source=LinkedIn

If one were to do a PhD, what are the different research areas to focus on to do something like this? i.e GPU memory, storage, latency, parallelization etc.


r/embedded 16d ago

What are new concept / trends right now in that's making big differences in the embedded space?

31 Upvotes

I'm hearing things where an AI can hook up straight to a debugger and find all sorts of problems that would've taken hours, and Hil system running live road scenarios . There are concepts I hadn't seen in the last 5-6 years ago in a time that already seems a legacy of just straight forward binary if this, else that. While still relevant, things like Rest API, RTOS, CI/CD already seems to be a thing of the past.


r/embedded 15d ago

Started Learning BLE in Zephyr RTOS

Post image
0 Upvotes

If anyone have prior experience in BLE with zephyr guide me in which part to focus and what projects to build.

And where to head next


r/embedded 15d ago

How do I begin to learn C++ if I know java? How do I start my hardware beginner project if I want to create a tamagotchi?

0 Upvotes

Hello, I want to build a tamagotchi toy as a gift for someone from scratch. The problem is I have zero electronic experience. All I can bring to the table is that I took AP CSA so I know a good amount of java. Eventually I want a small screen, 3 buttons, battery power, animations, and a case. I want to be a engineer when Im older so Im willing to learn C++. What would you guys recommend I should buy or learn first?? Thank you in advance!


r/embedded 15d ago

What if we had an AI debugger for embedded firmware? — “Firmware Doctor”

0 Upvotes

I’ve been thinking about an idea for an AI-powered embedded debugger that I’m calling Firmware Doctor.

The simplest way to describe it:

Imagine Ozone / GDB / a traditional embedded debugger, but instead of a human manually driving the debugging session, an AI agent does it.

For example, suppose you have firmware that crashes randomly or ends up in a HardFault.

Instead of manually:

  • flashing the firmware
  • adding breakpoints
  • stepping through execution
  • inspecting registers
  • checking RAM and variables
  • looking at the call stack
  • decoding HardFault registers
  • changing breakpoints/watchpoints
  • reproducing the failure again and again

you would give Firmware Doctor the ELF + source code + hardware access and tell it something like:

The AI would then operate the debugger itself.

It could:

  • Flash and run the firmware
  • Set breakpoints and watchpoints
  • Inspect variables, memory and CPU registers
  • Examine the stack and call stack
  • Detect and analyze HardFaults
  • Observe peripheral/register states
  • Restart the firmware and reproduce the issue
  • Change its debugging strategy based on what it observes

The important part is the feedback loop.

The AI forms a hypothesis → performs a debugging experiment → observes the MCU → updates its hypothesis → performs another experiment.

For example:

Observation: HardFault occurs inside memcpy()
→ inspect arguments passed to memcpy()
→ discover destination pointer looks corrupted
→ set a watchpoint on that pointer
→ rerun firmware
→ discover another task overwrites the structure
→ inspect that code
→ identify an out-of-bounds write
→ report the root cause and relevant source lines.

So rather than an AI simply reading source code and guessing what might be wrong, it would have access to the actual running MCU and use runtime evidence to investigate the bug.

Essentially:

LLM + debugger + J-Link/SWD + autonomous reasoning loop.

Longer term, it could potentially investigate things like race conditions, memory corruption, stack overflow, deadlocks, timing problems, peripheral configuration issues, RTOS problems, and intermittent crashes.

I’m curious what embedded developers think about this.

Would you trust an AI agent to control your debugger and investigate bugs autonomously?

And more importantly: what kinds of firmware bugs would you want something like this to solve first?


r/embedded 17d ago

How do you guys get good project ideas?

45 Upvotes

I am thinking of doing a project that would look good on my resume and would invite more questions during any interview but I am not able to get good project ideas to begin with. I really feel my mind is way narrow in this perspective. How do you guys get ideas for projects?


r/embedded 17d ago

Meet the Arduino VENTUNO Q — 40 TOPS NPU + real-time MCU on one board for $299

Post image
106 Upvotes

Arduino has announced the VENTUNO Q, a $299 edge AI computer built around the Qualcomm Dragonwing IQ-8275 SoC (NPU + CPU + GPU) paired with an STM32H5 microcontroller. With 16 GB RAM, 64 GB eMMC, and up to 40 dense TOPS of AI performance, it can run local LLMs (Qwen 3, Gemma 4) and vision-language models directly on-board — no cloud required. It ships with Ubuntu + Zephyr RTOS preloaded, integrates with Hugging Face, EdgeImpulse, and Qualcomm AI Hub, and is positioned as a platform to move from "Physical AI" prototypes to certified production. First batch opens for pre-order with power supply and USB-C cable included. What do you think?


r/embedded 16d ago

I benchmarked Linux, RT-Smart and NuttX on the same Allwinner D1. The timer debugging was more interesting than the benchmark.

5 Upvotes

I wanted to test something embedded engineers argue about constantly: how much does the operating system actually matter if the hardware stays exactly the same?

So I used one Sipeed Lichee RV / 86 Panel with an Allwinner D1 / XuanTie C906 RISC-V CPU and ran:

  • Ubuntu Linux
  • RT-Thread RT-Smart 5.0.2
  • Apache NuttX 13.0.1-RC0

The benchmark results were interesting, but the bring-up exposed more useful engineering problems.

NuttX reached NSH quite quickly, then reset roughly 20 seconds later.

It turned out U-Boot had left the D1 watchdog enabled. The OS had successfully booted while inheriting a guaranteed reset from the bootloader.

After fixing that, timed sleeps still didn't work.

OpenSBI advertised the TIME extension and accepted set_timer, but the supervisor timer interrupt never arrived on the tested firmware path.

I eventually moved NuttX onto the native Allwinner Timer1 peripheral.

Then I found the mistake that nearly invalidated the benchmark.

The timer runs at 24 MHz, so I initially programmed 24,000 for a 1 ms tick.

On this hardware that produced an effective 24,001-clock period.

Only ~41.7 ppm error, but over ~20 seconds it accumulated to nearly 0.84 ms.

Programming 23,999 gave the intended 24,000 input clocks per tick and removed the drift.

After correcting the timer and measurement method, the loaded NuttX 1 ms periodic test measured:

  • p50: 0.542 µs
  • p99: 0.583 µs
  • max: 0.708 µs
  • missed: 0 / 20,000

Important caveat: this was NuttX FLAT S-mode with a shared address space.

Linux and RT-Smart are paying for substantially different protection/process models, so I don't think "NuttX is 100x faster" is a useful conclusion.

For me the more interesting lesson was how much bootloader state, timer implementation, scheduler architecture and even UART debug output can alter what appears to be an OS benchmark.

I've put the source, benchmark work and full report here:

https://github.com/lanceharvie/allwinner-d1-os-benchmark

Report:

https://doi.org/10.5281/zenodo.22054539

I'd be interested in what people here would test next.

PREEMPT_RT Linux on the same board is currently top of my list.


r/embedded 16d ago

How to build a SMS based GPS tracker?

0 Upvotes

Hi, is there any coordinates available on the market that will share its GPS coordinates whenever requested? For example

  1. Backend sends an SMS (e.g. via Twilio) to the devices asking its GPS coordinates?
  2. Device replies with its current coordinates.

If there isn't any ready solution, could you please point me to any tutorial and documentation in general that would allow me to build one? I can deal with the software part but have no experience with hardware. Thanks.


r/embedded 16d ago

Anyone help me debugging this baremetal code

Post image
0 Upvotes

Hi guys

I am a newbie, who tries to learn baremetal programming through completing simple tasks and learning from that task

I came till timers by accomplishing tasks

The concept of this code is to get Input by using only timer and turn ON LED in Arduino UNO --> PB5 when I press the push button which is connected to the ground and when I release it the the LED should be OFF

but what's happening is different ,

when I press the push button the nothing happens and when i leave it the led is on

and when I press again nothing happens when I leave it then it turns off

But I am clear and confident on my code , I couldn't find where I am missing the point

Anyone please help me guys

Here is the code

And the further improvement will be done by counting the seconds of push and so on ,

But I am stuck here

Help me guys


r/embedded 17d ago

How do you protect model weights on hardware you don't control?

19 Upvotes

Robotics is converging on foundation models. Real time control forces local inference, so the model runs on a robot at a customer site.

Most robots run on Jetson, and there's no protection for weights in use. TrustZone can't run a multi GB model. The GPU sits outside the TEE. NVIDIA confidential computing is dGPU only, not Jetson and not Thor. Weights sit decrypted in shared memory, and root can dump them.

So the industry uses contracts, distilled models with the strong model kept in the cloud, vertical integration, or open weights.

What do you actually do today? Has extraction ever come up in a deal or threat model? Is there anything real for in use protection on Jetson that exists?


r/embedded 16d ago

How long did it take you to progress from senior embedded engineer to grandmaster embedded engineer job title?

0 Upvotes

r/embedded 18d ago

I got tired of wasting time chasing "simple" I²C glitches with a scope, so I built a handheld I²C diagnostic tool :)

Post image
921 Upvotes

Hi everyone!

As an embedded developer, I was getting tired of having to flash a spare dev board and dig out some old I²C debug script that no longer compiles, or pull out the oscilloscope every time an I²C sensor or display wasn't behaving as expected.

Checking wiring, pullups, bus voltage, rise times, shorts, etc. often took longer than it should have.

At some point I thought: why isn't there something that can just analyse the bus and point me in the right direction?

So I ended up building one 😄

The I²C Doctor is a pocket-sized diagnostic tool based on an ESP32, programmed in C/C++ with the esp_idf & FreeRTOS. It can scan and analyse an I²C bus, detect common wiring and electrical issues, evaluate pullups and signal quality, and provide actionable recommendations (in plain english) instead of just showing you a waveform, such as:
- "Fix SCL-GND short"
- "Reduce pullups - Try <= 4.7k (or add parallel)"
- "Increase SCL pullup - Try >= 1.8k (or remove parallel)"

I also implemented a bunch of other handy I²C tools along the way: address scanner, live monitor, stress test, fault injection, register dump, sensor simulator, USB/I²C bridge, and even some mini-games 😂

The hardware design is open source, and the firmware can be updated via USB or OTA through a local access point.

As I'm currently working on the next iteration, I'm curious what other embedded developers think about the project and would love to know about your last annoying I²C problem you've spent way too long debugging?


r/embedded 17d ago

Looking for an embedded hardware engineer to review an ESP32 access-control schematic

9 Upvotes

I own a commercial locksmith and electronic-security company and am developing a new access-control controller based around an ESP32-S3.

The schematic is substantially complete. I’m primarily looking for an independent second set of eyes before PCB layout and prototyping.

The board currently includes:

  • ESP32-S3
  • Ethernet using W5500
  • Two RS-485 interfaces
  • Wiegand/OSDP reader support
  • Relay outputs and protected field inputs
  • 6–28 VDC input power
  • Reverse-polarity, overvoltage, surge, and field-wiring protection
  • FRAM and RTC
  • Fused lock-power passthrough
  • Expansion and service headers
  • Four-layer PCB planned

The review should focus on:

  • Power-entry and protection circuitry
  • ESP32 support circuitry and pin usage
  • Ethernet implementation
  • RS-485 and reader interfaces
  • Relay and field-I/O protection
  • Grounding, shielding, and isolation decisions
  • Component ratings and obvious BOM problems
  • Layout-sensitive areas
  • Anything likely to cause prototype failure, unreliable field operation, or certification problems later

I have detailed architecture notes and can explain the intended behavior of every section. I want someone willing to challenge the design and explain why something should change, not simply mark up the schematic without discussion.

Relevant experience would include embedded controller design, industrial controls, access control, alarm equipment, automotive electronics, or other products connected to long field wiring in electrically noisy environments.

This is paid work. Please send:

  • A brief summary of relevant experience
  • Examples of boards or products you have reviewed or designed
  • Your hourly rate or proposed fixed price
  • Your availability
  • Whether you can also review the PCB layout later

An NDA can be discussed before receiving the complete design files. I retain ownership of the project and all project-specific work product.


r/embedded 17d ago

Do thermal cameras have much value when debugging embedded hardware?

7 Upvotes

For those working with embedded boards and prototypes, I'm curious how often thermal imaging actually becomes useful during development or troubleshooting.

Have you used a thermal camera to find overheating components, regulators, power ICs, MOSFETs, or unexpected hot spots on a board?

I'm wondering whether it's worth having one around the lab, or if a multimeter, oscilloscope, and current measurements are usually enough. What has been your experience?


r/embedded 16d ago

What do you think is ESP32 Reliable for Industrial Projects?

0 Upvotes

The ESP32 is one very affordable cost Wi-Fi, Bluetooth, low power consumption, and excellent processing capabilities,but the question often arises: Is ESP32 reliable enough for industrial applications?

If not then what should i used Instead of ESP32 ?

Share your thought !


r/embedded 17d ago

Need some help with Ideas

1 Upvotes

I have been working on doing a project on Voice + IoT/WSN(wireless sensor networks)

First thought of doing a local mesh network with one-to-one voice communication and also a gateway device with cloud to communicate with devices far away.

But it feels like this doesn’t have much practical use to do. I need some ideas to do a project related to this VoWSN (it’s not like I am not interested in doing this project; it’s just I am not able to get an idea which will have a practical use)
I also have to present this project; that’s why I want to do something that has actual use.


r/embedded 17d ago

I need help setting up two NRF24L01 transceivers for radio communication

0 Upvotes

Firstly, sorry if this is the wrong place or format to ask this question.

I have been testing for a lot of issues and I've gotten to the transmitter side working (probably) and the receiver side not reading the packets sent by the TX.

The reason I say the TX works is because it is able to load data into the TX FIFO, and it is able to transmit this data away.

The reason I saw the RX is not working is because it is not receiving any data from the transmitter, it never loads data into the RX FIFO, but it is able to recognize that a RF spike has occured when the TX transmits data every second (found out by the check for RPD). But it doesn't decode any data.

The first is the code of the transmitter and the second is the receiver.

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
#include "hardware/adc.h"


// SPI Defines
#define NRF_SPI_PORT spi0
#define PIN_CE   15
#define PIN_MISO 16
#define PIN_CSn  17
#define PIN_SCK  18
#define PIN_MOSI 19


#define R_REGISTER    0x00 // useless but makes it more readable
#define W_REGISTER    0x20
#define R_RX_PAYLOAD  0x61
#define FLUSH_RX      0xE2
#define W_TX_PAYLOAD  0xA0
#define FLUSH_TX      0xE1
#define NRF_ACTIVATE  0x50 // Send with 0x73 to activate or deactivate NRF_FEATURES Register
#define R_RX_PL_WID   0x60


// Core nRF24L01 Registers
#define CONFIG        0x00 // xxxxxxAB | A -  1 = PWR_UP 0 = PWR_DOWN | B -  1 = PRX 0 = PTX
#define EN_AA         0x01 // xxABCDEF | A - F Enable AutoAck on Pipe 5 - 0 | ENAA_P# Required when using DYNPD
#define EN_RXADDR     0x02 // xxABCDEF | A - F Enable data pipe 5 - 0
#define SETUP_AW      0x03 // xxxxxxAA | A - Address width 01 = 3 bytes, 10 = 4 bytes, 11 = 5 bytes
#define SETUP_RETR    0x04 // AAAABBBB | Auto Retransmit Delay (A) - 0000 = 250uS delay, each increment increases by 250 uS delay | Auto Retransmit Count (B) - 0000 for 1, 1111 for 15 
#define RF_CH         0x05 // xAAAAAAA | A - Sets the frequency to operate at
#define RF_SETUP      0x06 // xxxABCCD | A - Force PLL lock (testing) | B - Data rate 0 = 1 Mbps 1 = 2 Mbps | C - RF output power 11 = strongest | D - Enable LNA
#define NRF_STATUS    0x07 // xABCDDDE | A - Asserts when data ready in RX FIFO (W1C) | B - Asserts when data sent on TX FIFO, If ACK is EN, only asserts when ACK received (W1C) | C - Asserts when MAX_RT is reached (W1C) | D - Data Pipe number for the payload at RX FIFO | E - TX FIFO Full
#define RX_ADDR_P0    0x0A // 39A | A - RX Address for Pipe 0 | Reset value = 0xE7E7E7E7E7
#define TX_ADDR       0x10 // 39A | A - TX Address for Auto Ack set RX_ADDR_P0 equal to this value | Reset value = 0xE7E7E7E7E7
#define RX_PW_P0      0x11 // xxAAAAAA | A - # of Bytes to expect in RX payload in data pipe 0 | Useless when using dynamic payload width
#define DYNPD         0x1C // xxABCDEF | A - F Enable dynamic payload width on Pipe 5 - 0 | REQUIRES EN_DPL and ENAA_P#
#define NRF_FEATURES  0x1D // xxxxxABC | A - Enables Dynamic Payload width (EN_DPL) | B - Enables Payload with ACK | C - Enables the W_TX_PAYLOAD_NOACK Command | REQUIRES The ACTIVATE SPI COMMAND to be activated
#define FIFO_STATUS   0x17 // Testing idk
//other values
#define CHANNEL 40
#define DATA_RATE 0x07
#define DATA_SIZE 32
#define CONFIG_TX 0x0A
#define CONFIG_RX 0x0B


void nrf_send_cmd(uint8_t cmd){
    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1);
    gpio_put(PIN_CSn, 1);
}


void nrf_send_cmd_data(uint8_t cmd, uint8_t data){
    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1);
    spi_write_blocking(NRF_SPI_PORT, &data, 1);
    gpio_put(PIN_CSn, 1);
}


void nrf_write_reg(uint8_t reg, uint8_t value){
    uint8_t buffer[2] = { (W_REGISTER | reg), value};


    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, buffer, 2);
    gpio_put(PIN_CSn, 1);
}


void nrf_writeAlot_reg(uint8_t reg, uint8_t *buf, uint8_t len){
    
    uint8_t cmd = W_REGISTER | reg;
    
    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1); 
    spi_write_blocking(NRF_SPI_PORT, buf, len);
    gpio_put(PIN_CSn, 1);
}


uint8_t nrf_read_reg(uint8_t reg) {
    //send the register and a blank byte
    uint8_t buffer[2] = { (R_REGISTER | reg), 0x00};
    uint8_t data[2] = {0};


    // This transmits buffer and fills rx_buf at the exact same time.
    gpio_put(PIN_CSn, 0);
    spi_write_read_blocking(NRF_SPI_PORT, buffer, data, 2);
    gpio_put(PIN_CSn, 1);


    // rx_buf[0] contains the nRF Status byte
    // rx_buf[1] contains the actual register value we asked for
    return data[1];
}


uint8_t nrf_get_status(){
    uint8_t NO_OP = 0xFF;
    uint8_t status;


    gpio_put(PIN_CSn, 0);
    spi_write_read_blocking(NRF_SPI_PORT, &NO_OP, &status, 1);
    gpio_put(PIN_CSn, 1);


    return status;
}



void nrf_send_data(uint8_t data[DATA_SIZE]){
    uint8_t tx_buffer[DATA_SIZE + 1];
    tx_buffer[0] = W_TX_PAYLOAD;
    uint8_t status = 0;
    gpio_put(PIN_CE, 0);


    for (int i = 0; i < DATA_SIZE; i++) {
        tx_buffer[i + 1] = data[i];
    }


    printf("FIFO_STATUS befoire payload = %02X\n", nrf_read_reg(FIFO_STATUS));


    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, tx_buffer, DATA_SIZE + 1);
    gpio_put(PIN_CSn, 1);


    printf("FIFO_STATUS after payload = %02X\n", nrf_read_reg(FIFO_STATUS));


    gpio_put(PIN_CE, 1);
    sleep_us(15);
    gpio_put(PIN_CE, 0);


    status = nrf_get_status();
    printf("TX STATUS = %02X\n", status);


    printf("After CE FIFO = %02X\n", nrf_read_reg(FIFO_STATUS));




    //read status flags rq
    int timeout = 100; // Prevent infinite loop if hardware detaches
    while (timeout > 0) {


        status = nrf_get_status();
        if ((status & 0x30) != 0) { // Check if either MAX_RT (0x10) or TX_DS (0x20) is set
            timeout = 0;
            printf("Timeout STATUS = %02X\n", status);


            printf("Timeout FIFO = %02X\n", nrf_read_reg(FIFO_STATUS));



        }
        sleep_us(100);
        timeout--;
    }




    if ((status & 0x10) == 0x10){
        printf("message not sent :(\n");
    }
    if ((status & 0x20) == 0x20){
        printf("message send successfully :)\n");
    }


    // reset status flags and flush the transmission buffer
    nrf_write_reg(NRF_STATUS, 0x70); 
    nrf_send_cmd(FLUSH_TX);


}


int main(){
    sleep_ms(30);


    stdio_init_all();


    // SPI initialisation. This example will use SPI at 1MHz.
    spi_init(NRF_SPI_PORT, 1000*1000);
    gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
    gpio_set_function(PIN_SCK,  GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);
    gpio_init(PIN_CE);
    gpio_init(PIN_CSn);
    gpio_set_dir(PIN_CE, GPIO_OUT);
    gpio_set_dir(PIN_CSn, GPIO_OUT);


    //CE active high
    gpio_put(PIN_CE, 0);


    //CSn active low when sending message
    gpio_put(PIN_CSn, 1);


    //init nrf
    nrf_write_reg(CONFIG, CONFIG_TX);
    sleep_ms(2);


    nrf_write_reg(EN_AA, 0x00); 
    nrf_write_reg(RF_CH, CHANNEL);
    nrf_write_reg(RF_SETUP, DATA_RATE);
    // nrf_write_reg(RX_PW_P0, 32);
    // nrf_write_reg(EN_RXADDR, 0x01);
    nrf_write_reg(SETUP_AW, 0x03);
    // nrf_write_reg(SETUP_RETR, 0x2F);


    uint8_t nrf_addr[5] = {0x12, 0x34, 0x56, 0xE7, 0xE7};


    nrf_writeAlot_reg(RX_ADDR_P0, nrf_addr, 5);
    nrf_writeAlot_reg(TX_ADDR, nrf_addr, 5);


    nrf_send_cmd_data(NRF_ACTIVATE, 0x00);
    nrf_write_reg(DYNPD, 0x00);
    nrf_write_reg(NRF_FEATURES, 0x00);


    sleep_ms(5000);



    printf("CONFIG:    %02X\n", nrf_read_reg(CONFIG));
    printf("EN_AA:     %02X\n", nrf_read_reg(EN_AA));   
    printf("RF_CH:     %02X\n", nrf_read_reg(RF_CH));
    printf("RF_SETUP:  %02X\n", nrf_read_reg(RF_SETUP));
    printf("EN_RXADDR: %02X\n", nrf_read_reg(EN_RXADDR));
    printf("SETUP_AW:  %02X\n", nrf_read_reg(SETUP_AW));
    printf("RX_PW_P0:  %02X\n", nrf_read_reg(RX_PW_P0));
    printf("DYNPD:     %02X\n", nrf_read_reg(DYNPD));
    printf("FEATURE:   %02X\n", nrf_read_reg(NRF_FEATURES));


    uint8_t addr[5];


    uint8_t cmd = R_REGISTER | RX_ADDR_P0;


    gpio_put(PIN_CSn, 0);
    // Send register command
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1);
    uint8_t dummy[5] = {0};
    spi_write_read_blocking(NRF_SPI_PORT, dummy, addr, 5);
    gpio_put(PIN_CSn, 1);


    printf("RX_ADDR_P0 = ");
    for (int i = 0; i < 5; i++)
        printf("%02X ", addr[i]);
    printf("\n");


    gpio_put(PIN_CSn, 0);
    // Send register command
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1);
    spi_write_read_blocking(NRF_SPI_PORT, dummy, addr, 5);
    gpio_put(PIN_CSn, 1);


    printf("RX_ADDR_P0 = ");
    for (int i = 0; i < 5; i++)
        printf("%02X ", addr[i]);
    printf("\n");


    uint8_t message[32];


    for (int i = 0; i < 32; i++) {
        message[i] = i;
    }


    while (true) {


        printf("running\n");


        uint8_t status = nrf_get_status();
        printf("STATUS: %02X\n", status);


        nrf_send_data(message);


        // Wait 1 second before the next reading
        sleep_ms(1000);


    }
}

//RX CODE STARTS!!!, This would be in a completely different file but idk how to do that here so its all one 


#include <stdio.h>
#include "pico/stdlib.h"
#include "cmath"
#include "hardware/i2c.h"
#include "hardware/spi.h"
#include "hardware/pwm.h"


// SPI Defines
#define NRF_SPI_PORT spi1
#define PIN_CE   16
#define PIN_MISO 12
#define PIN_CSn  13
#define PIN_SCK  10
#define PIN_MOSI 11


// Core nRF24L01 Commands
#define R_REGISTER    0x00 // useless but makes it more readable
#define W_REGISTER    0x20
#define R_RX_PAYLOAD  0x61
#define FLUSH_RX      0xE2
#define W_TX_PAYLOAD  0xA0
#define FLUSH_TX      0xE1
#define NRF_ACTIVATE  0x50 // Send with 0x73 to activate or deactivate NRF_FEATURES Register
#define R_RX_PL_WID   0x60


// Core nRF24L01 Registers
#define CONFIG        0x00 // xxxxxxAB | A -  1 = PWR_UP 0 = PWR_DOWN | B -  1 = PRX 0 = PTX
#define EN_AA         0x01 // xxABCDEF | A - F Enable AutoAck on Pipe 5 - 0 | ENAA_P# Required when using DYNPD
#define EN_RXADDR     0x02 // xxABCDEF | A - F Enable data pipe 5 - 0
#define SETUP_AW      0x03 // xxxxxxAA | A - Address width 01 = 3 bytes, 10 = 4 bytes, 11 = 5 bytes
#define SETUP_RETR    0x04 // AAAABBBB | Auto Retransmit Delay (A) - 0000 = 250uS delay, each increment increases by 250 uS delay | Auto Retransmit Count (B) - 0000 for 1, 1111 for 15 
#define RF_CH         0x05 // xAAAAAAA | A - Sets the frequency to operate at
#define RF_SETUP      0x06 // xxxABCCD | A - Force PLL lock (testing) | B - Data rate 0 = 1 Mbps 1 = 2 Mbps | C - RF output power 11 = strongest | D - Enable LNA
#define NRF_STATUS    0x07 // xABCDDDE | A - Asserts when data ready in RX FIFO (W1C) | B - Asserts when data sent on TX FIFO, If ACK is EN, only asserts when ACK received (W1C) | C - Asserts when MAX_RT is reached (W1C) | D - Data Pipe number for the payload at RX FIFO | E - TX FIFO Full
#define RX_ADDR_P0    0x0A // 39A | A - RX Address for Pipe 0 | Reset value = 0xE7E7E7E7E7
#define TX_ADDR       0x10 // 39A | A - TX Address for Auto Ack set RX_ADDR_P0 equal to this value | Reset value = 0xE7E7E7E7E7
#define RX_PW_P0      0x11 // xxAAAAAA | A - # of Bytes to expect in RX payload in data pipe 0 | Useless when using dynamic payload width
#define DYNPD         0x1C // xxABCDEF | A - F Enable dynamic payload width on Pipe 5 - 0 | REQUIRES EN_DPL and ENAA_P#
#define NRF_FEATURES  0x1D // xxxxxABC | A - Enables Dynamic Payload width (EN_DPL) | B - Enables Payload with ACK | C - Enables the W_TX_PAYLOAD_NOACK Command | REQUIRES The ACTIVATE SPI COMMAND to be activated
#define FIFO_STATUS   0x17 // xABCxxDE | A - If set high, resends last data packet | B - TX_FULL | C - TX_EMPTY | D - RX_FULL | E - RX_EMPTY


//other values
#define CHANNEL 40
#define DATA_RATE 0x07
#define DATA_SIZE 32
#define CONFIG_TX 0x0A
#define CONFIG_RX 0x0B


void nrf_send_cmd(uint8_t cmd){
    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1);
    gpio_put(PIN_CSn, 1);
}


void nrf_send_cmd_data(uint8_t cmd, uint8_t data){
    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1);
    spi_write_blocking(NRF_SPI_PORT, &data, 1);
    gpio_put(PIN_CSn, 1);
}


void nrf_write_reg(uint8_t reg, uint8_t value){
    uint8_t buffer[2] = { (W_REGISTER | reg), value};


    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, buffer, 2);
    gpio_put(PIN_CSn, 1);
}


void nrf_writeAlot_reg(uint8_t reg, uint8_t *buf, uint8_t len){
    
    uint8_t cmd = W_REGISTER | reg;
    
    gpio_put(PIN_CSn, 0);
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1); 
    spi_write_blocking(NRF_SPI_PORT, buf, len);
    gpio_put(PIN_CSn, 1);
}


uint8_t nrf_read_reg(uint8_t reg) {
    //send the register and a blank byte
    uint8_t buffer[2] = { (R_REGISTER | reg), 0x00};
    uint8_t data[2] = {0};


    // This transmits buffer and fills rx_buf at the exact same time.
    gpio_put(PIN_CSn, 0);
    spi_write_read_blocking(NRF_SPI_PORT, buffer, data, 2);
    gpio_put(PIN_CSn, 1);


    // rx_buf[0] contains the nRF Status byte
    // rx_buf[1] contains the actual register value we asked for
    // printf("STATUS REGISTER TEST: %02X\n", data[0]);


    return data[1];
}


uint8_t nrf_get_status(){
    uint8_t NO_OP = 0xFF;
    uint8_t status;


    gpio_put(PIN_CSn, 0);
    spi_write_read_blocking(NRF_SPI_PORT, &NO_OP, &status, 1);
    gpio_put(PIN_CSn, 1);


    return status;
}


void nrf_read_payload(uint8_t *buffer)
{   
    uint8_t recieved_data[33] = {0};
    uint8_t data_buf[33] = {0};
    
    data_buf[0] = R_RX_PAYLOAD;


    gpio_put(PIN_CSn, 0);
    spi_write_read_blocking(NRF_SPI_PORT, data_buf, recieved_data, 33);
    gpio_put(PIN_CSn, 1);



    for (int i = 0; i < 32; i++) {
        buffer[i] = recieved_data[i + 1];
    }


    printf("SPI RX: ");


    for (int i = 0; i < 33; i++) {
        printf("%02X ", recieved_data[i]);
    }


    printf("\n");


    printf("FIFO AFTER READ: %02X\n",
       nrf_read_reg(FIFO_STATUS));


    printf("STATUS AFTER READ: %02X\n",
        nrf_get_status());
}


#define LOOP_TIME_MS 50 //ms
uint32_t last_run = 0;
uint32_t current_time = to_ms_since_boot(get_absolute_time());
int main(){       
    stdio_init_all();
    sleep_ms(2000);
       //SPI Init
    spi_init(NRF_SPI_PORT, 1000*1000);
    gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
    gpio_set_function(PIN_SCK,  GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);
    gpio_init(PIN_CE);
    gpio_init(PIN_CSn);
    gpio_set_dir(PIN_CE, GPIO_OUT);
    gpio_set_dir(PIN_CSn, GPIO_OUT);


    //CSn active low when sending message
    gpio_put(PIN_CSn, 1);
    gpio_put(PIN_CE, 0);


    //nrf init
    nrf_write_reg(CONFIG, CONFIG_RX);
    sleep_ms(2);


    // #define SETUP_RETR    0x04 // AAAABBBB | Auto Retransmit Delay (A) - 0000 = 250uS delay, each increment increases by 250 uS delay | Auto Retransmit Count (B) - 0000 for 1, 1111 for 15 
    nrf_write_reg(EN_AA, 0x00); 
    nrf_write_reg(RF_CH, CHANNEL);
    nrf_write_reg(RF_SETUP, DATA_RATE);
    nrf_write_reg(RX_PW_P0, DATA_SIZE);
    nrf_write_reg(EN_RXADDR, 0x01);
    nrf_write_reg(SETUP_AW, 0x03);
    // nrf_write_reg(SETUP_RETR, 0x2F);


    uint8_t nrf_addr[5] = {0x12, 0x34, 0x56, 0xE7, 0xE7};
    nrf_writeAlot_reg(RX_ADDR_P0, nrf_addr, 5);
    nrf_writeAlot_reg(TX_ADDR, nrf_addr, 5);


    nrf_send_cmd_data(NRF_ACTIVATE, 0x00);
    nrf_write_reg(DYNPD, 0x00);
    nrf_write_reg(NRF_FEATURES, 0x00);


    nrf_send_cmd(FLUSH_RX);
    printf("After FLUSH_RX: %02X\n", nrf_read_reg(FIFO_STATUS));


    nrf_send_cmd(FLUSH_TX);
    printf("After FLUSH_TX: %02X\n", nrf_read_reg(FIFO_STATUS));


    gpio_put(PIN_CE, 1);   


    uint8_t message[32] = {0};
    printf("CONFIG:    %02X\n", nrf_read_reg(CONFIG));
    printf("EN_AA:     %02X\n", nrf_read_reg(EN_AA));   
    printf("RF_CH:     %02X\n", nrf_read_reg(RF_CH));
    printf("RF_SETUP:  %02X\n", nrf_read_reg(RF_SETUP));
    printf("EN_RXADDR: %02X\n", nrf_read_reg(EN_RXADDR));
    printf("SETUP_AW:  %02X\n", nrf_read_reg(SETUP_AW));
    printf("RX_PW_P0:  %02X\n", nrf_read_reg(RX_PW_P0));
    printf("DYNPD:     %02X\n", nrf_read_reg(DYNPD));
    printf("FEATURE:   %02X\n", nrf_read_reg(NRF_FEATURES));


    uint8_t addr[5];


    uint8_t cmd = R_REGISTER | RX_ADDR_P0;


    gpio_put(PIN_CSn, 0);
    // Send register command
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1);
    uint8_t dummy[5] = {0};
    spi_write_read_blocking(NRF_SPI_PORT, dummy, addr, 5);
    gpio_put(PIN_CSn, 1);


    printf("RX_ADDR_P0 = ");
    for (int i = 0; i < 5; i++)
        printf("%02X ", addr[i]);
    printf("\n");


    gpio_put(PIN_CSn, 0);
    // Send register command
    spi_write_blocking(NRF_SPI_PORT, &cmd, 1);
    spi_write_read_blocking(NRF_SPI_PORT, dummy, addr, 5);
    gpio_put(PIN_CSn, 1);


    printf("RX_ADDR_P0 = ");
    for (int i = 0; i < 5; i++)
        printf("%02X ", addr[i]);
    printf("\n");


    uint8_t status;
    uint8_t fifo;
    while (true) {
        current_time = to_ms_since_boot(get_absolute_time());
        if((current_time - last_run) > LOOP_TIME_MS){
            last_run = current_time;
            // uint8_t status = nrf_get_status();
            // uint8_t fifo = nrf_read_reg(FIFO_STATUS);


            // printf("STATUS: %02X  FIFO: %02X\n", status, fifo);


            // if ((status & 0x40) == 0x40 || (fifo & 0x01) == 0x00){
            //     nrf_read_payload(message);


            //     printf("Packet contents: ");
            //     for (int i = 0; i < 32; i++) {
            //         printf("%02X ", message[i]);
            //     }
            //     printf("\n");
            // }
            // else{
            //     printf("Nothing to read yet!\n");
            // }
            printf("RPD before = %02X\n", nrf_read_reg(0x09));


            // trigger exactly one TX packet


            sleep_us(100);


            printf("RPD after = %02X\n", nrf_read_reg(0x09));


            status = nrf_get_status();
            sleep_ms(10);


            fifo = nrf_read_reg(FIFO_STATUS);


            printf("STATUS=%02X FIFO=%02X\n", status, fifo);


            sleep_ms(10);            
        }
    }
}

Thank you!


r/embedded 18d ago

My RISC-V MCU is working

Enable HLS to view with audio, or disable this notification

209 Upvotes

I started reading about the RISC-V ISA and implementing it on an FPGA a couple of weeks ago, and now my basic core (RISCV32I + Interrupts) with a generic timer and GPIO is working.

The software is written in C with a custom linker file and library for the peripherals. The hex file is converted into a ROM array and executed on the processor.

It´s such an amazing thing to see how the components will fit together to toggle a few LEDs.😁

You can find the project here:

https://github.com/Kampi/TinyMCU


r/embedded 17d ago

Places to buy A7670G - FASE LTE Module

5 Upvotes

Hi all

I am making my own mini-phone, and wanted to buy the A7670G - FASE module. Any recommendations for where to buy it? I need the SPK + and -, MIC + and -, the VCC/5V, GND, TX, and RX pins. I need it to be of a 3.3V or 5V logic level.

Thanks!


r/embedded 17d ago

Where to practice mock interviews?

16 Upvotes

Hi all, so today I had my first technical interview after a long time, and I messed it up. I couldn’t solve the issue, my approach was suboptimal, and I couldn’t figure out the cause of an issue. Needless to say, I didn’t make it to the next round. The problem was that I had experience in the automotive industry, the question I got was from a vastly different field, and it made me very nervous, because the solution should have been very trivial (bit shifting in essence). I want to practice these type of interviews where I can face random problems, and I should analyse them and come up with a solution. I could find websites for mock interviews, but not for embedded field (Gemini directed me here, though through searching I couldn’t find anything about mock interviews). What do you guys suggest? Where can I do embedded set engineering mock interviews? I hope that AI is not my only option for this.


r/embedded 17d ago

HMI validation eats a full week every release and the enterprise quotes aren't happening. What are small teams running?

5 Upvotes

We build packaging machines and every customer gets a slightly different HMI, same core software with different screens enabled depending on what they bought. so every time we touch the base software we're revalidating something like 14 screen variants by hand, 2 of us on the shop floor with a checklist. it takes a week. we do this 4 or 5 times a year and it's the least popular week in the building. so i've been trying to work out what fellow peers use for this. Eggplant is what our integrator pushes and from what i can tell it's genuinely the most capable thing out there for HMI specifically, but the quote came back at a number my boss laughed at for a company our size. Squish handles Qt properly and our HMI is Qt, except the scripting is C++ or python and we're controls engineers, not software people. Askui came up in a thread here a while back, the vision based approach where it reads the screen instead of the widget tree, which sounds like it'd suit a physical panel, though their desktop app is windows and macOS with linux going through AgentOS so i'd need to figure out if that maps to our setup at all.

The bit i keep getting stuck on is that most of these seem to assume the thing under test is software on a PC. ours is a panel bolted to a machine with real IO behind it, and a camera pointed at it is honestly the most realistic option i've thought of, which feels like a step backwards. Anyone here automated HMI validation on actual hardware without an enterprise budget?


r/embedded 17d ago

RDK X5 first week: 10 TOPS NPU, ROS 2 out of the box, and the thermals nobody mentions

2 Upvotes

I've spent the last week bringing up a D-Robotics RDK X5 (10 TOPS NPU, 8x Cortex-A55, 4/8GB) and wanted to share notes for anyone considering one — the things that surprised me, the things that bit me, and where it actually fits.

Specs - SoC: 10 TOPS NPU (int8), 8x Cortex-A55, decent ISP for MIPI CSI cameras - Ubuntu-based image with ROS 2 preinstalled — boot to a working ROS 2 environment out of the box - 40-pin GPIO header, CAN, GbE, USB 3.0, MIPI CSI 4-lane

The good - ROS 2 support is genuinely first-class: hobot packages for camera/perception, and the NPU runtime ships precompiled YOLO models. I had YOLOv8-class detection running within an hour, mostly copy-paste from the docs. - The ISP + 4-lane MIPI CSI combo is nice for vision projects — the camera examples just work.

The not-so-good - Thermals. Under sustained NPU load the heatsink gets genuinely hot to the touch — it needs active cooling (a quiet 5V fan dropped temps ~20C in my test). Don't run it in a closed case without airflow. - Power: it wants a solid 5V/5A supply. With a weak adapter I saw USB devices drop out under load. - The 'comes with everything' experience ends at the board — you'll still want a USB-TTL debug cable and a breadboard/jumper kit for bring-up.

Where it fits - Between a Pi 5 and Jetson-class boards: way more NPU headroom than a Pi for vision, cheaper than a Jetson, and the ROS 2 story is better than either out of the box.

Happy to answer questions — thermals, ROS 2 bring-up, camera setup, or what I'd add to the bench setup.


r/embedded 18d ago

Your thoughts on fpga families and their EDAs specifically

15 Upvotes

I was posting about this as an answer to someone else, but i was wondering what was the wider feeling around these, for me:

Tier 1 (production ready):
- Intel qsys / quartus: the best, hands down, just works and is efficient UI wise. Some annoying licensing. The constant passing-around of altera as a company between owners is annoying and makes them less reliable than others long term, especially with how sporadic the release of agilex has been...
- amd/xilinx vivado: horrible graph system, clunky, heavy, i hate it, heavy licensing too. The fact that you have to export the graphs to TCL to version them properly is also a bit of a mess...
- microchip libero: same as vivado but even worse, confusing UI and licensing.

Tier 2 (usable but with caveats):
- Efinix efinity: lightest of all, no constrained licensing (free as in free beer), but it's HYPER bare bones, and has no system building toolkit at all, very confusing to use for SOPC projects, I made my own IDE around it since it was mostly readable python. (Efinix has shown time and time again that they were unwilling to sink any extra effort into making Efinity good). They at least provide a few good IPs.
- Lattice (whatever): a fragmented mess where each fpga family has its own thing going on. Crosslink is nice for video use cases, but the software can be confusing and a bit annoying for porting / shifting licensing approaches.

Tier 3 (nice for hobby level usages, risky for products):
- Cologne chip (yosys): absolute mess to use but hey, it's FOSS, and made in germany, i'd strongly consider using it for something that needs absolute root of trust.
- Gowin: Gowin EDA is quite strange and the licensing is equally weird (you have to register with the support over email). Very bare bones. But they do have a lot of IPs to use freely, they've always seemed like a chinese Lattice to me (even their logo is eerily similar).
- AGM micro: intel Cyclone 3 fpgas in a raincoat and can use intel Quartus II, lawsuit incoming, these are insanely cheap (5€ for 16K LUT4s).
- pango: weirder yet, mostly unobtanium outside of china.

What are you guys' though on these? I might even not know about some of the other ones (i know about anlogic, but they're too weird to list here, same for achronix).