So, some updates on the project so far. First, I received my nice new solder station. Second, I started porting the code to the BluePill (was previously using Teensy 3.1) in order to be closer to what the final device will be (as I will use same STM32F103C8T6 microcontroller).
A bit of surgeryThe first thing I had to deal with using the BluePill is the wrong resistor on the USB D+ line. The board comes with a wrong resistor value of 10k, which should be actually 1.5k (pulled to 3.3v). Now, replacing a 0603 (I believe) resistor crammed between other resistors requires some work: a perfect opportunity to test the hot air of my station. After a few second under hot air (at around 300C), I managed to remove the resistor easily.
On my finger is the resistor (R10 on the board). Yes, I'm using a french wrench as a ghetto vise. I then later soldered a 0805 resistor of the correct value, which luckily still fitted the original pads.
Now that USB supposedly worked, I tried flashing the USB bootloader (using the ST Link v2 programmer). Obviously this didn't work (the device would not enumerate on Linux when plugged). After several hours of searching and asking around in some forums, complaining that this did not work, I eventually found out the problem was actually a bad soldered USB connector. So, some flux and a pass of the solder and now I was getting some response from the board.
With the bootloader loaded I managed to flash the example blink program from within the Arduino IDE. So the second issue was to do this from platformio. This required fiddling a bit with board definition files since it seems a wrong linker script is chosen (you can see the issue here https://github.com/platformio/platform-ststm32/issues/38).
Also, I had to configure the board as being STM32F103CB (not C8) which allows me to use the whole 128KB of the flash which is present on most of C8 boards. I needed this since I'm already at 112KB on my code.
Fighting with Arduino Code
The final issue I had was with the change of board. I amusingly assumed that since Arduino is mostly standarized nowadays and since I was not using any really advanced or low level stuff the change from Teensy to STM32 should be more or less simple. Wrong.
The main problem is that the STM32 Arduino port is not as complete or carefully organized as Teensy core libraries. For example, by default Wire is actually software I2C and you actually need to use HardWire to use hardware I2C. This in turn implies that STM32 Arduino port includes many I2C libraries simply because they need to change Wire to HWire. Since these libraries are actually a bit old now, luckily I managed to make this change to my copy of a recent version of Adafruit's SSD1306 driver.
Another issue is the lack of printf in Print class, which affects SSD1306 driver. I had to resort to calling sprintf() using a local buffer, which was not that bad but a bit annoying.
In the end I managed to port most of the functionality I had with the exception of RTC. For some reason, when I enable the RTC (using the RTClock library which comes with STM32 Arduino) it hangs. It appears the 32k crystal is not oscilating. I'm not sure if there is (another) hardware issue or there's something missing. This is a bit worrisome since I copied this part of the circuit for my device so I hope it works in my case.
All this testing on the BluePill was actually good since I realized I had some design flaws on the PCB. First, I was not grounding the RTC cristal capacitors (ouch). Also, there are some pins which, when SWD is enabled, cannot be used since they are supposed to be used for JTAG. I was using these pins for reading buttons, so I switching pins. Also, I decided to wring back the user LED and tie it to PC13 to conform the BluePill. I think this will simplify any customization down the line.
A few days ago I ordered some of the difficult SMD components, which should arrive in about a week. In the meantime I will probably go and buy the "easy" components (such as resistors, capacitors, etc). After I get all this I will verify the board design to see if footprints match. If so, I will send it for fabrication. This will probably give me some dead time which I will use to continue working on the code.