SpeedTouch 780 ConfigurationLast edited on Feb 25, 2012

The speedtouch 780 is a DSL modem combined with a 4 port managed switch/router, 1 FXO and 2 FXS. One great thing about this modem is that it is possible to telnet on the device and get access to a CLI. Using the CLI, one can achieve great things with this piece of hardware.

The specs will say that the FXO is a "Full-Mode" FXO. I don't know what they mean by that, but I was very disapointed when I used it. The FXO does not register itself with a PBX. Meaning that it is impossible to use it for placing outgoing calls or to receive calls using Asterisk (for example). You can setup a dialplan (in the device) that will allow certain numbers to be dialed directly on the FXO (i.e: 911) using the FXS ONLY! The FXO can also be used as a Fallback (for the FXS only) if registration with the PBX failed. It is then impossible to use the ST780 for PSTN access with Asterisk. For that purpose, I am using a SPA3102


This is just a sample of what I have. You will find the things I found to be the most usefull.


Before configuring this, make sure no one has a lease. In this example I am adding a pool named LAN_private. The addresses will be assigned on the interface LocalNetwork. Specifying the interface is very usefull when using several VLANs.

:dhcp server lease flush
:dhcp server pool config name=LAN_private intf=LocalNetwork poolstart= poolend= gateway= leasetime=21600 primdns= secdns=


This was hard to figure out. The way I am setup, I have two different VLANs. One which is the default VLAN (untagged) and the other one is tagged with ID 3. I have a Dell PowerConnect 3348 switch which has 24 port that belong in the untagged VLAN and the other 24 in VLAN3. Traffic comming from/goint to the switch for the untagged VLAN is plugged on ethernet port 1 of the st780. Traffic for VLAN 3 is also connected to ethernet port 1. The trunk comming from the switch thus transports both VLANs. I have two different DHCP pools for each VLAN so that they can be assigned different addresses in two distinct subnets.

I don't fully understand all this. All I know is that it works. I have searched everywhere and only found bits of information about that particular setup. I figured everything out by trying different stuff until it worked and trying to understand how to connect the dots between different setup I saw on other sites. Please feel free to contact me to inform me of any mistake I did here or to give me advices.

; Create vlan #3 named vlan3
:eth vlan add name=vlan3 vid=3

;Add the OBC interface in vlan3. disabling untagging will prevent the switch from stripping 
; off the tag of the incomming frame on that interface. I think that the OBC interface is the interface
; on which the router resides. If you don't add this interface in the VLAN, you won't be able to ping to router.
:eth bridge vlan ifadd name=vlan3 intf=OBC untagged=disabled

;Add the ethernet port 1 in the vlan #3. We want to preserve the VLAN tag. Untagged frames will be assigned
; the default VLAN (VLAN ID 0)
:eth bridge vlan ifadd name=vlan3 intf=ethport1 untagged=disabled

; Unttaged egress traffic on ethport1 will be tagged with VLAN ID "default" (0)
:eth bridge ifconfig intf=ethport1 vlan=default

; Create a new ethernet logical interface
:eth ifadd intf=eth_vlan3

; frames transmitted through this interface will be tagged with vlan3
:eth ifconfig intf=eth_vlan3 dest=bridge vlan=vlan3

;enable the interface (put it up)
:eth ifattach intf=eth_vlan3

; when using this ip interface, transmit using vlan3 logical ethernet interface. I'm not sure why I have to use the group "lan".
;  if I don't use that group, it doesn't work.
:ip ifadd intf=ip_vlan3 dest=eth_vlan3 group=lan

:ip ifattach intf=ip_vlan3

; when using this subnet, use vlan3 ip interface. 
:ip ipadd intf=ip_vlan3 addr=

; Add a second DHCP pool for the 2nd vlan
:dhcp relay add name=relay_vlan3
:dhcp relay ifconfig intf=ip_vlan3 relay=enabled maxhops=4 trusted=disabled
:dhcp relay modify name=relay_vlan3 addr = intf =ip_vlan3 giaddr =

I might be wrong here, but this is the way I understand it: When a frame comes in on an ethernet interface, it VLAN ID is looked at and the frame is forwarded to every ethernet port that belongs to that VLAN. When transmitting a packet on the subnet, the IP interface ip_vlan3 will be used. ip_vlan3 uses the logical ethernet interface eth_vlan3. When a frame is transmitted on eth_vlan3, it will be tagged with VLAN vlan3. Since ethport1 is a member of vlan3, the frame will be forwarded on it.

Port Forwarding

This is one of the easyest thing. No explanation needed here

nat mapadd intf=Internet inside_addr= inside_port=5060-5062 outside_port=5060-5062


My st780 is setup to register both FXS ports on my Asterisk PBX.

; Disable the service already provided by the device
:connection appconfig application=SIP SIP_ALG=disabled
:voice config digitrelay=rfc2833 rtp_portrange=10000-10100

;FIRST: delete current profiles
:voice profile add SIP_URI=username username=username password=your_password voiceport=FXS1

; is the address of the PBX
:voice sip config useragentdomain= primproxyaddr= primregaddr=
:service system modify name=VOIP_SIP state=enabled port=5060

;allow 2000ms between each DTMF before assuming that dialing is completed.
:voice fxsport config interdigitOpen=2000 interdigit=2000

; When a call comes in on the FXO, don't forward it anywhere. You could forward it to one of the FXS, but
;  not to your PBX unfortunately 
:voice fxoport config incfxodest=none

; the voice interface should use the ip interface ip_vlan3
:voice config intf = ip_vlan3

; any number between 3 and 14 digits long must be forwarded to the PBX without being altered. If VOIP cannot be accessed, (PBX down, 
power failure, ...) use FXO
:voice dialplan add prefix=0-8 defaultport=Voip fallbackport=FXO priority=Low fallback=enabled minimumdigits=3 maximumdigits=14 posofmodify=0 remnumdigits=0 rescan=no action=none

; 911 must be forwarded on the FXO directly
:voice dialplan add prefix=911 defaultport=FXO fallbackport=FXO priority=High fallback=enabled minimumdigits=3 maximumdigits=3 posofmodify=0 remnumdigits=0 rescan=no action=none

The other day, my PBX was down. I noticed that every outgoing calls were automatically sent on the FXO instead of the PBX. This is the way I want it (because of the "fallback" option). The odd thing was that incomming calls were not forwarded from the FXO to the FXS. This is one thing I will have to figure out.

NGW100 - My OSLast edited on Feb 25, 2012


This section describes the implementation of my OS at a high level. Not all of it is working right now but this is the basic idea.

Source code

You can download the current code but it is far from being complete.

The big picture

The OS is not meant to be an operating system like linux or windows where user application can run. The purpose is to provide a basic platform to implement different "firmwares". A firmware is a set of application in this context. Depending on what you want your NGW100 to be, you would run a different firmware (set of applications) that would drive the board through services provided by the OS.

The following picture describe what components will be handled by the OS.

The orange boxes represent modules that will be implemented in the future. The "EDX/LSE" is an OS specific component, don't try to find info about it in the datasheet. This is described here

Note how the USB controller, AC97 device, timers and several other devices are not represented in the graphics. This is because the OS won't take care of these devices. Drivers for these devices will be implemented as applications. So if I want to make my NGW100 device act as a USB storage device, I would have to write an application that implements the USB Mass Storage device protocol and use the file system module of the OS through the API. So building a router with my NGW100 would be a matter of developping applications that would run cooperatively like a serial shell app, packet-routing app, web-server app, usb mass storage app, etc.

Virtual file system

The OS will locate files using the following path structure: /0/dir/file. "/0" is the storage device number and the "/dir/file" is the path of a file on that storage device. The following storage devices will be recognized:

0Onboard Dataflash
1SD card


Booting is currently done with u-boot as I don't have a JTAG tool yet. Eventually, I would like to have it boot on its own. Since u-boot initializes stuff for me, I will be own my own when I take the step.

With u-boot, I am downloading the firmware trough a tftp server and I save the image in the parrallel flash at address 0x00100000. I then execute the code from address 0x80100000 (remember, 80000000 is mapped to 0x00000000). Executing from that address makes the code run in priviledged mode.

After the kernel will start running and all initialization is done, it will look in the dataflash for the boot script. This script contains a list of applications (located on dataflash or SD card) that should run at startup and a some other settings.

Boot script

This file will be located at "/0/boot.script". todo: not designed yet


The following is a list of things I am doing before attempting entering the idle loop in my OS

  • Reset some CPU settings to default. I looked at what u-boot was doing on reset and I do the same.
  • Configure the PM to enable PLL and run at 150MHZ.
  • Not sure what the SMC is, but I think I have to set it up in order to use ethernet devices
  • Initialize the EVBA and clear interrupt mask flag
  • Initialize SDRAM
  • Initialize the MMU
  • Initialize serial port

Memory Management


Physical memory usage

Physical memoryDescription
0x00000000 - 0x000FFFFFReserved (u-boot is in there) in parallel flash
0x00100000 - 0x0010FFFFKernel code in parallel flash
0x00110000 - 0x007EFFFFParallel flash. reserved by kernel. Unused yet
0x007F0000 - 0x007FFFFFReserved by u-boot (parallel flash)
0x00800000 - 0x0FFFFFFFINVALID
0x10000000 - 0x1000FFFFPage table(SDRAM)
0x10010000 - 0x11E73FFFprocess memory (SDRAM)
0x11E74000 - 0x11F09FFFgraphic memory
0x11F0A000 - 0x11FAFFFFreserved
0x11FF0000 - 0x11FFFFFFkernel buffers (SDRAM)
0x12000000 - 0x23FFFFFFINVALID
0x24000000 - 0x24000FFFKernel Stack (SRAM)
0x24001000 - 0x24007FFFKernel heap (SRAM)
0x24008000 - 0xFEFFFFFFINVALID
0xFF000000 - 0xFFFFFFFFMemory-mapped IO

Memory mapping viewed by kernel

Address rangeDescriptionRelation to physical memory
0x00000000 - 0x03FFFFFFINVALIDPage translated but not handled by OS
0x04000000 - 0x04000FFFKernel StackPage translated to SRAM
0x04001000 - 0x0400107FProcess TablePage translated to SRAM
0x04001080 - 0x0400108FUSART0 TX bufferPage translated to SRAM
0x04001090 - 0x0400109FUSART0 RX bufferPage translated to SRAM
0x040010A0 - 0x040010AFUSART1 TX bufferPage translated to SRAM
0x040010B0 - 0x040010BFUSART1 RX bufferPage translated to SRAM
0x040010C0 - 0x040010CFUSART2 TX bufferPage translated to SRAM
0x040010D0 - 0x040010DFUSART2 RX bufferPage translated to SRAM
0x040010E0 - 0x040010EFUSART3 TX bufferPage translated to SRAM
0x040010F0 - 0x040010FFUSART3 RX bufferPage translated to SRAM
0x04001100 - 0x0400117FReserved fo MMC driverPage translated to SRAM
0x04001180 - 0x04007FFFKernel heapPage translated to SRAM
0x04008000 - 0x7FFFFFFFINVALIDPage translated but not handled by OS
0x80000000 - 0x800FFFFFReserved (u-boot is in there) in parallel flashCached, Segment translated to flash
0x80100000 - 0x8010FFFFKernel code in parallel flashCached, Segment translated to flash
0x80110000 - 0x807EFFFFParallel flash. reserved by kernel. Unused yetCached, Segment translated to flash
0x807F0000 - 0x807FFFFFReserved by u-boot (parallel flash)Cached, Segment translated to flash
0x80800000 - 0x8FFFFFFFINVALIDN/A
0x90000000 - 0x9000FFFFPage tableCached, Segment translated to SDRAM
0x90010000 - 0x91E73FFFprocess memoryCached, Segment translated to SDRAM
0x91E74000 - 0x91F09FFFgraphic memoryCached, Segment translated to SDRAM
0x91F0A000 - 0x91FAFFFFreservedCached, Segment translated to SDRAM
0x91FA0000 - 0x91FAFFFFdataflash temp bufferCached, Segment translated to SDRAM
0x91FB0000 - 0x91FBFFFFmmc temp bufferCached, Segment translated to SDRAM
0x91FC0000 - 0x91FC017FMACB0 rx descriptor tableCached, Segment translated to SDRAM
0x91FC0180 - 0x91FC01DFMACB0 tx descriptor tableCached, Segment translated to SDRAM
0x91FC01E0 - 0x91FC19DFMACB0 rx bufferCached, Segment translated to SDRAM
0x91FC19E0 - 0x91FC31DFMACB0 tx bufferCached, Segment translated to SDRAM
0x91FC31E0 - 0x91FC31E3MACB0 current RX entryCached, Segment translated to SDRAM
0x91FC31E4 - 0x91FC31E7MACB0 current TX entryCached, Segment translated to SDRAM
0x91FC31E8 - 0x91FC31FFMACB0 net configCached, Segment translated to SDRAM
0x91FC3200 - 0x91FC337FMACB1 rx descriptor tableCached, Segment translated to SDRAM
0x91FC3380 - 0x91FC33DFMACB1 tx descriptor tableCached, Segment translated to SDRAM
0x91FC33E0 - 0x91FC4BDFMACB1 rx bufferCached, Segment translated to SDRAM
0x91FC4BE0 - 0x91FC63DFMACB1 tx bufferCached, Segment translated to SDRAM
0x91FC63E0 - 0x91FC63E3MACB1 current RX entryCached, Segment translated to SDRAM
0x91FC63E4 - 0x91FC63E7MACB1 current TX entryCached, Segment translated to SDRAM
0x91FC63E8 - 0x91FC63FFMACB1 net configCached, Segment translated to SDRAM
0x91FC6400 - 0x91FC67FFARP cacheCached, Segment translated to SDRAM
0x91FC6800 - 0x91FFFFFFreservedCached, Segment translated to SDRAM
0x92000000 - 0x9FFFFFFFINVALIDN/A
0xA0000000 - 0xBFFFFFFFSame as 0x80000000-0x9FFFFFFFSame as 0x80000000-0x9FFFFFFF but uncached
0xC0000000 - 0xDFFFFFFFINVALIDPage translated but not handled by OS

Memory mapping viewed by application process

Address rangeDescription
0x00000000 - 0x000000FFApplication stack
0x00000100 - 0x000001FFsupervisor stack
0x00000200 - 0x000002FFReserved
0x00000300 - 0x00000343Task context
0x00000344 - 0x000003FFReserved
0x00000400 - 0x01FFFFFFUser space. Size may differ, depending on allocated space
0x02000000 - 0x7FFFFFFFINVALID
0x80000000 - 0xFFFFFFFFAccess denied

Memory mapping viewed by system threads

Address rangeDescription
0x00000000 - 0x000000FFThread stack
0x00000100 - 0x00000143Task context
0x00000144 - 0x01FFFFFFReserved
0x02000000 - 0x7FFFFFFFINVALID
0x80000000 - 0xFFFFFFFFkernel space


The OS will use paging and segmentation at the same time. This means that the first 2gigs of addressing space will be separated in 4k chunks and remapped on the physical space in another way. More information on this can be found in the AVR32 architecture section of this site. Paging allows us to remap the memory in a non-contiguous way.

Application processes will use the SDRAM memory. Only the SRAM and SDRAM memories will be paged. The page table will be stored in the sdram and will be 64K in size (8192 pages). 8192 pages will allow us to maintain 4k pages for the reset of the SDRAM and the whole 32K sram. The sram pages will be used as the heap for the kernel and will be protected. The SDRAM pages will be set as private and will be associated with the owning process ASID. In the page table, a page entry will take 64bit in size. The first 32bit is going to be structured like TLBEHI. This 32bit field will allow us to find an entry on the table based on the requested page number and ASID. The last 32bit will be a copy of what should be copied in TLBELO when finding a match for TLBHI. The first 8 entries in the page table will be reserved for the SRAM. The rest of the entries will reflect the physical SDRAM space in the same order. The first 32bits of each entry do not have to be linear though.

Example Page table:

PageTable 1st 32bitsPage table last 32bits

The page table will also be used by the kernel to track available memory. A page with the "v" flag cleared means that this page is not reserved by any application so that 4k of memory is free. When allocating memory to a process, the "v" flag of the reserved pages will be set.


The scheduler will use a timer to switch task. A task switch will occur about 20 times per seconds. In order to switch tasks, the current context must be saved in the application space. The scheduler will perform the following tasks:

  • Go through the list of process and find the next one to be switched to in a round-robin fashion.
  • Using the stmts instruction, save all registers from ro to r14 to the application space buffer. stmts will save the registers from the application context. We will be executing from INT3 so registers r8 to r14 will be shadowed, meaning that even if we change them, stmts will pickup the right values that were assigned before entering INT3.
  • Save the RSR_INT3 register to the application space. RSR_INT3 contains the system flags before entering INT3. If the interrupt occured between a "cp.w" and a "breq", teh flags need to be preserved.
  • Save the RAR_INT3. This register contains the return address that rete is going to use to resume execution of the interrupted code.
  • Change the TLBEHI's ASID. Since we are switching context, the pages won't be mapped the same way. From now on, accessing the data in the application space will give us the data from the new application space.
  • using ldmts, restore R0-R14.
  • restore RSR_INT3
  • restore RAR_INT3, so we can use rete to resume the task.


The dataflash is accessed with the SPI bus. Since the dataflash is not a protable device and only the MCU can access it, it is a good opportunity to design my own file system. That memory will contain the boot script.

Dataflash file system

todo: not designed yet

NGW100 - Getting startedLast edited on Feb 25, 2012

Installing the development environment

I wrote this howto because everywhere I was looking , people kept talking about the "buildroot". I didn't want that. I just wanted the basic stuff to get me going and do standalone development without installing all the linux kernel files and libc etc...

First, download these files:

  • AVR32_Header_Files.zip
  • binutils-2.18.atmel.1.0.1.tar.bz2
  • gcc-4.2.2.atmel.1.1.3.tar.bz2

1 - compile binutils

./configure  --prefix=/opt/avr32 --program-prefix=avr32- --target=avr32-linux
make install

Now add the /opt/avr32/bin path in your PATH. I installed that in /opt/avr32 and all the applications are prefixed with "avr32-" (avr32-ar, avr32-as etc)

2 - compile GCC

mkdir build
cd build
../configure --target=avr32-linux --prefix=/opt/avr32 --enable-languages=c --disable-threads --disable-libmudflap --disable-libssp --disable-libgomp --program-prefix="avr32-"
make install

3 - copy the header files

Now unzip the header files in /opt/avr32/avr32-linux/include (the "include" folder will need to be created first)

4 - Make a test application

I made this code as a test application that flashes a led on the board. Compile it using this Makefile and see if it works

5 - upload the test application on your device

The first thing to do is to connect the board using a serial port. By default communication is established at 115200 8N1. when booting the device, you have 1second to press "space" to get in the uboot prompt. I connected the "lan" port of the device to my switch and entered the following commands:

setenv tftpip
setenv serverip
setenv bootcmd 'set ipaddr;tftpboot 0x24004000 firmware.bin;go 0x24004000'

the bootcmd variable tells uboot what to do at boot time. In this case, it will connect to the tftp server located at the address provided in 'tftpip' and download "firmware.bin" and store it at memory location 0x24004000. After that, it will jump to that address.

If you're trying to upload in flash memory, you need to unprotect a whole block, erase it and write to it. Blocks are 64k in size and alligned on 64k boundaries. So let's say we want to copy our firmware at 0x100000 (23rd sector in parallel flash chip) we would do the following. Assume that the firmware has been downloaded to 0x24004000 first and is 0x242 byte in size:

protect off 0x100000 0x10ffff
era 0x100000 0x10ffff
cp.b 0x24004000 0x100000 242
protect on all

AVR32 OS for NGW100Last edited on Feb 25, 2012

These pages are meant to describe the AVR32 architecture and how to do standalone development. This is basically a collection of notes that I am writting to help myself. Ususally I would do that in a text file on my computer but this time I said to myself "Why not share it with everyone?". It is hard to find information about this as everyone is talking about linux development everywhere. If you search on google, chances are that you will land on a forum where a guy asked the exact same question you were asking yourself and someone will have answered "Look on the internet" so you will be back to square one. So I decided to write my own web page as I learn to get my project going. Basically what I want to do is to build an OS for the NGW100 board.

Development is done in assembly language. It is easier to know what you are actually doing and it is more fun. You won't find a lot of resources on how to get you started with ASM for this CPU. Again, everyone is talking about Linux and C/C++, which is fine, but not usefull for what I am doing.

So I hope this information can be usefull to someone else. And if you see something wrong with what I am doing please tell me. I want this information to be accurate, and I want my OS to work.

That article does not exist