[ZeROSEro7] Transparent keyboard

This week, I worked on the USB keyboard, the SPI Slave, the read/write in Flash and casing.

USB Keyboard

The USB keyboard is now fully transparent. All input works and LED about Caps lock and NUM lock are managed according to SET REPORT from the computer as well.

I could add a feature to copy directly important descriptor of the keyboard plugged like PID and VID to be more transparent. It will be done if the time allows it.

SPI Slave

Currently, the most important part is the SPI slave. It’s used on two devices (USB Sniffer and Stealth Drop) to communicate between nRF52 (Master) and STM32 (Slave).

The configuration of the STM32 is as follow:

  • 16bit
  • CPHA = 0, CPOL = 0
  • MSB-first
  • NSS Hardware
  • Motorola mode
  • Slave mode
  • Rx interrupt on

I also add SPI_IRQHandler() in the vector table which called every interrupt.

I receive some data from the nRF52 but I got only the first byte of each tram and the Overrun flag turn on. So I fixed it while using mail box to manage received data.


I tried to read and write in the flash of the STM32F407 (Olimex). It’s not the most important features, but there is more storage in the flash memory than RAM and password will be safe in flash memory if the device is unplugged or the host computer is turned off.

First of all, I added a section in the linker script reserved for password data. I choose a lonely sector to be sure to not conflict with other data. In the software, I got back address from this section.

I can easily read in my section with the right address. Nevertheless, to write inside, I have to unlock the flash access with the right code in the right register. Every first write works well when flash is 0xFF value… But to write again, I have to erase the section before. And I have some trouble with the erase instruction because the STM32 crash… And the device become no bootable at all. I have to reload a program to fix it…


With Vincent, we designed the prototype casing of USB Sniffer and Spy Talk. We worked on Autodesk Fusion 360 software. See results on the following pictures:

Spy Talk

USB Sniffer

Last week

I have to fix the SPI slave and code the USB Sniffer demo software.

[Little Brosers] Indeed, dealing with flash is lightning fast

Hello everyone !


Don’t ask me how, my brain seems to have enough battery life to keep writing posts here.

Let’s get to it, shall we?


First: The flash

Last week I left you with a code very approximative trying to stimulate the flash.

One week later, we fully control it. I just needed more of those sweet full sleeping night (and some ROSE Guru’s advice). After reading even more the datasheet and insulting my computer for no reason, I got it to work as expected. We can now, read/write in a page any amount of data up to a page size (528 bytes). Also, I tested the “super-duper amazing ultra low power mode” of the flash. Just kidding, just note that we are able to put the flash in its deepest power mode and wake it.


Second: We gotta make it fit in 64 ko


Indeed, our NRF52832 can only provide 64 ko of RAM. This few kilobytes are supposed to hold our Merkle tree and the slots. (c.f. older posts if you don’t know what ‘slots’ refers to). And let’s not forget all the crypto code as well as the RAM that BLE needs.


So, with Guillaume, we tried to reduce the size of our structures as much as we could. Choosing space-saving over run-time optimization. For instance, the width of a node’s children can be deduced from its ‘start’ and ‘end’ fields. Same for its depth in the tree. So yes, we reduced the size of our structures by removing as much ‘not so essential” fields as possible (which was previously stored in each node).

Also, we dramatically reduced the size and count of the messages that will be stored in a drop. Being optimistic, I would say that we could fit 1000 messages in a drop. We’ll see. The ideal would be to use a NRF52840 (which has way more RAM), but this SoC was not available to buy when we started the project, and still isn’t, I think.


Third: the diff

Ok, the rest of the week was dedicated to the diff. I you forgot what ‘diff’ means in our super fancy vocabulary, it means “comparing two Merkle trees and determining which messages those trees need to send to each other in order to be identical”.

This has been done in python by Guillaume at the beginning of the project. The thing is, he had not the RAM limitation that I encounter now with the Drop’s CPU. So with Guillaume we worked on translating his diff algorithm to C. I Started by implementing in C the stack he was using in python. Saturday, I spent the day connecting the diff code to the C++ simulation. And dude, that’s so satisfying. I can launch as many drops as I want now and ask them to launch a diff with another one. All of this being done in separated threads. Since I use UDP for emulating BLE communication, we can even launch one drop per terminal. It even should work for computers in the same local network.


Oh yes, and the best part is, I tried to keep the diff hardware independent. Indeed, at first we thought we would have to code a diff in Java for the Android part in addition of the C one. Mostly because of the difference between Drops and Android phones about BLE, events and interrupts. But since we now master the JNI and the Android NDK , my fellow mates only need to provide two C function pointers, one for sending, one for receiving. Those function need to be blocking, and write to/read from a byte array for which I will provide a size, that’s all. There is also a void* in the function signature, if the language which uses the diff needs to pass something to its send/recv functions. (I do for C++ simulation)

And finally, because unitary testing is always around the corner, we started today testing each part of the diff algorithm with Criterion. The diff is not fully functional yet, but it shouldn’t be long.


What’s next…?

Basically everything. I mean, there is only 4 days left. I still need to write code for the merge (not very complicated I think, the diff does all the handwork), the date shift, the flash monitor to know which page of the flash is dead or not and the battery monitor.


That is my program for the following days.


Have fun guys !




[Little Brosers] PCB, Images, hash digests and flash memory

Hello everyone,


This week, and particulary this week-end have been quite intense. Let’s sum it up.

PCB : First hands-on and testing

We received our PCBs this week ! It was awesome to see it, like, for real, not only on my screen. We spent a day testing each component and all went beautifully well. We had a software issue with the external flash’s pins but somme google research solved it. We forgot to configure the pin used for SPI’s CS, which is used for NFC by default. We juste had to declare a preprocessor constant to remove the NFC from this pin.


Some pics :


Banana for scale
























In case you wonder, our drop’s PCB roll very well and resists to battery pole inversion 🙂

Docker images

Finally, after weeks of procrastination about Docker, I finally took the time to make a precisely adapted image for each jobs of our CI. “Took the time” means 1 full night and one full day but at least we now have beautiful lightweight alpine/arch docker images for our jobs. Tests run way faster than before !


Hash digests

So, for the last weeks, I have been in charge of our merkle tree and for simplicity, I never implemented messages hash. I always used the first byte of the message’s payload to run our sub-sorting, first one being timestamp. Also I never took care of computing the nodes’s hash of our merkle tree. This was just not usefull for what I had to do.

However the project is progressing and we came to the point where we needed those hash digests. Thus during friday, I sat at a table with Chris and we reviewed together the hash code for the drop. At the end of the day, we ended up with the exact same code for computing code from simulation or from the drops. We just made sure to redirect the “#include”s to the appropriate header files.

This is going to be merged into master branch pretty soon.


External flash memory

Ok, this time, it’s simple : my whole week-end was dedicated to the external flash memory. Saturday I started from master with what Xavier had already written for it and started to build basic functions like a get_status() function allowing main() to read the status register of the flash and I spent the rest of the day reading the datasheet. Today was all about writing a full Little Brosers message to the flash. Knowing that a flash page is 528 bytes, we decided that our messaged would be 528 bytes long for the maximum length. The external flash memory has 8192 pages.

So to make a quick summuray of what I have learned:

The flash has two SRAM buffer of 528 bytes buffer. They are used to optimize writing and reading operation. In our case it is very usefull.

Indeed, the nrf52 SPI driver only allows SPI transfers up to 255 bytes(i.e. 251 bytes of payload, 4 bytes being used by the flash commandID and page/word address). We won’t be able to fill a full page with only one transfert, even if the flash allows it, the nrf doesn’t. I mean, we could force the sending of more than 255 bytes using nrf52’s SPI driver but it would require a heavy structure using nrf52’s timers and PPIs to make it possible. We don’t have time for such a complex thing. Instead, we chose the following procedure to write a msg in the page i using buffer1:

-> transform the message_t C struct into a byte array of size 528
-> write msg[0] to msg[250] in buffer1[0] for 251 bytes
-> write msg[251] to msg[501] in buffer1[251] for 251 bytes
-> write msg[502] to msg[527] in buffer1[501] for 26 bytes
-> push whole buffer1 to page i


The procedure for reading is quite similar except that we do not use the buffers. Indeed, we use the low power continuous array read on the page i three times (0->250, 251->501, 502->527).


It is 22h36 and for now, it “seems” that writing works fine, not so sure about reading. I’ll stop here for today, we’ll see tomorrow with a full night of recover. I’ll have to show it to my coworkers and see if they have any idea how to debug this part. I have to admit that it is not very easy since we still not fully master the NRF_LOG macro which is supposed to replace the usual printf() of the libc. It very often doesn’t actually print the characters I asked for; skipping some of them if the number of characters is too high. Even if I raise the RTT buffer size.

So for now, flash support is not reliable.


See you


Antony Lopez