STM32F103 driving the TCD1304

Thanks to Zied Guermazi for showing me some time ago, that the STM32F103 “blue pill” can drive the TCD1304. Back then, he ported my UART-firmware for the STM32F401 to the STM32F103.

This week, while waiting for my small CNC mill to arrive (still waiting), I’ve been looking at GRBL. It was originally made for arduino, but fortunately there’s a port for the STM32F103. I first thought it was an STM32duino build, but it’s actually made with the standard peripherals library, so I became curious how USB was implemented.

After realizing that STMicro has a USB-library for the STM32F1xx, I quickly fell into the rabbit-hole.

There were two things that didn’t make me jump on Zied’s port back when he made it:

  1. The STM32F103 doesn’t have 32-bit timers, meaning the integration time is quite limited. Even with the slowest MCLK supported by the CCD it’s:
    tint (max) = 2¹⁶ / MCLK = 2¹⁶ / 800 kHz = 82 ms
  2. UART isn’t that convenient without the nucleo-board’s built-in USB->UART connection.

So I dug into the datasheet, reference manual and USB-library for the STM32F103. It took me some time to get USB working, especially how to send more than 64 bytes at a time.

I still haven’t solved the issue of the 32-bit timer. First I thought I could chain TIM3 and TIM1, and use TIM1’s capability for complementary outputs.

Using TIM1 in slave mode means timer’s counter is only increased when TIM3 overflows (that’s the whole point of chaining them together), however that also means the pulse-length is dependent on the period of TIM3. So I’ve put that idea on the shelf.

I left the 32-bit timer configuration intact, so if someone wants to implement the SH- and ICG-pulses manually through TIM1’s update interrupt, they can.

Back to what’s working:

The STM32F103 presents itself as a virtual com port, so the command-line interface, and the python-interface works out of the box. And here’s the first capture using the blue pill:


Yes. It’s a cork-screw:


And here’s the whole setup:


The firmware runs the CCD at 800 kHz, so the timer violation warnings given by the pyCCDGUI shouldn’t be taken to seriously, just remember to keep SH and ICG smaller than 65536. I will probably add a radio-button or something in the pyCCDGUI to choose between the STM32F103 and STM32F40x.

Oh, and for good measure, here’s the pinout :

  • OS – PA1
  • ICG – PA10
  • SH – PB4
  • fM – PA15

Download the firmware over at

I will most likely make a TCD1304-shield for the blue pill with all the credit I’ve saved up over at dirtyPCBs from whenever people order one of my designs. Which side of the blue pill should the CCD be on?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.