The BeagleLogic cape: Assembly and Testing

A day before Christmas, I was greeted by a yellow DHL packet from Hong Kong. The panels had finally arrived after 8 days – I had chosen rush (48hrs turnaround) and express shipping, and it did work out well as I received them before Christmas. The boards turned out to be nice. Not dirty at all and at a price which was reasonable to me.

Assembly

Ready for assembly
Before assembly – the board with applied solder paste and a few parts

I reflowed the board with a hot air gun. Applied solder paste with a toothpick and placed the parts with the naked eye using a pair of good quality tweezers. The passives are all 0603 size (1.5mm x 0.76mm). Since I was yet to receive the batch of BSS138 FETs I ordered, I used a BC847 NPN transistor for the build instead. Reflowing left a couple of solder bridges on the 74LVCH16T245 (now onwards referred to as ‘the 245’) buffer chip (smallest pitched part on board – 0.5mm) which I removed using a solder wick. Then soldered the pin headers manually.

Cleaned up after soldering using nail polish remover. It’s terribly inefficient, and I plan to get a bottle of concentrated isopropyl alcohol (IPA) at some point of time. Here’s the finished result:

“Smoke Test”

A colloquial reference to the first power-on of the assembled circuit. I plugged the cape into the BeagleBone Black and powered on the assembly. The LEDs lit up and the board booted. No smoke or burning smell. Woohoo, test passed, or …

Errata

I then probed the BeagleBone P8 header pins which serve as inputs to BeagleLogic using an LED, and did the same with the input pin headers. The LED were brighter on the inputs to the ‘245 than the P8 pins, which was contrary to expectations. A quick check on the schematics and turns out that I wired the 245 to translate from rail B to rail A while connecting the inputs to rail A and the Bone pins to rail B. Whoops! However I quickly resolved the problem by lifting pads 1 and 24 (DIR1 and DIR2) off the PCB (which was simple as those were on the ends) and soldered a bit of magnet wire through and to one of the pads of C1 going to +3.3V. Neatly done, and a lesson not to design and send off PCBs to a fab while pulling an all-nighter 😛 .

Testing

Once this was done all was back on track and the circuit worked as expected. The cape as designed did not interfere with the boot-up process due to the action of the transistor pull-down that ensured that the buffer did not drive the P8 pins until SYS_RESETn signal was high.

I tested it with SPI signals upto 24 MHz using the BeagleBoard itself and results are good at a 100Msps sample rate. I could also subject the input pins to 5V freely, without fear that I would burn the board. That’s exactly what the cape is meant for, and I’m happy with the results.

I am planning to give away the surplus boards from the first batch so anyone interested in testing it out can get in touch and depending upon where you are, I may be able to send you one of the surplus unpopulated boards (no parts included) which can be assembled yourself (1 IC, 4 passives, 1 transistor and pin headers). The Cape EEPROM section can be left unpopulated without affecting the functionality.

The design files are now available here. I made some changes to the design after fixing the errata, so the cape version is bumped to 1.1 .

Suggestions and feedback on the cape are welcome. The design is Open Hardware, so you have the freedom to use it and improve it as you like. Let me know if there’s anything that could be added in the cape as there is plenty of board real estate.

Introducing: The BeagleLogic Cape

BeagleLogic Cape - 3D Render

After coding up the BeagleLogic project, I thought that it would be great to have an add-on cape for the project that provides buffering and also makes the inputs of the BeagleBone Black tolerant to TTL logic voltage levels (up to 5.5V) allowing BeagleLogic to debug external projects with ease. Hence introducing the BeagleLogic cape, the 3D render of which you can see above. The design is done in KiCad.

The design source and gerbers will be made available on the BeagleLogic GitHub repository after I physically assemble and verify the design.

Design & Layout

The cape design is simple enough to just have a single layer layout, as you can see in the render above the top layer is entirely a ground plane but for a single trace. Since the top isn’t much populated I added useful information on the top silkscreen including indexing the pin headers on the Bone on both sides.

The logic channels are accessed via 2×14 right angled pin headers. The upper row of headers are the actual logic channels while the bottom row is all GND pins. The pin headers are arranged in a MSB-to-LSB fashion. This means that the rightmost pin when viewed from the top is raw bit 0 of the captured logic samples. Note that sigrok will use the names of the actual Bone pins so bit 0 (Channel 1) is to be identified as P8_45, bit 1 (Ch2) is P8_46 and so on. The numbering is a little non-obvious but it’s because that’s the way the pins are arranged on the BeagleBone GPIO header. But don’t worry as the cape lists the pin ID of each logic channel so you don’t have to look it up in the pin diagrams.

One important point here. Only the first 12 channels can be used by default. To use the last two channels, you must disable eMMC first and solder 0R resistors or bridge the two resistors R8 and R9 on the bottom side to enable them. Otherwise the buffer will drive those two pins and you will damage the eMMC of the board and also void the warranty.

Here’s a shot of the schematic (click to enlarge). This is for reference only with respect to the current board and the released schematic may or may not be the same

Cape Schematic

The active buffer is a TI 74LVCH16T245 or equivalent. The buffer is powered from the VDD_3V3B power rail. The OE pin initially pulled is driven using an arrangment of a BSS138 N-MOSFET whose gate is connected to SYS_RESETn of the Bone. This should ensure that the logic input pins, which are also the system boot pins, are not driven by the buffer until the startup has completed.

This version of the design has a 0R resistor through which the VDD_3V3B powers the VDDA side rail of the 16245. If you remove the short and connect it to a 1.8V supply it should become compatible with 1.8V logic levels. I am however thinking of a better solution to the problem and should address this in the next released design.

There’s the officially required cape EEPROM on the bottom side as well, I presume this could be rendered redundant as the community moves towards the Universal Cape concept. But the footprints are there, just in case.

Manufacturing

The first prototype cape has been manufactured by DirtyPCBs.com as a 2-layer Black 10x10cm protopack. It has been shipped as of the time of writing and should reach me next week. I ordered the boards as a Rush order (48h turnaround time) and got it shipped via DHL so that I could have the boards in hand before Christmas rush. I would be using their services further if the boards work out well, looking forward to receive them!

Since I had left space on the panel, and there’s free panelizing so I managed to squeeze some more of my designs into the panel and make the best use of the available real estate. I would write more about those in the coming posts.

So that’s pretty much it. Design suggestions are welcome, and I’ll see if they can be accomodated in the subsequent hardware revisions. Once I test and it all works, the design files will be made available as I have written above.

Re-furnishing

I just refurnished The Embedded Kitchen, both on the outside as well on the inside, or I should say, on the front-end and hosting levels; it is still powered by WordPress. I was contemplating moving the site to static pages using Jekyll or Nikola, but WordPress (with Jetpack) now also supports Markdown-based content authoring so the biggest reason for migration to a static system is no longer there so this decision may be deferred indefinitely.

The site is now powered by OpenShift by RedHat PaaS (hover over the word for the definition).

Phase 1 – I just want a Sandbox

I had come across OpenShift some time before and (almost immediately) signed up for the free tier of the service – which gives me 3 “gears” to experiment with whatever I like – PHP, Node.JS, MySQL, MongoDB … . Since I had been contemplating installing a new theme on the website and didn’t want to fiddle with the old site too much so I exported all my data in the WordPress XML format, and created a test site on OpenShift and used it as a sandbox to try out various themes. I settled on Nirvana first (too many choices, I was overwhelmed) and then stumbled across the Freelancer child theme based on the GeneratePress theme framework and liked it more. So that’s the current theme on the website.

After checking my site with PingDom I thought it might be a good idea to migrate the site to OpenShift.

And so wp-embeddedkitchen.rhcloud.com was born.

Phase 2 – blog.theembdeddedkitchen.net

I decided to give the OpenShift version of my blog a proper subdomain blog.theembdeddedkitchen.net (does not exist as of now). This was simple, just one CNAME record to add to my DNS Zone settings, and tell OpenShift and WordPress (admin panel) about it, and boom. Checkpoint 2 crossed.

Now the acid test – getting theeembeddedkitchen.net to point to my blog. I had read enough about CNAME at the root DNS level (since the IP address of RedHat’s service could change without notice, so I cannot just use an A record of the current IP) to be wary of this.

In my excitement, I updated my new blog address in the WordPress admin panel from blog.theembeddedkitchen.net to theembeddedkitchen.net at the point where the DNS hadn’t moved. Yikes! The transition is going to happen faster than it should have.

I added a “Moving” sticky post to the old blog just in case someone might view the site in the transition phase.

Phase 3 – Enter CloudFlare

Of all the alternatives out there, CloudFlare (at least) looked to me the safest. As a side effect, its CDN infrastructure should accelerate my website and help Akismet further in deterring spammers (In over 7 months I guess I had tens and thousands of spam comments)

Configuring CloudFlare was as easy as advertised, just a quick DNS Server change and I was on board CloudFlare. I then added CNAME records and configured OpenShift to catch theembeddedkitchen.net and www.theembeddedkitchen.net for my application. I waited for the DNS changes to take effect and opened theembeddedkitchen.net . All looks well, I think I could call it a day now.

But when I opened www.theembeddedkitchen.net , the site just hung up and I get – “too many redirects”. Wait. A redirect loop! Ok, no problem – I changed my blog URL in WordPress to www.theembeddedkitchen.net and it seems that the problem is fixed. Then I open http://theembeddedkitchen.net and get the same redirect loop. It seemed like a cat-and-mouse game.

However on more digging I figured out that the missing piece of the Jigsaw puzzle to set up a redirect rule on CloudFlare to give a HTTP 301 redirect from http://www.theembeddedkitchen.net/* to http://theembeddedkitchen.net/$1. So if you are stuck in a redirect loop and using both OpenShift and CloudFlare, here’s what you have to do (assuming your-domain.com):

  • In the DNS Control panel in CloudFlare settings, add a CNAME for your-domain.com to your destination (theembeddedkitchen.net => wp-embeddedkitchen.rhcloud.com).
    If you do this correctly, CloudFlare will tell you that “CNAME Flattening will be applied to this record”.
  • Add CNAME www and point it to your-domain.com (theembeddedkitchen.net)
  • Goto the Rules section and set up a redirect rule [HTTP 301] from http://www.your-domain.com/* to http://your-domain.com/$1). This is important to curtail that nasty redirect loop, so that the WordPress installation gets requests only for the non-www domain [Needless to say, the blog address in WordPress should be http://your-domain.com] and CloudFlare takes care of that even before OpenShift kicks in.

All this done the site was back online to its full glory. Now just a few finishing touches…

Phase 4 – Plugins

I installed the Jetpack plugin first so that I could get all the goodies and a site check every 24 hours which ensures that the site never “idles” (apps in the free tier are put into standby if it doesn’t receive an HTTP request in 24 hours).

Also I decided to put a Disqus comment system in place of the old comment form. This was as simple as setting up my Disqus account and installing the Disqus comments plugin.

There’s also WP Super cache that makes this (almost) a static site. Not sure if N levels of caching are going to help anyway but I think it might speed up things a bit.

I am thankful to the shared PHP hosting service provided by edaboard.com to its members which powered my website so far. The old content would still be there, albeit not really accessible for the time being.

And yes, I write this I am finalizing a panel to be sent to the board house. What the circuits are about, is in the next post.
EDIT: Panels are already sent to the board house and I’m waiting for them to arrive. Yay!

BeagleLogic: 14 weeks and counting; The journey so far

BeagleLogic was born out of a project idea using the BeagleBone Black, and I am thankful to Jason Kridner and the BeagleBoard.org community for accepting it as a mentored project under the Google Summer of Code 2014. As the GSoC program officially ended last week, here is a video report highlighting what’s been accomplished so far, over a period of 3 months from 19th May to 18th August.

It was an awesome experience this summer, interacting with the community and developing the codebase for a project that showcases the capability of the two little yet powerful integrated Programmable Real-Time Units (PRUs) on the AM335x SoC that powers the BeagleBone Black to realize a 14-channel, 100Msps, 360 MB buffer Logic Analyzer which by far, offers the best value for a 55$ board which you can use not only to develop your embedded projects but also to debug them on-site without any extra hardware requirement. All the magic happens inside the firmware loaded into the PRUs and the kernel driver which manages sharing the system memory with them.

This project also saw me doing many things for the first time. It was the first time I compiled a Linux kernel and wrote myself a kernel module that is now a part of the BeagleBone community kernel, and I look forward to getting it merged upstream. The Web Client for BeagleLogic (link) is my first web application using HTML5 and Bootstrap for a lightweight web client for BeagleLogic. The backend I’ve written for the web client is my first Node.JS based application. I found these frameworks quite interesting and hope to work on projects in these areas in the future.

Google Summer of Code has been the best thing to happen to me so far, and I’ll be looking forward to it in the years to come.

Have fun with BeagleLogic. Also, do write back to me with how BeagleLogic helped you debug helped you debug your circuit and learn more about logic protocols!

BeagleLogic and sigrok: The beginning

This week I spent some time familiarizing myself with the libsigrok components, and developed bindings for BeagleLogic into libsigrok. The development work walked me through non-blocking I/O, which I implemented into the BeagleLogic kernel module only to realize that it had a major bug that causes the client to sleep uninterrupted and froze my BeagleBone Black everytime. The bug got identified and fixed and after that non-blocking I/O worked as expected.

Memory Mapped Kernel Buffers
This was another optimization I made use of in the sigrok bindings. The sigrok library internally keeps logic data in packets and it is exchanged with the host application via pointers. I exploited this good opportunity to use the mmap() functionality I designed into the kernel driver, so the sigrok implmentation just passes a mmap()’ed pointer to the host application instead of read()-ing the data.

However the currently being read buffer still needs to be updated for poll() to work properly. For this reason I implemented dummy reads. When a NULL pointer is passed as the buffer to read(), it does not read any data from the buffer, and just updates the read state within the drivers so that poll() works fine.

The flow of data is like this:

  • libsigrok bindings signal the BeagleLogic module to start the sampling operation, and starts polling on the /dev/beaglelogic node using a GPollFD
  • Once the PRU fills up a data buffer, it sends an IRQ that wakes up the the polling thread and the beaglelogic_receive_data() callback in protocol.c executes
  • The callback sends a packet with the pointer to that segment of data required, and adjusts the internal offsets for the next callback

The process goes on till the sample limit has been reached. BeagleLogic also supports streaming but…

sigrok-cli on the BeagleBone Black
To test the results of the bindings, I ran a sample operation on BeagleLogic using the sigrok bindings and it worked fine. I was able to decode a wave file from my trusty audio player hardware 🙂 to wav right there on the BeagleBone Black using the article on the sigrok blog as a reference. I got 6 seconds of a wave file directly from the dump. This took ~750 seconds to process from RAM on the BeagleBone Black.

I also tested sampling into a 256 MB buffer in the RAM

BeagleLogic goes kernel-mode with PRU remoteproc[Week 2-3]

The first week was spent well in prototyping the PRU firmware. Problems with the memory management [Maximum of 8 MB of memory] and dismal memory copy speeds [10-20 MB/s] with UIO and libprussdrv prompted me to escalate the back-end to the remoteproc kernel driver. It took me a while before I started off based on the WS28xx lighting firmware example to build up the necessary kernel driver infrastructure for BeagleLogic, and it’s now close to the first set of stress tests and actual data capture for the PRU.

Going into the kernel driver, here is a summary of what’s coming up in the next update [the experiment is with dummy data, the PRU’s aren’t engaged] :

Screenshot from 2014-06-11 23:01:19

BeagleLogic Week 1: Building the PRU Firmware

The first week of the Summer of code began with the build of the core PRU firmware for data capture. I coded up firmware for both the Programmable Real-Time units operating in tandem to sample the pins and transfer it to the DDR memory directly. The code can be viewed at these links:
PRU0 assembly code
PRU1 assembly code

It makes good use of the XIN/XOUT broadside interface available for inter-PRU communication allowing movement a chunk of sampled data from PRU1 to PRU0 [currently 8 registers = 16 samples = 32 bytes] in one clock cycle. PRU0 then writes the data into the DDR memory in bursts of 32 bytes. Inter-PRU signalling is achieved through interrupts.

For buffer overflow/underflow detection, there is a global byte counter running in PRU0, which is moved alongwith the logic data “for free” via XOUT. PRU0 compares the received value of the counter with the value received from the previous interrupt, and if they differ by more than 32, then there has been an overflow. Also, when the ARM core is signalled for data, an interrupt counter is incremented. The counter is compared to its previous value, and the delta here again enables us to determine if an underflow has occurred.

This approach works fine for one-shot sampling, and I have been able to achieve all the way up to 4 MSamples of 12 pins running at 100 MHz [40ms], although the limitation on the maximum sample rate is likely to be the hardware of the BeagleBone Black in this case, remember there’s a 47pF capacitive load on the HDMI shared pins, and it is yet to be tested with actual hardware.

Currently there’s only 8 MB of memory shared with the PRU for storing samples, there’s an issue with the UIO kernel driver that prevents reserving more memory. The UIO driver will not be fixed, rather the issue will be addressed in the remoteproc interface of the PRU with the kernel. Until then, there is a workaround by adding mem=448m to the boot command line in uEnv.txt, to reserve the upper 64 MB of the memory for the PRU.

Reducing the sample rate is just inserting more NOPs into the sample loop to adjust the cycles. However, availability of more room between two sampling instructions turn out to be potential cycles for performing RLE (which will be implemented very soon), which seems achievable at 50 MHz.

Overwriting previous chunks of data works fine as well, stress tested upto overwrite 500x. See here for an example run.

The amount of samples collected is still limited by only the amount of memory available. The PRUs are quite fast and capable of sample rates like 100 MHz. The only bottleneck is to hold the data and process it before it runs out, and this is the target for the coming week.

The current test code will be adapted to the sigrok bindings once it is in good shape. The current stable code is available at the repo here, and the latest development is in the “prutest” branch here

Next update due on June 4th.

BeagleLogic Update 0 – 18th May 2014

The introduction video to BeagleLogic is now released! Check it out here:

The slides are available here.

This week I spent time understanding the remoteproc implementation and UIO implementations of the kernel drivers of the PRU in the kernel source tree.

One of the important decisions this week was the confirmation of UIO implementation for the PRU drivers. Although a remoteproc implementation is a better approach, the initial implementation of the core would be in UIO, and as the remoteproc infrastructure improves, BeagleLogic will eventually migrate. Since this would be a core change, it would have minimal impact on the functionality.

All set for May 19th when the coding period commences.

Next update coming up on 21st May.

BeagleLogic Update -1 : 7th May 2014

It’s been almost a week since I began work on BeagleLogic after my finals, and with another 12 days remaining for the Community Bonding period, here’s an update on the things accomplished so far (mostly administrative):

  • We now have beaglelogic.net currently as a mirror to this blog. In due course of time, the project will migrate to its own GitHub pages and website.
  • The GitHub repository for BeagleLogic has been created. This will carry the front-end HTML files mostly, with the actual libraries including sigrok, sigrokdecode and our BeagleLogic Server as submodules to it.
  • Set up a build environment for cross-compilation with the required libs and package config files copied in from the BeagleBone Black Debian System Image (23rd April beta release). Successfully built libsigrok, libsigrokdecode and sigrok-cli and executed on the BeagleBone Black and it decodes a bundled sample DS1307 I2C dump as shown below:
    sigrok-cli SSH BeagleBone Black
    SSH from the BeagleBone Black: Screenshot showing sigrok-cli successfully decoding a dump of DS1307
  • Create the presentation for my project as required by BeagleBoard.org. The draft slides can be viewed here, I will be recording, uploading and posting the video soon, and also updating it at the eLinux wiki page.

The cross compilation, though accomplished, has a few rough edges as I had to edit the pkg-config descriptors for each dependency library for a non-standard prefix. I now use PKG_CONFIG_SYSROOT_DIR and compile with a standard ‘/usr’ prefix with untouched pkgconfig files from the BeagleBone Black, but it seems that a few modifications are needed in the build script to build smoothly. Once this is accomplished, I would be publishing complete build instructions and a cross-compilation script to build sigrok from source for the BeagleBone or BeagleBone Black running Debian Wheezy.

There will be the next update on 14th May 2014, which would be Update 0, after which Update 1 will happen on 21st once coding begins on May 19th.

Stay connected for the latest updates on BeagleLogic.

Google Summer of Code 2014 with BeagleBoard.org

I’m delighted to announce that my proposal with BeagleBoard.org has been accepted for the Google Summer of Code 2014. Here is a link to the announcement on the official BeagleBoard.org page.

[A brief introduction to Google Summer of Code [GSoC]: it’s an initiative by Google to encourage student participation in Open Source projects. Through this program, students work on projects and proposals under participating organizations for a period of 3 months, and Google pays a handsome stipend. The students are paired with experienced mentors from the organization who assist them and guide them during the period]

For the next 3 months, I will be working on building BeagleLogic, a software that will be leveraging the power of the Programmable Real-Time Unit [PRU] available on the BeagleBone Black (and the original BeagleBone) to convert it into a Logic Analyser that can help people understand and visualise the digital signals they are dealing with.

Matt Ranostay and Hunyue Yau from BeagleBoard.org will be my mentors for the project.

I will be working closely with the sigrok project, which is an open source signal analysis software, and which would act as the back-end of the project. It supports a large family of digital multimeters, oscilloscopes, logic analyzers, and also includes scriptable protocol decoding support. One of the first tasks in this project is to integrate support for the on-chip PRU under libsigrok, the skeleton driver has already been created in my fork of the library.

I’m looking forward to a great summer 🙂 and I would like to thank BeagleBoard.org community for their acceptance. I would also like to thank Google for the wonderful opportunity you provide to us students to connect with the Open Source Community through your Summer of Code program, and seek to gain experience that will help me in the future.

Future updates will be posted on this blog, or will be shared on a separate blog, if necessary.

For reference, and as a guideline for future GSoC applicants, I attach a copy of the proposal I submitted. The format of the proposal varies from organization to organization; yet the proposal would give a clear idea of the groundwork that is done in general before a proposal is submitted. The proposal has been subject to several revisions after feedback from the BeagleBoard.org community.