6lowpan Gateway

My attempt to home automation and wireless lightning. The goal is to get a similar function compared to the “Philips HUE” system but open source, using 6lowpan and allow for more than light’s to be connected. I’ve currently designed two boards; the gateway and a small LED-driver / 6lowpan device.

On this page I’ve published the design for the “Ethernet – to – 6lowpan” gateway.

3D Model

3D model of the gateway board

The boards have been designed using kicad (http://http://kicad-pcb.org/). The PCB’s are 4 layers and components on one side only. The boards were manufactured by OSH Park and can be ordered here!

13071875_1108344995891328_598766305408386593_o (1)

Soldered gateway board

 

Some specs:

  • CPU: Atmel, AT91SAM9G25, ARM926-EJS, 400MHz
  • DRAM: DDR2, 128MByte
  • Flash: SLC NAND, 128MByte
  • Ethernet: 10/100 MBps
  • High speed USB, which is also used to power the board
  • 802.15.4 Transceiver: TI CC2520

All of the project files are stored on github, here: https://github.com/jonpe960/blixten

I’ve reflowed these board on a hotplate with a skillet. This method worked really well, even with the BGA -parts. For this reason the boards only have components on the top side.

I have access to an x-ray machine and took the following x-rays of the board:

As can be seen there is very little voiding. This is easily on the level you would get using a professional, standard, reflow process. The QFN:s all have ground via’s in the exposed pad which are tented on the bottom side. This can sometimes be problematic because solder will escape through the via’s or create out-gassing. The via’s are drilled 0.254mm then plated with, I’m guessing, 18µm gold and there is also some ingress of solder mask because of the tenting from the bottom layer.

This seems to be small enough to prevent this, at least on the few boards i’ve reflowed using this method.

Some of the solder balls on the DRAM are a bit gray, this is because those balls are note populated on the chip.

Screen Shot 2016-07-30 at 18.47.13.png

PCB Design

The board is designed with the following rules:

  • 0.15mm/0.15mm trace width/spacing, with the exception of a few places, but from what I’ve seen, the OSH Park process would work with 0.1/0.1mm
  • All routing is done on top and bottom layer
  • Layer 2 is a solid ground plane
  • Layer 3 is used for power distribution

The most challenging part to route is of course the DRAM, but this the external memory bus on these CPU’s run relatively slow which allows for relaxed requirements for impedance control, length matching and de-coupling.

The DDR traces on the top layer are referenced to ground on layer 2 and the trace on the bottom side are referenced to the 1.8V DRAM fill.

Schematic: https://github.com/jonpe960/blixten/raw/master/Blixten%20Gateway/Blixten%20Schematic%20R2.pdf

BOM: https://github.com/jonpe960/blixten/raw/master/Blixten%20Gateway/BOM.ods

The BOM is in libre office -format. There is an HTML version available in the git repo as well.

Screen Shot 2016-04-30 at 14.51.54

First boot :)

The u-boot / kernel are from the Atmel linux4sam repositories with some adaptation for this particular hardware.

OpenWRT felt like a suitable candidate for operating system. It seems to have a lot of bells and whistles that might come in handy for this router project.

13116522_1109779192414575_2782609531782732852_o

WPAN Interface up

All of the hardware is up and running, the CC2520 seems to respond and the driver is initialized.

Screen Shot 2016-07-30 at 19.10.07.png

LuCI Interface

OpenWRT comes with a nice Web interface (LuCI)

The complete source code is available here:

It is not possible to use the sam-ba tool on this board, at least unless you add/copy the DRAM setup from the at91bootstrap -repo and recompile the applets. However JTAG works well.

I had an old keil adapter which seems to work fine with openocd. I’m sure there are a lot of other, cheap, adapters that will work.

ulink2_lg

U-link 2 JTAG debugger

Openocd configuration that will initialize the DRAM and NAND flash:

################################
# Target:    Atmel AT91SAM9G25
######################################
if { [info exists CHIPNAME] } {
set AT91_CHIPNAME $CHIPNAME
} else {
set AT91_CHIPNAME at91sam9g25
}
source [find target/at91sam9.cfg]
# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).
adapter_khz 5
# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The
# AT91SAM9G25 has one 32kByte SRAM area, starting at 0x00300000.
$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x8000 -work-area-backup 1
set _FLASHTYPE nandflash_cs3
# Set reset type.  Note that the AT91SAM9G20-EK board has the trst signal disconnected.  Therefore
# the reset needs to be configured for “srst_only”.  If for some reason, a zero-ohm jumper is
# added to the board to connect the trst signal, then this parameter may need to be changed.
reset_config srst_only
adapter_nsrst_delay 200
jtag_ntrst_delay 200
# If you don’t want to execute built-in boot rom code (and there are good reasons at times not to do that) in the
# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has
# some powerful features, we want to have a special function that handles “reset init”.  To do this we declare
# an event handler where these special activities can take place.
scan_chain
$_TARGETNAME configure -event reset-init {at91sam9g25_reset_init}
$_TARGETNAME configure -event reset-start {at91sam9g25_reset_start}
# NandFlash configuration and definition
nand device nandflash_cs3 at91sam9 $_TARGETNAME 0x40000000 0xffffe014
at91sam9 cle 0 22
at91sam9 ale 0 21
at91sam9 rdy_busy 0 0xfffff800 5
at91sam9 ce 0 0xfffffA00 4
proc read_register {register} {
        set result “”
        mem2array result 32 $register 1
        return $result(0)
}
proc at91sam9g25_reset_start { } {
# Make sure that the the jtag is running slow, since there are a number of different ways the board
# can be configured coming into this state that can cause communication problems with the jtag
# adapter.  Also since this call can be made following a “reset init” where fast memory accesses
# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower
# jtag speed without causing GDB keep alive problem.
arm7_9 fast_memory_access disable
adapter_khz 2                   ;# Slow-speed oscillator enabled at reset, so run jtag speed slow.
halt                            ;# Make sure processor is halted, or error will result in following steps.
wait_halt 10000
#mww 0xfffffe08 0xa5000001       ;# RSTC_MR : enable user reset.
#mww 0xFFFFFE00 0xA500000B ;# Reset CPU
}
proc at91sam9g25_reset_init { } {
mww 0xfffffe44 0x00008000 ;# WDT_MR : disable watchdog.
# Enable the main 12 MHz oscillator in CKGR_MOR register.
# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.
mww 0xfffffc20 0x01370F01
while { [expr [read_register 0xfffffc68] & 0x01] != 1 } { sleep 1 }
echo 1
## PMC Clock generator PLLA register
# DIVA = 3
# PLLACOUNT = 0x3F
# MULA = 0xc7
# OUTA = 0
# PLLA Frequency = 12 MHz / DIVA * (MULA + 1) = 800MHz
mww 0xfffffc28 0x20C73f03
while { [expr [read_register 0xfffffc68] & 0x02] != 2 } { sleep 1 }
echo 2
        mww 0xfffffc30 0x00001300
        while { [expr [read_register 0xfffffc68] & 0x08] != 8 } { sleep 1 }
echo 3
# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.
# Wait for MCKRDY signal from PMC_SR to assert.
# System Clock = 800 MHz / 6 = 133MHz
# CPU Clock = 800 MHz / 2 = 400 MHz
#
mww 0xfffffc30 0x00001302
while { [expr [read_register 0xfffffc68] & 0x08] != 8 } { sleep 1 }
echo 4
# Switch over to adaptive clocking.
adapter_khz 100000
# Enable faster DCC downloads and memory accesses.
arm7_9 dcc_downloads enable
arm7_9 fast_memory_access enable
### Configure NAND
#
mww 0xFFFFFA04 0xffffffff
mww 0xfffffa74 0x3fef
mww 0xfffffc10 0x00000008
mww 0xfffffa00 0x00000030
mww 0xfffffa10 0x00000010
mww 0xfffffa30 0x00000010
mww 0xFFFFEA30 0x00020002
mww 0xFFFFEA34 0x04040404
mww 0xFFFFEA38 0x00070007
mww 0xFFFFEA3c 0x00030003
# configure NAND PMECC
### DRAM Setup
#
#
#
# CCFG_EBICSA
# Configure DRAM on EBI CS 1
# Set low drive strength
mww 0xFFFFDF20 0x0102000A
        # 0. Enable DDR2 Clock
        mww 0xfffffc00 0x4
# DDRSDRC_HS
# Disable Anticipated read access
mww 0xffffe82c 0x04
# DDRSDRC_MD
# 16-bit databus
# DDR-2
# According to the datasheet this value SHOULD be 0x14 for 16-bit DDR2!
mww 0xffffe820 0x16
# DDRSDRC_CR
#
# 10 col bits
# 13 row bits
# CAS 3
mww 0xffffe808 0x100039
## DDRSDRC_TPR0
#
mww 0xffffe80c 0x21222226
## DDRSDRC_TPR1
#
mww 0xffffe810 0x2c81312
## DDRSDRC_TPR2
#
mww 0xffffe814 0x1372
## DDRSDRC_MR
mww 0xffffe800 0x01 ;# NOP
mww 0x20000000 0x00
sleep 1
mww 0xffffe800 0x01 ;# NOP
mww 0x20000000 0x00
mww 0xffffe800 0x02 ;# All banks pre-charge
mww 0x20000000 0x00
mww 0xffffe800 0x05 ;# Extended load mode register
mww 0x24000000 0x00
mww 0xffffe800 0x05 ;# Extended load mode register
mww 0x26000000 0x00
mww 0xffffe800 0x05 ;# Extended load mode register
mww 0x22000000 0x00
## DDRSDRC_CR
mww 0xffffe808 0x1000b9
# Reset DLL
mww 0xffffe800 0x03 ;# LMR
mww 0x20000000 0x00
mww 0xffffe800 0x02 ;# All banks pre-charge
mww 0x20000000 0x00
mww 0xffffe800 0x04 ;# Auto refresh
mww 0x20000000 0x00
mww 0xffffe800 0x04 ;# Auto refresh
mww 0x20000000 0x00
        # DDRSDRC_CR
        #
        # 10 col bits
        # 13 row bits
        # CAS 3
        mww 0xffffe808 0x100039
       mww 0xffffe800 0x03 ;# LMR
        mww 0x20000000 0x00
        mww 0xffffe808 0x100739
       mww 0xffffe800 0x05 ;# eLMR
        mww 0x22000000 0x00
        mww 0xffffe808 0x100039
       mww 0xffffe800 0x05 ;# eLMR
        mww 0x26000000 0x00
       mww 0xffffe800 0x00 ;# Normal
        mww 0x20000000 0x00
## DDRSDRC_RTR
mww 0xffffe804 0x411
mww 0xffffe82c 0x04
sleep 1
mww 0x20000000 0xdeadbeef
mdw 0x20000000
nand probe 0
}

There is still a lot of software that needs to be written, this project is far from complete but the hardware and the linux stuff is working well.

Drop a comment if you like it :)

/Jonas

23 thoughts on “6lowpan Gateway

  1. Hello Jonas,
    Congrats for your work. It is amazing!!
    If you want, I can colaborate with you in the software side.
    I have some experience.

    Regards!

    • Thanks! You’re more than welcome, at the moment I don’t really have a solid plan on how I want the software to be structured. I think that some more testing and experimenting is necessary.

  2. Nice work you are doing here. I would be interested to see the LED driver boards on the other side.
    As one of the linux-wpan and wpan-tools developers I’m happy to see that you are using our project. :)

    You might run into trouble with the cc2520 transceiver on the Linux side though. Compared to other transceivers it misses a hardware accelerated automatic re-transmission based on ACKs. When driven by a MCU with RIOT or contiki this could possible be done in software but on the Linux side its not. The automatic re-transmission really gives a reliability benefit on L2 for IEEE 802.15.4.

    I would suggest you switch the transceiver to something like the at86rf233 to gain this capability.
    https://github.com/linux-wpan/wpan-tools/wiki/Driver-Features

    • Why would a Linux driver be incapable of including something like an automatic “do it again” type of feature? Are drivers not able to schedule another task after a time delay? Just curious really. I know nothing about writing Linux drivers. I only know STM32 + RTOS.

      • The question is not if the driver could do that (it could, but it would be rather the stack and not the driver handling this) but if the ACK could be send in the tight time frame specified by IEEE 802.15.4.

        For the 2.4 GHz PHY 802.15.4 defines macAckWaitDuration as 54 symbols which equals 864 micro seconds. Getting the frame out of the transceiver into the drivers, checking the ack request bit in the header, constructing the ACK, sending it and arriving in time at the original sender is nothing we think is possible with Linux. Granted, I never did a practical proof for this. :)
        We rely on the hardware to handle this for us. And all transceiver I have seen but the cc2420 and cc2520 do this in hardware.

        The problem now shows its ugly head if Node A send frames with the ack request bit set to Node B (our node here with the cc2510 and Linux). An ACK is requested but B is not able to send one back in time thus A will re-send the original frame as its thinks it was lost. The end result is that B receives every frame from A maxFrameRetries + 1 times.

    • Thanks! I’m waiting for the solder paste stencil, in a week or so I think I’ll make an update on the actual LED-board. I’ll look into the atmel part, thanks!

      • Other transceivers will work as well for you but given you already have other atmel chips on your design and the at86rf233 for example is well supported I thought it would fit.

        If you control all components of your 6LoWPAN network and do not experience packet loss you could also simply disable ACK request and the problem would vanish as well. As soon as there is a node requesting it though the problem is there again. And given that 2.4 GHz could be really crowed with WiFi, BT and your neighbors microwave oven I would recommend to use this 15.4 feature. :)

    • Yes, I used kapton stencils from OSH-park. The BGA:s are actually not that difficult, the ones I have on this board have 0.8mm pitch. The QFN:s and all the discrete parts 0402:s etc are more tedious to place and align.

  3. You have a really awesome work !! I would like to order it.

    I have a question about the JTAG socket on the board. Is it a normal one ? Do I need a special adapter for it ?

  4. Hey,

    could you move forward with this project?
    How can I send commands from the gateway to the “slave”? Is this already working (controlling leds over the gateway)?

    I would like to contribute on software side.

    Regards,
    Gabriel

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s