Handling Counter Wrap Around

You need to delay a certain amount of time ticks. Easy, right? You can just say:

target=get_ticks()+100;
/* Do some things */
/* wait for target time to pass */
while (get_ticks()<target);

This works fine as long as adding 100 (the delay count) to the current tick counter doesn’t cause an overflow. Remember 100 is 64 hex and consider this 16-bit counter incident (assuming 16 bit math):

target=get_ticks();  // target=0xFFF0
target=target+100;   // target=0054
while (get_ticks()<target);  // get_ticks is FFFE which is not < 54! Immediate fall through

The same problem occurs with any wrap around, regardless of the word size. However, there is an old trick as long as you can do unsigned math. Let’s look at the following cases:

Case A: Current tick=0x0000; target=0x0100

Case B: Current tick=0xFFFE; target=0x00FE

Case C: Current tick=0xFF00; target=0x0000

When you do a subtraction, the top bit will be set if there was a borrow off the end of the word. That is, subtracting 0x0010 from 0x1234 is really the same as subtracting 0x0010 from 0x11234 and and the end you throw away the extra bit at the left. This helps solve our problem. What if you subtracted the target time from the current time?

Let’s consider the case where the tick is just one more than the original current tick:

Case A: 0x0001-0x0100 = 0xFF01

Case B: 0xFFFF-0x00FE= 0xFF01

Case C: 0xFF01-0x0000=0xFF01

And the case where the current tick has wrapped but isn’t up to the target yet (only applies to B):

Case B: 0x0000-0x00FE=0xFF02

Then consider the case when you are one away from matching:

Case A: 0x00FF-0x0100=0xFFFF

Case B: 0x00FD-0x00FE=0xFFFF

Case C: 0xFFFF-0x0000=0xFFFF

Of course, when you hit the target, you get zero. The key takeaway here is that every result will have bit 15 (in this case; the top bit, in general) set until the result matches. This can be fast to implement. For example, here’s a 32-bit timer from an NXP LCP111x delay loop:

// Set up timer 0 
SIM->SCGC6|=SIM_SCGC6_PIT_MASK; 
PIT->MCR=0; 
PIT->CHANNEL[0].LDVAL=0xFFFFFFFF; 
PIT->CHANNEL[0].TCTRL=PIT_TCTRL_TEN_MASK; 
// Ok here's our start time 
counts=PIT->CHANNEL[0].CVAL; 
// do some stuff here and when done 
// compute the target 
count counts=~counts; // convert to count up (this counter runs down) 
counts+=474; // how many ticks before we proceed (40nS per tick + a little overhead) 
do { clock=~PIT->CHANNEL[0].CVAL; // again, convert to up count 
 } while (clock-counts>=0x80000000UL); // could do a bit test here as well (e.g., while (clock_counts[31]);

 

Naturally, there are other ways to solve this. If the timer isn’t used for anything else, I could have preloaded it and waited for it to hit zero, but that’s not always an option.

Easy mbed Programming from Linux

If you use mbed you know it is cool not to have to install compilers or build libraries and toolchains. You just enter some code, grab some up to date libraries and press compile. Everything runs in your browser and you download a binary file with your program in it. However, you still have to get it to the board. Most of the Arm boards look like a USB drive and you can simply copy or move the file over to do a program. However, I get tired of manually doing that step. This is especially a problem if you use a GUI. You have to remember to move and not copy (so your browser doesn’t keep renaming the file) and you also need to keep confirming the overwrite on the phantom file still on the “fake” USB drive.
So instead, I write a little command line “script” to do it all for me. You could use inotify, but this is easy and I just do it when I’m developing and stop it when I’m done. Suppose your object file is XXX.bin and you are in the /tmp/mbed directory.

Open a shell and go to the /tmp/mbed directory. In my case, the fake USB drive is at /media/USER/FRDM-KL25Z. Then enter this:

while true
 do if [ - f XXX.bin ]
 then echo Programming
 sleep 1
 mv -f XXX.bin /media/USER/FRDM-KL25Z 
 echo Done
 fi
 sleep 2
done

Now when you save your binary file to /tmp/mbed, it will automatically program the device. Simple!

Quick Qt5 Example for GP3

I noticed Qt5 has a QtSerialPort class. Here’s a simple example of talking to the GP3  using this library:

 

    static int state=0;
    QSerialPort port("ttyUSB8",this);  // works with /dev/ttyUSB8 or ttyUSB8
    qDebug()<<port.setBaudRate(QSerialPort::Baud57600);
    qDebug()<<port.open(QIODevice::ReadWrite);
    qDebug()<<port.write(state?"\x0C":"\x0D",1);  // Turns on/off light
    state^=1;
    port.waitForBytesWritten(1000);
    port.close();

Pretty simple. You can read data back either blocking or using slots. I’ll cook up an example of that later.

PICP (Linux PICSTART Plus) for 16F883 and 16F886

Just in case you want to use PICP with either the 16F883 or 16F886, add this to your picdevrc file:

[16F883]
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
PICSTART

[16F883:def]
10 00 3f ff 3f ff 00 7f
00 7f 3f ff 3f ff 00 ff
00 ff 00 00 00 00 00 00
0D 10 20 00 04 20 07 02
00 00 01 00 00 00 00 00
00 01 22 0f

[16F883:defx]
3f ff 07 00 00 00 00 00
00 00 00 00 00 00 00 00
3f ff 07 00 00 00 00 00
00 00 00 00 00 00 00 00

[16F886]
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
PICSTART

[16F886:def]
20 00 3f ff 3f ff 00 7f
00 7f 3f ff 3f ff 00 ff
00 ff 00 00 00 00 00 00
0D 10 20 00 04 20 07 02
00 00 01 00 00 00 00 00
00 01 22 0f

[16F886:defx]
3f ff 07 00 00 00 00 00
00 00 00 00 00 00 00 00
3f ff 07 00 00 00 00 00
00 00 00 00 00 00 00 00

New GP-3X Boards Available

Here’s a chance to pick one up at a promotional auction price.

The firmware on these boards is the normal GP-3. You can use it as a PC A/D interface for data acquisition or control You can also create a program with GP3EZ and then “download” it to the board so the board will function without a PC.

The differences in this board from the regular board:

1) All I/O is out to the edge and marked. Screw terminals are optional (included in the auction).

2) Dedicated jumper for GP3EZ run/program mode

3) USB daughterboard available

4) Room for a “regular” LED or a 2nd 5V LED.

5) Large ground lands for the analog converters to decrease noise pickup

6) Spare area for op-amps or other devices (if not using USB daughterboard); flexible I/O lets you “interrupt” the analog and digital I/O to reroute.

7) Slot for resonator OR crystal.

8 ) Switchable DTE or DCE serial port (and connections for TTL serial)

There is also a new manual for ALL GP-3s. Unlike the old “two part” manual, this is one manual for all GP-3 boards and should not require any other manual regardless of which kit you have. http://www.awce.com/gp3.pdf

SuperProbe

We have a group of hams that homebrew that meets once a month for breakfast. A while back I noticed the and thought it would be a good way to get some of the guys started with Microchip PICs.

I started out breadboarding the circuit, but they will eventually go into nice cases we bought from Kelvin.

Here it is in logic probe mode, reading a logic 1 (High):

Breadboarded Super Probe reads a logic high

And here it is reading a voltage (just an output from a pot):

Inside view of the probe
Inside view of the probe

Where have all the posts gone

It looks like I’ve gotten busy lately and neglected Hotsolder. Not exactly. You know a lot of my postings relate to embedded systems. You might also know that I have a long history with Dr. Dobb’s Journal as an author, columnist, and editor. Well, I’ve recently started blogging about embedded systems on the . Stay tuned to Hotsolder for things that don’t fit there, but for embedded items, check out DDJ.

SXKey Under Wine

Since I often program Parallax/Ubicom/Scenix SX chips, I needed a good way to program the chips under Kubuntu/Ubuntu. The installation of the software under Wine worked fine. However, the program didn’t work right away.

Of course, I had already set up ~/.wine/dosdevices to have a link for com1 (ln -s /dev/ttyS0 ~/.wine/dosdevices/com1). You need to make sure you have permissions on that device also. Rather than open the port to the world, I noted the port is in the “dialout” group, so you can simply add yourself to that group to get read/write access to the port. For example:

alw@enterprise:~$ ls -l /dev/ttyS0

crw-rw—- 1 root dialout 4, 64 2008-08-13 06:45 /dev/ttyS0
alw@enterprise:~$ sudo usermod -a -G dialout alw

Naturally if you aren’t using your real COM1, you’d need to change /dev/ttyS0 to the right designator (although you can still call it COM1 for Wine!).

The com port autodetection was the culprit.  The trick was to open ~/.wine/user.reg and add this line:

[Software\\ParallaxInc\\SX-Key\\2.0\\Configuration\\ComPort]

“Configuration\\ComPort”=”COM1”

I’m not sure if it mattered, but since the entries are alphabetical, I put it in the “right” place. After that, it all worked fine!

Uncommon Nonvolatile Memory Powers 8051

The 8051 is a popular microcontroller core. In the “old” days we used external EPROMs. Modern versions have onboard EPROM or EEPROM (like flash).

Ramtron recently announced their new 8051 with onboard FRAM (8K worht). FRAM is a nonvolatile memory that is fast to write, byte-writeable, and has virtually unlimited read/write cycles. So you get the advantages of nonvolatile memory without the disadvantages of flash.

FRAM is a ferroelectric-based technology that does not require battery backup like SRAM. Of course, you can get FRAM to include with a traditional microprocessor, but this is the first microcontroller I know of that has FRAM right in the device.

Link: