Sunday, January 27, 2013

PIC Command Line Programming

New MPLAB X does not come with command line tools for device programming especially on Linux. MPLAB IPE(Integrated Programming Environment) might have been useful if it works properly. Unfortunately it doesn't. Instead you can use mdb.sh as a standalone programming tool. It is actually a shell script to run a java program (dammit!). You can find it in the directory:

/opt/microchip/mplabx/mplab_ide/bin/mdb.sh

And its manual is in the directory:

/opt/microchip/mplabx/docs/MDBUserGuide.pdf

Prepare a script file for the mdb.sh. For example, my script file prog.cmd to download a hex image to PIC32MX220 using PICkit3 looks like this:

Device PIC32MX220F032B
Hwtool PICkit3 -p
Program "YourProgram.hex"
Quit

You may not want to forget the -p option in the 'Hwtool' line. Otherwise it won't run.

Then you can download your image by running the following command in the terminal emulator.

/opt/microchip/mplabx/mplab_ide/bin/mdb.sh prog.cmd

You can put this into the Makefile, which is created by MPLABX by default. If you add it under .build-post: section then it will run when ever you (re)build your program. Or you can create a new target for downloading the image:

program:
        /opt/microchip/mplabx/mplab_ide/bin/mdb.sh prog.cmd


Friday, September 28, 2012

OpenOCD-0.6.0 install on Debian Wheezy

As of Sep. 7,  OpenOCD v0.6.0 was released but  I have to wait for a while until the new version will appear in the Wheezy package list. So I decided to manually install it. Actually, since OpenOCD needs to be updated throughout the numerous patches, it may not be desirable to simply install the official package.

Compared with the previous one, this version claims to have a lot of new features including
  • STLink V2 adapter support: STmicro STM32Fx DISCOVERY boards  
  • OSJTAG adapter support: Freescale TWR-K60 board and possibly FRDM-KL25Z board (this does not work for now)
  • Microchip PIC32MX1xx/2xx support(this also does not work)
and much more.  It is easy to find good reference about installing OpenOCD, however actual details may differ in  the various versions and flavors of the Linux desktop. The procedure below is for the Debian Wheezy (LinuxMint Debian edition).


PREREQUISITES

First, you may want to uninstall the previous version

$sudo apt-get remove openocd

Then, install two packages, which will be required for compiling the openocd.

$sudo apt-get install libusb-dev, libftdi-dev

If you want to build the manual also, then you may need

$sudo apt-get install texinfo

According to the desktop setting, one may also need other packages such as autoconf and libtools.


COMPILE AND INSTALL

 Download the source from this and expand it to the directory of your convenience, say '~/openocd'. Rest of the procedure is straightforward.

$cd ~/openocd
$./configure --enable-ft2232_libftdi --enable-doxygen-pdf
$make
$sudo make install

Note that unlike the source downloaded form the git tree, you don't need to bootstrap for the release version. And it is not recommended to use '--enable-maintainer-mode' switch either. You can add the adapter support as much as you want. For example, if you want to use it with STM32Fx DISCOVERY board, you can add

--enable-stlink

Or if you want Freescale(PE micro) OSBDM/OSJTAG support, then

--enable-osbdm

should do the job. Unfortunately, it turned out that this feature does not work for now. It may be the issue of pemicro's USB driver though.  If you failed to include the adapter support when you build the openocd, then you will get the error:

Error: The specified debug interface was not found (...)
The following debug interfaces are available:
Runtime Error: /usr/local/share/openocd/scripts/interface/...


Error: unable to open xxxx device: unable to fetch product description

Basically, OpenOCD requires superuser privileges to access the JTAG device via USB. Instead, you can edit the udev rule to save the inconvenience of 'sudo'. Add yourself to the 'plugdev' group

$sudo adduser USERNAME plugdev

You may want to restart the computer at this point. Then you need to create a udev rule under /etc/udev/rules.d with the contents for your JTAG devices, i.e.,


# Stellaris ICDI
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcda", GROUP="plugdev", MODE="666"
# Bus Blaster v2.5
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", GROUP="plugdev", MODE="666"
# ST-LINK/V2
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", GROUP="plugdev", MODE="666"

You can get the vendor id and the product id for your device using 'lsusb'. Do not forget to reload the udev rules.

$sudo udevadm trigger

You may also have to re-plug the JTAG device to reflect the udev rule change.


Error: An adapter speed is not selected in the init script. ...

Sometimes, you need to specify the connection speed for the OpenOCD to work properly. Just add the following lines in the cfg file

adapter_khz 500

You can try other clock speed of course.


STILL WAITING FOR SOME FIX?

As I noted above, I cannot get the osbdm interface(comes with TWR-K60N and FRDM-KL25Z) to work. It fails to detect the device

Error: Can't open OSBDM device

even after the pemicro driver installed. And it also failed to connect PIC32MX chips

Error: JTAG scan chain interrogation failed: all zeroes
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: pic32mx.cpu: IR capture error; saw 0x00 not 0x01

You are supposed to be patient. It is an open source project after all.

Tuesday, August 28, 2012

Python script for BACnet MS/TP packet log

UNPLEASANT TRUTH ABOUT GTKTERM

During recent work about BACnet port, I have encountered tricky situation. I was using a RS232-to-RS485 converter to connect my desktop RS232 port to BACnet MS/TP network. And lack of better alternatives, I chose GtkTerm to view and log the packet. It was the only terminal emulator I know that can handle raw hex data stream. Naturally, I didn't question its function.

However, after much struggle I had a hunch that it was the GtkTerm that gave me totally unexpected data from time to time, which made me believe that there was an issue in the firmware(BACnet code) or hardware. So, I thought it was a good time to give python a try.

PYTHON SCRIPT FOR PACKET CAPTURE

If you are already familiar with C/C++, then it will take only a week for you to create a python program for your job. For the quick testing purpose like this, there should be no better programming language than python. For example, if you want to read data from the serial port byte by byte, then the following 4 lines will do the job.

import serial
ser = serial.Serial('/dev/ttyUSB0', baudrate=9600)
while True
    data = ser.read()

If you want to display the packet on your terminal then just add a line

    print "%x" % ord(data)

That's it! With these 5 lines, I confirmed the problem of the GtkTerm. If you want a bit more nice features, then surely your script will be longer than this. But definitely there is no other programming language can do the job as simply as this.

My final version of the script includes features such as
  • display BACnet packet stream with easy to read format
  • BACnet compliant CRC check
  • save packet data into a text file
  • automatically exiting after capturing predefined number of packets
Still it has only around 100 lines including comments. You can find my script here.


Monday, August 27, 2012

I2C Control on QNX Neutrino

One of the I2C devices populated on the P1025-TWR is MMA8451Q 3-axis accelerometer. It gives you a good example of I2C communication on QNX. As for any other devices on QNX, your I2C control program opens the device with 'open()' and closes the device with 'close()'. Whereas, for the actual I2C transaction, you need 'devctl/devctlv' function with DCMD_I2C_XXX flags.

READ/WRITE CONTROL ON I2C

First of all, you need to include at least these header files.

#include <fcntl.h>
#include <devctl.h>
#include <hw/i2c.h>

For the write control, you have to define iov_t structure and fill it with information  about the target i2c address, address format(7bit or 10bit), length of the command bytes, and trailing stop bit(P). Then issuing the command with DCMD_I2C_SEND flag:

iov_t           siov[3];
i2c_send_t      hdr;

hdr.slave.addr = i2c_addr;         // target address
hdr.slave.fmt = I2C_ADDRFMT_7BIT;  // address format
hdr.len = 1;                       // num of cmd bytes
hdr.stop = 1;                      // attach stop condition

SETIOV(&siov[0], &hdr, sizeof(hdr));
SETIOV(&siov[1], &reg, sizeof(reg));
SETIOV(&siov[2], val, num);

devctlv(fd, DCMD_I2C_SEND, 3, 0, siov, NULL, NULL)

For the read control, you are using DCMD_I2C_SENDRECV flag in most of the cases where the target has more than one registers so you have to specify the register address to be read first(i.e, read immediately after write). So you need to prepare two successive packet(iov_t) at once.

iov_t                  siov[2], riov[2];
i2c_sendrecv_t  hdr;

hdr.slave.addr = i2c_addr;         // target address
hdr.slave.fmt = I2C_ADDRFMT_7BIT;  // address format
hdr.send_len = 1;                  // number of cmd bytes
hdr.recv_len = num;                // number of receive bytes
hdr.stop = 1;                      // attach stop condition

SETIOV(&siov[0], &hdr, sizeof(hdr));
SETIOV(&siov[1], &reg, sizeof(reg));

SETIOV(&riov[0], &hdr, sizeof(hdr));
SETIOV(&riov[1], val, num);

devctlv(fd, DCMD_I2C_SENDRECV, 2, 2, siov, riov, NULL)

READING THE ACCELEROMETER

MMA8451Q has 6 successive 8-bit registers starting with 0x01 location, corresponding to x, y, and z axis measurements (2 bytes for each axis). But you need to bring it into ACTIVE mode by writing 0x01 at the control register 1(0x2A) first. The following screen shows successive i2c operation of

  • writing 0x01 at 0x2a
  • reading x axis value from 0x01 (2 bytes)
  • reading y axis value from 0x03 (2 bytes)
  • reading z axis value from 0x05 (2 bytes)

where the MMA8451Q has its i2c address as 0x1c and is hooked at the second i2c channel (/dev/i2c1).



Building TFTP connection to QNX target board

While I'm playing with QNX and P1025-TWR board, I need to have a connection between my desktop as a host system and the P1025-TWR as a QNX target device, to download programs to the device. It shouldn't be any issue if I install QNX Momentics IDE on my Linux box. But the last thing I want to do is to install the Eclipse. I'm sure I'm not alone in this matter.

My Momentics IDE is installed on the virtual machine, which has no connection with the target board. So, I decided to have TFTP connection with QNX Neutrino on P1025-TWR. Actually, I already have TFTP connection with the u-boot of P1025-TWR.  But, there are several things to be cleared for the TFTP connection with QNX Neutrino, especially with the P1025-TWR board.

MAC ADDRESS PROGRAMMING

First thing you have to remember is that the P1025-TWR board had no MAC address programmed on its EEPROM. It does not make any problem with the u-boot. But as soon as you boot up the QNX, your ethernet won't work any longer. Fortunately this issue is well addressed and MAC address programming utility is provided with the QNX BSP.

After booting up the QNX, you can check the contents of the EEPROM by:

#freescale-mac-eeprom /dev/i2c1 52

which will dump the EEPROM contents. Note that the EEPROM is on the system I2C bus with address 0x52.

You can find the MAC addresses assigned for the board written on the sticker on the RJ45 socket. Use the same program to write the addresses on the EEPROM. For some reason you need 3 MAC addresses.

#freescale-mac-eeprom /dev/i2c1 52 xx:xx:xx:xx:xx ... ...

You may need to reboot QNX at this point.

TFPT AND OTHER UTILITIES

Default Neutrino setting does not include TFTP (it includes FTP though). And you may also need other utilities. So what you have to do is to rebuilt QNX kernel from the BSP. You can easily add these utilities by editing the build script file, which is located at:

<BSP_root>/source/hardware/startup/boards/<your_board>/build

Add the utilities of your choice after the line

[data=c]

In this case, you may want to include

tftp
chmod

The chmod utility is required if you want to change the attribute of the downloaded files.

Rebuild your kernel, download via TFTP using u-boot, boot up the new QNX Neutrino, then you should be able to connect your host via TFTP and download any file you want

#tftp 192.168.1.100
tftp> get foo
Received xxxx bytes in yy seconds
tftp> quit

If it is an executable file but it does not have appropriate attribute. Then you can change the attribute of the file bye the chmod:

#chmod a+x foo

Friday, August 10, 2012

TFTP server setup for LinuxMint

In this post, TFTP connection will be established between the TWR-P1025 board and the Linux box via ethernet. TFTP server setup varies over the flavors and versions of the desktop. A LinuxMint(Debian Wheezy based) is used here.

TFTPD-HPA INSTALL

First of all, tftpd-hpa package is preferred over the original BSD version:

"tftp-hpa is an enhanced version of the BSD TFTP client and server. It possesses a number of bugfixes and enhancements over the original."

So, install it

$sudo apt-get install tftpd-hpa

And edit the configuration file

$sudo vi /etc/default/tftpd-hpa

to change the TFTP directory

TFTP_DIRECTORY="/var/lib/tftpboot"

This could be any directory of your choice. But you have to give the guests permission to use that directory

$sudo mkdir /var/lib/tftpboot
$sudo chmod 777 /var/lib/tftpboot

Then (re)start the tftpd service

$sudo /etc/init.d/tftpd-hpa restart

This particular step varies over the versions and the flavors of the Linux. If you are using a different desktop, you have to refer to the corresponding manual. Now, it is a good time to check the service is running. In order to that you can use the tftp client package.

$sudo apt-get install tftp
$touch /var/lib/tftpboot/foo
$tftp 127.0.0.1
tftp> get foo
tftp> q
$ls -l
-rw-r--r-- 1 user user 0 Aug 10 12:26 *
-rw-r--r-- 1 user user 0 Aug 10 12:26 foo
$rm foo

NETWORK SETUP

A separate network should be prepared for the tftp connection. For example,


If you don't want your main network connection to be affected by this connection, you also need to check this



SERIAL CONNECTION

While the tftp transaction is going on via the ethernet, you need to connect your target board via the serial connection to control and monitor the u-boot. Plug in the TWR-P1025 board and check the USB device list

$lsusb
...
Bus 001 Device010: ID 0403:6010 Future Technology Devices International...

That will add two more serial devices to your system

$ls /dev/ttyUSB*
/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2

You can use minicom or gtkterm to connect the target board using these parameters. Actual port number may vary.


Be sure to add yourself to the dialout group before using any serial ports

$sudo usermod -a -G dialout user

Otherwise, you are not allowed to use the port.


This is the initial output you would get when you cycle the power or reset the board:


What you need to set here are

=> setenv ipaddr 192.168.2.102
=> setenv serverip 192.168.2.100
=> setenv gatewayip 192.168.2.1

Save it and reset the board

=> saveenv
=> reset

Then you are able to ping the host from the target board

=> ping 192.168.2.100

Speed:100, full duplex

Using eTSEC1 device

host 192.168.2.100 is alive


You are ready to download the target image. Compile it and put it on the tftp directory. Then download from the target board

=> tftp 0x100000 ifs-p1025twr.raw
TFTP from server 192.168.2.100; our IP address is 192.168.2.102
Filename 'ifs-p1025twr.raw'
Load address: 0x100000
Loading: ##############################
               ##############################
               ##############################
               ###
done
Bytes transferred = 2902528 (2c4a00 hex)

This should be done in a couple of second unless your image is particularly large. Now, fire up the image

=> go 0x100000

This would be what you can see after firing up the QNX image


You may need to re-configure the network after the QNX bootup.


This assumed that you have dhcp client module in your QNX image.

Sunday, August 5, 2012

XMEGA-A1 Xplained on Linux

XMEGA-A1 Xplained board is a low cost demo kit populated with a ATxmega128A1 device. So you can play with ATxmega A series device before you take this for your design. Unfortunately, there are several obstacles you may encounter especially if you are a Linux user like me.

PAINFUL FIRMWARE UPDATE OF JTAGICE mkII

As I understood, I have to update the firmware of my dev tools such as JTAGICE mkII or AVRISP mkII regularly to work with newer devices. And this can only be done using AVR Studio. However recent version of AVR Studio is using Visual Studio as its IDE. And it means that there are good chances that you will suffer from the notorious Microsoft .Net versioning issues and service pack troubles unless you dedicate a clean copy of Windows for it.

In my case, I downloaded 700MB of AVR studio, knowing that most of the contents are just .Net and VS garbages, installed it any way, only to realize that it is not compatible to my original visual studio 2010 already there. I didn't surprise when I failed to apply service pack on the AVR studio and stuck there. That service pack won't be installed nor uninstalled. No surprise!

Eventually, I had to reinstall my Windows entirely. It was O.K. though because I have my Windows on  virtual machine. It only took 20 min to reinstall it. After all things were cleared, however, I realized this time that firmware update via AVR studio does not work in virtual machine for some unknown reason. So I successfully bricked my JTAGICE mkII. Great! Lesson learned. Do not update your dev tool on virtual machine.

USB PORT DOWNLOAD(FLIP) DOES NOT WORK ON Linux

XMEGA-A1 Xplained board has USB connector for downloading firmware as well as for supplying power to the board. However, you cannot use that port on Linux because FLIP utility, which is supposed to talk with the board via USB, does not support Linux.

That USB connection with FLIP is not useful at all any way. Because it only provide USB-to-UART translation, so you need to

  • install a dedicated bootloader on ATxmega128A1 for self-flashing its memory via UART connection
  • recycle the power each time you want to flash

You are not allowed to expect the same level of convenience as you can find in the Arduino board. So, you don't have to be feel sorry for not being able to use USB+FLIP. Just forget about the USB.

POSSIBLE RESET ISSUE / MIX OF JTAG AND PDI PORT CAUSE TROUBLE

After much struggling, I managed to build my development environment with the firmware updated JTAGICE mkII, avrdude, avr-gcc toolchain, and my precious vim. I compiled my first test code and downloaded it. Although I didn't find any issue during download via the JTAG connection, I encountered with very weird situation that

  • sometimes it worked, sometimes it didn't
  • even if it worked, it stopped to work after a while

During debugging, I found out that the reset signal of ATxmega128A1 became very sensitive so it failed to boot after flash download or it was forced to enter the reset state by JTAGICE mkII in the middle of running for some unknown reason. My hunch is that the 100K pull-up resistor for the reset signal is too weak but I don't want to bother with this issue for now.


The manual comes with this board recommends me to install 10K pull-down resistor at the reset signal to work around some other issue about PDI connection. But if I install the pull-down resistor, I cannot even flash it.

So, basically you need additional reset switch to bring the board up after flashing. And sometimes, you also need to connect the reset signal to VCC rail to take the board out of the reset state brought by JTAGICE mkII. If you use a squid cable for the JTAG connection, you can easily install the reset button as shown below. For the VCC pull-up, I use a tweezer.



Speaking of PDI connection, just for the curiosity, I changed the fuse bytes of the ATxmega128A1 to try PDI, only to find out that

  • as soon as I changed the fuse bytes, I lost the JTAG connection with the device
  • there is no information about PDI connection of JTAGICE mkII

This time, I successfully bricked my XMEGA Xplained board! For those who may follow the same step, I attached this chart so you don't have to be panic. Just refer to the last table. Then you have the PDI connection hopefully.


Actually, PDI port shares the same connector with JTAG port, meaning that one of its signal, PDI_DATA is tied to the TDO signal of the JTAG. I have no idea why they prepare a separate connection but I'm afraid it might create nasty issue if

  • PDI is activated when JTAG is working or
  • Port B is being used when PDI is working

The manual suggests to install a 10K resistor at the reset signal for the work around this issue. But I found out that only brought another issue.

AVRDUDE: LACK OF SUPPORT FOR RECENT DEVICES

Actually, ATxmega128A1 or any ATxmega A series were not my concern. It is ATxmega D series, which is my original target device because of its competitive price point. I don't find any merit in other series in terms of price. However, ATxmega D devices are not supported in avrdude as of ver. 5.11.1. In other words, you cannot flash them if you are a Linux user like me.

So, if you are Linux user or if you are concerning about commercial products, then forget about xmega for a while. That is my two cents.