Sunday, June 14, 2015

AMS00x BLE Module

I found this little guy while looking for parts on Mouser the other day:
It's a $6.50 certified BLE module from ACKme Networks based on a Broadcom ARM Cortex-M3 SoC! The module breaks out the ADC, USART, SPI, I2C, PWM and GPIOs and ships with a pre-loaded firmware called TruConnect that lets you control the module via the serial port.

They also have a dev board, with switches, buzzer, RGB LED, accelerometer, switching regulator and an FTDI chip great for quick evaluation but It's a bit expensive and there's a jumper on the backside! I had to buy one anyway because the module was not stocked yet, but I'll be getting the modules next time.
ACKme also released an iOS and Android apps for quick testing, the  iOS app has more features, it lets you read the ADC and switches, use the serial interfaces and upgrade the firmware OTA. However, I don't have an iOS device so I just used the Android app to connect to the module and blink the LED:

I made a quick breakout board for future modules, you can order it directly from OSHPark or checkout the repo if you don't need a dev board. Note: This breakout is Not tested!

Read more ...

Saturday, March 14, 2015

THP 2014/2015, OpenMV, Kickstarter and Pi Day!

It's been a while since I last wrote about anything, been very busy with THP, Kickstarter, new projects and day dreaming (more on that later), also I've been documenting OpenMV mostly on

However, today is a very special day, it's Pi Day of course, but it’s not just any Pi Day, today at 9:26:53 will describe Pi up to 10 digits, yay!  Something that happens once in a lifetime, and if that's not enough, today marks exactly 5 years since my very first blog post and it also happens to be my birthday ;D

Not being able to resist this historic day, I had to write something, so here's a long overdue post in which I'll try to document my experience with all this stuff, and share with you some of the lessons I've learned along the way.

THP 2014
Last year I submitted OpenMV for THP, I clearly remember saying to myself "Well, here goes nothing" and then I clicked submit, and bang it went viral! I received lots of comments, feedback, orders, even a few job offers!
Shortly after that, OpenMV became the second most "Skulled", viewed and commented project on (and still is, so far). Even though I did not make it to the finals at the end of it, but overall, I think joining the contest was one of the best things I ever did.

Hint: Just put your project out there, you have nothing to lose, try to document a lot, and if you're lucky, lots of awesome people will give you feedback and support.

Having received lots of request for cameras, with the help of my friend Michael Shimniok we (well, mostly just him :D) went ahead and made a small prototyping run, just to see how things go before doing anything serious:

This was the original OpenMV cam in the photo, we only made about 20 units of these, the biggest issue was Windows support, which had me recently sit down and rewrite the whole debugging interface to use CDC and, sadly, ditch libusb all together (it's a shame because I enjoy coding with libusb) I might document this issue here one day.

Hint: plan and *test* cross-platform support as early as possible, before anything else, if you want that eventually (in my defense I didn't want to support Windows at all when I started)

20 cameras were sold on Tindie, and we had more than 100 backorders, at this point, we decided to move forward and seriously consider mass production (by "mass" I was thinking 500-1000 units)

Making a product is no picnic, everyone knows that, you have to consider many factors when doing more than a few prototypes, from parts sourcing, programming and testing to order fulfillment and support, then there's always some product-specific issues that might catch you off guard, something as simple as focusing the lens!

At this point small costs start to creep in and If you're not careful enough or don't know what you're doing, something is bound to go wrong, and you might end up loosing money instead making profit.

One option is to outsource the whole thing to someone, and that's exactly what we did to minimize risks as much as we could, we've been in contact with MacroFab and decided to go with them, they'll be taking care of everything, I have to say I'm still impressed with the idea of a whole production backend as a service :)

On my end of things, other than working on the software, I went through a few designs trying to find that perfect balance between features, cost and "manufacturbility".

Some of the things that I've encountered may (or may not) surprise you, I found out that a cheaper connector or sensor might end up costing a lot more to assemble and test, so unless you plan on assembling 1000s of something yourself, think very carefully which parts you want to use, and consider the costs of assembling and testing those parts.

I finally settled on the latest hardware seen on the Kickstarter and then designed a small programming/testing jig, which I'll keep working on and improve further, if needed, in the following days.

Hint: think very carefully which parts you want to use, and consider the costs of assembling and testing those parts.

This brings us to funding and the Kickstarter, although we've been planning this for a while but it obviously was not enough, I think we did great and all (900 backers/208% funded) but we could have done much better (with some more planning and time) but that's okay for a start :)

If I learned anything from this KS, is that one should plan on every little detail before starting, this the best advice I can give anyone who wants to do this, plan and then plan some more, this includes reward tiers, stretch goals, content, logos, even updates timing and post-KS sales!

Hint: Be prepared for post-KS sales, have a website up and running, ready to receive back orders as soon as the KS ends (A lesson painfully learned as we still can't accept backorders yet :( )

THP 2015
Moving on to THP 2015, which just launched a few days ago, I've been eager to participate this year too, if for no other reason than the excitement of it :) sadly, I'm not sure I'll have the time this year and so far I don't have any worthy ideas (well maybe I have one or two tucked away ;))

This year's theme is about solving important world problems, some folks like this theme, personally I believe the world is doomed and I can hardly solve my own problems :) but I am still interested, also there's something new this year "The Best Product Prize" a grant of sorts to bring your product to the market, which sounds great.

If you have an idea go ahead and sign up, you do have a chance (not to save the world of course) but you'll get exposure for your project and maybe you'll win some cash too ;)
Read more ...

Wednesday, July 9, 2014

Using the STM32 DCMI with JPEG Sensors

If you've been looking for this, chances are you saw Frank's post on the subject, while it contains very useful information and he mentions reading JPEG, he didn't explain his approach in details, so here's my soultion.

First, let me reiterate the issue with JPEG and the STM32, as you already know JPEG images are compressed, so you don't know the exact image size beforehand, you expect to read it after a complete transfer, however, the STM32 DMA data count register (NDTR) counts down, and therein lies the problem, the counter reaches zero after a complete transfer (or gets reloaded in case of a circular mode) either way, you can't find the transfer size after a DMA transfer is complete.

So here's my solution to this problem, first set the DMA stream to transfer the maximum frame size you expect or the absolute max for a DMA transfer (2^16 bits), afterwards, start the DCMI, it will generate a FRAME_IT when a whole frame has been read (VSYNC is asserted high/low depending on the polarity) however, the DMA will never stop, so at this point you should abort the DMA transfer, this will leave the remainder of the transfer size you requested earlier in the NDTR register (it's guaranteed to be there because the transfer was interrupted) now subtract that from the initial transfer size and you have the frame size.

Here's an example code, which uses the STM32Cube (HAL):

uint32_t addr;
uint16_t length;

addr = (uint32_t) image->pixels;
length = MAX_XFER_SIZE;

/* Start the DCMI */
        DCMI_MODE_SNAPSHOT, addr, length);

/* Wait for frame */
while ((DCMI->CR & DCMI_CR_CAPTURE) != 0) {


/* The frame is finished, but DMA still waiting
   for data because we set max frame size
   so we need to abort the DMA transfer here */

/* Read the number of data items transferred */
image->size = (MAX_XFER_SIZE - DMAHandle.Instance->NDTR)*4;
One issue remains, what if it overflows ? well that would mean you're really cutting it close, but anyway (I haven't tested this) but you should be able read the overflow flag in the DCMI port, or check the JPEG markers.
Read more ...

Tuesday, June 3, 2014

OV9650 Breakout

I made this breakout for the OV9650 a while ago, and I've been waiting to test it before sharing, I finally had the chance to do so, I used an FPGA this time for testing, and here's the result:

The breakout has two SOT23 LDOs for the sensor's core, digital and analog supplies and requires a single external 3.3v supply, note that most sensors have internal regulators for the core supply, so technically you only need one, anyway, those LDOs should be fairly easy to source, their exact voltages depend on the sensor used. The board is compatible with a few other Omnivision sensors, such as the OV9655, OV7660, OV2640 etc... however, make sure it has the same pinout...

Here's the breakout and Eagle library:

Alternatively, you could order the PCB directly from OSHPark:
Read more ...

Saturday, April 26, 2014

Running ZPU Softcore on Lattice ICE40

So I got my hands on a new FPGA development board, a Lattice ICE40HX8K eval kit, this is a really basic low-cost board/breakout with a few LEDS, EEPROM and a dual FTDI2232H UART/FIFO, that you can use for programming the EEPROM/FPGA...What I really love about this board, other than the low cost and many I/Os, is that the second FTDI port is configured as a serial port and connected to the FPGA, so basically you get a free USB<->USART bridge which you can use to talk to the FPGA with the same USB cable used for programming (see Linux notes) that's basically all I need as I'm already familiar with FPGAs...
I wanted to evaluate those FPGAs for a new project I'm working on, which will most likely require a minimal SoC with a wishbone bus... My first thoughts was to use my uMIPS core, but it doesn't support the wishbone bus (I might fix that later) so I decided to give the ZPU core a shot, which was definitely worth the time it took to get it working on the Lattice FPGA.

In an effort to save someone else's time, I created this github repo for the project, it has the sw, hdl, project files and a tested bitmap file, all you need to do is to program the bitmap (or synthesis the project with iCEcube2 if you want), open /dev/ttyUSB1, set it to 8N1, 9600, parity=none and reset the core (you will need and external switch for that, connect it between H16 and GND), it should print out "Hello World!"...

ZPU Core:
The ZPU is small 32-bit stack-based CPU, it comes with a gcc-toolchain, lots of variants and examples... For this project I used the zealot/medium variant which comes with a physical I/O layer (provides a USART, GPIO and a timer) and I'm using a single port RAM, no PLLs (to keep things simple) and all the RAM blocks on the ICE40HX8K (16KBs total) for the program image. There's no wishbone yet, I will work on that next.

Compiling Stuff:
First It's worth mentioning here that I modified the I/O memory map (crt_io.c) since there's only 16KBytes of on-chip ram, I modified it to use bit 15 for the I/O space, the modified crt_io.c is included in the repo and the Makefile will compile and link this modified map for you.

If you want to compile a new program, you'll need to download the ZPU toolchain first and use the Makefile in zpu/sw it will generate a bunch of files, the one we're interested in is hello.bram, this contains the instructions/data used to initialize the embedded RAM, copy the contents of this file and replace the one in bram.vhdl.

Linux notes:
I didn't have much trouble getting the software running on Linux, but one thing you might want to do to make things nicer, is to use this udev rule to unbind ftdio-sio from the first FTDI port when the board is connected, this will allow the programmer to use the first port as JTAG with the second (USART) port bound to ftdi-sio at the same time, so you can use it as to talk to the FPGA after programming:

,ATTR{bInterfaceNumber}=="00",RUN+="/bin/sh -c 'echo `basename %p` >/sys/bus/usb/drivers/ftdi_sio/unbind'"

The following is the iCEcube report for this design:

Total Logic Cells: 3099/7680
Combinational Logic Cells: 2471     out of   7680      32.1745%
Sequential Logic Cells:    628      out of   7680      8.17708%
Logic Tiles:               473      out of   960       49.2708%
Logic Registers:           628      out of   7680      8.17708%
IO Registers:              0        out of   1280      0
Block RAMs:                32       out of   32        100%
Input Pins:                3        out of   206       1.45631%
Output Pins:               9        out of   206       4.36893%
InOut Pins:                0        out of   206       0%
Global Buffers:            6        out of   8         75%
PLLs:                      0        out of   2         0%

Read more ...