Zigbee, NXP, Jennic in module (JN5168-001-Myy)

2341778-40

Via customer I got few JN5168-001-Myy modules. It’s a Zigbee module by NXP. Since I never really worked with Zigbee there were quite a lot of things to read and study.

Just to test things I decided to try with Jennic IP and according to Google it is a company (web page)… but, they were bought by NXP and the web page is now defunct so where to find tools?

Google didn’t help – all I could find was pointing me to Jennic’s web page. Contacted NXP and got no answer. I decided to contact our local NXP distributer to ask them if  they know where I can find the tools and voila.

I guess I could find the link via search on NXP’s web page, but I just could not. Go figure.

nrf51 blinking LED (“self programming”)

A green, glowing SMD (surface-mount device) LE...
A green, glowing SMD (surface-mount device) LED (light-emitting diode) on the Arduino NG board from arduino.cc. The LED is marked with PWR. (Photo credit: Wikipedia)

It took me some time to start properly playing with nrf51822.

Managed to create my own board and get reading the button and lighting LED without a problem, but getting BLE working was whole new issue, so I decided to first work on my nrf51 programming skills, to really understand inner workings of BLE and then try to switch it on on my board.

This is the first attempt in creating my version of Blinky demo on dongle (and I will obviously try it on my board too).

#include "nrf_delay.h"
#include "boards.h"

#define LED_OUT                       23

int main(void)
{
    // Configure LED-pins as outputs.
    nrf_gpio_cfg_output(LED_OUT);

    // Toggle LEDs.
    while (true)
    {
        nrf_gpio_pin_clear(LED_OUT);
        nrf_delay_ms(500);
        nrf_gpio_pin_set(LED_OUT);
        nrf_delay_ms(500);
    }
}

is the code. Following is the Makefile needed to compile it. You will need to set path to SDK. Variable is named SDK_PATH :)

PROJECT_NAME := hello


SDK_PATH := ../../nRF51_SDK_9
export OUTPUT_FILENAME
MAKEFILE_NAME := $(MAKEFILE_LIST)
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) ) 

TEMPLATE_PATH = $(SDK_PATH)/components/toolchain/gcc
ifeq ($(OS),Windows_NT)
include $(TEMPLATE_PATH)/Makefile.windows
else
include $(TEMPLATE_PATH)/Makefile.posix
endif

MK := mkdir
RM := rm -rf

#echo suspend
ifeq ("$(VERBOSE)","1")
NO_ECHO := 
else
NO_ECHO := @
endif

# Toolchain commands
CC           	:= "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc"
AS       		:= "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as"
AR       		:= "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar" -r
LD       		:= "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld"
NM       		:= "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm"
OBJDUMP  		:= "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump"
OBJCOPY  		:= "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy"
SIZE    		:= "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size"

#function for removing duplicates in a list
remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1))))

#source common to all targets
C_SOURCE_FILES += \
$(SDK_PATH)/components/toolchain/system_nrf51.c \
main.c \
$(SDK_PATH)/components/drivers_nrf/hal/nrf_delay.c \

#assembly files common to all targets
ASM_SOURCE_FILES  = $(SDK_PATH)/components/toolchain/gcc/gcc_startup_nrf51.s

#includes common to all targets
INC_PATHS  = -I$(SDK_PATH)/components/toolchain/gcc
INC_PATHS += -I$(SDK_PATH)/components/toolchain
INC_PATHS += -I$(SDK_PATH)/examples/bsp
INC_PATHS += -I$(SDK_PATH)/components/device
INC_PATHS += -I$(SDK_PATH)/components/drivers_nrf/hal

OBJECT_DIRECTORY = _build
LISTING_DIRECTORY = $(OBJECT_DIRECTORY)
OUTPUT_BINARY_DIRECTORY = $(OBJECT_DIRECTORY)

# Sorting removes duplicates
BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY) )

#flags common to all targets
CFLAGS  = -DNRF51
CFLAGS += -DBOARD_PCA10031
CFLAGS += -DBSP_DEFINES_ONLY
CFLAGS += -mcpu=cortex-m0
CFLAGS += -mthumb -mabi=aapcs --std=gnu99
CFLAGS += -Wall -Werror -O3
CFLAGS += -mfloat-abi=soft
# keep every function in separate section. This will allow linker to dump unused functions
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
CFLAGS += -fno-builtin --short-enums

# keep every function in separate section. This will allow linker to dump unused functions
LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map
LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m0
# let linker to dump unused sections
LDFLAGS += -Wl,--gc-sections
# use newlib in nano version
LDFLAGS += --specs=nano.specs -lc -lnosys

# Assembler flags
ASMFLAGS += -x assembler-with-cpp
ASMFLAGS += -DNRF51
ASMFLAGS += -DBOARD_PCA10031
ASMFLAGS += -DBSP_DEFINES_ONLY
#default target - first one defined
default: clean hello

#building all targets
all: clean
	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e cleanobj
	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e hello

#target for printing all targets
help:
	@echo following targets are available:
	@echo 	hello


C_SOURCE_FILE_NAMES = $(notdir $(C_SOURCE_FILES))
C_PATHS = $(call remduplicates, $(dir $(C_SOURCE_FILES) ) )
C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILE_NAMES:.c=.o) )

ASM_SOURCE_FILE_NAMES = $(notdir $(ASM_SOURCE_FILES))
ASM_PATHS = $(call remduplicates, $(dir $(ASM_SOURCE_FILES) ))
ASM_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASM_SOURCE_FILE_NAMES:.s=.o) )

vpath %.c $(C_PATHS)
vpath %.s $(ASM_PATHS)

OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)

hello: OUTPUT_FILENAME := hello
hello: LINKER_SCRIPT=blinky_gcc_nrf51.ld
hello: $(BUILD_DIRECTORIES) $(OBJECTS)
	@echo Linking target: $(OUTPUT_FILENAME).out
	$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e finalize

## Create build directories
$(BUILD_DIRECTORIES):
	echo $(MAKEFILE_NAME)
	$(MK) $@

# Create objects from C SRC files
$(OBJECT_DIRECTORY)/%.o: %.c
	@echo Compiling file: $(notdir $<)
	$(NO_ECHO)$(CC) $(CFLAGS) $(INC_PATHS) -c -o $@ $<

# Assemble files
$(OBJECT_DIRECTORY)/%.o: %.s
	@echo Compiling file: $(notdir $<)
	$(NO_ECHO)$(CC) $(ASMFLAGS) $(INC_PATHS) -c -o $@ $<


# Link
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out: $(BUILD_DIRECTORIES) $(OBJECTS)
	@echo Linking target: $(OUTPUT_FILENAME).out
	$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out


## Create binary .bin file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
	@echo Preparing: $(OUTPUT_FILENAME).bin
	$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin

## Create binary .hex file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
	@echo Preparing: $(OUTPUT_FILENAME).hex
	$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex

finalize: genbin genhex echosize

genbin:
	@echo Preparing: $(OUTPUT_FILENAME).bin
	$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin

## Create binary .hex file from the .out file
genhex: 
	@echo Preparing: $(OUTPUT_FILENAME).hex
	$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex

echosize:
	-@echo ""
	$(NO_ECHO)$(SIZE) $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
	-@echo ""

clean:
	$(RM) $(BUILD_DIRECTORIES)

cleanobj:
	$(RM) $(BUILD_DIRECTORIES)/*.o

Using dongle you already get SEGGER (possibility to program the micro controller) and you just use whatever tool you like otherwise I’m not sure what you can use other than SEGGER programmer.

I have tried and failed – at the end decided to just buy a programmer.

 

APF28DEV and SD boot (Armadeus)

 

You need to compile the kernel and root the same way as I wrote previously. This must be done on the Linux, so VirtualBox, Parallels, VMWare or whatever you like to use.

 

After that you can use any OS you like, but I will talk about Mac OSX, because … well, I use it.

 

Let’s roll (use Terminal):

 

  1. You need to install e2fsprogs. (use Homebrew or whatever you like)
  2. Install fuse-ext2. 
  3. Do mkdir /Volumes/disk.
  4. In Disk Utility check disk number (of SD) and create one partition.
  5. Unmount the card
  6. Use sudo mkfs.ext2 /dev/disk? (instead of ? use disk number) – in Homebrew you need to use whole path to it (/usr/local/Cellar/e2fsprogs/…)
  7. sudo fuse-ext2 /dev/disk? /Volumes/disk -o rw+ (instead of ? use disk number)
  8. sudo tar xvf rootfs.tar -C /Volumes/disk
  9. cp apf28-linux.bin /Volumes/disk/boot
  10. sudo umount /Volumes/disk

 

You can use the card to boot from it on apf28dev.

 

According to http://www.armadeus.com/wiki/index.php?title=MultiMediaCard

 

You now have to go to boot menu and use:

 

run mmcboot

 

or to make it boot forever

 

setenv bootcmd run mmcboot
saveenv

 

ARM USB OCD programming

ARM-USB-OCD-01

So I got myself a device to program and debug ARM micro controllers by using JTAG. It’s an Olimex ARM-USB-OCD.

Tried to use OpenOCD on Mac OSX to program LPC2103,  but had troubles getting it recognised. After some googling and testing I finally managed to get it recognised. Here are the findings:

  • Compile OpenOCD with just regular ./configure (you can obviously add –prefix or whatever you want :)) and install it
  • The settings for interface in OpenOCD are using deprecated interface ft2232 so you need to change it a bit.
#
# Olimex ARM-USB-OCD-H
#
# http://www.olimex.com/dev/arm-usb-ocd.html
#

interface ftdi
ftdi_device_desc "Olimex OpenOCD JTAG"
ftdi_vid_pid 0x15ba 0x0003

You need to check data for device description (should be the same as in the device) and PID and VID number. To get that info just click on the apple sign (on the top left side of the screen), select About This Mac and press button System Report. Under USB you will find the device and copy the name (at the top) and Product ID and Vendor ID. Copy that to the interface file.

  • Choose the target you want to program (lpc2103.cfg in my example)

The command is:

 openocd -f olimex-arm-usb-ocd-h.cfg -f lpc2103.cfg

With proper paths, of course.

nrf51 debugging

USB Port Connection
USB Port Connection (Photo credit: Wikipedia)

 

I was playing with nrf51 dongle some more and I stumbled on some troubles, so debugging would be handy. After some playing around I found out you need to add following to Makefile:

CFLAGS += -D__HEAP_SIZE=0
CFLAGS += -DBSP_UART_SUPPORT
ASMFLAGS += -D__HEAP_SIZE=0
ASMFLAGS += -DBLE_STACK_SUPPORT_REQD
ASMFLAGS += -DBSP_UART_SUPPORT

After that you just use whatever you need for debugging in the code (e.g. printf).

The result can be read on serial terminal over the USB port (e.g. minicom). You need to set the speed to 38400).

 

nrf51 dongle and BLE

English: Cirago Bluetooth dongle, bottom view,...
English: Cirago Bluetooth dongle, bottom view, with USB series A plug (Photo credit: Wikipedia)

Last week I bragged about managing to compile simple blinky code for nrf51 dongle on Mac OS X.

The problem was that I couldn’t make BLE work. After banging my head against the wall and trying to tackle the problem I slowly got the info I need to add softdevice to the code and flash it before the program code.

At the end I tried to compile the softdevice and program code on Windows and it worked, so the problem was with the way JLinkExe is working on Mac OSX. After some googling I found out there is also a rknrfgo app for Mac OSX.

I’ve installed it and it worked like a charm. Just had to add link of softdevice and code to the app and finish everything by clicking the button Both.

nrf51 dongle, Mac OSX and programming

English: a bluetooth dongle
English: a bluetooth dongle (Photo credit: Wikipedia)

Since I need to work on very small form factor device I searched for a tiny microcontroller with BLE and found Nordic Semiconductor with their nRF1822 and it is a perfect thing for my needs.

 

Since the customer will order the elements I ordered a nRF51 dongle so I can play with programming it before starting “proper” work on it.

 

The device came today and I tried to flash a blinky example which is more or less an easy thing… on Windows. But I wanted to do it on Mac OSX so … here are the findings:

 

1. Download the J-Link software from SEGGER webpage – Mac OSX version, obviously.

 

2. Under developer on Nordic web page download latest SDK (you might need to create an account there – by using My Page on their home page).

 

3. Go to <SDK directory>/components/toolchain/gcc and correct links in Makefile.posix (if needed).

 

4. Go to <SDK directory>/examples/peripheral/blinky/pca10028/blank/armgcc and compile the code with make command

 

5. The easiest way to upload the code to the dongle is to use the nrfjprog.sh script and the syntax is ./nrfjprog.sh –flash <hex code>. You might need to reset it before that with ./nrfjprog.sh –reset.

 

6. Voila – it should work :)