Archive for the ‘Embedded’ Category

Configure Nordic Softdevice to Support Custom BLE Profile with Multiple Services and Characteristics

August 8, 2016

My recent BLE project involves developing a custom peripheral profile for a 9 DOF sensor fusion embedded system with multiple sensors, such as accelerometer, gyroscope, magnetometer, and altimeter, etc. The system employs a nRF52 BLE module to transfer raw sensor data, plus calculated sensor fusion data, to a BLE central device, namely an iOS/Android mobile device, or a desktop computer with BLE capability, such as OSX or Windows 10 PC.

Softdevice is Nordic’s BLE stack implementation. The nRF52 softdevice is named s132. The project uses the recent nRF5 SDK version 11.0.0 released in March 2016 for development.
This version of SDK comes with version 2.0.0 softdevice s132.

By default, s132 supports one custom service and reserves memory for some characteristics. When you dig into the softdevice’s header files, you can find that reserved memory size is 0x580. My experiments tell me that amount of memory can support over one dozen of characteristics. That’s good in many situations, but not enough for my project, which requires 3 custom services and 42 characteristics, including many with notification.

Fortunately the softdevice is architectured in such way that it can be configured in runtime to meet application developer’s need.
There are couple of example projects in nRF5 SDK use multiple custom services, but there is none about expanding the reserved memory to support many more characteristics.
Hopefully my experience mentioned here is of useful for people needs more characteristics, and save some of their time to avoid troubles I had.

The screenshot below shows all services and characteristics of the custom BLE profile designed in BDS. BDS (Bluetooth Developer Studio) is Bluetooth SIG‘s design, development and testing tool. Many vendors, including Nordic and TI, provide BDS plugins. A vendor’s plugin can be used to generate certain code for its platform, saving tremendous amount of time for developers. For example, with this shown design, Nordic version 1.2.4 plugin generates 6,393 lines of code in multiple source files. Imagine how long it may take coding all of this manually. I will cover BDS in more details later in a separate blog.

em-sfm_bds

 

Here’re the steps I used to configure the softdevice to meet the project requirement.

  1. Configure the count of custom services
    According to Nordic programming convention, softdevice configuration is done in the following function:

        static void ble_stack_init(void)                                    
    

    To specify the number of supported custom services is easy. The following code snippet sets up 3 services:

        ble_enable_params_t ble_enable_params;
        ble_enable_params.common_enable_params.vs_uuid_count = 3;           
    

     

  2. Configure the attribute table size
    Set up attribute table size is trickier, and I don’t think Nordic provided any such example in nRF5 SDK.
    In my instance, I added 0x700 more bytes of memory to support 42 characteristics. The reason is the default memory size of 0x580 supports 17 characteristics, and it supports 9 more characteristics after the size is adjusted to 0x800.

        /* 0x580 added by 0x700 */
        ble_enable_params.gatts_enable_params.attr_tab_size = 0x0c80;        
    

    Here’s the complete function:

    /**@brief Function for the SoftDevice initialization.
     *
     * @details It initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        uint32_t err_code;
        
        nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
        
        // Initialize SoftDevice.
        SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
        
        ble_enable_params_t ble_enable_params;
        err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
                                                        PERIPHERAL_LINK_COUNT,
                                                        &ble_enable_params);
        APP_ERROR_CHECK(err_code);
        
        /*
         * Supports 3 custom services
         */
        ble_enable_params.common_enable_params.vs_uuid_count = 3;
    
        /* 0x580 added by 0x700 */
        ble_enable_params.gatts_enable_params.attr_tab_size = 0x0c80;
    
        //Check the ram settings against the used number of links
        CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);
        // Enable BLE stack.
        err_code = softdevice_enable(&ble_enable_params);
        APP_ERROR_CHECK(err_code);
        
        // Subscribe for BLE events.
        err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
        APP_ERROR_CHECK(err_code);
    }
    

     

  3. Configure the user application memory location and size
    The last key step is to update the linker script to adjust the offset and size of the memory available to the BLE peripheral application.
    I’m using GNU/Eclipse toolchain, the idea is the same when MDK or IAR is used.
    Here’s the default MEMORY section’s RAM attribute values of the linker script:

      RAM (rwx) :  ORIGIN = 0x20002080, LENGTH = 0xdf80               
    

    Here’s the modified values. Basically it moves forward the memory offset by the memory amount added (0x700), and reduce the available memory size by the same amount to make sure there is no overlap between softdevice and application memory regions.

      RAM (rwx) :  ORIGIN = 0x20002780, LENGTH = 0xd880                
    

    Note the up end of the RAM region is 0x20010000 (0x20002080+0xdf80, or 0x20002780+0xd880). Consider RAM origin starts at 0x20000000 for the softdevice, 0x10000 (64KB) is exactly the size of nRF52 RAM.

    Here’s the complete linker script:

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x1c000, LENGTH = 0x64000
      /* 0xc80 = 0x580 + 0x700 */
      RAM (rwx) :  ORIGIN = 0x20002780, LENGTH = 0xd880                
    }
    
    SECTIONS
    {
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
    } INSERT AFTER .data;
    
    INCLUDE "nrf5x_common.ld"
    

Nordic just released s132 softdevice v3.0.0 in August 2016, I will migrate soon and find out more details about the release.

Using Motion Detection To Wake Up Embedded System – A Practical Example

February 2, 2016

Put the embedded system into sleep while not in use is a must have for any battery powered applications.The tricky part is how to wake up the system if it has no peripherals, such as switch, to interact with. Using motion detection to wake up the system is a natural choice.
The example demonstrated here uses a digital accelerometer via I2C interface for motion detection. The accelerometer is configured to generate interrupts after motion is detected. The motion interrupt then wakes up the system from the deep sleep mode.
The following hardware, software and system configurations are used in the project. The custom KL03Z board is designed by Embedded Masters, other parts not used in the demo are not mentioned here. EFM32 Giant Gecko board and Simplicity Studio is optional and only used for Power/Energy Profiler.

Hardware Description
Freescale Kinetis Custom Board KL03Z MCU (Cortex-M0+ 48MHz, 32KB flash, 2 KB SRAM)
MMA8652 3-Axis 12-bit Digital Accelerometer
RGB LEDs
Silicon Labs EFM32 Giant Gecko (STK3700) Run Power/Energy Profiler
Segger JLink Debugger Program and/or Debug Kinetics MCU based hardware
Software Description
Freescale KDS 3.0 Freescale Kinetis MCU Eclipse IDE
Freescale KSDK 1.3 Kinetis SDK
Silicon Labs Simplicity Studio v3 Run Power/Energy Profiler
System Configuration Description
LPO Internal low power oscillator(1000Hz) works in very low power/leakage modes
LPTMR Low power timer with prescaler 3 to accommodate timer period up to 17.6 minutes
Clocking by LPO
I2C Baud rate 100Hz
MMA8652 Configured in Free-fall/Motion detection mode
Enable motion detection interrupt 2
Route motion detection interrupt 2 pin to PTB0 per KL03Z datasheet
PMC (Power Management Controller) VLPR (Very Low Power Run) mode while the system is up
VLPS (Very Low Power Stop) mode while in deep sleep
LLWU (Low Leakage Wakeup Unit) Route LLWU wake-up source pin P4 to MMA interrupt 2 pin
RGB LEDs Active-low

The key is to configure MMA8652 motion detection interrupt 2 and LLWU P4 to share the same pin such that the motion detection becomes the wake-up source. The following picture shows the KL03Z data sheet about how pins are assigned.

Pin Assignment

This is the application code blinks red and green LEDs 5 times before entering the sleep mode, and blinks blue LED once after waking up. Wakeup source is a 5 second timer and/or motion detection.

Application Code
/*!
 *  @brief Enter deep sleep mode, and use timer/motion detection to wakeup
 */
void enter_sleep()
{
    /*  Step 0 - Init MMA */
    mma8652_init( &i2c_devices, 0 );
    /* Step 1 - enable LPO timer to make it another wake up source (5s) */
    timer_set_period( 5*1000, true );

    /* Step 2 - Enable motion detection interrupt */
    enable_motion_interrupt( true );

    /* Step 3 - Switch to deep sleep mode VLPS */
    /* Using motion detection/timer as the wakeup sources */
    pmc_sleep( true, true );

    /* Step 4 - Exiting sleep mode */
    /* timer is reenabled by pmc_sleep call */
    /* disable motion detection interrupt */
    enable_motion_interrupt( false );
}

/*!
* @brief Main routine
*/
void main (void)
{
    hardware_init();
    /* initialize peripherals */
    peripheral_init();

    while(1)
    {
        for(int i=0; i<5; i++ )
        {
            LED1_ON;
            LED2_ON;
            delay100ms(1);
            LED2_OFF;
            delay100ms(1);
            LED1_OFF;
            delay100ms(1);
        }

        enter_sleep();
        LED3_ON;
        delay100ms(2);
        LED3_OFF;
        delay100ms(5);
    }
}

The following screenshot is taken from Simplicity Studio/Energy Profiler running session. It clearly indicates the system behavior and power consumption.
Power Profiler

This video clip shows the complete running, including power profiling process.

After much efforts, include working with Freescale FAE and applying some tricks listed in chip’s errata, the system consumes about 10uA while in sleep in VLPS mode.

Altera MAX10 DECA Board Fun Projects – Part 1 Graphics

September 22, 2015

DECA, a new Altera MAX10 FPGA evaluation board from Arrow/Terasic, is the most versatile low cost FPGA board I have.
I’m planning to write a series covering some projects for DECA, and the graphics is the first topic.
I’m using Quartus 15.0 for Linux Update 2 for the projects.

Here’s some details about the DECA.
DECA_Board
Currently it sells for $169. Arrow holds a series of global workshops covering DECA since May 2015.
The small form factor FPGA board packs with features:

  • High end MAX10 device with 50,000 LEs, and pin count 22×22
  • 4 PLLs
  • Dual ADCs
  • 512MB DDR3
  • 64MB Flash
  • 10/100 Ethernet
  • USB2.0 OTG
  • SDHC
  • HDMI v1.4 Transmitter
  • MIPI CSI-2
  • 24bit Audio
  • 2 SMA inputs
      Various sensors

    • Gesture, Proximity/Ambient light
    • Humidity and temperature
    • Power monitor
    • Accelerometer
  • BeagleBone I/O expansion headers

The board I have is an evaluation kit comes with a wireless WiFi/BLE BeagleBone Cape and a 8M camera module. In my opinion, BeagleBone I/O expansion makes many kinds of interesting DIY projects possible.

The graphics for MAX10 is implemented in VIP (Altera Video and Image Processing Suite IPs).
The following block diagram shows the FPGA setup and software processes for graphics rendering.
DECA VIP Graphics
There are some challenges, the tough hardware and software ones are listed below:

  • Choosing proper parameters for VIP components to generate proper video timing signals
  • Low graphics rendering frame rate. In 1024×768 resolution, HMI application’s rendering performance is in the range of couple frames per second.

Hardware Challenges

To address the video timing issue (i.e., pixels drawn to the screen are not properly displayed), different parameters are tried to configure IP cores. This design uses DDR3 controller with 64 bit Avalon interface data width. The Frame Reader IP (VFR), which converts user graphics/image/video data stored in external memory to a video stream understood by VIP, should have the same master port data width as the DDR3 controller. According to the VIP user guide, VFR’s control register “Frame Words” should be “The number of words (reads from the master port) to read from memory for the frame”.
VFR Registers
To calculate the “Frame Words”, VFR pixel counts is used as the dividend and 2 (64/32) as the divisor. This configuration worked for one resolution, but not in other resolutions. Different VFR’s master port widths were tried (32 and 128), but had the same result. After days of struggles, I finally settled down the proper parameter combination working with all 640×480, 800×480 and 1024×768 resolutions.

IP Parameter Value
DDR3 Controller Avalon Interface Data Width 64
Frame Reader Master Port Width 256
Color Plane Sequencer Halve Control Packet Width disabled

Other key things I learned from hardware perspective:

  • With the current configuration, it can only have up to two VFRs in the design, or Quartus Analysis & Synthesis, namely quarts_map, will crash. I believe the reason is the hardware resource limitation from the parts used in DECA
  • To get correct DDR3 pin assignments and interconnects, run deca_vip_mem_if_ddr3_emif_p0_pin_assignments.tcl at least once, after Analysis & Synthesis but before Fitter (Place & Route) compilation. The reminding notice is buried in synthesis compiling messages.

Software Challenges

The graphics software demonstration is done in uCOS II environment, it has 3 tasks. The main task performs HMI (Human-Machine Interface) displaying 640×480 automotive glass cluster.

HMI GlassCluster

The other rendering task draws two vertical and horizontal bars in 800×480 screen. The third task moves the main HMI screen.
When the HMI screen is in 1024×768 resolution, the rendering frame rate is in the range of 1 to 2 fps. If the resolution is reduced to 640×480, fps improves but is still slow. Further investigation indicates the performance issue lies within HMI code itself, not necessary due to VIP or graphics implementation.
HMI code used is based on Altia’s proprietary framework.
In theory, the graphics hardware has enough bandwidth to drive a 640×480 32bit/pixel screen approaching 30 fps.
The following NIOS II Eclipse screenshot shows assembly and C code snippet of a pixel filling routine.
Pixel Filling
The Nios II Gen 2 softcore is clocked by a 100MHz PLL. Assuming in a best scenario, there is no CPU pipeline stall, no RTOS context switch, and one clock cycle per instruction.
The inner loop (j loop) takes:
2 + ( 2 + ( 5 + 6 ) * inner_loop_count ) cycles.
The outer loop (i loop) takes:
( 2 + ( inner_loop_cycles + 7 + 6 ) * outer_loop_count ) cycles
Therefore to update 640×480 pixels screen, cycle total needed is 3,388,320, or it takes about 33ms or in 30 fps. This is a simplified case, the actual frame rate depends on rendering content and will be of course much lower.
VFR supports two frame buffers, and the feature is very useful for double buffering. While displaying the front buffer, you can build scene in the back buffer and swap the buffers when the back buffer building is done. Although it won’t improve rendering performance, the technique effectively eliminates video flickering. The demo code for the drawing task uses the approach.

The hardware design, software demo code and HMI library, plus prebuilt FPGA bitstream and application binary are available at:
https://github.com/fpga4fun/deca_graphics
Note: I don’t have commercial VIP license, the prebuilt bitstream is time-limited.
You may need turn off and then on the HDMI monitor for the monitor to pick up the video signal (at least for the Sceptre monitor I’m using).

This video clip shows the complete process to configure FPGA, download and run graphics demo from command line, and debug the code from Eclipse for Nios.

The graphics design is now at Altera Design Store as
DECA Graphics Design Example

A Supercomputer for only $100 – The Kickstart project Parallella

October 26, 2012

Check out Kickstarter project Parallella

Parallella, a personal supercomputer, is using Zynq 7010 FPGA SoC as the host, and Epiphany 16- or 64-core Microprocessor as the accelerator.
Adapteva, owner of the Epiphany technology, already has a SDK, and OpenCL SDK (beta). Parallella would be very useful for embedded vision, SDR, HPC and many other computation intensive projects.

The following diagram shows Parallella specification.

The Kickstarter goal is $750,000, and it ends on 2012-10-27. At the time of writing this post (2012-10-25, 23:33 MDT), there are 3,325 backers, and $578,542 pledged.
I pledged $99, and if you’re interested, please do the same. There are less than 2 days left to make it a success.

Vivado 2012.1

May 11, 2012

When I installed ISE 14.1 System Edition, I found Vivado 2012.1 comes with it.

I will contact Xilinx and Avnet FAEs to see if I could get early access license.

Vivado 2012.1

I’m told Vivado public access will be in July.

Some Zynq related Announcements

March 28, 2012

There are many workshops, demos, announcements about Zynq from DESIGN West.

One of the announcements is from iVeia about the availability of its Android Distribution for Zynq.

The other one is from Adeneo about reference Windows Embedded Compact 7 BSP for Zynq.

Configure FPGA/SPI Flash to Run Linux on LX9 MicroBoard, Part 1 – Preparation

October 17, 2011

This is Part 1 for the topic, to prepare configuration data for LX9 MicroBoard.

The FPGA design is done with ISE 13.2 based on AXI/Little Endian MicroBlaze 8.20a. The details were presented here at Run Linux on Avnet Spartan-6 LX9 MicroBoard.

The Linux kernel is built with Petalinux SDK 2.1. You may contact PetaLogix to obtain a license and SDK to try out. If you prefer Xilinx’s embedded Linux solution, you can find useful information from its Open Source Wiki. From configuration point of view, it makes no difference which one is used.

The keys to prepare the configuration data are:

  • understand how SPI Flash is partitioned
  • understand how each partition is used
  • make sure proper sizes for partitions, especially for the partition where Linux is at

You may need build kernel more than once, if you don’t know the kernel size beforehand. For example in the second build, you can adjust partitions to fit Linux into flash.

Here’s Flash partitions used by Petalinux, and sizes are modified because of 11MB kernel. Note SPI Flash on the MicroBoard has 256 64KB blocks, total space is 16MB.

Partition Name Size (blocks) Flash Address Usage
0 fpga 2MB (32) 0x0 bitstream and fs-boot
1 boot 256KB (4) 0x200000 u-boot
2 bootenv 128KB (2) 0x240000 u-boot environment variables (not used here)
3 config 128KB (2) 0x260000 used by flatfsd to store persistent data, required but not used by configuration
4 image 12.5MB (200) 0x280000 Linux kernel and filesystem
5 spare 1MB (16) 0xf00000 remaining space (not used here)

Here’s how partitions are specified in kernel configuration (System Settings -> Flash Partition Table -> Image Partition Size).

System Settings

Flash Partition Table

Image Partition Size

Once the kernel is rebuilt, along with the outputs of FPGA bitstream from ISE/EDK, and U-Boot from XSDK, the following files are used to construct configuration data, and/or bootstrap Linux:

File Description Built by Usage
system_bd.bmm BRAM memory map ISE/XPS to generate download.bit by script d2m
mb_system_top.bit design bitstream
fs-boot_0.elf fs-boot XSDK
u-boot.elf u-boot executable Petalinux SDK not used by configuration, but useful to transfer images to Flash
u-boot-s.bin u-boot relocatable binary to generate sopc_lx9.mcs by script pgen.ub
image.ub Linux kernel and filesystem binary

This is the script d2m, a wrapper of data2mem:

d2m
#!/bin/sh
data2mem \
  -bm mb_system_bd.bmm \
  -p xc6slx9csg324-2 \
  -bt mb_system_top.bit \
  -bd fs-boot_0.elf \
  tag microblaze_0 \
  -o b download.bit

This is the script pgen.ub, an wrapper of promgen:

pgen.ub
#!/bin/sh
promgen -w \
  -p mcs \
  -c FF \
  -o sopc_lx9 \
  -s 16384 \
  -u 0000 download.bit \
  -data_file up 200000 u-boot-s.bin \
  -data_file up 280000 image.ub \
  -spi

The following capture summarizes the procedure to generate configuration data.

Generate Configuration Data

If you would rather prepare PROM from iMPACT GUI, here’re the steps (Note, the files could be at any folder).
Launch iMPACT and select “Prepare a PROM File”.

Prepare PROM File

Select and Enter as following (highlighted).

Prepare PROM Steps

Add device bitstream.

Add Device Bitstream

Add 2 data files.
The first one is U-Boot, and make sure it is at proper address on Flash, in this case it is 0x200000.

U-Boot Flash Address

Add U-Boot

The second data file is Linux kernel and filesystem. Make sure the Flash address is set to 0x280000.

Kernel Flash Address

Add Kernel

Here’s the resulting data file assignment.

Data File Assignment

Proceed to generate configuration data.

Generate File

You can find scripts and source data files from here.

As a side note, when people move to high end FPGA solutions with processor integration, as Xilinx calls Zynq as EPP (Extensible Processing Platform), and Altera calls SoC FPGA with HPS (Hard Processor System), there is less or no need, in a sense, to configure FPGA from persistent storage such as Flash. The processor can easily make bitstreams and software images available to FPGA.
For large volume and low cost applications, soft-cores such as MicroBlaze and Nios are good solutions, and configuration is still needed.

Configure FPGA/SPI Flash to Run Linux on LX9 MicroBoard, Part 3 – Easy Way

October 15, 2011

This is Part 3 for the topic.
In Part 2 – Quick Way, network connection and tftp server, plus certain knowledge of U-Boot are needed. You can avoid them by just using iMPACT to program the FPGA/SPI Flash. Here’s how.

On the host with Xilinx design tools installed, navigate to the folder with following files.

File Description Usage
sopc_lx9.mcs configuration data program FPGA/SPI Flash
impact.cmd programming script for Xilinx USB II cable (6MHz)
impact.12Mh.cmd programming script for Xilinx USB II cable (12MHz)
impact.onboard.cmd programming script for Digilent Onbard JTAG

Program FPGA/SPI Flash by running iMPACT in batch mode.

USB II Batch Program

The Linux kernel and u-boot has a size about 10MB (still have some rooms left for 16MB Flash, I could see many potentials there), and FPGA/fs-boot has only 336KB. The final MCS data triples the size (in ASCII format).
It takes about 68 minutes on my Linux host, including verification. Program alone may take about 43 minutes, by using default JTAG clock speed, 6MHz.

USB II Program Done

With impact.12Mh.cmd, it takes about 35 minutes. iMPACT complains 24MHz is not supported.

Program at 12MHz

I also tried several times to program by using MicroBoard’s Onboard USB/JTAG. It is supposed to be running fast (in 15MHz?). By 1) modifying Avnet Tom’s script listed in LX9 board forum Remarks on AvtS6LX9MicroBoard_SW302_PetaLinux, and 2) by iMPACT GUI, but I was never able to go to the end. I remembered once I let it run overnight from GUI, it was less than half way through in the next morning, and I had to abort the process.
It could be I didn’t specify options correctly. I attach the programming script for Onboard JTAG, just for reference, but be warned, don’t try it, it may take forever to program.

If you’re more interested at programming through iMPACT GUI to have a good understanding what’s going on, here’re some screenshots.

Start iMPACT by choosing “Configure devices using Boundary-Scan (JTAG)”.

Configure Devices

Select “No” for “Auto Assign Configuration Files Query Dialog”.

No for Auto Assign

Right click the device from “Boundary Scan” tab to add SPI Flash.

Add SPI Flash

Select attached SPI Flash (N25Q128 1.8/3.3V).

Select SPI Flash

Right click added SPI Flash device and select “Program”.

Program

It achieves identical result as running the script in batch mode, and takes about the same time to finish.

If you’re interested, here’s the link for scripts and configuration data.

Configure FPGA/SPI Flash to Run Linux on LX9 MicroBoard, Part 2 – Quick Way

October 13, 2011

This is Part 2 for the topic, I will present Part 1 (Preparation) after Part 3 (Easy Way) is done.

Petalinux is using a 2-stage booting process. The First Stage boot, FS-Boot, is running from FPGA’s BRAM once powered on. It’s sole responsibility is to load the main system bootloader, i.e., U-Boot, from the flash to the larger external memory, and run U-Boot from the external memory.

One of the quick ways to configure FPGA is to copy binary images to the flash, instead of programming it, which could take significant time depends on programmer used.

In order to do that, networking connectivity and a mechanism to deliver and retrieve images are required.
As used by almost everyone, I’m using tftp. The host runs tftpd is connected to the LX9 MicroBoard via a router.

The following images are needed.

Image Description Usage
download.bit bitstream plus fs-boot binary FPGA and fs-boot image on flash
u-boot.elf U-Boot in ELF format to transfer u-boot-s.bin and image.ub to flash
u-boot-s.bin relocatable U-Boot in binary format U-Boot on flash
image.ub Linux kernel and root filesystem in binary format Linux on flash
impact.cmd script for impact (not required) transfer download.bit
xmd.ini script for xmd (not required) run u-boot.elf

I am using Platform Cable USB II programmer, usb/uart port is directly connected to the host via minicom.

This is the board connection

Board Connection

Start tftp daemon, and point the working folder to where the above files are.

Start tftp Daemon

Start tftp

Next step is to program FPGA through impact. If you’re using Digilent’s HS1 or onboard JTAG connection, your script should be different.

Program FPGA through impact

Program FPGA

Then download and run U-Boot through xmd. If you’re using Digilent’s HS1 or onboard JTAG connection, your script should be different.

Download and Run U-Boot through xmd

Download and Run U-Boot

If the flash is programmed already, stop the autoboot process from the uart port console, in order to move new U-Boot and Linux to the flash.

Stop Autoboot from uart console

Stop Autoboot

Now it is time to copy Linux kernel and U-Boot to flash. But before doing that, IP addresses for the tftp server (host) and the board (target) need be set. Your IP addresses could be different the ones used below.
Here’s how to do it and copy the Linux kernel (image.ub) to the flash.

IP Addresses setup and copy Linux kernel

IP Setup and Copy Kernel

Then copy the U-Boot.

Copy U-Boot to Flash

Copy U-Boot

Now if everything goes well, you can run Linux by either hitting the reset button or issuing boot command from U-Boot prompt.

Booting Petalinux

Booting

Here’s the booted console, and SPI flash’s partitions.

Booted Console and SPI Flash Partitions

Booted Console and SPI Flash Partitions

You can find listed binary images and scripts here.

Run Linux on Avnet Spartan-6 LX9 MicroBoard

September 6, 2011

AV-LX9 MicroBoard is a new low cost Spartan-6 LX9 device based development kit from Avnet. XC6SLX9
has 1,430 slices, or 5,720 LUTs, and 32 Block RAM. Rich features, such as 64MB DDR, 128Mb SPI Flash, 10/100 Ethernet PHY, USB-UART port, JTAG, LEDs, DIP switches and expansion ports, make the board an affordable and very useful experimental prototyping tool.

Thanks for Avnet’s Frank for the LX9 MicroBoard, I was lucky to be able to try out the board early. My main goal was to get Petalinux running on this this USB-stick form factor board, with httpd server serving web pages and certain peripherals to demonstrate user defined functionalities. After many weekends’ efforts, I was always couple hundreds of LUTs in short to fit designs of MicroBlaze with MMU into LX9 device, even after removing most peripherals, and enabling Legalizer placement algorithm.

Then Petalogix’s John offered me a Linux BSP, used for hobby purpose. This convinced me the goal was possible, and kept me trying my own SOPC designs.

Finally I got it working before the recent Avnet LX9 MicroBoard SpeedWay Design Workshops. The keys were to remove non-essential MicroBlaze features and not use MDM’s JTAG-based UART thus saves a AXI4-Lite connection. I am sure it can go further to use less resources and/or add more peripherals, but still has a stable Linux running on the board.

Here’s how the working design was done in details. I am using PetaLinux SDK 2.1 and ISE 13.2 for 32 bit Linux, starting design flow from Project Navigator.

Create a new project based on Avnet LX9 MicroBoard XBD.

Create New ISE Project

Select Embedded Processor for Source Type with New Source Wizard.

Select Source Type

When BSB starts, choose AXI flow.

AXI Flow

And configure below processor, cache and peripherals.

Processor, Cache and Peripheral Configuration

Once XPS project is created, configure MicroBlaze by double clicking the IP from System Assembly View.

MicroBlaze with MMU Configuration

After select MMU configuration, click Advanced button to fine tune. The following setups can be done by going back and forth to enable then disable certain features. Here’s General configuration.

MicroBlaze General Configuration

Disable all exceptions.

MicroBlaze Exception Configuration

Make sure instruction cache base address is setup properly. This is the location where Linux kernel starts.

MicroBlase Cache Configuration

Here’s MMU setup.

MicroBlaze MMU Configuration

Enable MDM so XMD can be used to debug.

MicroBlase Debug Configuration

No need for Processor Version Registers.

MicroBlase PVR Configuration

Here’s the Interconnection I used.

MicroBlaze Interconnect Configuration

Buses setup is the last MicroBlaze configuration.

MicroBlaze Buses Configuration

Now configure MDM by disabling JTAG UART.

MDM Configuration

Here’s XPS System Assembly View when design is done.

XPS System Assembly View

Return to Project Navigator when XPS is closed. Add constraints by Project > Add Copy of Source.

ISE Add Constraints

Double click Generate Top HDL Source to create HDL instantiation template for the MicroBlaze design.

ISE Generate Top HDL Source

Export hardware design to SDK.

ISE Export Hardware To SDK with Bitstream

If there are errors for placement and routing, try to set environment variable XIL_PAR_ENABLE_LEGALIZER to 1, and rerun PAR.

Here’s my XPS Synthesis Summary (estimated).

XPS Synthesis Summary

Here’s partial ISE Device Utilization Summary.

ISE Device Utilization Summary

Follow PetaLinux SDK Board Bringup Guide to configure software settings of the hardware project and fs-boot.

I am using the following XMD commands to configure FPGA and download Linux image.

This is the PetaLinux login screen.

PetaLinux Login Screen

And PetaLinux Process Status.

PetaLinux Process Status

Another fun experiment is to write code to turn on and off LEDs in certain patterns. 4 bit LED IP’s address is 0x40000000, to turn on all LEDs, you can use:

poke 0x40000000 0x0f

Let me know if you’re interested running my design, I have it here. If you like to try the commercial PetaLinux, please contact Petalogix.