pcb - part 1.
I was looking for a project with which I could learn how to make PCBs. My friend wanted a cheap MIDI-to-CV converter so I offered to make him one. It's a simple circuit and probably a good fit for a first PCB. It also fulfills my side-goal of using up all the components I've bought on aliexpress.
The circuit
The circuit is fairly straight-forward: signal goes as MIDI to optocoupler (6N137), then to attiny2313 as UART, then to MCP4921 DAC via SPI. Some additional things I wanted: dip-switch to set MIDI channel, ICSP 6-pin header to program the attiny (+ serial), maybe pin-header with jumpers to set what signal goes where on the TRS 3.5 mm output jack.
(TODO: try to look-up cheapest chinese no-name 8 bit MCU with serial on aliexpress and make something using it)
Problem 0
Even before I started I run into a problem when a simple LED-blinker didn't work properly. This turned out to be because I tried to call linker it without -mmcu=attiny2313
which didn't include correct linker script and caused __ctors_end
section to be linked at address 0 where __vectors
should have been.
This would be excusable if it hadn't happen to me at least twice before.
Problem 1: no SPI
The attiny2313 is the cheapest MCU with UART you can get in shops around here.
I've thought it had SPI controller as well, but it doesn't. Instead it has something called USI (Universal Serial Interface?), which is just a shift register with 4-bit counter. Each clock edge has to be flipped manually, but it's just single-cycle instruction, so you can reach speed up to f_osc/2
, which is actually the same maximum speed you get on atmega with real SPI controller.
Problem 2: not enough space
A program containing just UART initialization and printf("hello world %d\n", 9)
takes about 1570 bytes, which is just too big for an MCU with 2 KB of flash. I need a write a custom printf implementation if I want to see any debugging messages.
(If you wonder about the Hello world format string: printf("hello world\n")
gets optimized to puts("hello world")
and puts
takes much less code than printf proper.)
Problem 3: no float
Conversion from MIDI note to linear frequency with pitch-bend is easy to write in fixed-point arithmetic, but it's even easier to write in floating-point and AVR supports soft-float well.
But the soft-float code just doesn't fit!
- with float: 2042 bytes
- in 16-bit fixed-point arithmetic: 1052 bytes
- plus my own printf: 1396 bytes
Why not Arduino?
I started rolling out my own fixed-point arithmetic and printf even before I knew library functions don't fit. I just thought it would be cooler.
How come I am that dumb?
TODO: how long would it take to to write it on Arduino? Using libraries and Arduino IDE and every shortcut I could find?
Breadboard
Next up: schematic and board design.