DIY ez-FET lite…ghetto style

I have a few MSP430G2955 around but non of my Launchpads are capable of programming this MCU. Texas Instruments released a while back all the informtation needed to build the new ez-FET lite. The eZ-FET lite is a low cost USB-based on-board emulation solution for MSP430 microcontrollers. This debuger supports all MSP430 devices compatible with SBW programming and I could use it to program the MSP430G2955.

The hardware is based on an MSP430F5528 and I used a QFN version with an adapter board:



it ain’t pretty…

In order to program the MSP430F5528, I tried first using the FET-Pro430 from Elpotronic. I was able to flash the BSL firmware:


despite an error dialog about code size:


…then, I programmed the ez-FET firmware:


After reseting the programmer all the drivers were installed:


But every time I tried to program a device with CCS I would get this error message:


ok, fail…let’s start over.

According to this post the error might be caused by the the custom BSL portion of the ezFET firmware being not properly flashed.  I did read this other post in 43oh about flashing the firmware with MSP430Flasher, I just wanted to see if the Elpotronic software would work.

I tried  to re-program the MSP430F5528 using MSP430Flasher but I get this “BSL memory segments are protected” error.


According to this post I have to add options to unlock  BSL memory as well as the INFO A memory. I added for that -b and -u:


Success!! At least the BSL.  Then I attemped a firmware update with MSP430Flasher:


More success!!! I should have tried this in first place…

Anyway, I tested the programmer with the old and beloved “blink” and It’s working. I still need to test the UART interface but this should work as well.



MSP430 and a HC-SR04 Ultrasonic Ranging Module

A while back I bought an HC-SR04. It sat in a box until yesterday when I tried to use it with an MSP430G2553 but unfortunately it wasn’t working. I used Energia to program the Launchpad but I wasn’t getting any response from the device. I hooked up my Logic analyzer to see what was going on and….

hc-sr04…the trigger pulse (channel 1) is there but the device will produce essentially the same echo (channel 0), regardless of whether I put an object in front of the module or not. It wasn’t working.

A quick visual inspection and a comparision with other boards photos showed that two components where missing, a capacitor and a SOT-23 device.


The capacitor was easy to replace. The device near it is a MAX232 used to drive the piezo tranducer and the capacitor is connected between GND and the VCC pin. Acording to the datasheet a 1uF decoupling cap is used.


For the SOT device I made a search looking for a module similar to the one I have but I needed a photo in which the device markings were readable. Eventually I found one with the marking J3Y which turned out to be a S8050LT1 NPN transistor and I replaced it with a PMBS3904.


A quick test with the Launchpad and….It’s working!!!!… now the module responds (now is channel 1) to the trigger (channel 0) with a longer pulse proportional to the distance being measure and the MSP430 is sending data. The Analyzer is showing an echo of 7,206 mS and that translate to 124,24 cm, quite a difference with the value calculated with the Launchpad. The MSP430 is using the internal oscilator as the main clock and is not as accurate as the crystal used for the clock in the Logic analyzer. The error quoted in the datasheets for the MSP430 give the calibrated DCO frequencies a tolerance over temperature and any other changes of ±3%.  The difference in this case is close to 10% and I don’t think it can be entirely explained by the clock source.


Interfacing the ADS8328 to an MSP430

The ADS8328 is a high-speed, low power, successive approximation register (SAR) analog-to-digital converter (ADC) that uses an external reference. The ADS8328 has an internal clock that is used to run the conversion but can also be programmed to run the conversion based on the external serial clock, SCLK.

The ADS8328 has two inputs. Both inputs share the same common pin—COM. The ADS8328 can be programmed to select a channel manually or can be programmed into the auto channel select mode to sweep between channel 0 and 1 automatically.

The ADS8327/28 can operate with an external reference with a range from 0.3 V to 4.2 V. A clean, low noise, well-decoupled reference voltage on this pin is required to ensure good performance of the converter. A 10-µF ceramic decoupling capacitor is required between the REF+ and REF– pins of the converter. These capacitors should be placed as close as possible to the pins of the device. REF– should be connected to its own via to the analog ground plane with the shortest possible distance. The test was performed on a breadboard with poor decoupling. The goal was to test the library and the SPI interface to be used in the final setup.

The ADS8327/28 has an oscillator that is used as an internal clock which controls the conversion rate. The frequency of this clock is 10.5 MHz minimum. The oscillator is always on unless the device is in the deep power-down state or the device is programmed for using SCLK as the conversion clock (CCLK).

Channel selection can be done both manual or automatically if auto channel select mode is enabled. The manual conversion mode is used and the conversion cycle starts with selecting an acquisition channel by writing a channel number to the command register (CMR).

The end of acquisition or sampling instance (EOS) is the same as the start of a conversion. This is initiated by bringing the CONVST pin low for a minimum of 40 ns. After the minimum requirement has been met, the CONVST pin can be brought high. A conversion can also be initiated without using CONVST if it is so programmed (CFR_D9 = 0). To have more control over the whole process the CONVST pin is used to start conversion.

The status pin is programmed as EOC and the polarity is set as active low, with this configuration the pin works in the following manner: The EOC output goes LOW immediately following CONVST going LOW when manual trigger is programmed. EOC stays LOW throughout the conversion process and returns to HIGH when the conversion has ended (as seen in the last picture).

Internal Register

The internal register consists of two parts, 4 bits for the command register (CMR) and 12 bits for configuration data register (CFR).

Command Set Defined by Command Register (CMR)


The following table shows the Configuration Register (CFR) Map.


To start the communication first the CFR data is sent.


Then the converted values are read. The ADC reference is connected to 3,4 V and the channel is reading the 2,5 V from a DAC7564 internal voltage reference.



ADS8328 Datasheet


Interfacing the DAC7564 to an MSP430

In this article I’ll try to show how to use an MSP430 with a DAC7564. This is probably the first from a series of articles showing different devices I plan to use in a project.

The DAC7564

The DAC7564 is a low-power, voltage-output, four-channel, 12-bit digital-to-analog converter (DAC). The device includes a 2.5V, 2ppm/°C internal reference. The device is monotonic, provides very good linearity, and minimizes undesired code-to-code transient voltages (glitch).  A DAC is said to be monotonic if the output either increases or remains constant for increasing digital inputs such that the output will always be a nondecreasing function of input. The DAC7564 architecture consists of a string DAC followed by an output buffer amplifier. An N-bit string DAC simply consists of 2N equal resistors in series and 2N switches (usually CMOS), one between each node of the chain and the output. The output is taken from the appropriate tap by closing just one of the switches. The string DAC is inherently monotonic—even if a resistor is accidentally short-circuited, output n cannot exceed output n + 1.

Linearity error of a converter is a deviation of the analog values, in a plot of the measured conversion relationship, from a straight line. The string DAC it is lineal if all the resistors are equal.

A glitch is a switching transient appearing in the output during a code transition. The worstcase DAC glitch (in R-2R) generally occurs when the DAC is switched between the 011…111 and 100…000 codes. In sting DACs only two switches operate during a transition, resulting in a low-glitch architecture Also, the switching glitch is not code-dependent.

The DAC7564 uses a versatile 3-wire serial interface that operates at clock rates up to 50MHz. The interface is compatible with standard SPI, QSPI, Microwire, and digital signal processor (DSP) interfaces.

The DAC7564 input shift register is 24 bits wide. Bits DB23 to DB16 are used for control and configuration and bits DB15 to DB4 for data. Bits DB0, DB1, DB2, and DB3 are ignored by the DAC. All 24 bits of data are loaded into the DAC under the control of the serial clock input, SCLK.

The DAC7564 receives all 24 bits of data and decodes the first eight bits in order to determine the DAC operating/control mode. The 12 bits of data that follow are decoded by the DAC to determine the equivalent analog output.

The write sequence begins by bringing the SYNC line low. Data from the DIN line are clocked into the 24-bit bits wide shift register on each falling edge of SCLK. After receiving the 24th falling clock edge, the DAC7564 decodes the eight control bits and 12 data bits to perform the required function, without waiting for a SYNC rising edge. A new write sequence starts at the next falling edge of SYNC.

Data Input Register Format

The first two control bits (DB23 and DB22) are the address match bits. The DAC7564 offers hardware-enabled addressing capability, allowing a single host to talk to up to four DAC7564s through a single SPI bus without any glue logic, enabling up to 16-channel operation. The state of DB23 should match the state of pin A1; similarly, the state of DB22 should match the state of pin A0. If there is no match, the control command and the data (DB21…DB0) are ignored by the DAC7564. That is, if there is no match, the DAC7564 is not addressed.  Both pins are connected to ground therefore those bits are 0.

Data Input Register Format

Data Input Register

LD1 (DB21) and LD0 (DB20) control the loading of each analog output with the specified 12-bit data value or power-down command. In the final setup the DAC will need to update each channel individually and at different times so Single-channel update will be used which implies having DB21 = 0 and DB20 = 1.  The final control bit, PD0 (DB16), selects the power-down mode of the DAC7564 channels as well as the power-down mode of the internal reference. In this application there is no concern over power savings so bit SB16 will be 0.

Load commands

Load commands

Bit DB19 must always be ‘0’.The DAC channel select bits (DB18, DB17) control the destination of the data (or power-down command) from DAC A through DAC D.

The final control matrix to be used is as follow;

Control matrix

The initial test are done using the internal voltage reference enabled by default. The DAC7564 includes a 2.5V internal reference with 0.004% Initial Accuracy (typ) and 5ppm/°C Temperature Drift (max). In the future a 4.096 V reference will be used and for that the internal reference need to be disabled. To do that a serial command that requires a 24-bit write sequence must be used.

The software

An MSP430 is used to send the data and the SPI communication is done by bit-banging. A library provides functions to send, receive and transfer data using SPI protocol. Being a bit-bang communication there is no particular hardware module necessary and any MSP430 would work, in this particular case a MSP430F2274 is used. The function send 8 bit at a time and the data needs to be rearranged before sending. The first byte (DB23…DB16) corresponds to the address, the load command, power down bit and the channel selection. The second byte (DB15…D8) corresponds to the eight most significant bits of the 12 bits DAC value. In the third and last byte the remaining 4 bits of the DAC value is sent. The image below shows a capture of the data pattern made using a logic analyzer.



A Launchpad was used as an oscilloscope to see the DAC’s outputs (I don’t have a scope, I’m saving for one. If you have found the site useful, please consider making a donation and help me buy one 🙂). For the test the internal 2.5 V voltage reference was used and the microcontroller generated a ramp style signal and a couple of sine waves. The picture shows the DAC’s outputs (sampled at 55[Hz]).


The sine waves are generated using a 256 points look-up table. For the green one the value from the table is divided by two.



The data conversion handbook. Analog Devices Series Electronics & Electrical. Walter Allan Kester. 3 Ed. Newnes, 2005.

DAC7564 Datasheet.


Making an FM radio-Part 2; the incremental encoder

Despite being a digital radio capable of doing a lot of stuff I wanted a simple design with a knob for volume and another one to change station. The volume is just a potentiometer and for the stations I wanted to use an encoder, unfortunately I didn’t have one. What I did have is a hard drive motor and as it turns out you can use them as rotary encoders. I found two ways to do this; one is to use the signals from the hall sensors and the other one is to use the back fem generated by the winding. The motor has all the electronics sealed making it difficult to figure out how to use the sensors so I used the second method. I found two projects that use brushless motors as encoders taking advantage of the back EMF. In one op-amps are used as amplifiers and the outputs are sampled with a microcontroller’s ADC, in the other the op-amps are used as comparators thus generating a couple of square waves. With the second approach I could use interruptions instead of sampling both ADC channels all the time so I went for the comparator setup.
For the first tests I used only a couple of led at the op-amp outputs to see if the circuit was doing something. Then I watched the outputs with a logic analyzer and let me tell you, it wasn’t pretty. Anyway, I searched for ways to read encoder signals with a microcontroller and I found this. I copied that code and add it a few lines to have a couple of pins generating pulses depending on the direction of rotation.

Unfortunately that code was made to be used with a real encoder with a much cleaner signal. In the picture I’m moving the motor in one direction but both outputs (channel 2 and 3) are generating pulses.

If you use an optical encoder all you have to do is detect a flank (either low->high or high->low) in one signal and check the value of the other one. With my “encoder” I have to detect both flanks and check the values of the other signal in those situations to see if an acceptable sequence has occurred.  And after a few changes I got this;

The first picture shows the signals generated when I move the motor fast first in one direction and then in the other. In the second picture I’m moving the motor slower (as if I’m looking for a station) in only one direction.  The signal is worst when I turn it slower but the microcontroller managed to detect a few pulses which I’ll be using to control the radio. Finally the code;

#include <msp430g2452>;
#include "stdint";
int aux=0;
int edge=1; //0=high-&gt;low, 1=low-&gt;high
int dir=0;
int accept=0;
void main( void )
 // Stop watchdog timer to prevent time out reset
BCSCTL1 = CALBC1_16MHZ; // Set range
P1REN |= BIT1 + BIT2;  // select pullup resistors for pin 1.1 and 1.2
P1DIR |= BIT5 + BIT4;  // outputs for testing
P1OUT |= BIT1 + BIT2;  // need to set P1.1 and P1.2 to high so PULLUP resistor will be selected
P1IES &= ~ BIT2;  // select low to high transition for interrupts on all port pins (this actually the default)
P1IE  |= BIT2;  // enable interrupt for P1.2 to reader status of encoder every time Encoder sigal A goes high
P1IFG = 0x00;  // clear interrupt register
__bis_SR_register(LPM0_bits + GIE);
for (;;) {
#pragma vector = PORT1_VECTOR
 __interrupt void InterruptVectorPort1()
 if( P1IFG &amp; BIT2 ) {
     case 1://always start with the 0-&gt;1 edge
      aux=( P1IN &amp; BIT1 );//save the other channel input
      P1IES =BIT2; //Edge sensitivity
      edge=0;//the next interruption will be in 1-&gt;0
      accept=0;//reset value
     case 0:
      if((P1IN & BIT1)==aux){accept=0;}//Not a good pulse sequence;
      else{accept=1;//Good pulse sequence
      P1IES &= ~BIT2 ; // Toggle Edge sensitivity
      if(P1IN & BIT1){dir=2;}//save direction of movement
 } if(accept){//if a good sequence is detected...
    switch(dir){//output a short pulse in the correct direction
     case 2:
      P1OUT |= BIT4; // output P1.4
      P1OUT &= ~BIT4;
    case 1:
      P1OUT |= BIT5; // output P1.5
     P1OUT &= ~BIT5;
 P1IFG&= ~ BIT2;