Home‎ > ‎

Sergey's Blog

Building ZX Spectrum Clone - Harlequin - Part 2

posted Mar 2, 2016, 9:26 AM by Sergey Kiselev   [ updated Mar 3, 2016, 11:40 AM ]

Read part 1 here

Board Bring-Up

Yesterday evening I received the missing IC socket, soldered it to the board, plugged that 74HC245 IC, connected the keyboard, and quickly moved to test the board. For testing purposes I used this Diag ROM. During the initial power on no magic smoke escaped, and it all looked pretty good. My oscilloscope was showing the right CPU clock frequency, it appeared that CPU is fetching the instructions, and it was some kind of signal on the video output. So I decided to connect the board to the TV... Well, the board appeared to be dead: I didn't get any picture, and it didn't generate any sounds either. It turned to be a few simple mistakes - I plugged it into an Audio input instead of the Composite, and I forgot to install jumpers one connecting the speaker, another one connecting A14/PGM signal to the EPROM :-). That was soon corrected, and I proceeded with the testing.

Upper RAM Issue

This time Diag ROM started properly, and I've got the picture on the TV, and some beeps sounded through the speaker. While performing the upper RAM test Diag ROM reported errors at address $FFDC, I repeated the test, this time the error was elsewhere but still within the last 256 bytes of memory space (addresses $FFxx). I tried swapping out and replacing the SRAM chip, which didn't help. So I am still puzzled, perhaps there is something wrong with the address decode / chip select logic?! (I have to go back and check the schematic) Any ideas?
Update: I have tested my board using System Test ROM and ZX Spectrum Diagnostics and these programs found no problems with upper RAM whatsoever... So it must be a bug in the Diag ROM.

Defective Video Input?

Other than the issue above it appeared that the Diag ROM was working OK, except that the picture on the TV was black and white.

I worried that I've done something wrong with setting up the board to work in NTSC mode. I checked the signals on the relevant pins on AD724JR video encoder, and they all looked good. I hooked up my oscilloscope, and it showed perfect (as far as I can tell) composite color signal. I checked the video timing - it looked OK too. After several minutes of confusion, searching the Internets, etc., I've decided to try another video input on the TV. It worked just fine this time:

ZX Spectrum ROM

I did a few more tests and finally I replaced the Diag ROM with the ZX Spectrum ROM. It booted up happily. And I even ran a small BASIC program (oh boy, now I need to recall how to program this thing):



To be continued...

Building ZX Spectrum Clone - Harlequin - Part 1

posted Feb 29, 2016, 5:16 PM by Sergey Kiselev   [ updated Mar 2, 2016, 11:42 AM ]

ZX Spectrum was a very popular (well, at least in Great Britain and Spain) home computer released in 1982 by Sinclair Research Ltd. And while towards the end of 1980's its popularity declined in the West (due to availability of better computers), various ZX Spectrum clones became immensely popular in Soviet Union. They were manufactured by quite a few factories, as well as built by hobbyists. Several of my friends had one of these ZX Spectrum clones back then, and I was thinking about building my own (and even started to collect components for it). But somehow that didn't work out, and soon enough I've got an IBM PC/XT compatible, which shortly was upgraded to an AT-386 machine. As you might know I designed and built quite a few computers already, but every now and then I have a thought of building one of these 8-bit home computers from 80's (be that ZX Spectrum or MSX). Now might be the right time to build the ZX Specturm...

Design and PCB

There is one particular roadblock to building ZX Spectrum compatible computer: It uses a proprietary chip, so called "ULA" (basically a programmable logic). To get around, ZX Spectrum clones normally implement ULA functionality using regular logic ICs, but none of them are 100% compatible with the original. Several years ago Chris Smith reverse engineered the ULA, implemented a ZX Spectrum clone (Harlequin), and wrote a book about it. And several other folks designed the board (in Spanish, use Google Translate) based on this work. I came across a fellow selling Harlequin PCBs on eBay for a reasonable price of $23 a piece, and bought one.
The PCB is a very good quality, with what appears to be ENIG
 finish. It is also the latest Rev G. of the Harlequin. So I hope it will work nicely without mods.... Actually I do plan to modify the video output circuitry to have S-Video output using this mod. It also quite possible that my flat screen TVs only support NTSC format, so I might do some other modifications as well. Thankfully it seems that this revision of the board has some jumpers to enable NTSC support. We'll see how it works...

Bill of Materials

It took me several hours to build the BOM based on the schematic and the PCB layout. So here is the link to the project BOM on Mouser for your enjoyment.

Case

What could be better than a 3D printer? Well, it turns out - a free 3D printer. Last week I've got access to several pretty nice Type A Machines Series 1 Pro 3D printers at TechShop San Francisco and took advantage of them by printing this ZX Spectrum case I found on the Thingiverse. After 10 or so hours of printing I had the case ready:


Now, it looks like the case is modeled very closely to the original injection molded ZX Spectrum case, and it is not quite optimized for 3D printers. To print it successfully I had to trim the standoffs on the top part, to reduce the amount of support material, and to make sure that the part lays flat on the 3D printer bed. If modifying the case model, I'd also reduce the wall thickness to 2-3 mm or so... Also it appears that mounting holes in the PCB do not quite align with the holes and standoffs in the printed case. It is not a huge problem. I'll enlarge the holes with a file.

Keyboard

I considered several possibilities for obtaining a keyboard:
  1. Making an adapter for PS/2 keyboard (rejected, because it would be too bulky, and not quite original look and feel)
  2. Making a complete keyboard using good mechanical switches (expensive, but I might come back to this later)
  3. Buying a ZX Spectrum replacement keyboard. I ended up getting this keyboard. While it is not very cheap, it is still cheaper than the previous option. And while it looks like a membrane keyboard, it is not. It uses tactile switches, and it actually feels pretty good. 

Putting it all together

It took me quite some time  to solder all the components to the PCB (yeah, that's a lot of components). As usual I started with soldering SMD parts - the AD724JR, the LM2596, and the inductor. Next I soldered all the low profile components (resistors, diodes, quartz crystals). Next - ceramic capacitors, IC sockets, electrolytic capacitors, and connectors. The speaker was soldered the last, after I cleaned the flux with isopropyl alcohol (it is probably not a good idea to get the speaker wet... who knows). Unfortunately I ran out 20-pin sockets (reordered, should get any time now), so that is the only component missing for my build. I decided not to install diode bridge at the power input, and soldered two pieces of wire instead. Modern power bricks are regulated switching mode power supplies anyway, and they provide DC output.


Here is how the board and the keyboard look in the case (note that mounting holes are not quite aligned, and one 74HC245 IC is missing...):

To be continued... Read part 2 here

Intel Edison and Open Music Labs' Audio Codec Shield

posted Aug 31, 2015, 6:29 PM by Sergey Kiselev   [ updated Aug 31, 2015, 6:36 PM ]

Recently I found this Audio Codec Shield made by Open Music Labs. Surprisingly the pinout of this shield, and I2S signals particularly, match the pinout of the Intel Edison Arduino breakout board.

And so it is not difficult to make this shield work with Intel Edison. For the simple audio playback it is needed to setup pin multiplexing on the Arduino breakout board, so that I2S and I2C signals are routed to the Arduino headers, and then to configure the codec, in the way similar to what I've described in my previous post.

Hardware Setup

I'd recommend configuring Arduino breakout board pins voltage to 3.3V by setting jumper J9 to position 2-3. Once it is configured, plug the Audio Codec Shield into the Arduino breakout board.

Pin Multiplexing Setup

Use the following code to setup the I2S and I2C signals on Arduino breakout board headers. You might want to create a script with this code, and make it run on the boot.

# Export GPIOs that control I2S signals

echo 263 > /sys/class/gpio/export
echo 240 > /sys/class/gpio/export
echo 262 > /sys/class/gpio/export
echo 241 > /sys/class/gpio/export
echo 242 > /sys/class/gpio/export
echo 243 > /sys/class/gpio/export
echo 258 > /sys/class/gpio/export
echo 259 > /sys/class/gpio/export
echo 260 > /sys/class/gpio/export
echo 261 > /sys/class/gpio/export
echo 226 > /sys/class/gpio/export
echo 227 > /sys/class/gpio/export
echo 228 > /sys/class/gpio/export
echo 229 > /sys/class/gpio/export

# Export GPIOs that control I2C signals

echo 28 > /sys/class/gpio/export
echo 27 > /sys/class/gpio/export
echo 204 > /sys/class/gpio/export
echo 205 > /sys/class/gpio/export
echo 236 > /sys/class/gpio/export
echo 237 > /sys/class/gpio/export
echo 14 > /sys/class/gpio/export
echo 165 > /sys/class/gpio/export
echo 212 > /sys/class/gpio/export
echo 213 > /sys/class/gpio/export

# Export TRI_STATE_ALL control GPIO

echo 214 > /sys/class/gpio/export

# Disable all pins (enable TRI_STATE_ALL)
echo low > /sys/class/gpio/gpio214/direction

# Configure I2S signals on Arudino pins 10-13

# Pin 10 
# set to GPIO (not PWM)
echo high > /sys/class/gpio/gpio263/direction
# I2S (map to GP41)
echo low > /sys/class/gpio/gpio240/direction
# output
echo high > /sys/class/gpio/gpio258/direction
# disable pull up
echo in > /sys/class/gpio/gpio226/direction

# Pin 11
# set to GPIO (not PWM)
echo high > /sys/class/gpio/gpio262/direction
# I2S (map to GP43)
echo low > /sys/class/gpio/gpio241/direction
# output
echo high > /sys/class/gpio/gpio259/direction
# disable pull up
echo in > /sys/class/gpio/gpio227/direction

# Pin 12
# I2S (map to GP42)
echo low > /sys/class/gpio/gpio242/direction
# input
echo low > /sys/class/gpio/gpio260/direction
# disable pull up
echo in > /sys/class/gpio/gpio228/direction

# Pin 13
# I2S (map to GP40)
echo low > /sys/class/gpio/gpio243/direction
# output
echo high > /sys/class/gpio/gpio261/direction
# disable pull up
echo in > /sys/class/gpio/gpio229/direction

# Configure I2C signals on Arduino pins A4 and A5

# Pin A4
# set to GPIO (not analog in)
echo low > /sys/class/gpio/gpio204/direction
# configure gpio14 as input (tri-state it)
echo in > /sys/class/gpio/gpio14/direction
# output
echo low > /sys/class/gpio/gpio236/direction
# disable pull up
echo in > /sys/class/gpio/gpio212/direction
# set to mode1 (I2C)
echo mode1 > /sys/kernel/debug/gpio_debug/gpio28/current_pinmux

# Pin A5
# set to GPIO (not analog in)
echo low > /sys/class/gpio/gpio205/direction
# configure gpio165 as input (tri-state it)
echo in > /sys/class/gpio/gpio165/direction
# output
echo low > /sys/class/gpio/gpio237/direction
# disable pull up
echo in > /sys/class/gpio/gpio213/direction
# set to mode1 (I2C)
echo mode1 > /sys/kernel/debug/gpio_debug/gpio27/current_pinmux

# Enable all pins (disable TRI_STATE_ALL)
echo high > /sys/class/gpio/gpio214/direction

Codec Configuration

Use the following commands to configure the codec:
# reset codec
i2cset -y 6 0x1a 0x1e 0x00

# disable DAC and output powerdown
i2cset -y 6 0x1a 0x0c 0x07

# set volume for headphone output (both channels)
i2cset -y 6 0x1a 0x05 0x50

# analog audio path control (DAC enabled)
i2cset -y 6 0x1a 0x08 0x12

# digital audio path control
i2cset -y 6 0x1a 0x0a 0x00

# set sample rate (48000Hz, assuming 12.288MHz codec clock)
#i2cset -y 6 0x1a 0x10 0x00

# set sample rate (44100Hz, assuming 11.2896MHz codec clock)
i2cset -y 6 0x1a 0x10 0x20


# digital audio interface format set (DSP mode, 24 bit)
i2cset -y 6 0x1a 0x0e 0x8b

# activate interface
i2cset -y 6 0x1a 0x12 0x01

Using the Audio Device

The codec is connected to ALSA device hw:1,0 . Refer to the software documentation on configuring the device name. For example in mpg123 player the audio device can be specified using -a switch:
mpg123 -a hw:1,0 -v "Dave Brubeck - Take Five.mp3"

AlexT's repository has several software packages that support audio output.

Output volume can be adjusted by writing headphone out register at address 0x05 (both channels) or 0x04 (left channel) and 0x06 (right channel), e.g.:
i2cset -y 1 0x1a 0x05 0x50

References

Intel® Edison Kit for Arduino* Hardware Guide

Intel Edison - Simple I2S Audio Setup

posted May 21, 2015, 8:48 PM by Sergey Kiselev   [ updated May 21, 2015, 9:11 PM ]

Introduction

Intel Edison board provides I2S interface, and the recent firmware adds the I2S support. The default image provides two machine drivers: The default "dummy" driver simply outputs PCM data using I2S in DSP format, 24-bit, 48000 samples per second. The other machine driver is for the WM8958 codec, which appears to be a fairly complicated codec intended to be used in phones and tablets. The straight forward way to add support for another codec (say popular WM8731) is to write a machine driver for it. And I am currently working on it.
Meanwhile there is a simpler, but perhaps a bit more hackish way to get audio output working on Edison: by configuring the codec directly using I2C interface, and i2cset command in particular.

Hardware Setup

The following hardware is required:
  • Intel Edison board with a Mini Breakout board (Mouser: 607-EDI2BB.AL.K). Arduino breakout board might work as well, but it will require some modifications (and I haven't tested it yet).
  • Wolfson WM8731 codec based board like MikroElektronica Audion Codec Proto board (Mouser: 932-MIKROE-506). I used a board that I designed previously for Raspberry Pi Model B. Texas Instruments TLV320AIC23B codec appears to be compatible, and might work as well.
Connect the WM8731 codec to the Intel Edison board as indicated in the table below:
 Intel Edison Signal Name Pin number on Intel Edison Mini Breakout board Pin name on WM8731 Pin name on MicroElectronika Audio Codec Proto board  Comments
 I2C1_SDA (GP20) J17 - pin 8 SDIN SDA Data signal for the #1 I2C interface on Edison
 I2C1_SCL (GP19) J18 - pin 6 SCLK SCL Clock signal for the #1 I2C interface on Edison
 V_V1P80 J19 - pin 2 DBVDD, DCVDD 3.3V 1.8V power output from Edison. It is used to power WM8731 I/O and core.
 GND J19 - pin 3 DGND, AGND, CSB GND This is the ground rail. Connecting CSB to ground configures WM8731 in I2C mode. Some boards might already have it hooked up to the ground.
 SSP2_CLK (GP40) J19 - pin 10 BCLK SCL I2S clock signal
 SSP2_TXD (GP43) J19 - pin 11 DACDAT MOSI I2S transmit data output from Edison to codec
 V_V3P30 or V_VSYS J20 - pin 2 or J20 - pin 1 AVDD, HPVDD Connect directly to L2, cut trace going to 3.3V This is used as analog power supply. Ideally it should be an LDO on this signal. In my case I connected a 3.3V LDO to V_VSYS, and output of that LDO to the analog supply of the codec.
 SSP2_RXD (GP42) J20 - pin 9 ADCDAT MISO I2S receive data input from codec to Edison
 SSP2_FS (GP41) J20 - pin 10 DACLRC, ADCLRC DACLRC, ADCLRC I2S frame sync output

Note: It is likely that most codec breakout boards will have digital and analog power rails connected in some way (e.g. through an inductor based filter). In Edison's case digital I/O is 1.8V and so separate digital and analog supplies must be used. Modify your board accordingly. Note that maximal allowed analog supply voltage is 3.6V.

My Prototype Setup


Software Configuration

First of all Intel Edison board needs to be upgraded to the latest firmware image with I2S support (release 2.1 at the time of writing). The images and instructions are available from Intel at this page.
Connect the Intel Edison board with two micro USB cables to your PC, and run a terminal emulator (such as Putty on Windows or screen on Linux) and connect to USB-Serial port. Serial port settings are 115200 bps with 8 data bits and 1 stop bit, no parity. Login with user root, and run the i2cset commands below to configure the codec. Note that i2cset will return "Write failed" error if codec is not responding, e.g. if codec is not connected or powered properly.

I2C Configuration Script

#!/bin/sh

# reset codec
i2cset -y 1 0x1a 0x1e 0x00

# disable DAC and output powerdown
i2cset -y 1 0x1a 0x0c 0x07

# set volume for headphone output (both channels)
i2cset -y 1 0x1a 0x05 0x65

# analog audio path control (DAC enabled)
i2cset -y 1 0x1a 0x08 0x12

# digital audio path control
i2cset -y 1 0x1a 0x0a 0x00

# set sample rate (48000Hz, assuming 12.288MHz codec clock)
i2cset -y 1 0x1a 0x10 0x00

# digital audio interface format set (DSP mode, 24 bit)
i2cset -y 1 0x1a 0x0e 0x8b

# activate interface
i2cset -y 1 0x1a 0x12 0x01

Using the Audio Device

The codec is connected to ALSA device hw:1,0 . Refer to the software documentation on configuring the device name. For example in mpg123 player the audio device can be specified using -a switch:
mpg123 -a hw:1,0 -v "Dave Brubeck - Take Five.mp3"

AlexT's repository has several software packages that support audio output.

Output volume can be adjusted by writing headphone out register at address 0x05 (both channels) or 0x04 (left channel) and 0x06 (right channel), e.g.:
i2cset -y 1 0x1a 0x05 0x50

References



Intel Galileo - Configuring the Serial Port in Linux

posted Jan 23, 2014, 3:46 PM by Sergey Kiselev   [ updated Jan 23, 2014, 3:47 PM ]

Introduction

Intel Galileo board features three serial ports:
  1. /dev/ttyGS0: This is the port provided by client USB connector. It is normally used by Arduino IDE to upload sketches to the Galileo.
  2. /dev/ttyS1: This is the serial port that is connected to the 3.5 mm connector, and it is normally used for the Linux console.
  3. /dev/ttyS0: Galileo can be configured to connect this serial port to Arduino pins 0 and 1. In this post I am going to talk about configuring this port.

Note: I will use UART (Universal Asynchronous Receiver/Transmitter) as a name for for the hardware inside the Quark SoC that provides serial port functionality.

GPIO Configuration

There are several GPIOs that control multiplexing of pins 0, 1, and enable a level shifter that need to be set in order to enable serial port on Arduino pins 0 and 1:
  • gpio4: This GPIO controls level shifter for UART signals and some other signals connected to Quark SoC, such as SPI and fast I/O. Writing '1' to this GPIO enables level shifter.
  • gpio40: This GPIO controls multiplexer for pin 0. Writing '0' to this GPIO connects pin 0 to UART's RxD (receive data) signal.
  • gpio41: This GPIO controls multiplexer for pin 1. Writing '0' to this GPIO connects pin 1 to UART's TxD (transmit data) signal.
The the following commands can be used to set these GPIOs so that pins 0, and 1 are connected to UART:
root@clanton:~# echo -n "4" > /sys/class/gpio/export
root@clanton:~# echo -n "40" > /sys/class/gpio/export
root@clanton:~# echo -n "41" > /sys/class/gpio/export
root@clanton:~# echo -n "out" > /sys/class/gpio/gpio4/direction
root@clanton:~# echo -n "out" > /sys/class/gpio/gpio40/direction
root@clanton:~# echo -n "out" > /sys/class/gpio/gpio41/direction
root@clanton:~# echo -n "strong" > /sys/class/gpio/gpio40/drive
root@clanton:~# echo -n "strong" > /sys/class/gpio/gpio41/drive
root@clanton:~# echo -n "1" > /sys/class/gpio/gpio4/value
root@clanton:~# echo -n "0" > /sys/class/gpio/gpio40/value
root@clanton:~# echo -n "0" > /sys/class/gpio/gpio41/value
The following commands will unexport GPIOs from sysfs (this is optional):
root@clanton:~# echo -n "4" > /sys/class/gpio/unexport
root@clanton:~# echo -n "40" > /sys/class/gpio/unexport
root@clanton:~# echo -n "41" > /sys/class/gpio/unexport

Software

Once serial port is configured it can be accessed using /dev/ttyS0 device just as any other serial port. One possible use is to run getty on it for an additional serial console. This can be done by adding the following string to /etc/inittab:
S0:2345:respawn:/sbin/getty 115200 ttyS0

And then reloading init configuration using:

root@clanton:~# kill -1 1

RS-232 Level Shifter Hardware

Galileo uses a logic-level signals (either 5V or 3.3V level). For connecting Galileo to another device with an RS-232 serial port, signals need to be converted to RS-232 levels. There are several shields and converters available that implement this functionality, for example this RS232 shield sold by SparkFun. Alternatively it is possible to build a level shifter using ICs like MAX232 (Maxim Integrated, Texas Instruments), MAX3232 (Maxim Integrated, Texas Instruments), or similar. Or use a serial to USB converter such as FTDI DB9-USB-D5-M module.


Microchip PIC Microcontrollers - Part 1

posted Nov 16, 2013, 12:02 AM by Sergey Kiselev

In the next couple of posts I'd like to deviate from my previous Galileo topic and talk a bit about much simpler microcontrollers that IMHO get frequently overlooked with all the Arduino craze. Yet these microcontollers are pretty simple to program, and much cheaper than Arduino (just a few $$ vs. tens of $$). More specifically I am going to talk about my favourite mid-range devices like PIC12F629, PIC12F675, and PIC16F88. Other popular with hobbyists PIC controllers include PIC16F84A (mostly because it is a direct replacement of venerable PIC16C84), PIC16F627 and PIC16F628. All these microcontrollers can be replaced by PIC16F88.

Introduction

Microchip PIC microcontrollers have been around for quite some time, at least 20 years in their current form - PIC16C84 was released in 1993. When released PICs were among first microcontrollers to use electrically erasable memory. Early devices (like PIC16C84 mentioned above) employed EEPROM for both instruction and data memory, later devices (all these with 'F' in between numbers in the part name, like PIC16F88) use flash for instruction memory and EEPROM for data memory (because it is byte-programmable).
From computer architecture perspective PIC microcontrollers are Harvard type RISC processors. This means that they have separate program and data memories, and relatively small instruction set with fixed instruction size. Most mid range devices have only 35 instructions. Another interesting fact that the instruction word size in these devices is 14-bit and not a multiply of 8-bit (a byte).

Specifications

The specifications vary between different microcontrollers in Microchip PIC family. So I will give some highlights. Hopefully it will help in picking up the right microcontroller for your project.
  • Multifunctional I/O ports with 25 mA sink/source current (more than enough to drive a LED, or a small speaker or buzzer).
    • 8-pin PIC12F629, PIC12F675 have 6 I/O pins.
    • 18-pin PIC16F88 have 16 I/O pins.
    • Analog comparator or two, with inputs and outputs accessible through I/O pins.
    • 10-bit analog to digital converter on PIC12F675 and PIC16F88. Input to this ADC can be multiplexed between several I/O pins. So it is possible to measure signals on all of these inputs (not at the same time, but in very close intervals).
    • PWM and RS-232 compatible UART, SPI, and I2C serial interfaces on PIC16F88
  • Wide operating voltage. Generally from 2 V to 5.5 V. Some devices, for example PIC16F88 require 4V to 5.5V, but they usually have lower voltage equivalents, e.g. PIC16LF88.
  • Built in oscillator. This will save you a quartz resonator in applications where high timing precision is not required. Of course you can use an external resonator, but that would take two I/O pins.
  • Processor clock frequency is up to 20 MHz. But it depends on the voltage (higher frequency requires higher voltage).
  • 2 or 3 timers.
  • Flash based instruction memory:
    • PIC12F629, PIC12F675 - 1024 words (14-bit instructions)
    • PIC16F88 - 4096 words
  • SRAM data memory:
    • PIC12F629, PIC12F675 - 64 bytes
    • PIC16F88 - 368 bytes
  • EEPROM based data memory:
    • PIC12F629, PIC12F675 -128 bytes
    • PIC16F88 - 256 bytes
  • Programmable interrupts on timer overflow, input pin change, and so on.
  • Various microcontroller goodies (power on reset, brown-out detect, watchdog timer)

Programming PIC Microcontroller

First of all I would recommend getting familiar with PIC hardware capabilities. Read a datasheet specific for the PIC you're planning to use. You don't have to read everything, but at least get familiar with I/O ports functionality and other features you want to use.

Important Stuff

I'll just mention a few things to pay attention to. First is the configuration word it is programmed into special location in microcontroller's memory and used to configure basic things like what type of oscillator to use, whether enable watch dog timer, copy protection and so on. Normally you can define the configuration word when you write your program. Some programmer software also allow changing configuration word when programming the PIC.

Next is the internal oscillator calibration value. Microchip calibrates internal oscillator during manufacturing and writes the calibration value into the last word of program memory (address 0x3FF in case of PIC12F629 and PIC12F675). Programmer software normally should preserve this value (but I've seen some that erased it). You might want to read that value and write it somewhere (e.g. on the chip itself). Also as one of the first steps in initialization sequence you might want to calibrate the oscillator by doing:

        bsf STATUS,5    ; bank 1 (RP0 = 1)
        call 0x3ff      ; get the OSCCAL value
        movwf OSCCAL    ; calibrate
        bcf STATUS,5    ; bank 0 (RP0 = 0)

Other important steps of initialization sequence is configuring I/O ports and interrupts. Here are some registers you might want to setup here:

  • CMCON - comparator configuration
  • ANSEL - analog to digital converter configuration (if ADC is present)
  • TRISIO - I/O pin direction - input or output
  • WPU - weak pull up enable / disable. Note that not all pins have weak pull ups.
  • OPTION_REG - various options: global weak pull up enable/disable, timer configuration, and so on
  • INTCON - interrupts control register

Programming Languages

As far as programming languages there are several possibilities here:

Assembler

PIC assembly language is pretty simple (did I mention - only 35 instructions). But it is significantly different from x86 assembler we all (or at least I) used to. So it takes a little exercise to get familiar with it. As far as assembler software I personally like open source GPUTILS suite.

C Language

There are several C language compilers for PIC, most of them commercial ones. SDCC is notable free and open source compiler.

Other

Commercial BASIC and Pascal compilers are available. Another thing that worth mentioning is Flowcode development environment.

Uploading Programs to PICs (Programming Instruction Flash Memory)

This is probably a more tricky part for Arduino users and it requires a one time investment - buying or building a programmer. In old days a popular solution was building a serial port based JDM programmer, which contains only a few components. This still might be a viable solution if you have an older computer with serial port. For newer computers you'll have to find a USB based programers. There are several such programmers available. The official Microchip programmer is PICKit, which is a bit expensive to my taste. eBay is full of K150 programmers, that IMHO is a simple JDM programmer connected to a FT232 USB to serial converter IC. The scary part about them is software, which might be or might be not compatible with your OS. Usbpicprog seems to be a good choice here. It is an open source design. And it is based on a PIC chip itself. So you'll need another programmer to program the programmer's PIC if you'll be building it. Alternatively you can buy the programmer from project's web site (20 euro + shipping). Another positive side is that usbpicprog project supplies programmer software for all popular OSes (Linux, Windows, Mac OSX).


Intel Galileo - Programming GPIO From Linux

posted Oct 28, 2013, 11:59 PM by Sergey Kiselev   [ updated Jan 15, 2014, 12:14 PM ]

Most of GPIO capabilities of Galileo board are exposed through Linux Sysfs interface, and can be controlled using file based I/O. I will show how to use some of these capabilities using simple shell commands. Of course instead of shell you can implement I/O using file manipulations from your program written using your favorite programming language.

Digital GPIO - Sysfs Interface

GPIO Information

The following command gives information about GPIO in the system and shows if an IO port was allocated to a module or Sysfs (user).

root@clanton:~# cat /sys/kernel/debug/gpio

GPIOs 0-1, platform/sch_gpio.2398, sch_gpio_core:


GPIOs 2-7, platform/sch_gpio.2398, sch_gpio_resume:


GPIOs 8-15, intel_cln_gip_gpio:

gpio-8   (SPI_CS              ) out hi

gpio-10  (SPI_CS              ) out hi

gpio-13  (cy8c9540a-int       ) in  hi


GPIOs 16-55, cy8c9540a, can sleep:

As you can see from the output all the GPIOs of Galileo board is divided into 4 chunks:
  1. GPIOs 0-1 - Intel Quark X1000 - GPIO[9:8] pins. These are GPIO pins on Legacy I/O bridge. They are powered and active in S0 state only.
  2. GPIOs 2-7 - Intel Quark X1000 - GPIO_SUS[5:0] pins. These are GPIO pins on Legacy I/O bridge. They are powered and active in S3 (suspend) and S0 states.
  3. GPIOs 8-15 - Intel Quark X1000 - GPIO[7:0] pins. These are GPIO pins on GPIO controller. They are powered and active in S0 state only.
  4. GPIOs 16-55 - Cypress CY8C9540A I/O Expander

Exporting a GPIO Port to Sysfs

To make GPIO port controllable from sysfs you'll need to export it. This is done by writing GPIO port number to /sys/class/gpio/export:

root@clanton:~# echo -n "27" > /sys/class/gpio/export

When this operation completes successfully a directory corresponding to the GPIO port number will appear in sysfs. In this case /sys/class/gpio/gpio27. Once you finished working with I/O you should un-export it by writing the GPIO port number to /sys/class/gpio/unexport.

Setting GPIO Port Direction

I/O direction is set by writing "in" (for input) or "out" (for output) to /sys/class/gpio/gpioXX/direction file.

root@clanton:~# echo -n "out" > /sys/class/gpio/gpio27/direction

Setting GPIO Port Drive Configuration

When configured for output GPIO ports that are connected to CY8C9520A can be configured to one of the following drive modes:

  • Resistive high, strong low (drive = pullup)
    • This is the default, but it not suitable for driving devices that source significant current, for example for driving an LED connected between GPIO port and GND (it will work though if the LED is connected between GPIO and 5V or 3.3V rails)
  • Resistive low, strong high (drive = pulldown)
  • Strong low and high (drive = strong)
    • This mode is appropriate for most applications.
  • High Z state (drive = hiz)
  • (CY8C9520A also supports open drain and open source drive modes, but it is not currently exposed through SysFS)

The drive mode is set by writing the mode string ("pullup", "pulldown", "strong", or "hiz") to /sys/class/gpio/gpioXX/drive.

root@clanton:~# echo -n "strong" > /sys/class/gpio/gpio27/drive

Reading and Writing GPIO Port

When GPIO port is configured for input the input value (0 or 1) can be read from /sys/class/gpio/gpioXX/value file.
root@clanton:~# cat /sys/class/gpio/gpio27/value
0
When GPIO port is configured for output the output value can be written to the same file:
root@clanton:~# echo -n "1" > /sys/class/gpio/gpio27/value
root@clanton:~# echo -n "0" > /sys/class/gpio/gpio27/value

Pulse-Width Modulation

Pulse width modulation (PWM) is a technique of simulating an analog output signal using a digital signal switched on and off repeatedly for certain intervals. It is widely used to regulate intensity of LEDs, to control speed of DC motors, and so on.

Checking the number of PWM Channels

root@clanton:~# cat /sys/class/pwm/pwmchip0/npwm
8

In Galileo all PWM outputs are implemented using Cypress CY8C9540A. It supports 8 PWM channels, but only 6 are used in Galileo. They are mapped as follows:

  Arduino Digital Pin NumberPWM Channel Number
 3 3
 5 5
 6 6
 9 1
 10 7
 11 4

Exporting a PWM Channel to Sysfs

root@clanton:~# echo -n "3" > /sys/class/pwm/pwmchip0/export
This is very similar to exporting GPIO above. Same as with GPIO once a port is exported a corresponding directory with control files will appear in Sysfs: /sys/class/pwm/pwmchip0/pwm3/enable in this case. And just as with GPIO when PWM port is no longer needed it should be un-exported by writing the port number to /sys/class/pwmchip0/unexport.

Enabling PWM and Setting PWM Parameters

To enable a PWM on a port write "1" to a corresponding enable file. To disable a port write "0".
root@clanton:~# echo -n "1" > /sys/class/pwm/pwmchip0/pwm3/enable

To set a PWM period write period in nanoseconds to period file. In example below it is set to 1000000 nanoseconds or 1 millisecond:
root@clanton:~# echo -n "1000000" > /sys/class/pwm/pwmchip0/pwm3/period

To set a PWM duty cycle write its length in nanoseconds to duty_cycle file. In example below we set duty cycle to 50% (500000/1000000*100%):
root@clanton:~# echo -n "500000" > /sys/class/pwm/pwmchip0/pwm3/duty_cycle

Analog Input

Analog inputs in Galileo implemented using Analog Devices AD7298 ADC IC. This IC has 8 channels, but only 6 channels are connected in Galileo. The resolution of each channel is 12 bit. So resulting values will be in range 0 - 4095. 0 - input voltage 0V (ground), 4095 - input equals 5V (power supply).

In Sysfs analog inputs can be read from /sys/bus/iio/devices/iio:device0/in_voltageX_raw files. Since analog inputs are multiplexed with GPIO and I2C (in case of A4 and A5) it is needed to enable analog input first. Multiplexers are controlled using regular GPIO pins. Example below shows how to do that for A0. Refer to the table below to find out corresponding multiplexer ports for other analog ports.

root@clanton:~# echo -n "37" > /sys/class/gpio/export
root@clanton:~# echo -n "out" > /sys/class/gpio/gpio37/direction
root@clanton:~# echo -n "0" > /sys/class/gpio/gpio37/value
First echo command exports GPIO port 37 which is used to control A0 multiplexer. Second echo command configures that GPIO for output. Third echo command connects A0 to ADC chip.

Once analog port is connected, its value can be read from Sysfs:
root@clanton:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw
2593

Other Functionality

Fast I/O

In addition to regular I/O through Sysfs Galileo supports fast I/O on digital pins 2 and 3 which can be connected using multiplexer directly to Intel Quark X1000. The fast I/O is done using /dev/uio0 device. I haven't tested this functionality yet and will report it later.

SPI I/O

Digital pins 10 - 13 can be connected to Intel Quark X1000's SPI1 interface. I am not sure yet if this interface is exposed to userspace. I need to investigate it.

I2C I/O

Pins A4 and A5 and also SDA and SCL pins can be connected to Intel Quark X1000's I2C interface. Again I haven't tried this functionality yet.

GPIO Mapping in Galileo

This is probably the most important (and the most confusing) part of this post. It took me a while to parse the schematic and the supplied Arduino code to come up with this diagram and table. Hopefully it will tell you exactly what to do if you want to use some pins for certain function.

GPIO Pins Connection Diagram

Labels on the left size indicate names of ports in SysFS GPIO and PWM (where applicable) interfaces, or Intel Quark X1000 connections: ttyS0 for the serial port signals; SPI1 for SPI interface signals, and I2C for I2C signals. ADC inputs are named vin0 to vin7 and correspond to /sys/bus/iio/devices/iio:device0/in_voltage0_raw - /sys/bus/iio/devices/iio:device0/in_voltage7_raw respectively.

Labels on the right side indicate names of Arduino shield ports.

The trapezoid shaped things are bidirectional multiplexers (or switches). They are controlled by the signal coming on the top (selector input). When the selector value is 0 it connects 0 pin on the left side of multiplexer to the pin on the right side of multiplexer; when the selector value is 1 it connects pin 1 on the left side to the pin on the right side. To give an example if you want to connect Arduino A1 pin to ADC vin1, you'll need to set gpio36 to "0".

(Click on the diagram to zoom in)

GPIO Pins Assignment

Quark X1000

Sysfs GPIO #

Signal Name / Arduino Port #

Function and Comments

GPIO_SUS0

gpio2

INT_N_S3

Don’t touch, or bad things will happen :-)

GPIO_SUS1

gpio3

GP LED

LED between Cypress CY8C9540A and RTC battery header

GPIO_SUS2

gpio4

LVL_OE

TXS0108E level shifter output enable.

GPIO_SUS3

gpio5

GPIO_SUS3_PCIE_RESET_N

Reset to Mini PCI-E slot

GPIO_SUS4

gpio6

GPIO_SUS4_W_DISABLE_N

Wireless disable (RF Kill to PCI-E Slot)

GPIO_SUS5

gpio7

A0_N

Jumper J2 (Cypress CY8C9540A I2C address select)

GPIO0

gpio8

SPI0_CS_N

Select SPI for AD7298

GPIO1

gpio9

Not Connected


GPIO2

gpio10

SPI1_CS_N

Routed to IO10 if selected by IO10_MUX (libgpio42=0)

GPIO3

gpio11

Not Connected


GPIO4

gpio12

XRES

Reset to Cypress CY8C9540A

GPIO5

gpio13

INT_N_S0

Don’t touch too :-)

GPIO6

gpio14

IO2

Selected by IO2_MUX (gpio31=0)

GPIO7

gpio15

IO3

Selected by IO3_MUX (gpio30=0)

GPIO8

gpio0

GLN_IO2_PU_EN

Enable pullup on IO2/GPIO6

GPIO9

gpio1

GLN_IO3_PU_EN

Enable pullup on IO3/GPIO7

CY8C9540A

Sysfs GPIO #Signal Name / Arduino Port #Function and Comments

GPORT0_BIT0

gpio16

IO10

Selected by IO10_MUX (GPORT3_BIT6, gpio42)

Also controlled by pwm7

GPORT0_BIT1

gpio17

IO5

Also controlled by pwm5

GPORT0_BIT2

gpio18

IO3

Selected by IO3_MUX (gpio30=1)

Also controlled by pwm3

GPORT0_BIT3

gpio19

IO9

Also controlled by pwm1

GPORT0_BIT4

gpio20

A5_MUX

Selects A5 pin routing:

0 = AD7298 (VIN5)

1 = Cypress CY8C9540A (GPORT4_BIT5, gpio49)

GPORT0_BIT5

gpio21

A4_MUX

Selects A4 pin routing:

0 = AD7298 (VIN4)

1 = Cypress CY8C9540A (GPORT4_BIT4, gpio48)

GPORT0_BIT6

gpio22

A3_MUX

Selects A3 pin routing:

0 = AD7298 (VIN3)

1 = Cypress CY8C9540A (GPORT4_BIT3, gpio47)

GPORT0_BIT7

gpio23

A2_MUX

Selects A2 pin routing:

0 = AD7298 (VIN2)

1 = Cypress CY8C9540A (GPORT4_BIT2, gpio46)

GPORT1_BIT0

gpio24

IO6

Also controlled by pwm6

GPORT1_BIT1

gpio25

IO11

Selected by IO11_MUX (GPORT3_BIT7, gpio43)

Also controlled by pwm4

GPORT1_BIT2

gpio26

IO8


GPORT1_BIT3

gpio27

IO7


GPORT1_BIT4

gpio28

IO4


GPORT1_BIT5

gpio29

I2C_MUX

Selects between GPIO and I2C on pins A4 and A5:

0= Quark I2C

1 = GPIO (Cypress CY8C9540A, AD7298)

GPORT1_BIT6

gpio30

IO3_MUX

Selects IO3 pin routing:
0 = Quark (GPIO7, gpio15)

1 = Cypress CY8C9540A (GPORT9_BIT2, gpio18)

GPORT1_BIT7

gpio31

IO2_MUX

Selects IO2 pin routing:

0 = Quark (GPIO6, gpio14)

1 = Cypress CY8C9540A (GPORT2_BIT0, gpio32)

GPORT2_BIT0

gpio32

IO2

Selected by IO_MUX (gpio31=1)

GPORT2_BIT1

gpio33

Not Connected


GPORT2_BIT2

gpio34

Not Connected


GPORT2_BIT3

gpio35

Not Connected


GPORT3_BIT0

gpio36

A1_MUX

Select A1 pin routing:

0 = AD7298 (VIN1)

1 = Cypress CY8C9540A (GPORT4_BIT1, gpio45)

GPORT3_BIT1

gpio37

A0_MUX

Select A0 pin routing:

0 = AD7298 (VIN0)

1 = Cypress CY8C9540A (GPORT4_BIT0, gpio44)

GPORT3_BIT2

gpio38

IO12

Selected by IO12_MUX (gpio54=1)

GPORT3_BIT3

gpio39

IO13

Selected by IO13_MUX (gpio55=1)

GPORT3_BIT4

gpio40

IO0_MUX

Select IO0 pin routing:

0 = Quark UART0 RXD (/dev/ttyS0)

1 = Cypress CY8C9540A (GPORT4_BIT6, gpio50)

GPORT3_BIT5

gpio41

IO1_MUX

Select IO1 pin routing:

0 = Quark UART0 TXD (/dev/ttyS0)

1 = Cypress (GPORT4_BIT7, gpio51)

GPORT3_BIT6

gpio42

IO10_MUX

Select IO10 pin routing:

0 = Quark SPI1_CS

1 = Cypress (GPORT0_BIT0, gpio16)

GPORT3_BIT7

gpio43

IO11_MUX

Select IO11 pin routing:

0 = Quark SPI1_MOSI

1 = Cypress (GPORT1_BIT1, gpio25)

GPORT4_BIT0

gpio44

A0

Selected by A0_MUX (gpio37=1)

GPORT4_BIT1

gpio45

A1

Selected by A1_MUX (gpio36=1)

GPORT4_BIT2

gpio46

A2

Selected by A2_MUX (gpio23=1)

GPORT4_BIT3

gpio47

A3

Selected by A3_MUX (gpio22=1)

GPORT4_BIT4

gpio48

A4

Selected by A4_MUX (gpio21=1) and I2C_MUX (gpio29=1)

GPORT4_BIT5

gpio49

A5

Selected by A5_MUX (gpio20=1) and I2C_MUX (gpio29=1)

GPORT4_BIT6

gpio50

IO0

Selected by IO0_MUX (gpio40=1)

GPORT4_BIT7

gpio51

IO1

Selected by IO1_MUX (gpio41=1)

GPORT5_BIT0

gpio52

RESET (Input)

Connected to shield and to the RESET button.

GPORT5_BIT1

gpio53

RESET (Output)


GPORT5_BIT2

gpio54

IO12_MUX

Selects IO12 pin routing:

0 = Quark SPI_MISO

1 = Cypress (PORT3_BIT2, gpio38)

GPORT5_BIT3

gpio55

IO13_MUX

Selects IO13 pin routing:

0 = Quark SPI_SCK
1 = Cypress (PORT3_BIT3, gpio39)

AD7298

Sysfs GPIO #Signal Name / Arduino Port #Function and Comments

VIN1

in_voltage0_raw

A0

Selected by A0_MUX (gpio37=0)

VIN2

in_voltage1_raw

A1

Selected by A1_MUX (gpio36=0)

VIN3

in_voltage2_raw

A2

Selected by A2_MUX (gpio23=0)

VIN3

in_voltage3_raw

A3

Selected by A3_MUX (gpio22=0)

VIN4

in_voltage4_raw

A4

Selected by A4_MUX (gpio21=0) and I2C_MUX (gpio29=1)

VIN5

in_voltage5_raw

A5

Selected by A5_MUX (gpio20=0) and I2C_MUX (gpio29=1)

VIN6

in_voltage6_raw

Not Connected


VIN7

in_voltage7_raw

Not Connected





Intel Galileo Meets Wireless

posted Oct 25, 2013, 9:19 PM by Sergey Kiselev   [ updated Oct 30, 2013, 8:08 AM ]

One of significant advantages of Galileo over similar SBCs is availability of mini PCI Express connector. It can be used to add a high speed WiFi adapter without taking the USB port.

Construction

Parts

Mini PCI-E Wireless Adapter

I recommend using an Intel Wireless adapter. These adapters are well supported by Linux. There are several wireless adapter models available. Some of them include Bluetooth support, some 5 MHz band, some even have WiMax. Note that officially current Galileo SD image only supports Intel® Centrino® Wireless-N 135 and Intel® Centrino® Advanced-N 6205 adapters. Although support for many other adapters can be easily added. I used Intel® Centrino® Advanced-N 6235. While it is a bit more expensive than N135 or N6205, it supports 802.11a/b/g/n standards, including 5 GHz band, and also has a built in Bluetooth.

Antenna

You'll need a pair of WiFi antenna with Hirose U.FL connectors. There are two options here:

  1. A pair of antenna with RP-SMA connectors (these are common on home wireless routers), and a pair of U.FL to RP-SMA cables.
  2. Laptop style antenna with U.FL connectors.
With the first option you'll get better wireless reception. The second option is preferable for compact systems, as these antenna can be mounted inside the enclosure you'll be using to host your Galileo project. I decided to go with the first option and purchased a kit with a pair of antenna and cables from Amazon.

Full Size to Half Size Mini PCI-E Bracket

Modern PCI-E WiFi adapters have a half size form factor, while Galileo has a retention latch spaced for a full size adapters. If you'll try to install a half size card in it, it will not stay in place (unless you use glue or a sticky tape :-)). Fortunately full size to half size brackets are cheaply available from multiple sources like Amazon and eBay.

Mounting Antenna

Hirose U.FL. connectors are fragile and not supposed to be reconnected multiple times. Thin coaxial cables are not very sturdy either. So I recommend attaching antenna to Galileo to reduce movement of these cables and connectors. Of course if you are using an enclosure for your project, you can mount antenna on that enclosure. Since I am still experimenting with my Galileo, and like to have it open I made a bracket myself from a spare piece of aluminum. An aluminum angle would work as well. I drilled four holes: Two 9/64" holes spaced at 2.5" on one side for attaching the bracket to the Galileo. And two holes 1/4" for RP-SMA connectors on the other side.

Putting It All Together

The process is pretty straightforward:
  • Attach the adapter bracket to mini PCI-E wireless adapter with two screws supplied with the bracket.
  • Install wireless into Galileo. Insert it at approximately 30 degrees. Push it sideways and then down. Make sure retention latches are locked inside the holes of the bracket.
  • Install pigtail cables in the angle bracket.
  • Install angle bracket on the Galileo board.
  • Attach pigtail cables to U.FL connectors on the mini PCI-E.
  • Attach antenna.
Picture below shows my Galileo board with wireless card and bracket installed and cables attached to the wireless card.

Complete assembly

Configuring Wireless In Linux

Intel Supplied SD Card Image

Intel supplied SD card image only includes iwlwifi-135-6.ucode and iwlwifi-6000g2a-6.ucode firmware. In my case for the N6235 card I needed to get iwlwifi-6000g2b-6.ucode from http://wireless.kernel.org/en/users/Drivers/iwlwifi (it is in iwlwifi-6000g2b-ucode-18.168.6.1.tgz file). To install firmware on my Galileo I copied the iwlwifi-6000g2b-ucode-18.168.6.1.tgz archive to SD card, booted the Galileo, unzipped and copied firmware to the /lib/firmware directory:

root@clanton:/tmp# tar xzvf /media/mmcblk0p1/iwlwifi-6000g2b-ucode-18.168.6.1.tgz
iwlwifi-6000g2b-ucode-18.168.6.1/
iwlwifi-6000g2b-ucode-18.168.6.1/iwlwifi-6000g2b-6.ucode
iwlwifi-6000g2b-ucode-18.168.6.1/README.iwlwifi-6000g2b-ucode
iwlwifi-6000g2b-ucode-18.168.6.1/LICENSE.iwlwifi-6000g2b-ucode
root@clanton:/tmp# cp iwlwifi-6000g2b-ucode-18.168.6.1/iwlwifi-6000g2b-6.ucode /lib/firmware/
root@clanton:/tmp#

Once proper firmware is installed use the following steps to configure wireless (this assumes using WPA security).

  1. Login to your Galileo as root
  2. Run the following command to generate wpa_supplicant configuration file for your network. Replace MyWiFi with the SSID of your wireless networkand MyPassPhrase with the real passphrase:
    root@clanton:~# wpa_passphrase MyWiFi << EOF > /etc/wpa_supplicant.conf
    > MyPassPhrase
    > EOF
  3. If you wish to configure your Galileo to connect to the wireless network automatically, edit /etc/network/interfaces file and add auto wlan0 line somewhere in the file. I suggest putting it right before iface wlan0 line:

    # /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)

    # The loopback interface
    auto lo
    iface lo inet loopback

    # Wireless interfaces
    auto wlan0
    iface wlan0 inet dhcp
            wireless_mode managed
            wireless_essid any
            wpa-driver wext
            wpa-conf /etc/wpa_supplicant.conf
  4. Restart networking:
    root@clanton:/etc# /etc/init.d/networking restart
    Running /etc/init.d/networking restart is deprecated because it may not enable again some interfaces
    Reconfiguring network interfaces...
    ifdown: interface wlan0 not configured
    ifdown: interface eth0 not configured
    udhcpc (v1.20.2) started
    Sending discover...
    Sending select for 192.168.1.9...
    Lease of 192.168.1.9 obtained, lease time 86400
    /etc/udhcpc.d/50default: Adding DNS 192.168.1.254
    udhcpc (v1.20.2) started
    Sending discover...
    Sending discover...
    Sending discover...
    No lease, failing
  5. You can also bring wireless interface up or down using ifup wlan0 and ifdown wlan0 command (even if you didn't enable auto connect in step 3):
    root@clanton:/etc# ifdown wlan0
    [ 1180.113711] wlan0: deauthenticating from c8:60:00:d2:95:2c by local choice (reason=3)
    [ 1180.183410] cfg80211: Calling CRDA to update world regulatory domain
    root@clanton:/etc# ifup wlan0
    Successfully initialized wpa_supplicant
    [ 1186.273174] iwlwifi 0000:01:00.0: L1 Disabled; Enabling L0S
    [ 1186.287015] iwlwifi 0000:01:00.0: Radio type=0x2-0x1-0x0
    [ 1186.563247] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
    udhcpc (v1.20.2) started
    Sending discover...
    [ 1189.866932] wlan0: authenticate with c8:60:00:d2:95:2c
    [ 1189.888080] wlan0: send auth to c8:60:00:d2:95:2c (try 1/3)
    Sending discover...
    [ 1190.100271] wlan0: send auth to c8:60:00:d2:95:2c (try 2/3)
    [ 1190.106813] wlan0: authenticated
    [ 1190.120257] wlan0: associate with c8:60:00:d2:95:2c (try 1/3)
    [ 1190.127349] wlan0: RX AssocResp from c8:60:00:d2:95:2c (capab=0x11 status=0 aid=2)
    [ 1190.159137] wlan0: associated
    [ 1190.162421] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
    Sending discover...
    Sending select for 192.168.1.9...
    Lease of 192.168.1.9 obtained, lease time 86400
    /etc/udhcpc.d/50default: Adding DNS 192.168.1.254

LSB-compliant Image

If compiled correctly LSB image will contain iwlwifi kernel module and firmware for current Intel wireless adapters.

Poky LSB compliant image uses connman for managing network connections. I used the following procedure to configure wireless there.

  1. Login to your Galileo as root
  2. Start connmanctl:
    root@clanton:~# connmanctl
  3. Enable wireless using enable wifi command:
    connmanctl> enable wifi
  4. Scan for available wireless networks using scan wifi command:
    connmanctl> scan wifi
    Scan completed
  5. Display available wireless network and note one you want to connect to:
    connmanctl> services
        MyWiFi               { wifi_b4b6765faaf0_4d7957694669_managed_psk }
        Guest                { wifi_b4b6765faaf0_4775657374_managed_psk }
        kafenet              { wifi_b4b6765faaf0_6b6166656e6574_managed_psk }
        DIPPELFAMILY         { wifi_b4b6765faaf0_44495050454c46414d494c59_managed_psk }
        aussie               { wifi_b4b6765faaf0_617573736965_managed_psk }
        aussie               { wifi_b4b6765faaf0_hidden_managed_psk }
        EverydayParadise     { wifi_b4b6765faaf0_45766572796461795061726164697365_managed_psk }
        5VHXG                { wifi_b4b6765faaf0_3556485847_managed_psk }
        Moria-2G_xt          { wifi_b4b6765faaf0_4d6f7269612d32475f7874_managed_psk }
        unknown_protocol     { wifi_b4b6765faaf0_756e6b6e6f776e5f70726f746f636f6c_managed_psk }
        Stock-House          { wifi_b4b6765faaf0_53746f636b2d486f757365_managed_psk }
        Moria-2G             { wifi_b4b6765faaf0_4d6f7269612d3247_managed_psk }
        5NFP6                { wifi_b4b6765faaf0_354e465036_managed_wep }
        Moria-Guest          { wifi_b4b6765faaf0_4d6f7269612d4775657374_managed_psk }
        XEMT2                { wifi_b4b6765faaf0_58454d5432_managed_wep }
        4RDS1                { wifi_b4b6765faaf0_3452445331_managed_wep }
        Kingdom1             { wifi_b4b6765faaf0_4b696e67646f6d31_managed_wep }
        Belkin_N+_D57D20     { wifi_b4b6765faaf0_42656c6b696e5f4e2b5f443537443230_managed_none }
        Comcast              { wifi_b4b6765faaf0_436f6d63617374_managed_wep }
    (As you can see I have way too many wireless access points in my neighborhood... some are even wide open)
  6. Next three steps are needed because currently connmanctl lacks command to setup passphrase for a network.
    Exit connman for now using exit command:
    connmanctl> exit
    root@clanton:~#
  7. Create a file in /var/lib/connman/. The file name is not really important. The header (first line of the file) should be in [service_<service_name>] format, where <service_name> is the name from the services command output above matching SSID of your network. Set the Security value according to the security type of your network (wep, wpa, none). Also set the Passphrase value to the passphrase of your wireless network:
    root@clanton:~# cat << EOF > /var/lib/connman/wifi.config
    [service_wifi_b4b6765faaf0_
    4d7957694669_managed_psk]
    Type = wifi
    Security = wpa
    Name = MyWiFi
    Passphrase = MyPassPhrase
    EOF

    root@clanton:~#
  8. Stop and start connman to re-read configuration:
    root@clanton:~# /etc/init.d/connman stop
    Stopping Connection Manager
    root@clanton:~# /etc/init.d/connman start
    Starting Connection Manager
    Shortly you should see something like this on your console:
    [ 1879.331020] eth0: device MAC address 00:13:20:ff:16:af
    [ 1879.357126] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
    [ 1879.403465] iwlwifi 0000:01:00.0: L1 Disabled; Enabling L0S
    [ 1879.417585] iwlwifi 0000:01:00.0: Radio type=0x2-0x1-0x0
    [ 1879.701814] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
    [ 1892.405363] wlan0: authenticate with c8:60:00:d2:95:2c
    [ 1892.431336] wlan0: send auth to c8:60:00:d2:95:2c (try 1/3)
    [ 1892.640274] wlan0: send auth to c8:60:00:d2:95:2c (try 2/3)
    [ 1892.647289] wlan0: authenticated
    [ 1892.660276] wlan0: associate with c8:60:00:d2:95:2c (try 1/3)
    [ 1892.674197] wlan0: RX AssocResp from c8:60:00:d2:95:2c (capab=0x11 status=0 aid=2)
    [ 1892.706347] wlan0: associated
    [ 1892.709495] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
  9. You can run ifconfig command to make sure that wlan0 interface is configured correctly:
    root@clanton:~# ifconfig
    eth0      Link encap:Ethernet  HWaddr 00:13:20:ff:16:af
              UP BROADCAST MULTICAST DYNAMIC  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:0 (0.0 B)  TX bytes:322 (322.0 B)
              Interrupt:40

    lo        Link encap:Local Loopback
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:32 errors:0 dropped:0 overruns:0 frame:0
              TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:2240 (2.1 KiB)  TX bytes:2240 (2.1 KiB)

    wlan0     Link encap:Ethernet  HWaddr b4:b6:76:5f:aa:f0
              inet addr:192.168.1.9  Bcast:192.168.1.255  Mask:255.255.255.0
              inet6 addr: fe80::b6b6:76ff:fe5f:aaf0/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:936 errors:0 dropped:453 overruns:0 frame:0
              TX packets:153 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:142868 (139.5 KiB)  TX bytes:36885 (36.0 KiB)

Intel Galileo - Building Linux Image

posted Oct 24, 2013, 5:17 PM by Sergey Kiselev   [ updated Oct 27, 2013, 2:27 PM ]

As I mentioned in my previous post the capabilities in Intel provided SD-based Linux image is somehow limited. Fortunately the image is built using Yocto Project embedded Linux build system and Intel provides all files necessary to rebuild the Linux image. Here I will describe how to do that.

Prerequisites

  • Intel Galileo Board (well, not really needed for the build process, but you want to run the image somewhere, right?). Update the boards' firmware. Older firmware has a bug that prevents booting from SD card.
  • A computer with a fairly new Linux distribution installed on it. I used Ubuntu 12.04.
  • Development tools, GCC compiler, etc. You'll also need 7zip utility. Debian/Ubuntu people do:
    sudo apt-get install build-essential p7zip-full
  • 70GB or so available space on the hard drive.
  • Fairly fast Internet connection. It is going to download all the sources required for the image from the Internet.
  • A few hours to complete the build process. This will depend on the performance of your computer and the Internet connection speed.

Basic Steps to Rebuild The Image

  1. Create a directory you'll be using for the build process. Do not use spaces in the directory name. Yocto doesn't like them.
  2. Download "Board Support Package Sources for Intel Quark" from https://communities.intel.com/community/makers/software/drivers. And copy it to your build directory. In my case the file was named Board_Support_Package_Sources_for_Intel_Quark_v0.7.5.7z.
  3. Unzip the file:
    7z x Board_Support_Package_Sources_for_Intel_Quark_v0.7.5.7z
  4. Unzip meta-clanton_v0.7.5.tar.gz:
    tar xzvf Board_Support_Package_Sources_for_Intel_Quark_v0.7.5/meta-clanton_v0.7.5.tar.gz
  5. Change directory to meta-clanton_v0.7.5:
    cd meta-clanton_v0.7.5
  6. Run setup.sh:
    ./setup.sh
  7. Source poky/oe-init-build-env script, giving it the build directory (yocto_build) as a parameter:
    source poky/oe-init-build-env yocto_build
  8. Run bitbake to build the image:
    bitbake image-full
    • Note: image-full - SD card image, image-spi - SPI flash image.
  9. Wait several hours, and if everything goes well you'll get your image in tmp/deploy/images/ directory. It will include:
    • The Linux kernel: bzImage--3.8-r0-clanton-YYYYMMDDhhmmss.bin (YYYYMMDDhhmmss - timestamp indicating the build start time)
    • Initial RAM FS: core-image-minimal-initramfs-clanton-YYYYMMDDhhmmss.rootfs.cpio.gz
    • File system image: image-full-clanton-YYYYMMDDhhmmss.rootfs.ext3
    • Kernel modules: modules--3.8-r0-clanton-YYYYMMDDhhmmss.tgz (not really needed, they are already in the file system image)
    • Grub configuration: boot/grub/grub.conf
  10. Copy these files to SD card renaming files as follows (resulting paths are relative to SD card's root):
    • bzImage--3.8-r0-clanton-YYYYMMDDhhmmss.bin -> bzImage
    • core-image-minimal-initramfs-clanton-YYYYMMDDhhmmss.rootfs.cpio.gz -> core-image-minimal-initramfs-clanton.cpio.gz
    • image-full-clanton-YYYYMMDDhhmmss.rootfs.ext3 -> image-full-clanton.ext3
    • boot/grub/grub.conf -> boot/grub/grub.conf
    • Note that you can keep names or use different names for all files except of the image-full-clanton.ext3, and just update grub.conf with the correct names. The file system image must be named image-full-clanton.ext3 (initramfs will look for that) unless you update the configuration.
  11. Insert SD card to your Galileo board, reboot it, and enjoy!

Building Linux Standard Base (LSB) Image

In my case I wanted to get an LSB (Linux Standard Base) compatible image, with development tools installed on it, and USB audio support. I choose to use Poky core-image-lsb-sdk image profile as it includes all the stuff I needed. (Poky is a Yocto project reference distribution.)

The instructions below assume that you already done steps 1 - 7 above, and you are in meta-clanton_v0.7.5/yocto_build/ directory.

Update local.conf

Edit conf/local.conf. We will want to use to use eglibc instead of uClibc (LSB requires eglibc/glibc). Set DISTRO to clanton-full:
DISTRO ?= "clanton-full"
Note that supplied Arduino IDE cross compiles sketches with uClibc and they will not work with eglibc.

You might also want to tweak BB_NUMBER_THREADS and PARALLEL_MAKE variables. Increase numbers if you have a computer with many cores or processors to speed up compilation process. I would recommend having 2-3 threads per core. The default configuration is OK for a dual or quad core processor system.

Comment out uClibc patch for v4l2apps

Edit ../meta-clanton-distro/recipes-multimedia/v4l2apps/v4l-utils_0.8.8.bbappend, prepend each line with a hash (#) sign:
#FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
#SRC_URI += "file://uclibc-enable.patch"
#DEPENDS += "libiconv"

Create recipe for the image

Copy ../meta-clanton-distro/recipes-core/images/image-full.bb  file to ../meta-clanton-distro/recipes-core/images/image-sdk.bb:

cp ../meta-clanton-distro/recipes-core/images/image-full.bb to ../meta-clanton-distro/recipes-core/images/image-sdk.bb

Edit ../meta-clanton-distro/recipes-core/images/image-sdk.bb file. Append packagegroup-core-basic packagegroup-core-lsb kernel-dev to IMAGE_INSTALL:

IMAGE_INSTALL = "packagegroup-core-boot ${ROOTFS_PKGMANAGE_BOOTSTRAP} ${CORE_IMAGE_EXTRA_INSTALL} packagegroup-core-basic packagegroup-core-lsb kernel-dev"


Append tools-sdk dev-pkgs tools-debug eclipse-debug tools-profile tools-testapps debug-tweaks to IMAGE_FEATURES:
IMAGE_FEATURES += "package-management tools-sdk dev-pkgs tools-debug eclipse-debug tools-profile tools-testapps debug-tweaks"

You might also want to increase root file system size from the 300 MB default to 3 GB or so. If configured as described here image will use about 1.5GB so with 3 GB you'll have plenty of space for other things.

IMAGE_ROOTFS_SIZE = "3072000"

Other Changes

I made a couple more tweaks to the image. First is an update to Galileo kernel patch to fix an issue with CY8C9540A I/O expander. By default intel_cln_gip module configures Intel Quark to use I2C fast mode, and CY8C9540A doesn't want to work with that mode. So the change is to make standard mode default. Find +static unsigned int i2c_std_mode; line in ../meta-clanton-bsp/recipes-kernel/linux/files/clanton.patch file and assign 1 to that variable (add = 1 before semicolon):

+static unsigned int i2c_std_mode = 1;

Another patch is to allow configurable file system image file name. So that I can have multiple file system images on one SD card, and switch between them easily using GRUB menu. The patch is attached to this blog (rootimage.patch). Copy it to ../meta-clanton-distro/recipes-core/initrdscripts/files/ directory and add SRC_URI += "file://rootimage.patch;patchdir=${WORKDIR}" line to ../meta-clanton-distro/recipes-core/initrdscripts/initramfs-live-boot_1.0.bbappend file:

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI += "file://name.patch;patchdir=${WORKDIR}"
SRC_URI += "file://rootimage.patch;patchdir=${WORKDIR}"

Once this patch is applied you can use rootimage=<filename>.ext3 option in the kernel command line in grub.conf to specify the root file system image file name. For example:

title Clanton SDK
    root (hd0,0)
    kernel /bzImage--3.8-r0-clanton-20131027083753.bin root=/dev/ram0 console=ttyS1,115200n8 earlycon=uart8250,mmio32,0x8010f000,115200n8 reboot=efi,warm apic=debug rw LABEL=boot debugshell=5 rootimage=image-sdk-clanton-20131027083753.rootfs.ext3
    initrd /core-image-minimal-initramfs-clanton-20131027083753.rootfs.cpio.gz

Reconfigure kernel, enable whatever features you like

bitbake linux-yocto-clanton -c menuconfig

Build the image

bitbake image-sdk

For information more information on available image profiles, see the "Images" chapter in the Yocto Project Reference Manual.

Install the image

Follow steps 9 - 11 above to install the image on the SD card.

Files and patches

For your convenience I attached a tarball which includes files with all the modifications described above and my kernel configuration with USB audio enabled. You can simply unpack it in to your build directory (one with meta-clanton_v0.7.5/ directory).

Intel Galileo - Introduction

posted Oct 24, 2013, 12:59 AM by Sergey Kiselev   [ updated Oct 30, 2013, 9:34 AM ]

I've got my Intel Galileo board view days ago and started playing with it. I will be putting some useful information and my thoughts about this board in this blog.

Unboxing


The kit itself is nicely packaged and other than Galileo board itself it includes 5V/3A power supply, a collection of power plug adapters for various countries, four plastic standoffs, four screws, and a USB Type A to micro USB Type B cable (one you use to connect the board to a computer). The package also has a small thingy that plays Intel chime when Galileo board is removed.



Hardware Specifications

  • Processor: Intel Quark X1000
    • Supports Pentium (the original, P54C) instruction set, plus few newer features, such as support for XD (execute disable) bit and for various power states.
    • Runs on 400 MHz clock
    • Integrated USB Host interface with two ports. In Galileo one of the ports is routed to a micro USB connector and another one is connected to mini PCIe.
    • Integrated USB Device interface. It is connected to a micro USB connector.
    • Two PCIe lanes. On Galileo one is connected to mini PCIe, and another one is unused.
    • Two high speed SPI interfaces. One is used for ADC, another one is routed to ICSP connector.
    • One "legacy" SPI interface. On Galileo it is connected to a 8 MiB flash chip.
    • One I2C interface. On Galileo it is used for I/O expander, but I think it is also available on the Arduino headers.
    • SDIO interface. On Galileo connected to a Micro SD slot.
    • Two UARTs. One can be connected to the ports 0 and 1 on the Arduino headers. The other one is connected to a 3.5 mm connector.
    • Single channel DDR3 controller.
    • Built in Ethernet controller (less PHY).
    • A number of GPIO pins.
  • Memory:
    • 8 MiB SPI flash
    • 256 MiB DDR3
    • Micro SD card slot. (SD and SDHC types are supported, SDXC is not)
    • 512 KiB eDRAM inside the Intel Quark (as I understand it can be mapped to the CPU's memory space and used as a really fast memory)
    • Apparently Intel Quark has some built in firmware flash, not sure if and how it is used in Galileo.
  • Connectors:
    • Arduino-compatible headers. Since Intel Quark doesn't have enough GPIO pins and existing pins don't offer the same versatility as on ATMega micro-controllers used in the original Arduino board, Galileo uses several external ICs to emulate missing GPIO pins: I/O expander - Cypress CY8C9540A; ADC - Analog Devices AD7298; and several MUXes. Pins 3 & 4 are connected directly to the Quark processor, and can be used for high speed I/O.
    • 5V connector. Note Galileo doesn't have a voltage regulator on this input, and so it requires a regulated 5V power supply. Intel also recommends to always use an external power supply and don't rely on USB power from host. It is possible that 500mA USB can provide wouldn't be enough in some situations, for example if powering additional USB or PCIe adapters through the board.
    • Ethernet connector - 100Mbps/10Mbps
    • 3.5mm connector for serial port. It is the same type as used for headphones, but it is not an audio connector. This port is used by BIOS/UEFI for boot messages and also by Linux as a console. Default configuration is 115200 bps, 8 bit, 1 stop bit, no parity. Pinout is as follows:
      • Tip - Tx
      • Ring - Rx
      • Sleeve - Ground
    • Micro USB device port (type B connector)
    • Micro USB host port (type AB connector). I found it useful to have a micro USB to female USB type A adapter to connect USB devices with regular USB plugs. Ubiquitous OTG  (on the go) cables can be used too. (Note that port itself does not support OTG, and will work only as USB host).
    • An unnamed 7-pin header on the top right of the board. It appears to be connected to the SPI flash, and possibly can be used to re-program it.
    • ICSP header - connected to SPI port.
    • Micro SD card connector.
    • 2-pin header for RTC battery (the battery is optional)
    • JTAG connector.
    • Full size mini-PCIe slot.
  • Configuration Jumpers:
    • J2 - Changes the address of onboard Cypress I/O extender so that shields can use its address. The default address is 0x20, and currently the firmware only supports that address, and doesn't know anything about the jumper.
    • IOREF - Selects 5V (default) or 3.3V shields.
    • VIN - Connects VIN pin on Arduino's power header to the Galileo's 5V.
  • Switches:
    • Reboot - Reboots the firmware (Linux image running on the Galileo).
    • Reset - Restarts a sketch without rebooting the firmware.

Software

Galileo comes with a minimal, so called SPI Linux image programmed in the onboard SPI flash. The current image only allows execution of Ardunio sketches. It should be noted that the current firmware will not store sketch in the flash, so it will be lost on power cycle.
Intel supplies "Full" Linux image which can be installed on a micro SD card. It is far from being full, but at least offers wireless support, SSH daemon, etc.
Fortunately Intel supplies Board Support package, which among other things includes everything needed to rebuild the Linux image using Yocto.

Of course Intel also supplies modified Arduino IDE which supports Galileo. Sketches are getting compiled into regular Linux executable files, which are run as root on Galileo. One useful thing - it is possible to use "system" function in sketches to start processes on Linux (for example to configure the Ethernet using ifconfig, and start the SSH daemon).

Serial Console

Serial console is very useful especially if you want to play with firmware and Linux running on the board. A serial console cable is easy to make and requires basic soldering skills and a few components found in your local RadioShack store. Note that most newer computers don't have a serial port. In such case a USB to Serial adapter can be used (I am using an adapter like this).

Making a Serial Console Cable

You'll need:
  • 3.5 mm stereo plug, aka 1/8" plug (e.g. RadioShack 274-284)
  • DE9 female connector (e.g. RadioShack 276-1538)
  • Some wires (use different colors if possible).
  • Some heat shrink isolation
  • Soldering iron, solder, wire stripper or cutters.
Solder wires to connect 3.5 mm connector to DE9 as follows:
  • Tip of 3.5 mm connector - pin 2 of DE9 connector
  • Ring of 3.5 mm connector - pin 3 of DE9 connector
  • Sleeve of 3.5 mm connector - pin 5 of DE9 connector

Pin are usually numbered on DE9 connector - look for really tiny numbers molded in the plastic part of the connector.

Using Serial Console

  1. Install terminal emulator software. For Windows I personally like PuTTY which in addition to serial terminal also includes SSH and telnet clients. On Linux it is possible to use GNU screen or minicom.
  2. Install driver for your USB to serial adapter.
  3. Connect everything together: USB to serial adapter to the computer and to the console cable you made, console cable to your Galileo board.
  4. Start terminal emulator, and configure it as follows: 115200 bps, 8 data bits, 1 stop bit, no parity, no flow control. You will also need to configure serial port name. If using USB to serial adapter with Windows open Device Manager, expand Ports section, and note the port name (COM<some_number>) your USB to serial converter is using. For example to start GNU screen use something like screen /dev/ttyS0 115200,cs8 (replace /dev/ttyS0 with the actual serial port device name).
  5. Power on your Galileo, you should see UEFI boot messages, followed by GRUB menu, followed by Linux boot messages.
  6. Login to Galileo's Linux system using root as user name. By default root account doesn't have any password, but I really recommend setting one especially if you will be connecting your Galileo to the network.

1-10 of 10

Comments