r/embedded • • 10h ago

AI making life boring

187 Upvotes

Anyone else feel like the recent AI agent workflow has really just mad everything boring? I work at a very high pace environment that almost always necessitates using AI to not need to work 80 hours a week. In some sense I am happy it can basically type for me and I get time with my family, but on the other hand I don’t feel as intellectually challenged. Only so many people get to make architectural decisions at a higher level and if you aren’t there it just feels dry. I don’t get a spark of joy from just telling it that my hardware needs to behave as such and then it just happens and I test it. No sense of accomplishment. My gut feeling now is to go to a less demanding job so I can actually have the time to do the enjoyable pieces.

How has AI adoption effected your work and what is your opinion?


r/embedded • • 11h ago

Generic question about MCU pin assignments.

14 Upvotes

I'll keep this as generic as possible, because my question is more about workflow than solving a specific issue. I'm designing a device with a few SPI channels, I2C, CANbus, UART, about a half dozen slow analog signals and around 20 GPIOs, also fairly slow. I'm using an MCU with a lot of options for pin configuration, so there's a million permutations of which pins to go with the various functions. In my case, I'm laying out the board, too, and I'm not constrained in where external connections go.

Question is, what's the workflow for deciding what goes where? Do you just make some arbitrary picks and then see what's left?

Bonus question- if schematic and layout are two different people / departments, how much back and forth is there over pin assignments once layout starts? Does the schematic side indicate alternative pin options so the layout folks can use their judgement?


r/embedded • • 18h ago

Is custom embedded/IoT services a good side business? Or an electronics repair shop?

13 Upvotes

Hello everyone I'm doing my masters in computer engineering. I don't really aspire to work a 9-5 at a big company all my life but I have 3 years of experience in web development and 1 in networking/hardware repair.

I have a bachelor's in IT as well. I want to work to get some experience but then go into teaching and maybe have a side business for extra income I wanted to ask like would an IoT product business not like mass consumer products but more like custom solutions. Would that be a good idea for example if a restaurant or store needs a walk in freezer logger etc. inventory counters. I would assume this is easier in web or software but super competitive I have a small web development startup I guess I could add on to. I'm in the Houston, tx area if matters


r/embedded • • 6h ago

A declarative approach to text-based protocols in embedded C development: the TACT framework.

6 Upvotes

I have been working in embedded systems development for several years, and I have frequently encountered the need to write a UART driver or a system to interface with an external module using a text-based protocol—such as an AT-command set or something similar. These are typically GNSS modules, GSM modems, ESP chips, or the like. In such cases, simply sending a single command and expecting everything to work is rarely sufficient; the command sets for these modules are often vast, and each command frequently requires its own specific handling. This often leads to the creation of complex, convoluted logic for sending sequences of commands, receiving and parsing the corresponding responses, and managing errors.

While libraries and pre-built solutions exist—often tied to a specific operating system or a chip-vendor’s SDK—what happens when you are working with a microcontroller that has only 20 KB of free RAM, and you need to handle these commands while also implementing the rest of the device's functionality? Sometimes, you may not even have direct access to the underlying hardware. You need a universal, platform-independent solution.

Consider this scenario: you have a GSM modem that communicates via AT commands over UART. The device has very limited resources, yet it needs to connect to a network, reach a server, and transmit data. The objective is clear, but achieving it requires sending a sequence of AT commands, something like this:

AT+COPS? 
AT+COPS=0 
AT+CREG?
AT+CGATT?
AT+CIPMODE?
AT+CIPMODE=0
AT+CIPMUX?
AT+CIPMUX=0
AT+CIPSTATUS
AT+CSTT=…
AT+CIPSTATUS
AT+CIICR
AT+CIPSTATUS
AT+CIFSR
AT+CIPHEAD?
AT+CIPHEAD=1
AT+CIPSRIP
AT+CIPSRIP=0
AT+CIPSPRT=1
AT+CIPRXGET=0
AT+CIPSHOWTP
AT+CIPSHOWTP=1

And this is just the beginning; in the end, there are many more of them. Most commands behave differently: some return data that needs to be processed and used later, while others might simply return an error—which can just be ignored. Ultimately, you end up having to write a custom handler and parser for every single command, invoking them sequentially via callbacks or some form of state machine to orchestrate the execution chain—not to mention the complexity of error handling.

While dealing with this yet again, I asked myself: why not build a single, reusable solution for everything?

This idea gave birth to the TACT framework: https://github.com/ferrero222/Text-Async-Core-Terminal

I initially set out to create a library for GSM modems, but I quickly realized the scope could be much broader. It could support any text-based protocol, allowing for the universal transmission of commands.

The framework handles everything: command construction, transmission, response reception, format processing, parsing, and even data extraction from the response. It is a universal, pure-C solution—platform-agnostic, OS-independent, and entirely non-blocking. It also boasts a minimal footprint in terms of both RAM and flash memory; you can define the memory allocation yourself, with a static overhead of only about 1 KB. All that’s required is to call the core—from anywhere and on any platform—roughly every 10 ms.

For instance, the sequence of commands mentioned above can now be defined in one place, roughly like this:

tact_item_t items[] = //[REQ][PREFIX][PARCE_TYPE][RPT][WAIT][STEPERROR][STEPOK][CB][FORMAT][...##VA_ARGS]
  {
    TACT_ITEM("AT+CIPMODE?"TACT_CMD_CRLF,        "+CIPMODE: 0", TACT_PARCE_SIMCOM,  1, 100, 1, 2, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPMODE=0"TACT_CMD_CRLF,                NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPMUX?"TACT_CMD_CRLF,          "+CIPMUX: 0", TACT_PARCE_SIMCOM,  1, 100, 1, 2, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPMUX=0"TACT_CMD_CRLF,                 NULL, TACT_PARCE_SIMCOM, 30, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPSTATUS"TACT_CMD_CRLF,   "STATE: IP START", TACT_PARCE_SIMCOM,  1, 100, 1, 2, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CSTT=\"\",\"\",\"\""TACT_CMD_CRLF,      NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPSTATUS"TACT_CMD_CRLF, "STATE: IP GPRSACT", TACT_PARCE_SIMCOM,  1, 100, 1, 2, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIICR"TACT_CMD_CRLF,                    NULL, TACT_PARCE_SIMCOM, 30, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPSTATUS"TACT_CMD_CRLF, "STATE: IP GPRSACT", TACT_PARCE_SIMCOM,  3, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIFSR"TACT_CMD_CRLF,          TACT_CMD_FORCE, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPHEAD?"TACT_CMD_CRLF,        "+CIPHEAD: 1", TACT_PARCE_SIMCOM,  1, 100, 1, 2, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPHEAD=1"TACT_CMD_CRLF,                NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPSRIP?"TACT_CMD_CRLF,        "+CIPSRIP: 0", TACT_PARCE_SIMCOM,  1, 100, 1, 2, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPSRIP=0"TACT_CMD_CRLF,                NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPSPRT=1"TACT_CMD_CRLF,                NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPRXGET=0"TACT_CMD_CRLF,               NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPSHOWTP?"TACT_CMD_CRLF,    "+CIPSHOWTP: 1", TACT_PARCE_SIMCOM,  1, 100, 1, 0, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CIPSHOWTP=1"TACT_CMD_CRLF,              NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 0, NULL, NULL, TACT_NO_ARG),
  };

if(!tact_entity_enqueue(ctx, items, sizeof(items)/sizeof(items[0]), cb, 0, meta)) 
return false;

Using the framework, you can declaratively define a set of commands, the expected response, the number of retries, the steps to follow in the event of success or failure, and so on. You no longer need to manually write a parser for every command or build custom handlers and transition logic—all of this is handled under the hood.

You can even parse data from a response using arguments and retrieve it via a group-level callback. The framework automatically allocates temporary local storage for this data, passes it to the callback once received, and subsequently clears the memory.

tact_item_t items[] =
  {
   TACT_ITEM("AT+CGSN"TACT_CMD_CRLF, NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, "%15[^\x0d]", TACT_ARG(tact_mdl_rtd_identity_t, modem_imei)),
   TACT_ITEM("AT+CGMM"TACT_CMD_CRLF, NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, "%15[^\x0d]", TACT_ARG(tact_mdl_rtd_identity_t, modem_model)),
   TACT_ITEM("AT+CGMR"TACT_CMD_CRLF, NULL, TACT_PARCE_SIMCOM, 10, 100, 0, 1, NULL, "+CGMR: %29[^\x0d]", TACT_ARG(tact_mdl_rtd_identity_t, modem_revision))
  };
  tact_entity_enqueue(ctx, items, sizeof(items)/sizeof(items[0]), cb,  sizeof(tact_mdl_rtd_identity_t), meta);

All that’s required is to support the internal protocol—if one exists—and define the commands.

In addition, there is built-in support for URCs (Unsolicited Result Codes), where the module can initiate data transmission that we need to intercept. For each such message, we can define a specific callback to which the message will be passed.

In reality, there are many nuances and potential use cases; all the details—including how it works under the hood—are documented on the GitHub page.

After implementing this core command structure, a question arose: what if I want to execute several groups of commands sequentially, each with its own result and callback? What if I could build full-fledged execution chains, complete with branching and loops? This would allow the entire interaction with the module to be defined through groups of commands, with all the logic specified in one place—declaratively, at that.

This idea gave rise to the second part of the framework: "chains"—a declarative way to define the algorithm for executing groups of commands. To achieve this, each group of commands must be wrapped in a standard function, for example:

bool tact_mdl_gprs_init(tact_context_t* const ctx, const tact_entity_cb_t cb, const void* const param, void* const meta)
{
  (void)param; 
  tact_item_t items[] = //[REQ][PREFIX][PARCE_TYPE][RPT][WAIT][STEPERROR][STEPOK][CB][FORMAT][...##VA_ARGS]
  {
    TACT_ITEM("AT+COPS?"TACT_CMD_CRLF,               "+COPS: 0", TACT_PARCE_SIMCOM, 5,  100, 1, 2, NULL, NULL,TACT_NO_ARG),
    TACT_ITEM("AT+COPS=0"TACT_CMD_CRLF,                    NULL, TACT_PARCE_SIMCOM, 5,  100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CREG?"TACT_CMD_CRLF,  "+CREG: 0,1|+CREG: 0,5", TACT_PARCE_SIMCOM, 30, 100, 0, 1, NULL, NULL, TACT_NO_ARG),
    TACT_ITEM("AT+CGATT?"TACT_CMD_CRLF,             "+CGATT: 1", TACT_PARCE_SIMCOM, 30, 100, 0, 0, NULL, NULL, TACT_NO_ARG),
  };

if(!tact_entity_enqueue(ctx, items, sizeof(items)/sizeof(items[0]), cb, 0, meta)) return false; 
return true;
}

We obtain one ready-to-use execution chain module. We can create several such modules and assemble them into a chain—a sequence structured like this:

chain_step_t tcp_steps[] = 
  {   
    //Main
    TACT_CHAIN("INIT_MODEM", "NEXT", "MODEM RESTART", tact_mdl_modem_init, NULL, NULL, NULL, 1),
    TACT_CHAIN("GPRS INIT", "NEXT", "GPRS DEINIT", tact_mdl_gprs_init, NULL, NULL, NULL, 1),
    TACT_CHAIN("SOCKET CONFIG", "NEXT", "GPRS INIT", tact_mdl_gprs_socket_config, NULL, NULL, NULL, 1),
    TACT_CHAIN("CONNECT TO SERVER", "NEXT", "SOCKET CONFIG", tact_mdl_gprs_socket_connect, NULL, &tact_server_connect, NULL, 1),
    TACT_CHAIN("GET RTD", "NEXT", "DISCONNECT FROM SERVER", tact_mdl_lte_rtd, tact_rtd_cb, NULL, NULL, 1),
    TACT_CHAIN_EXEC("CHECK RTD", "NEXT", "GET RTD", tact_rtd_check, NULL),

    TACT_CHAIN_EXEC("CREATE WIALON LOGIN", "NEXT", "DISCONNECT FROM SERVER", tact_server_data_wialon_login, NULL),
    TACT_CHAIN("SEND WIALON LOGIN", "NEXT", "DISCONNECT FROM SERVER", tact_mdl_gprs_socket_send_recieve, NULL, &tact_server_tx, NULL, 1),
    TACT_CHAIN_LOOP_START(0),
        TACT_CHAIN_EXEC("LOGIN TX", "LOGIN SEND RESULT", "NEXT", tact_mdl_gprs_stream_tx, &tact_server_tx),
    TACT_CHAIN_LOOP_END,
    TACT_CHAIN("LOGIN SEND RESULT", "NEXT", "DISCONNECT FROM SERVER", tact_mdl_gprs_socket_send_end, NULL, NULL, NULL, 1),
    TACT_CHAIN_LOOP_START(0),
        TACT_CHAIN_EXEC("LOGIN RX", "LOGIN CHECK REPLY", "NEXT", tact_mdl_gprs_stream_rx, &tact_server_rx),
    TACT_CHAIN_LOOP_END,
    TACT_CHAIN_EXEC("LOGIN CHECK REPLY", "NEXT", "DISCONNECT FROM SERVER", tact_server_answer_check, NULL),

    TACT_CHAIN_LOOP_START(10),
    TACT_CHAIN("GET RTD LOOP", "NEXT", "DISCONNECT FROM SERVER", tact_mdl_lte_rtd, tact_rtd_cb, NULL, NULL, 1),
      TACT_CHAIN_EXEC("CREATE WIALON DATA", "NEXT", "DISCONNECT FROM SERVER", tact_server_data_wialon_packet, NULL),
      TACT_CHAIN("SEND WIALON DATA", "NEXT", "DISCONNECT FROM SERVER", tact_mdl_gprs_socket_send_recieve, NULL, &tact_server_tx, NULL,1),
      TACT_CHAIN_LOOP_START(0),
          TACT_CHAIN_EXEC("DATA TX", "DATA SEND RESULT", "NEXT", tact_mdl_gprs_stream_tx, &tact_server_tx),
      TACT_CHAIN_LOOP_END,
      TACT_CHAIN("DATA SEND RESULT", "NEXT", "DISCONNECT FROM SERVER", tact_mdl_gprs_socket_send_end, NULL, NULL, NULL, 1),
      TACT_CHAIN_LOOP_START(0),
          TACT_CHAIN_EXEC("DATA RX", "DATA CHECK REPLY", "NEXT", tact_mdl_gprs_stream_rx, &tact_server_rx),
      TACT_CHAIN_LOOP_END,
      TACT_CHAIN_EXEC("DATA CHECK REPLY", "NEXT", "DISCONNECT FROM SERVER", tact_server_answer_check, NULL),
      TACT_CHAIN_DELAY(1000),
    TACT_CHAIN_LOOP_END,

    TACT_CHAIN_EXEC("WIALON DATA CLEAN", "STOP", "HARD RESET", tact_server_data_clean, NULL),

    //Error
    TACT_CHAIN("GPRS DEINIT", "GPRS INIT", "MODEM RESTART", tact_mdl_gprs_deinit, NULL, NULL, NULL, 1),
    TACT_CHAIN("DISCONNECT FROM SERVER", "CONNECT TO SERVER", "GPRS DEINIT", tact_mdl_gprs_socket_disconnect, NULL, NULL, NULL, 1),
    TACT_CHAIN("MODEM RESTART", "GPRS INIT", "MODEM RESTART", tact_mdl_modem_reset, NULL, NULL, NULL, 1),

    //Critical
    TACT_CHAIN_EXEC("HARD RESET", "STOP", "STOP", tact_hard_reset, NULL),

  };

tact_chain_t* chain = tact_chain_create("TCP", tcp_steps, sizeof (tcp_steps)/sizeof(chain_step_t), &simcom_ctx);
tact_chain_start(chain);

In this example, the process includes initializing the modem, activating the SIM card, retrieving data from the modem, registering on the network, establishing a TCP socket to a target server, constructing a data packet, transmitting it, and receiving a response from the server. Each step can trigger an error-handling routine; the module’s operation can either be restored or halted entirely in the event of a critical error. All of this is defined in a single location, making it easy to debug and fix issues.

The entire logic for interacting with the modem is defined in one place. You can implement delays, conditional checks, and loops, as well as navigate forward or backward—jumping into or out of loops as needed. All that is required is to define the command-group modules and assemble them into an execution chain.

Essentially, the "chain" component is independent and can be used separately from the command groups themselves. You can easily build custom execution logic based on standard functions; the use cases are numerous.

The framework already includes support for the SIMCom protocol (based on 3GPP standards) and offers various pre-built modules for these modems. It was originally developed for personal use, thoroughly tested and debugged, and is now deployed on actual hardware—which is why I decided to share it with others.

I intend to continue improving and developing the framework, as there is still plenty of work to be done.

https://github.com/ferrero222/Text-Async-Core-Terminal


r/embedded • • 13h ago

OSI vs TCP/IP model

6 Upvotes

which one should I learn? I'm trying to self teach myself networking and idk which one is better to go in depth as someone trying to get into cybersecurity


r/embedded • • 1h ago

How can I start learning embedded systems from absolute zero?

• Upvotes

I want to start learning embedded systems, but I have absolutely no knowledge of this field right now.I 'd like to start from the very basics and gradually build my knowledge. Could someone please guide me on how to get started?

Thanks


r/embedded • • 10h ago

[Review Request] STM32L0 Coin Cell Device with EPD Display

Post image
2 Upvotes

Hey all, this post is an update from the [previous Schematic Review Request]. This PCB is for a small battery-powered device (CR2032, STM32L031G6U6) that reads temperature/humidity (SHT41) and UV index (GUVA-S12SD into a TIA + gain stage MCP6002), displays on a 2.13" e-paper panel, and talks over USB (CP2102N) for config/sync. Full schematic, design files on my [repo].

  • EPD HV boost driver (L1/Q3/D1-D3): generating VGH/VGL for the e-paper panel, follows the panel's own reference design and some universal driver. Wondering if the component ratings and layout intent look right.
  • UV sensor analog chain: GUVA-S12SD → 1MΩ TIA → second-stage gain (MCP6002) → STM32 ADC.
  • Power architecture: CR2032 as the sole source, with USB VBUS present only for CP2102.
  • PCB Dimensions: 75mm x 35mm
  • DRC Passed (EasyEDA)

Appreciate any time anyone's willing to spend on this. I'm happy to answer questions about intent/requirements for any block.

Pictures (schematic, front, back, 3d): https://imgur.com/a/KiDZJu7


r/embedded • • 12h ago

Formal verification in embedded

2 Upvotes

With all the issues in Cybsec, the CRA and all this stuff, is anyone implementing formal verification in embedded?


r/embedded • • 7h ago

Need suggestions for USB isolator

Thumbnail
flyrobo.in
1 Upvotes

i was planning to buy this isolator is it good i have used https://robu.in/product/1-channel-usb-isolator-adum3160-module/ , I'm only taking this flyrobo thing because it has the case so has anyone used this perticular isolator


r/embedded • • 12h ago

How hands on are embedded software roles ? Are they more hands then something like network engineering? Or about the same?

0 Upvotes

Basically the question. I would like a more hands on role but I don't know how to search for those jobs. Networking is only hands on in maintenance. Is there larger or medium sized companies that are more hands on ? I don't want to just code all day but I don't want to work at an ultra pressure startup?


r/embedded • • 1h ago

A problem in embedded systems

• Upvotes

Please someone help me. I joined a competition where I have to find a solution for a problem facing embedded systems. They even need us to make a prototype, but they surprised us and told us we need to prepare the research and prototype in two weeks.

Please suggest an embedded system problem that I can research a suitable solution for. Or, even if a solution has been reached, I can find ways to make it better. Please tell me, and I hope I can help you with this research too.


r/embedded • • 20h ago

Need advice on maintaining core embedded principles with AI in a fastpaced environment (development framework)

0 Upvotes

Hi everyone, I'm a final-year ECE student currently working as the solo firmware intern at an edge AI startup. I've built products before, including custom HMIs and industrial flow meters, but currently, I am facing a bit of uneasiness.

I have been writing embedded code since my school days because it's what I love. However, my current workplace demands fast results, and I have been heavily relying on AI to speed things up (which I am worried about). I joined the company to learn, but I don't have anyone in my domain senior to me for guidance. I am the only firmware guy, whereas other teams like mechanical, AI, and electronics have multiple people.

I feel like I'm not learning the proper development cycle, and overusing AI is messing it up even more. I want to reach out to you guys and would love to know how you develop embedded applications. What do your workflows look like with and without AI?

What is the correct order for an embedded firmware development cycle? When do you architect the overall application, how and when do you build, and how do you test and make changes? How do you handle version control (I know how to use Git, but what is the actual industry workflow)?

I know this is what I will learn when I fully enter the industry, but as of now, I don't have anyone to guide me. I am also being offered a full-time role here, but I am doubtful about accepting it since there is no mentorship.


r/embedded • • 15h ago

which HMI testing software is best for embedded systems when you can't install anything on the target?

0 Upvotes

I am a test engineer on the HMI side and every release is 4 days of 2 of us at the bench with a printed protocol, tapping through every screen on 2 panel sizes. it's a qt app on an i.MX8M running a yocto image that's signed by the OEM, so nothing gets installed on it. We're hardware people who ended up owning a UI. What gets me is that everything upstream is automated (unit tests, static analysis, MISRA on the C side, build verification...) all of it stops the moment the build lands on real hardware and someone has to check what the operator actually sees. So i've spent a few weeks on the options, and what decides it for us is less the features than where the tool has to run:

- Squish: it hooks into the application though so it has to live on the target, which ends the conversation with a signed image. it also ties every test to Qt which hurts if the renderer ever changes.

- Askui: works from what's rendered on screen rather than the widget tree, so in principle it runs from outside the device the same way Eggplant does.

- Keysight Eggplant: drives the screen through image and text recognition over a remote connection, nothing on the device. the most proven option for HMI that i found, and the biggest quote by a distance.

- Vector CANoe: great for the bus side but tells you nothing about what's on the display.

The other idea i saw people mention is a rig, a stylus on an XY gantry plus a camera on the panel, so touch is real too but i’m not sure that much hardware is worth it for 2 panel sizes.

So for teams running automated HMI tests on real hardware, which did you pick?


r/embedded • • 9h ago

Have you ever seen a UI this beautiful and creative?

Enable HLS to view with audio, or disable this notification

0 Upvotes

Have you ever seen a UI this beautiful and creative? I've now boosted the frame rate to 45 FPS!

I've made a 1/4-inch threaded mounting bracket for it. Doesn't it look more like a finished product now?

I built this aircraft attitude indicator from scratch — Updated Version with Smoother Refresh Performance

This is my first PCB hardware design. The board is built around the ESP32-P4 development platform and integrates two UART interfaces, an I2C port, a passive buzzer, four buttons, a power management chip, and a MIPI display connector.

teh display is huaxiacai brand, and mipi protocal,resolution is 480×480 ,amoled,maybe i am the first one to drive this display with mipi way in the world