Copyleft Hardware
ZeptoBARS: 1986VE91T: What's inside Russian ARM?
As this chip was in ceramic package, no plastic etching was necessary - so all bonding wires are intact. Die size - 6.54x5.9 mm.
Etching metalization, almost there...
Now we've reached polysilicon level:
Die annotation

IO Cells & bonding pads - standard circuits to drive IO pins. Includes ESD protection, can work as in and out pin. There are no transistors below bonding pads - that's because bonding process could damage transistors there.
4x32KiB flash - 4 standard block of flash-memory. Why not 1 larger one? Apparently, foundry had standard 32 KiB modules, and for low-volume product it was cheaper to just use what's available instead of redesigning despite slightly large die area. .
32KiB SRAM - fast SRAM memory, looses it's content without power.
64x32B ROM - boot memory, programmed via poly-silicone "jumpers". It's so called "mask rom".
USB PHY - physical interface for USB IO. It only has transmitter/receiver, all logic is inside "synthesized logic" part of the crystal.
Internal linear regulator (1.8V) - required to lower power consumption, as 1.8V transistors uses much less power compared to 3.3V ones.
Battery domain - powered from external battery. Designed for minimal possible power consumption. Contains real time clock, oscillator for external 32 kHz crystal, and few bytes of memory.
RC Oscillators - internal generators (low speed and high-speed), allows to use microcontroller without crystal.
System/USB PLL - allows to multiply RC/crystal clock to get required frequencies for system and USB controller.
2xDAC - digital->analog converters.
2xADC - analog->digital converters. Apparently empty places were capacitors.
FIFO/Buffers - small blocks of static memory. Most likely these are FIFO buffers for dual CAN controllers and others.
One does not need to design most of the blocks above - it is a common practice to license already designed & tested pieces.
Cell based synthesized logic - automatically synthesized digital circuit from Verilog description. Both microcontroller core and digital part of peripherals are there. Also, instead of drawing transistors directly, synthesis software just places standard cells, and then automatically routes connections between them. Standard cells has the same height, but different width, and implement simple logic functions like AND, OR, trigger, e.t.c
Closer lookBoot ROM
One could extract boot rom content here. In this case it's not really necessary, as it's accessible in debug mode.
SRAM
Cell size 9.14 µm2, matches 180-250nm technology.

Flash
You can see that cell size is much smaller - as it only needs 1 transistor per bit (compared to 6 for SRAM):

Synthesized logic
And here we see columns of standard cells, implementing microcontroller core and peripherals. Of course, now it's impossible to guess function of each cell as all metal interconnect was etched away.

Hopefully that was interesting - follow us on Twitter @Zeptobars or subscribe to our RSS feed - we'll continue opening chips.
Free Electrons: FIQ Handlers in the ARM Linux Kernel
Part of the work on the CFA-10036 and its breakout boards was to write a driver that was using the FIQ mechanism provided by the ARM architecture to bitbang GPIOs on the first GPIO bank of the iMX28 port controller.
AbstractFIQ stands for Fast Interrupt reQuest, and it is basically a higher priority interrupt. This means that it will always have precedence over regular interrupts, but also that regular interrupts won’t mask or interrupt an FIQ, while an FIQ will mask or interrupt any IRQ.
FIQs are usually not used by the Linux Kernel, yet some infrastructure is available to do everything you need to be able to use the FIQs in a driver. And since Linux only cares about the IRQs, it will never mess with the FIQs, allowing to achieve some hard real time constraints, without having to bother about the masked interrupts.
There are two more things to know about the FIQs. First, FIQs are executed in a dedicated execution mode, and this FIQ mode has 7 dedicated registers, from r8 to r14. This allows to have persistent values between each FIQ handler code, and avoids the overhead of pushing and popping in the handler. The second thing to know is that, unlike the regular IRQ handlers, the FIQ handler has to be written using ARM assembly, mostly because the C compiler won’t produce any code that can use only these r8 to r14 registers.
Practical caseIn the CFA-10036 case, we wanted to bitbang a set of GPIOs at a programmable interval with a microsecond accuracy, and from a userspace application. The setup we chose was to make a large memory buffer of instructions available to userspace through mmap, and use a simple consumer/producer setup. An instruction was basically the interval to the next handler firing, which GPIOs values to clear, and which ones to set.
Step 1: Setup a timerOne thing to keep in mind is that basically, we will do many things behind the kernel’s back. So you won’t be able to use the standard kernel framework APIs from the FIQ handler. That means that we won’t be able to use the gpiolib, the regular timer API, etc. So you have to make sure to use either something that is not used at all by the kernel or something the kernel can deal with. The first thing to do then is to register a timer so that we can generate our FIQ on a regular basis. Here, we chose the third iMX28 timer, that is the first timer not used by the kernel. Of course, since it is device dependent and not using the kernel’s API, we had to do the timer initialization by hand in our driver.
We obviously made it generate an interrupt when it expires, and then had to poke into the iMX28 interrupt controller to generate a FIQ from this interrupt. How to achieve this is once again dependent on the hardware, and some architectures provide functions to do so (s3c24xx_set_fiq for Samsung’s Exynos, mxc_set_irq_fiq for Freescale’s IMX, etc.) while some others don’t, like it was the case for iMX28 (which is part of the MXS architecture), so we had to do it by hand once again in our driver.
Once this is done, we now have a timer that generates an FIQ on a regular basis. The second step will obviously be to register our handler for this FIQ.
Step 2: Register our handlerRegistering an FIQ handler is actually quite simple. The first thing to do is actually to call the claim_fiq function, that mostly makes sure no other FIQ handler has already been registered.
The next step is to register your FIQ handler. This is done with the set_fiq_handler function. This function takes a pointer to the handler and the size of the handler code as argument, to basically memcpy your handler directly into the interrupt vector.
Most of the time, we would have something like below in our assembly code, and compute the handler size by the difference between the two labels.
my_handler:
handler code
my_handler_end:
Beware that it can get nasty, especially when you use a numeric constant that will get stored in a literal pool (for example when storing large variables into a register using LDR), if you don’t pay attention, the literal pool will be stored outside of the bounds you asked to copy, resulting in the value you use in the actual FIQ handler being garbage. We can also pre-set some register values that you will find in FIQ mode, typically to pass arguments to your handler, using the set_fiq_regs function.
The last step is obviously to enable the FIQ, using the enable_fiq function.
Once this is done, we have the basic infrastructure to process the data that will come from the shared buffer.
Step 3: Allocate the instruction buffer and share itWe needed a pretty large instruction buffer to share with userspace. We wanted to store about 1 million instructions in the buffer, each instruction taking 12 bytes (3 unsigned long integers), which makes around 12 MiB.
The usual allocation mechanism couldn’t be used, because __get_free_pages can only allocate up to 512 pages. Each page on ARM being of 4 KiB, this function is thus limited to 2 MiB.
So we chose to use CMA (Contiguous Memory Allocator) that was introduced in the 3.4 kernel, and is used precisely to allocate large chunk of contiguous memory. It achieves this by allocating a given size of movable pages at boot time, that will be used by the kernel as long as no one needs them, and will be reclaimed when a driver needs them. CMA is also used directly through the regular DMA API, so we’re in known territory.
The first thing to do to use CMA is to declare the memory region we want to reserve for our device in the device tree (we have been using the “Device tree support for CMA” patchset).
As you may know, the device tree is for hardware description and the CMA shouldn’t be in it at all, since it doesn’t describe the hardware in itself, but how we need to allocate the memory for a given piece of hardware. The chosen node is here exactly for that, since it will hold all the things the system needs, but doesn’t describe hardware. A similar case is the kernel command line. In our case, we add a subnode to chosen, with which amount of memory we should pre-allocate (0xc00000, which is 12 MiB, in our case), at which kernel address (0 in our case, since we basically don’t care about the base address of the buffer, we just want it to be there), and which device should use it.
Then, in our driver, we only need to call dma_alloc_coherent from our driver, and that’s it.
Now, we need to share this memory through mmap. This wouldn’t be a big deal, except for the caches. Indeed, the ARMv5 caches are virtually tagged, resulting in cache coherency problem when using two different virtual addresses pointing to the same physical address, which is exactly the situation we will be in.
We thus need to disable the cache on this particular mapping. This is done through a flag set with the pgprot_noncached function, that sets the page protection flags before calling the remap_pfn_range function in the mmap driver hook.
This should be ok by now, and you should be able to use the data inside the buffer from both sides now.
Step 4: Actual ResultsWe here tried to generate a 50kHz square waveform by bitbanging the GPIOs both using a FIQ and using a regular IRQs, and here is the result (to emulate some load on the system, a dd if=/dev/zero of=/file was run when the captures were taken).
This is using regular IRQs. We can notice several thing wrong about this. The first one is pretty obvious, since we have a lot of jitter. The next one is that even though we requested a interval between each timer firing of 10microseconds, we here see that we are more around 16us, with quite a lot of latency.
Now, here is what we get with an FIQ:
We can see that there’s no longer any jitter, the 50kHz square waveform we requested is almost perfectly output by our FIQ handler. We can notice however that there is still a constant ~1us latency, presumably because we had to reprogram the timer from our handler.
Final WordsWorking on this FIQ thing has been really great, mostly because it involved several things I wasn’t used to, like CMA, or to make sure the kernel could deal with something changing behind its back. For example, we had to change slightly the imx28 gpio driver, because it was keeping an internal cache of the GPIO values it previously set, resulting in a pretty nasty behaviour when changing a GPIO value from the FIQ, and then controlling another one through the regular GPIO interface.
The application for this was to generate waveforms sent to stepper drivers, to control a 3D printer from the CFA-10036. You can watch the end result of all this work on Crystalfontz‘ Youtube channel, and especially on this video:
Finally, we can conclude that the FIQ can be an effective way to achieve near-real-time latencies, on a vanilla kernel without any RT patches.
Of course, you can find the whole code on Crystalfontz Github, most notably the driver, the handler and a small application demo for it.
Altus Metrum: bdale's rocket blog: Removing LiPo Protection Boards
In my post about Batteries and Pyro Circuits, one of my suggestions was to remove the protection circuit board from LiPo cells used with Altus Metrum flight computers. To help out folks who want to do this themselves, I put together and posted a how-to with photos in the Documents section of our web site.
ZeptoBARS: Toshiba TB6560AHQ : weekend die-shot
You can immediately notice dual bond wires for power outputs. Die is attached to 2mm-thick solid copper heat spreader.
I keep thinking that it might have been easier to dissipate heat if only power transistors were not clumped up on the left side (but length/resistance of power traces might be a limiting factor)
Die size if 5338x4828 µm.

Open Hardware Repository: FMC Projects - 26-04-2013: FMC group on LinkedIn
Peter Zotov, whitequark: Let's play with Ruby code
Are you tired of aligning those pesky equality signs by hand? Do you obsess over using (or not using) and, do and then? Do you want to enforce your corporative style guide without fixing all the indentation by hand?
All of the above, and without accidentally breaking code structure and unrelated formatting?
Parser has you covered.
“Parser”? What’s that?Parser is a gem for parsing Ruby code which I wrote. Unlike most other Ruby parsers, it keeps precise location information for all nodes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ gem install parser $ ruby-parse -L -e 'if foo then bar end' (if (send nil :foo) (send nil :bar) nil) if foo then bar end ~~ keyword ~~~ end ~~~~ begin ~~~~~~~~~~~~~~~~~~~ expression (send nil :bar) if foo then bar end ~~~ selector ~~~ expression (send nil :foo) if foo then bar end ~~~ selector ~~~ expressionIt also parses all Ruby code in existence by supporting 1.8, 1.9, 2.0 and upcoming 2.1 syntax, and is written in pure Ruby.
Equality for everyoneParser also supports rewriting: non-intrusively (with regard to formatting) modifying source code by applying deltas based on recorded location information.
Let’s start with an example: aligning equality signs. First, how does the AST look like?
1 2 3 4 5 6 7 8 $ ruby-parse -e $'@definition = defn\nsource = "foo"\nunrelated(:method_call)' (begin (ivasgn :@definition (send nil :defn)) (lvasgn :source (str "foo")) (send nil :unrelated (sym :method_call)))So, we’re looking for several consecutive assignment nodes inside a grouping (begin) node. How do we locate the equality sign?
1 2 3 4 5 6 7 8 9 10 11 $ ruby-parse -L -e $'@definition = defn' (ivasgn :@definition (send nil :defn)) @definition = defn ~~~~~~~~~~~ name ~ operator ~~~~~~~~~~~~~~~~~~ expression (send nil :defn) @definition = defn ~~~~ selector ~~~~ expressionThe sign is located by the operator field of the source map; if node is an AST::Node, then node.src.operator would refer to the Parser::Source::Range for the = sign.
The AST format has a reference, but it’s often faster to just try it out and look at the output of ruby-parse.
Parser also includes a convenient harness, Parser::Rewriter for writing simple rewriters. It allows you to schedule modifications to the source while walking through the AST. Let’s use it!
align_eq.rb 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class AlignEq < Parser::Rewriter def on_begin(node) eq_nodes = [] node.children.each do |child_node| if assignment?(child_node) eq_nodes << child_node elsif eq_nodes.any? align(eq_nodes) eq_nodes = [] end end align(eq_nodes) super end def align(eq_nodes) aligned_column = eq_nodes. map { |node| node.src.operator.column }. max eq_nodes.each do |node| if (column = node.src.operator.column) < aligned_column insert_before node.src.operator, ' ' * (aligned_column - column) end end end endSo… does it work?
1 2 3 4 $ ruby-rewrite --load align_eq -e $'@definition = defn\nsource = "foo"\nunrelated(:method_call)' @definition = defn source = "foo" unrelated(:method_call) Don’t. Just don’tWhat about removing superfluous (or adding missing, depending on your taste) dos and thens?
undo.rb 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Undo < Parser::Rewriter def on_while(node) remove_delimiter(node, 'do') super end def on_until(node) remove_delimiter(node, 'do') super end def on_if(node) remove_delimiter(node, 'then') super end def remove_delimiter(node, delimiter) if node.src.begin && node.src.begin.is?(delimiter) remove node.src.begin end end endDoes it work?
1 2 3 4 5 6 7 8 9 10 11 $ ruby-rewrite --load undo.rb -e $'if foo then\n bar\nend' if foo bar end $ ruby-rewrite --load undo.rb -e $'if foo then\n while bar do\n baz\n end\nend' if foo while bar baz end endBut what if I feed it something insideous? Will it start acting evil and break my code? *maniacal laughter*
1 2 3 4 5 6 7 8 9 10 11 12 13 $ ./bin/ruby-rewrite --load undo.rb -e $'if foo then bar; baz end' ASTs do not match: --- (fragment:0) +++ (fragment:0)|after Undo @@ -1,5 +1,4 @@ (if - (send nil :foo) - (begin - (send nil :bar) - (send nil :baz)) nil) + (send nil :foo + (send nil :bar)) + (send nil :baz) nil)Nope! Feel safe out there, and explore the possibilities: they are endless.
(Oh, and if you’re curious and want to fix the Undo rewriter: here, you’ll need this: bodies.compact.none? { |body| body.src.line == condition.src.line }. I’ll leave it as a homework.)
OggStreamer: #oggstreamer Lasermarkings Designfiles
The Design of the Laser-Markings was done using Inkscape and GIMP – Many thanks to my sister this way, who made the OggStreamer look proper. The font used in all of the Files is called Xolonium which is licensed under GPL special thanks go to Severin Meyer who designed this great font.
You will notice that only FRONT,BACK and TOP are drawn in Inkscape – thats because of the great number of Logos it was easier to draw the BOTTOM directly with GIMP – and we already new at this moment, that the CorelDraw wouldn’t open our SVGs.
here are the PNG
The whole process of Laser Marking was not really easy. One main reason for this was that Inkscape always exports Fonts Anti-Aliased … And opening the SVGs in CorelDraw directly didn’t work either. with Fonts Anti-Aliased exported we produced strange effects on the Laser, which apparently only uses Black and White as information … There was some trickery needed in order to get the Design done proper. We also tweaked the Bitmaps on Pixel-by-Pixel to get good results … So your millage may very if you want to use the PNGs from above.
Because the case was already anodized aluminum – and engraving already bright anodized aluminum results in poor contrasted, we needed to use special Transfer-Tape (CerMark LM6018) and Marking Paste (markSolid 904). The Transfer-Tape was used for the non-dense Designs (FRONT,BACK,TOP) – the Marking Paste was applied with an Airbrush for the denser populated BOTTOM.
the SVGs for FRONT, BACK, TOP can downloaded from the mcad-repository
Richard Hughes, ColorHug: Auto-EDID Profiles Results
First, thanks for everyone that contributed ICC profiles. I’ve received over 800 uploads in a little under 24 hours, so I’m very grateful.
TLDR:
Total profiles scanned: 800 Profiles with invalid or unlikely primaries: 45 EDIDs are valid 94.4% of the timeThis resulted in the following commit to colord:
commit 87be4ed4411ca90b00509a42e64db3aa7d6dba5c Author: Richard Hughes <richard@hughsie.com> Date: Wed Apr 24 21:47:14 2013 +0100 Do not automatically add EDID profiles with warnings to devicesI’ll explain a little about what these numbers and the commit means. The EDID reports three primaries, i.e. what real world XYZ color red, green and blue map to. It also tells us the whitepoint of the display. From basic color science we know that
- If R=G=B, we should be displaying a black/gray/white color without significant amounts of red green and blue showing
- The reported gamut of colors should not be bigger on real hardware than theoretical archive spaces like ProPhotoRGB.
- If R=G=B=100%, then we should have a good approximation of D50 white
- The temperature of the display should not be too cold (>3000K) or too warm (<10000K).
There are actually 11 checks colord now does on RGB profiles, similar to the checks done above. If any of the 11 checks fail, the automatically generated profile is not used. The user can still add it manually if they want and then of course it will be used for the monitor, but we don’t break things by default for 5.6% of users.
If anyone is interested, the results were generated by this program, and the raw results are available here. My personal take-home messages you can take from this file are:
- Sometimes blue and green are the wrong way around (Samsung SyncMaster)
- Vendors need to use something other than random binary data (AU Optronics)
- If you don’t know what a whitepoint is, don’t try and guess (Sharp and Lenovo YT07)
- Projectors generally don’t really know/care what values to use (OPTi PK301 and In Focus Systems)
There’ll be a new colord release with this feature released in the next couple of weeks.
Video Circuits: Signal Culture
http://signalculture.org
http://www.indiegogo.com/projects/signal-culture
Richard Hughes, ColorHug: Auto-EDID ICC Profiles
A favour, my geeky friends:
gnome-settings-daemon and colord-kde create an ICC profile based on the color information found in the EDID blob. Sometimes the EDID data returns junk, and so the profile is also junk. This can do weird things to color managed applications. I’m trying to find a heuristic for when to automatically suppress the profile creation for bad EDIDs, such as the red primary being where blue belongs and that kind of thing. To do this, I need data. If you could run this command, I’d be very grateful.
for f in $HOME/.local/share/icc/edid-* ; do curl -i -F upload=@$f http://www.hughski.com/profile-store.php doneThis uploads the auto-EDID profile to my webserver. There is no way I can trace this data back to any particular user, and no identifiable data is stored in the profile other than the MD5 of the EDID blob. I’ll be sharing the processed data when I’ve got enough uploads. If you think that your EDID profile is wrong then I’d really appreciate you also emailing me with the “Location:” output from CURL, although this is completely optional. Thanks!
Open Hardware Repository: TimEX3 - Our first board designed with KiCad finished and validated
Free Electrons: Sysadmin notes: post-only mailing lists with GNU Mailman
I found several people looking for a way to implement post-only mailing lists with GNU Mailman. However, I couldn’t find solutions that are described in sufficient detail.
In particular, this type of list is useful for notification mailing lists. In Free Electrons’ case, whenever someone pushes commits to our public git trees, a notification e-mail is sent. Sometimes, internal discussions can follow, but we do not wish to make them public. This is why we do not want the list e-mail address to be shown in the messages that are sent. If the list address doesn’t appear in the To, CC or in Reply-To headers, members who are authorized to post messages without moderation won’t post replies to the list by mistake by using the “Reply to all” functionality of their e-mail client.
The problem is that the current version of GNU Mailman doesn’t support this type of list yet, at least with the parameters in the list administration interface. You can turn on the “Full personalization” option, which will send messages to each member individually, so that the list address doesn’t appear in the To header. You can also customize the Reply-To header, to an address that is different from the list address. However, the CC header will still hard-code the list address.
A possibility is to hack the /usr/lib/mailman/Mailman/Handlers/CookHeaders.py file, but this solution would apply to all the lists at once, and the changes you could make may interfere with Mailman updates. A much nice solution is to extend Mailman, to modify its behavior for specific mailing lists.
A working solutionThis solution is based on explanations given on the Mailman wiki, and was implemented on Ubuntu 12.04.
First, create a list-test mailing list. Some of the commands below will assume that you named your new list this way. Now, go to its administration interface and enable “Full Personalization” in “Non-digest” options. In “General options”, in the “Reply-To: header munging” section, specify a reply-to address.
If you send a test message to your new list, you will see that the list address is still in the CC header of the message that you receive.
Now, create a RemoveCC.py file in the Handlers directory (/usr/lib/mailman/Mailman/Handlers/RemoveCC.py on Ubuntu 12.04):
# Your comments here """Remove CC header in post-only mailing lists This is to avoid unmoderated members to reply to messages, making their replies public. Replies should instead go to a private list. """ def process(mlist, msg, msgdata): del msg['Cc']This will be yet another filter the list messages will go through. Now compile this file in the directory where you put it:
pycompile RemoveCC.pyThe next thing to do is to modify the default filter pipeline for your new list. You can do it by creating a /var/lib/mailman/lists/list-test/extend.py file with the below contents:
import copy from Mailman import mm_cfg def extend(mlist): mlist.pipeline = copy.copy(mm_cfg.GLOBAL_PIPELINE) # The next line inserts MyHandler after CookHeaders. mlist.pipeline.insert(mlist.pipeline.index('CookHeaders') + 1, 'RemoveCC')This will add your new filter right after the CookHeaders one. To enable this, you have to run:
/usr/sbin/config_list -i /var/lib/mailman/lists/list-test/extend.py list-testYou can now send a new test message, and you will see that the CC header is now gone.
Notes- Of course, you can reuse the same extend.py file for multiple mailing lists. However, the solution doesn’t work if you don’t put the file inside /var/lib/mailman/lists/list-name (distributions other than Ubuntu 12.04 may have different paths).
- I didn’t manage to undo this change. The Mailman wiki gives a solution based on creating a file containing del mlist.pipeline and running /usr/sbin/config_list -i this-file list-name, but it didn’t work for me. Please post a comment below if you find a way to implement this, and return to “factory” settings.
- Don’t hesitate to share other ways of implementing this kind of functionality!
ZeptoBARS: Ti MAX3232 : weekend die-shot
Die size 3113x1955 µm.

FreakLabs: Ghetto G-Shock Battery Replacement
ZeptoBARS: On Semiconductor MC33152 : weekend die-shot
Note how trace thickness changes near large transistors to match flowing current.
Die size 1765x1470 µm.

PS. We had incorrect photo published for MC34063. Now it's fixed.
Video Circuits: Dazed Digital Article
http://www.dazeddigital.com/blog/article/15979/1/bring-your-own-body











