Debugging with the Saleae Logic

I just got a Saleae Logic analyzer and it’s immediately been useful. The software is pretty sparse but it’s easy to use.

Below is a screen shot of the traffic between an FT220X USB interface IC and an AVR. Here we can see a glitch at the end of the third clock period. The third clock is the bus turn around phase. The bug here is that I’m tristating the AVR’s data lines at the very end of the clock period.

glitch

The fix was simple:

glitchfix

The Saleae device is better than I expected given some of the reviews I’ve read. It doesn’t do much so there isn’t anything to learn. Software installation was easy and didn’t hog a ton of space on the PC. It does have some quirks. I get an error dialog every time I plug the device into the computer, but everything works fine. When it’s capturing it doesn’t update the memory usage counter as it goes along. By default the program uses an Aero theme which has the application window border areas translucent. Since the time line text, options menu and other things have white text, this means you can’t see them if the application window is sitting on top of a white surface. Fortunately you can turn off the Aero theme. You’ll need to float the app window over a dark surface to find the options menu to do that if you don’t know where it is at first… You can reorder the channels but you have to do so through a right click menu for each one, and you can only move them up or down one at a time which is annoying. It would be nice if you could simply drag them around. The T1 and T2 cursors can get stuck outside the graph on the right side and are unaccessable if you click in the wrong area. To get the back you have to zoom into the graph and reselect the T1 and T2 labels on the right side of the app window.

Minor annoyances. Once you position and label your channels, you can save the profile and then recall it later. That’s handy and works well.

Overall I’m fairly impressed with it. I was able to immediately hunt down problems the moment I had it out of the box and setup. It paid for itself the first day I used it. I have some i2c devices to work with after I finish ironing out this FT1248 interface. It will be interesting to see how useful the protocol analysis tools are with this thing.

Digital thermometer came in the mail today

It took forever to get here, almost two weeks. I ordered it from Amazon. It comes with two probes, one that can go up to 260°C and another that can handle 1000°C. I’ll be using it to measure temperatures of ICs in prototypes as well as to measure what temps are coming out of my hot air tool at various distances and flow rates.

Below is a picture of the setup. I’m measuring the temperature of a voltage regulator in a prototype. It’s throwing out over 60°C with a 5.5V input and a 300mA load on the 3.3V output. That’s too hot and it’s right on the edge of thermal shutdown. I won’t be using this regulator in the final design. It has no tab or pad underneath the IC, nowhere for heat to go.

temp_setup

A close up shot of the sensor on the IC. I’m holding it down with polyimide tape.

temp_probe

This meter is nice, only drawback is that it doesn’t log.

Current measurement device

The current project I’m working on has some issues that in the past I haven’t had to worry about too much, mainly power consumption requirements. In past projects I was able to get away with simply adding up the max power consumption values for each component in the device and then select a power supply that exceeds the minimum requirement. In this particular project the device has to have the option to run off of USB power but available USB power is under the maximum amount of current that the device can consume depending on what the user is doing with it. It’s ok if the user circuits can’t run off of USB power if they draw too much, but at no point should the device fail to be able to reprogram the CPLD when plugged into the USB bus. The solution is to have the micro controller manage the power input to the CPLD with a MOSFET. When the device powers up it checks to see if it’s running on USB power, if it is, it attempts to communicate with the PC via the FTDI220 to see if the user wants to reprogram the CPLD. If that is the case it supplies power to the CPLD and immediately goes into programming mode.

As I’m working through the prototyping phase, I want to be able to see what the current consumption is like with the device in it’s entirety and individual components and document as I go along. This allows me to verify that I understand the data sheets and that my power management circuitry is within spec. I can do a lot with my multimeter but I’d like to be able to use it with my oscilloscope and more importantly log data with my computer. None of the three multimeters I have output a voltage representing the current or have an interface for logging data.

To solve some of these issues I built a current meter that outputs a voltage based on the current flowing through it. With it I can view the output on my oscilloscope and log data with my USB daq.

cmeter_bottom

cmeter_top

It’s based around a hall effect based current sensor IC from Allegro Microsystems (ACS711), an opamp (AD8542) and a 3.3v LDO. It picks up a lot of noise unless it’s in a metal box (particularly from fluorescent lights).

cmeter_box

Below is a graph of current consumption from a 100uF electrolytic capacitor. The graph is clipped at 1.6V.

capcharge

Lots of EMI issues, especially with the gain jacked up. It’s useable in multiples of 50mA. At 10 the signal gets lost in the noise. I built this in one evening. With some work it could be a much more useful device, but I don’t have time right now to make it better.

A new project is born

I’ve been busy this past week on a new project centered around a Max V CPLD. Schematic isn’t final yet. Just about every time I think I have it nailed down, I find out that I could have used a cheaper part, a smaller part or a certain part ends up not meeting the requirements for one reason or another. Selecting an LDO turned out to be a chore. The one in the schematic below is being swapped out for another. Do I use two, or get one with dual output? Fixed, or adjustable output? Does the dropout line up with my input power requirements, etc? Is the one I selected a common device that’s likely to be available when it’s time to go into production, or is it something that just happened to be in stock, never to be seen again after it runs out? A part that’s unavailable means you have to wait for it to become available again, could be weeks, months, or never. Or it could mean you pay a high price to someone who has it. Or make a change to the PCB design to fit another part, that adds an extra month to the project.

The ATtiny40 I picked looked pretty good. Small, cheap, just enough IO pins to get the job done. Downsides are no on chip debugging support, slave only i2c, not supported by a lot of programmers. I was aware of the first two, they don’t bother me too much. Not working with a wide variety of programmers is a bummer. I’m swapping that out with an ATtiny48 which supports DebugWIRE, has proper i2c support and is on the supported devices list for the AVR Dragon. It costs 30 cents more, but I compensated for it by down costing another area of the circuit so I’m still within my parts budget. I’ll put those extra pins to good use, also, the pin layout is pretty nice.

I’d like to use a smaller, cheaper, lower power oscillator. There probably is one out there, but I haven’t found it. I’m using a 50MHz part because that’s what I need for some of my projects and there is no PLL on the Altera CPLDs. I wonder why they didn’t put one on there, it would be a nice thing to have. Would that significantly add to the cost of the device? Do PLL blocks take up a lot of space on the die? That would be an interesting question to ask an IC designer.

rtschematic

I’ll be ordering most of the parts this evening. By the time I get them in the mail I should have most of the PCB laid out. When that’s done I’ll print out the top layer to check that I got the pads laid out correctly for the parts that weren’t in the library (which was most of them). After that I’ll have some prototype boards made.

copperrt

The incident with the microwave

I found a beat up microwave in the trash the other day. Looks like the neighborhood kids had fun smashing it up. I took the opportunity to rip the display module from it.

In the FPGA projects I’m working on, it would be useful to have a simple hex display and some buttons for input, so I built one. It takes bytes in from a serial connection and displays them on a 4 segment LED module. Below is a picture of the assembled device.

serialhexAnd here is the schematic:

serhexled

Here is the device in action:

And here is the source code:

// This program reads bytes from an RS232 port and displays them in
// hex on a 4 segment LED module. It relies on the UART library that is
// included with the mikroC compiler. This program targets a PIC16f917.
// Source released as Public Domain
// 2013 Brian Miller

// segment commons
const segz = 0b01111111;
const segw = 0b10111111;
const segy = 0b11011111;
const segx = 0b11101111;

// segment pieces
const pa = 0b10000000;
const pb = 0b00000010;
const pc = 0b01000000;
const pd = 0b00000001;
const pe = 0b00000100;
const pf = 0b00100000;
const pg = 0b00001000;

// glyph definitons
const d0 = pa + pb + pc + pe + pf + pg ;
const d1 = pc + pf ;
const d2 = pa + pc + pd+ pe + pg ;
const d3 = pa + pc + pd + pf + pg ;
const d4 = pb + pc + pd + pf ;
const d5 = pa + pb + pd + pf + pg ;
const d6 = pa + pb + pd + pe + pf + pg ;
const d7 = pa + pb + pc + pf ;
const d8 = pa + pb + pc + pd + pe + pf + pg ;
const d9 = pa + pb + pc + pd + pf ;
const da = pa + pb + pc + +pd + pe + pf ;
const db = pb + pd + pe + pf + pg ;
const ddc = pa + pb + pe + pg ;
const dd = pc + pd + pe + pf + pg ;
const de = pa + pb + pd + pe + pg ;
const df = pa + pb + pd + pe ;

// returns the glyph code for the specified nybble in the word
unsigned char retchar ( unsigned int a, unsigned int pos){
         unsigned int tst ;
         switch (pos){
                case 0 :
                     tst = ( a << 12 ) >> 12 ;
                     break;
                case 1:
                     tst = ( a << 8 ) >> 12 ;
                     break;
                case 2:
                     tst = ( a << 4 ) >> 12 ;
                     break;
                case 3:
                     tst = a >> 12 ;
                     break;
         }
         switch ( tst){
                case 0 : return d0 ;
                case 1 : return d1 ;
                case 2 : return d2 ;
                case 3 : return d3;
                case 4 : return d4 ;
                case 5 : return d5 ;
                case 6 : return d6 ;
                case 7 : return d7 ;
                case 8 : return d8 ;
                case 9 : return d9 ;
                case 10 : return da ;
                case 11 : return db ;
                case 12 : return ddc ;
                case 13 : return dd ;
                case 14 : return de ;
                case 15 : return df ;
         }
}

void main() {
     // serial input
     unsigned int inDat;
     
     // individual display digits
     unsigned char s0, s1, s2, s3;
     
     // kp limits button sampling, i selects the digit to be refreshed
     unsigned char i;
     unsigned char kp;
     
     ANSEL = 0 ; // AN pins as digital
     CMCON0 = 0 ; // turn off comparators

     // Segment port
     TRISA = 0 ;
     // Commons port
     TRISB = 0 ;
     // Button inputs
     TRISD = 0xFF;
     
     // lib doc suggests waiting 100ms to allow serial port to settle
     UART1_Init(19200); // 19200 baud
     Delay_ms(100);
     
     // set all digits to 0 on startup
     s0 = d0;
     s1 = d0;
     s2 = d0;
     s3 = d0;
     
     inDat=0;
     i = 0 ;
     kp = 0;

     for (;;){
         // shift in a byte if there is one waiting
         if (UART1_Data_Ready()){
            inDat = inDat << 8 ;
            inDat = inDat + UART1_Read();
            s0 = retchar (inDat, 0);
            s1 = retchar (inDat, 1);
            s2 = retchar (inDat, 2);
            s3 = retchar (inDat, 3);
         }
         // if one or more buttons is pressed and sample limiter is 0
         // then write the button state to the serial port
         if ( kp++ == 0 && PORTD != 0 ) {
            UART1_Write(PORTD);
         }
         // we only update one segment per iteration so that each segment
         // stays lit an equal ammount of time.
         switch (i++){
                case 0:
                     PORTB = 0xFF;
                     PORTA = s0 ;
                     PORTB = segx;
                     break;
                case 1:
                     PORTB = 0xFF;
                     PORTA = s1 ;
                     PORTB = segy;
                     break;
                case 2:
                     PORTB = 0xFF;
                     PORTA = s2;
                     PORTB = segw;
                     break;
                case 3:
                     i=0;
                     PORTB = 0xFF;
                     PORTA = s3 ;
                     PORTB = segz;
                     break;
         }
     }
}

Syntax highlighting with custom Emacs generic mode

lichen_emacs_mode
I was expecting it to be difficult to get syntax highlighting setup. A quick look on google reveals a truck load of pages on how to do it when searching for “emacs generic mode”.  I’d like the labels to have a different color so they stand out from constants and variables, but this is good enough as it is.

The image to the left is a screen shot of Emacs showing off the highlighting.

The assembler is coming along pretty nicely. Still not sure how I ultimately want to handle looping constructs. I briefly thought about adding a third stack for local variables. I will end up doing that, but it won’t be part of the CPU design.

I’m now up to around 80 instructions. Most of the increase was due to adding in support for signed numbers. I added in some instructions for bit shifting, rotating and directly reading and writing individual bits.

Here’s the highlighting chunk in my emacs init file:

(require 'generic-x)

(define-generic-mode
    'lichen-mode
  '("//")
  '( "add" "sub" "div" "mul" "sadd" "ssub" "sdiv" "smul" 
     "and" "or" "xor" "not" "bsl" "bsr" "sbsl" "sbsr" 
     "bsnl" "bsnr" "sbsnl" "sbsnr" "rotl" "rotr"
     "nop" "inc" "dec" "drop" "dropa" "swap" "roll" 
     "a2d" "d2a" "dup" "push" "pushb" "spushb" "pusha"
     "store" "storei" "storeb" "fetch" "fetchb" "sfetchb"
     "incm" "incmb" "decm" "decmb" "bfetch" "bfetchb"
     "equal" "less" "great" "equalm" "lessm" "greatm" "equalmb"
     "lessmb" "greatmb" "equali" "lessi" "greati" "sless"
     "sgreat" "slessm" "sgreatm" "slessmb" "slessi" "sgreati" 
     "call" "callt" "calli" "callit" "jmp" "jmpt" "jmpi" "jmpit"
     "ret" "halt" "reset" )
  '(
    ("*" . 'font-lock-builtin-face)
    ("**" . 'font-lock-builtin-face)
    ("(" . 'font-lock-warning-face)
    (")" . 'font-lock-warning-face)
    (">" . 'font-lock-builtin-face)
    (">>" . 'font-lock-builtin-face)
    ("++" . 'font-lock-builtin-face)
    ("const" . 'font-lock-variable-name-face)
    ("file" . 'font-lock-variable-name-face)
    ("include" . 'font-lock-variable-name-face)
    ("db" . 'font-lock-variable-name-face)
    ("dw" . 'font-lock-variable-name-face)
    ("ddw" . 'font-lock-variable-name-face)
    ("dsn" . 'font-lock-variable-name-face)
    ("ds" . 'font-lock-variable-name-face)
    (":" . 'font-lock-builtin-face))
  '("\\.lasm$")
  nil
  "lichen assembler mode"
)

 

Designing an instruction set for a stack machine

omap

I’ve spent a lot of time hashing out the instruction set for the CPU I’m designing. My first shot at it didn’t work out too well for a number of reasons. For one, I originally tried to keep the number of opcodes with immediates down to a bare minimum.

Originally the only instruction I had with an immediate was push. To do conditional branches, I had an instruction called ‘istrue’ which would execute the next instruction if true and if false it would skip over it. That only left one instruction for the branch, not enough space to setup an address on the stack easily. There were only two ways to do it, write a really convoluted procedure which made loops practically impossible to understand or abuse the address stack and jump indirectly via the return instruction. The indirect jump via return method required setup in advance and careful attention to tear it back down if the condition was false or you end up accumulating garbage on the address stack or inadvertently jump back into the loop somewhere else down the line.

I’ve gone from around 30 instructions to 51. 15 instructions now have an immediate. I added a few instructions to make it easier to deal with variables in memory so there doesn’t have to be as much stack shuffling. I got rid of the ‘istrue’ conditional branch and now have seperate call and jmp instructions that can take values either off the stack or as an immediate with branching based on a boolean sitting on the data stack.

You can now store with or without an immediate either byte or word sized values. Also added instructions for incrementing and decrementing memory directly.

The new opcode map is here on the left. The stack columns have an In and Out section and each section have ‘ia,ib,ic’ and ‘oa,ob,oc’ fields. The ia-c fields are the inputs and the oa-c fields are the outputs. A,B, and C refer to elements on the stack with A being the top of the stack, B being below and so on. The code field is the byte representing the opcode. Fields i0-i5 are the bytes that make up the immediate associated with the opcode.

Fields are marked either a, d, or b which represent an address, data or a boolean. The in fileds represent what is being taken off of the stack and the out fields represent what is being placed onto the stack. For instance, drop takes an item off of the stack and leaves nothing on the stack after it executes. dup takes one item off of the data stack and leaves two identical items on the stack. a2d takes an item off of the address stack and leaves it on the data stack. ret takes an item off of the address stack and leaves nothing. (it assigns that item to the instruction pointer) fetch takes an item (address) off of the data stack and leaves an item on the datastack (the word at that address). calli doesn’t take any value off either stack, it has an immediate (a procedure address) and leaves an item on the address stack (the return address, which is IP + next opcode address).

Overall, this has been a lot more difficult to design than the VM’s I’ve written in the past. In those cases everything was 32bit, since none of the hardware was real I didn’t need to worry about things like reading and writing to different widths. (SFR mapped devices can be triggered on reads and writes). Communicating with the VM was done though mapped memory spaces and code complexity wasn’t much of an issue since most of the code was generated from python programs. Debugging with the VM was easy, it won’t be on the FPGA.

It’s starting to crystallize into something that could be useful. I’ll probably have to add a few more opcodes, change some others, but I think it’s going in the right direction.

More unhappy capacitors

DSC_0338

 

My power supply started emitting smoke today. Opened it up and found some bulging capacitors and greasy residue on the top of the chassis directly underneath them. Two 4700uF @ 16v caps. I don’t have any of those values on hand, so I had to use a pile of different ones to do the repair. Fortunately the PCB is resting on a set of metal standoffs so there was adequate room to solder some in underneath.

DSC_0342DSC_0340

I put everything back together and it works fine now. I had to adjust two pots for the variable +- 15vdc outputs. The +5v and -5v were spot on. The AC 6v out measures 7v and the AC 12v out measures 13.5v. Nothing I can do about that, those lines come directly out of the transformer.

 

Writing an assembler

I have a rough assembler written for the CPU I’m designing. Enough so far to convert simple programs such as :

shoved 12 shoved 12 add

Into:

14 00 0c 14 00 0c 00

This will make generating code for testing the instruction fetch / decode unit a lot more convenient. I’m also using a python module titled ‘IntelHex’. Quartus II requires Intel Hex format or a proprietary Altera format for ROM and memory initialization files. This python module makes it easy to generate  hex files. You can find it here: https://pypi.python.org/pypi/IntelHex/1.1 . I’m documenting my assembler at this page: http://www.dillo.us/wiki/projects/doku.php?id=fpga_stack_machine_assembler