Cappaddy: Difference between revisions

From SGMK-SSAM-WIKI
Jump to navigation Jump to search
Line 24: Line 24:
* 16 MB SPI Flash
* 16 MB SPI Flash
* Powered by 2x AAA batteries
* Powered by 2x AAA batteries
* Debug LED


=== Circuit ===
=== Circuit ===

Revision as of 18:12, 24 April 2016

Overview

cappaddy is a portable audio sample player with a capacitive touch controls.

A work-in-progress prototype to try out different things with capacitive touch interfaces. Another project to learn more about ARM dev, STM32's peripherals (SPI, TIMER, DAC, DMA, TSC...) and some nice new parts like SPI flash, a new mono audio amp and a 3.3V voltage regulator/boost-converter, ideal for normal AAA cells.

Hardware (Electronics)

General Notes

Key parts:

Revision 0.03

Features

  • 13 touch channels (15 when UART is not used)
  • Small 8 Ohm Speaker
  • 16 MB SPI Flash
  • Powered by 2x AAA batteries
  • Debug LED

Circuit

BOM

Reference			Value			Digikey			Count	Unit		SUM

cappaddy:U1			STM32F072x8		STM32F072C8T6-ND	1	2.00 EUR	2.00 EUR (estimated)

cappaddy:U2			N25Q128A13ESE40E	557-1562-ND		1	1.56 EUR	1.56 EUR

cappaddy:U3			TPA2006D1		296-20783-1-ND 		1	0.97 EUR	0.97 EUR

cappaddy:U4			AS1337			AS1337A-BTDTCT-ND	1	1.46 EUR	1.46 EUR
								
cappaddy:C13 C14 C17		1u			490-6423-1-ND 		3	0.09 EUR	0.27 EUR
cappaddy:C18			100pf			490-8180-1-ND 		1	0.09 EUR	0.09 EUR
cappaddy:C19			4u7			490-6407-1-ND		1	0.12 EUR	0.12 EUR
							490-12606-1-ND		0	0.13 EUR	0.00 EUR
cappaddy:C3-C6 C15 C16		100n			490-10777-1-ND		6	0.09 EUR	0.54 EUR
cappaddy:C7-C12			1n			490-6349-1-ND		6	0.09 EUR	0.54 EUR
								
cappaddy:R1-R3 R20 R27 R28	10k			CR0402-FX-1002GLFCT-ND 	6	0.09 EUR	0.54 EUR
cappaddy:R4			470R			CR0402-FX-4700GLFCT-ND 	1	0.09 EUR	0.09 EUR
cappaddy:R5-R19			1k			CR0402-FX-1001GLFCT-ND	15	0.08 EUR	1.22 EUR
cappaddy:R21-R23		100R			CR0402-FX-1000GLFCT-ND	3	0.09 EUR	0.27 EUR
cappaddy:R24			560k			1276-4267-1-ND		1	0.09 EUR	0.09 EUR
cappaddy:R25			330k			1276-4244-1-ND		1	0.09 EUR	0.09 EUR
cappaddy:R26			1M			CR0402-FX-1004GLFCT-ND	1	0.09 EUR	0.09 EUR
								
cappaddy:L1			4u7			490-6642-1-ND		1	0.39 EUR	0.39 EUR
								
cappaddy:D1			LED			511-1651-1-ND		1	0.41 EUR	0.41 EUR
cappaddy:battery_case		BC2AAAL-ND		battery_case		1	0.92 EUR	0.92 EUR

							speaker			1	1.50 EUR	1.50 EUR (estimated)

													13.16 EUR

Note: The prices of the microcontroller and the speaker were estimated, those parts were ordered on Aliexpress (Speaker: Asus Padfone 2 A68 replacement).


Digikey BOM (MCU and speaker not included):

1,557-1562-ND,cappaddy:U2
1,296-20783-1-ND ,cappaddy:U3
1,AS1337A-BTDTCT-ND,cappaddy:U4
3,490-6423-1-ND ,cappaddy:C13 C14 C17
1,490-8180-1-ND ,cappaddy:C18
1,490-6407-1-ND,cappaddy:C19
6,490-10777-1-ND,cappaddy:C3-C6 C15 C16
6,490-6349-1-ND,cappaddy:C7-C12
6,CR0402-FX-1002GLFCT-ND ,cappaddy:R1-R3 R20 R27 R28
1,CR0402-FX-4700GLFCT-ND ,cappaddy:R4
15,CR0402-FX-1001GLFCT-ND,cappaddy:R5-R19
3,CR0402-FX-1000GLFCT-ND,cappaddy:R21-R23
1,1276-4267-1-ND,cappaddy:R24
1,1276-4244-1-ND,cappaddy:R25
1,CR0402-FX-1004GLFCT-ND,cappaddy:R26
1,490-6642-1-ND,cappaddy:L1
1,511-1651-1-ND,cappaddy:D1
1,BC2AAAL-ND,cappaddy:battery_case

PCB

Get it at: OSH Park

Pinouts

/ todo

Errata / Known Bugs

  • flash footprint wrong! -> can still be soldered by bending legs. -> or order the right QFN part next time...
  • R23: audio amp ~SD pin: 100R -> 100K
  • audio amp: input caps -> 3.3 nF
  • audio amp: decoupling cap -> 1uF
  • audio amp: input resistor -> 1MOhm (- 100k) -> 200k is not bad!
  • spi / flash: pullup on chip select line and pull down on clock like in datasheet? (100kOhm)
  • uart connector further apart from swd connector
  • uart connector wider: for pin headers, not cables
  • consider pin placement inside case! - where do the physical cables connecto to what? easy assembling!!!

Hardware (Enclosure)

OnShape project

STLs: cappaddy1_case_v4_STL.zip

Software

Currently used/evaluated tools and sources to get the board up and running:

  • Free tools for ARM development (gcc-none-eabi toolchain, OpenOCD)
  • STM32CubeMX and sample code by ST
  • Code::Blocks as an IDE
  • Python with PySerial and matplotlib for scripting
  • SoX

More notes are collected here...

Firmware

In the current test, every touch pad (13 in total) plays a sample stored in SPI flash. Reads it out, writes it to RAM to the one of the two DMA buffers (double buffered), and then the hardware moves the samples (currently 8-bit samples at roughly 22 kHz -> trial and error tuning of TIM6) to the DAC and converts it there to analog voltage.

(The code is a mess and has to be cleaned up. - I somehow like to go back to messy C coding, after spending lots of time with high level object oriented stuff, spending way too much time with plumbing and syntax cosmetics, making sure things are reusable and work everywhere. - Firmware can be messy I guess. Nobody cares when it works on the device. And there's only that specific hardware. So things will behave very deterministically. - However, that attitude will only working when things are tested out. I should be cleaned up, because I'm sure things will be tricky when I come back that project later... - Also, it makes sense to split things into files, use proper formatting, naming etc. Put things into functions... I've already hit the RAM limit of that tiny device by just putting in too many arrays into the spaghetti mess, causing the stack to overflow.. --- SO beware: this is only a proof of concept test, nothing more.

A word on STM docs and tools. Overall this STM32Cube tool is really useful generating the necessary initialization code and drivers (HAL) to work with. On the downside of that, I couldn't find any proper documentation on all the HAL functions, beside the comments in the source files and all the scattered ST example projects. That makes things quite annoying to work with. I actually really prefer to use those HAL functions instead of twiddling bits on all the registers myself. However, without proper documentation things feel more like a puzzle game on a cryptic world without a map. - Once the peripherals are understood and understood well enough, I'm sure I can start to like that ARM world. )

cappaddy_TSC5.zip

Tool: Serial Monitor

While first always using Processing to display serial data, I've discovered a nice python library to draw all kinds of plots and visualize data, called matplotlib. There's a lot to be learned there, but it proved to useful to display very basic serial debug data, like the 13 TSC channel values:

$ plot_serial.py

Tmp script: plot_serial.py


Tool: Flash Downloader

In order to get data (audio samples) into the SPI flash on the board, the microcontroller has to play the middleman between the host PC and the flash. Things would be much easier with a standard SD card, but it was a fun exercise to get this working... The idea was, to make the microcontroller receive the data over UART, and send it down to the flash over SPI.

Again, Python is also a nice helper here to send out the sample data and talk to the hardware, using PySerial.

First, the samples have to be converted to raw 8-bit mono 22'050 Hz using SoX (later 12-bit samples should be used...). Then the Python script takes the raw samples, and transmits the bytes in chunks of a certain size to the microcontroller, that is in flash programming mode. To keep the process error free, a CRC check on the received data and a verification of all written data to the flash is made. - First all that took quite a bit of time, and writing the full 16 MB of flash would have taken hours... But switching to the right flash programming commands (write flash pages (of 256 bytes) instead of single bytes for example), raising the serial baud rate to max 115200 and some other refinements took the programming time of a couple of kilobytes down to a reasonable point of a couple of seconds/minutes. - NOR flash memory has to be erased before it can be written (subsectors of 4K), and it is generally much slower to write to it, than to read from it. Since this has to be done only once to get the samples into the device it isn't really a problem. Reading from the flash afterwards goes surprisingly fast and is easier to do, as I had to find out...

All wav header data is stripped off the files before sending them. But filename (8 characters) and some info on the sample data (sample rate/depth) and most importantly the offset address is written to the first sector of the flash, in order to find the data later to play it back...

(...)

The script can be started in the folder where the raw sample files reside while the board is listening in flash programming mode like that:

$ ./py_serial_send_wav.py -d /dev/ttyUSB0

serial 2 spi flash programmer started...
in< CMD_numbytes_chunk?:256
chunk size set to 256
in< CMD_nextfile?
------------------------------------------------------------
current file (0): cartoon_0101.mp3_8bit_22050Hz_mono.raw
out> OK
in< ok
in< CMD_filename?
out> crtn0101
in< received filename: crtn0101
in< CMD_numbytes_total?
out> 0069C0 
in< number of bytes in file total: 0x0069C0
in< deleting flash subsector at 0x10000
in< flash subsector 1/7 deleted
in< deleting flash subsector at 0x11000
in< flash subsector 2/7 deleted
in< deleting flash subsector at 0x12000
in< flash subsector 3/7 deleted
in< deleting flash subsector at 0x13000
in< flash subsector 4/7 deleted
in< deleting flash subsector at 0x14000
in< flash subsector 5/7 deleted
in< deleting flash subsector at 0x15000
in< flash subsector 6/7 deleted
in< deleting flash subsector at 0x16000
in< flash subsector 7/7 deleted
in< CMD_bytespls?:256
[                                        ]
in< CMD_crc?
out_byte> 0xEC 
in< CRC OK!
in< writing 256 bytes to flash at 0x10000
in< CMD_bytespls?:256
[                                        ]
in< CMD_crc?
out_byte> 0xA8 
in< CRC OK!
in< writing 256 bytes to flash at 0x10100
in< CMD_bytespls?:256
[.                                       ]
(...)
in< CMD_crc?
out_byte> 0x89 
in< CRC OK!
in< writing 64 bytes to flash at 0x65900
in< CMD_complete?
out> OK
in< transfer complete
in< CMD_nextfile?
------------------------------------------------------------
out> NO
in< finish
in< found flash snd entries: 13
in< sound entry: 0
in< ----------------
in< index: 0
in< name: crtn0101
in< byte_count: 0x6a00 (26.5000 KB)
in< start_address: 0x10000
in< sample_rate: 1
in< sample_depth: 0
in< 
in< sound entry: 1
in< ----------------
in< index: 1
in< name: crtn0104
in< byte_count: 0xe380 (56.8750 KB)
in< start_address: 0x17000
in< sample_rate: 1
in< sample_depth: 0
in< 
in< sound entry: 2
in< ----------------
(...)

Tmp script: py_serial_send_wav.py


Tool: Sample Converter

Here a bunch of scripts to convert wav or mp3 files to raw samples (and also header files to paste right into your code):

cappaddy_sample_converter0.zip

It can be used like that. The .raw file is the right one to use with the flash programmer above:

$ ./convert_8bit_22050hz_mono.sh cartoon_1302.mp3 
CONVERT cartoon_1302.mp3 WITH sox:
->  ./conv_cartoon_1302.mp3/cartoon_1302.mp3_8bit_22050Hz_mono.wav
->  ./conv_cartoon_1302.mp3/cartoon_1302.mp3_8bit_22050Hz_mono.raw
CONVERT WITH CUSTOM PROGRAM (hexd):
->  ./conv_cartoon_1302.mp3/cartoon_1302.mp3_8bit_22050Hz_mono.raw.hexd.txt
CONVERT WITH xxd (nicer output):
->  ./conv_cartoon_1302.mp3/cartoon_1302.mp3_8bit_22050Hz_mono.raw.xxd.txt

Notes

Remarks / Conclusions

TODOs

  • a
  • b
  • c

Info

Links

/ todo