In a previous project article, I covered the basic circuit design considerations for a custom capacitive touch interface with TI's MSP430FR2633. In this article, we'll instead take a closer look at the PCB design considerations and programming of the device.

My interface is made of two circuit boards: a four-layer circuit board that houses the microcontroller and support circuitry, and a two-layer circuit board that has the capacitive touch panels and indicator LEDs.

### PCB Layout Considerations for the MSP430FR2633

The main circuit board is a four-layer stack-up with internal ground plane and hatched power plane. Hatching helps to reduce parasitic capacitance that could negatively affect the performance of the capacitance touch sensing.

The components are mounted on the top side of the board, with the exception of the ESD diodes and USB connector. The USB connector is mounted on the bottom of the board to avoid a crossover of the differential pair lines between the micro USB connector and the CP2102N, as well as to take advantage of unused space between the circuit board and the case.

The fabrication house I ordered this board from, MacroFab, charges the same for one-sided and two-sided boards.

##### Shown above are top-down images of the four circuit board layers.

I was concerned about capacitive coupling between traces of the capacitive touch pins and the layers below. To minimize the capacitive effects, I used 5 mil traces for the connections and a hatched fill with fixed trace width and varying space width between layers.

It’s not strictly necessary to do so, but I wanted to offset the hatched fills on the different layers. Unfortunately, that is not a feature of my PCB design program (Diptrace), and manually shifting the hatched fills provided inconsistent results. Using minimal-trace-width capacitive-touch-sense lines with hatched fills on the nearby power layer is meant to decrease the capacitance on the capacitive touch pins.

##### The second layer of the circuit board (Vcc) can be seen in red. Hatched fills and thin traces are used to decrease the effects of capacitive coupling.

The hatched fill is connected to the same net as the solid fill. I added additional points in the solid fill to create a negative space that a second hatched copper area fills in. With Diptrace, defining the positive and negative area prevents the solid fill from filling the hatched area.

### LED Considerations

##### Bottom side of the capacitive control panel

Changes in signal state used to drive LEDs can be detected as a change in capacitance by the microcontroller. To avoid an accidental activation, TI recommends keeping digital and capacitive signal lines separated by at least 4 mm. Additionally, when crossing on different layers, they should cross at right angles.

Rather than routing traces through vias that place the LEDs on the same layer as the buttons and rotary wheel, I chose to use reverse-mount LEDs that shine through holes in the circuit board.

### CP2102N Programming

The CP2102N is programmed with the Simplicity Studio Express Configuration tool from Silicon Labs. Two GPIO pins are used to indicate UART data transmission between the MSP430FR2633 and the CP2102N. These LEDs are on different nets than the actual data transmission, and the LEDs appear to light up for transmitted bytes and strings of data, rather than the individual data bits.

Please see my other article about how I overcame a programming difficulty with the CP2102N

### MSP430FR2633 Programming

As I mentioned in the first article, the CapTIvate Design Center is a graphical software tool that can generate most of the code needed to get this project running. It does need to know what buttons and slider wheels exist and which pins they are attached to. The software generates all of the C source code, header files, and libraries required to run the microcontroller and the capacitive touch interface.

Unfortunately, at this point, the software had no idea that I have added indicator LEDs to my board. So I unfortunately couldn't simply build the code and upload it to the microcontroller. I first needed to tell the MSP430FR2633 that it had some LEDs attached to it and then come up with a way to turn them on and off.

I elected to do this through bitmasking. I have five LEDs in the upper left, bottom left, center, upper right, and bottom right corners of the control panel, and I wanted to create three ways to control them—on, off, and toggle.

The way to do this for the MSP is to treat the LEDs as though they are bits at a specific location in memory. Write a 1 and the LED turns on; write a 0 and it turns off; invert the value and you’ll toggle the LED state. The pins are mapped to bits in various registers. These bit locations are determined by the pinout on the microchip. For example, GPIO Pin P2.3 is at bit 3 in register 2. To turn the LED on and off, you simply manipulate the 3rd bit of register 2. The register location P2 is defined in another file specific to the microcontroller.

Fortunately, the basic structure is included in a sample sketch for the MSP430FR2633 in Code Composer Studio. All I had to do was copy and modify it for my LEDs.

LED_UL represents the LED in the upper left of the control panel.

                    #define LED_UL_POUT                  (P2OUT)
#define LED_UL_PDIR                   (P2DIR)
#define LED_UL_PIN                    (BIT3)
#define LED_UL_ON                    (LED_UL_POUT |= LED_UL_PIN)
#define LED_UL_OFF                    (LED_UL_POUT &= ~LED_UL_PIN)
#define LED_UL_TOGGLE                (LED_UL_POUT ^= LED_UL_PIN)


In the main() function, a small command needed to be inserted to disable the GPIO-pin high-impedance mode. If you're following along for your own project, insert the command after the watchdog timer is stopped or the LEDs will never light.

                    Void main(void){
WDTCTL = WDTPW | WDTHOLD;     // Stop watchdog timer
PM5CTL0 &= ~LOCKLPM5;          // Disable Power-On High-Impedance mode
…
}


Lastly, I needed to write a function that uses the capacitive touch interface sensor position to light the LEDs.

                    void my_slider_callback(tSensor* pSensor)
{
// FIRST CHECK IF THERE IS VALID TOUCH
if(pSensor->bSensorTouch == true)
{
// THEN GET THE CURRENT TOUCH POSITION ON THE SLIDER/WHEEL
position = (uint16_t)((tSliderSensorParams*)pSensor->pSensorParams)->SliderPosition.ui16Natural;
// Even though it is storing the data in a 16-bit integer, the numbers never exceed 8 bits in length
// Use the position to generate eight cases -- illuminate one of four corners, or illuminate one of four sides.
// Mask bits 5:7 thenshift them to become bits 0:2
// case8 = (position & 0x00E0) >> 5;
// add an integer offset if lights are rotated from wheel positions
case8 = ((position & 0x00E0)>>5) + 3 ) % 7
switch(case8)
{
case 0: // Light Upper Left Corner
LED_UL_ON;LED_UR_OFF;LED_BR_OFF;LED_BL_OFF;
break;
case 1: // Light Top Side
LED_UL_ON;LED_UR_ON;LED_BR_OFF;LED_BL_OFF;
break;
case 2: // Light Upper Right Corner
LED_UL_OFF;LED_UR_ON;LED_BR_OFF;LED_BL_OFF;
break;
case 3: // Light Right Side
LED_UL_OFF;LED_UR_ON;LED_BR_ON;LED_BL_OFF;
break;
case 4: // Light Bottom Right Corner
LED_UL_OFF;LED_UR_OFF;LED_BR_ON;LED_BL_OFF;
break;
case 5: // Light Bottom Side
LED_UL_OFF;LED_UR_OFF;LED_BR_ON;LED_BL_ON;
break;
case 6: // Light Bottom Left Corner
LED_UL_OFF;LED_UR_OFF;LED_BR_OFF;LED_BL_ON;
break;
case 7: // Light Left Side
LED_UL_ON;LED_UR_OFF;LED_BR_OFF;LED_BL_ON;
break;
Default: // Turn corner lights off and toggle center LED
LED_UL_OFF;LED_UR_OFF;LED_BR_OFF;LED_BL_OFF;LED_C_TOGGLE;
break;
}
}
}


### JTAG Troubleshooting

In a perfect world, I would have been able to immediately upload the code and begin experimenting. But that’s not the easy way.

My initial attempts to program the board failed with an error message indicating that no device was attached. I began to troubleshoot the issue with my oscilloscope and saw the following JTAG transaction.

##### Shown above is a nonfunctional JTAG transaction. Test, TMS, TCK, TDO, TDI, and nRST states are defined as low/high at the oscilloscope based on a 1.51 V threshold.

For those of you who are unfamiliar with JTAG programming, that is not at all what you would expect a JTAG transaction to look like. Ideally, there is an entry sequence followed by rapid transition of the clock signal and data transitions on the TDO and TDI lines.

Out of curiosity, I decided to add a normal analog probe to my investigations to see what the signals were doing in greater detail. The analog-probe trace is shown below in yellow.

##### Shown above in white is a complete JTAG transaction for the MSP430FR2633. The yellow trace is a normal analog measurement that is duplicating the TDI signal line.

Now I had some additional interesting information with the yellow probe trace. The signals were not always in a logic-high or logic-low state. Something else was interacting with the signal lines and maintaining a ~2 V potential difference that is interfering with the programming signals.

At the same time, I realized that the two pins I’d chosen for the USB-to-serial interface (UCA0TXD, UCA0RXD) happened to double as TCK\VREF+ and TMS, respectively. So there was absolutely no way to test the USB-to-serial interface while connected to a JTAG interface, and there was a strong likelihood that the CP2102N was actively interfering with the JTAG programming.

Unfortunately, I needed a board redesign that relocated the Tx/Rx pins of the CP2102N to the UCA1RXD and UCA1TXD lines.

##### MSP430FR2633 better JTAG transaction

After receiving my new circuit board and hooking it up to my JTAG programmer, I had one last hurdle. I was frustratingly still unable to program it until I performed a firmware upgrade on the programmer.

But, after all that, I finally have a project that allows me to better understand and program capacitive ring sliders.

The Texas Instruments MSP430 User's Guide demonstrates multiple ways to access the capacitive slider and buttons, and this is just one of them. However, this approach should help you to begin experimenting on your own with a capacitive touch slider in your next design. I hope you enjoyed it.
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.2562190890312195, "perplexity": 2829.3790460658647}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2018-17/segments/1524125945143.71/warc/CC-MAIN-20180421110245-20180421130245-00553.warc.gz"}