Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

Interfacing an Analog Joystick to the MSP430FR5739

From Texas Instruments Wiki
Jump to: navigation, search

We will be configuring an analog thumb joystick for use the MSP430FR5739. We will use Grace + DriverLib to quickly generate the peripheral initialization code and program the device. This will help demonstrate the ease of use Grace offers in configuring peripherals as well as a chance to demonstrate DriverLib’s abstraction from register level code.

An analog joystick has two variable resistors for the x and y axis. Each variable resistor has pins connected to VCC and ground andthe output voltage will always be between these two values. ADC10_B on the MSP430FR5739 will be used to sample the output pin for each axis. A value between 0-1023 will be returned where a reading of 512,512 should correspond to the origin (where the joystick is centered).

The values will then be sent serially to a host PC where the PC will manipulate the data to display the correct value. This solution, although not the most elegant was chosen for convenience since the TX buffer on the MSP430 is 8 bits and 10 bits are needed to display the correct value. Thus every two transmissions from the MSP430 will be treated as one value by the host PC.


Equipment

    • CCS5.3: http://processors.wiki.ti.com/index.php/Code_Composer_Studio_Beta_Downloads
    • Grace 2.0: http://www.ti.com/tool/grace
    • MSP430Ware 1.40: http://www.ti.com/tool/msp430ware
    • Analog Thumb Joystick: https://www.sparkfun.com/products/9032
    • MSP430FR5739: http://www.ti.com/product/msp430fr5739
    • Breakout Board; https://www.sparkfun.com/products/9110
    • Serial Terminal (Hterm): http://www.der-hammer.info/terminal/

Software

This project will make use of both MSP430Ware and Grace. MSP430ware is collection of code examples, datasheets and other design resources for ALL MSP430 devices delivered in a convenient package.

In addition to prodviding a complete collection of existing MSP430 design resources, MSP430Ware also includes high level API called MSP430 Driver Library which we will make use of. This new library makes it easy to control to MSP430 hardware from C programs.

Grace is a graphical peripheral configuration tool that is available as a stand along program within Code Composer Studio. Grace enables the configuration of ADCs, DACs, timers, clocks, serial communication interfaces and more, by interacting with buttons, drop-down menus, and text fields. Fully commented and easy-to-understand editable C code in the form of MSP430 Driver Library API’s is generated.

Procedure

We will need to solder the joystick to the breakout board and then the correct pins will need to be wired to the FR5739. We will need to connect the “HERZ” and “VERT” pins on the breakout board to two ADC channels on the experimenter’s board. P1.0 and P1.1 will be connected to the HERZ and VERT pins which correspond to ADC channel 0 and 1. Next, VCC and ground will be connected appropriately. The connections are shown in the picture below.

Analogjoystick.jpg

We will now walk through starting a new Grace project. After opening CCS (5.3 will be used for this demonstration) click on File  CCS Project and look at the settings below.

2wiki1.png

To use Grace you must select a Grace project from the CCS New Project Wizard, as shown above. Click on the “next” tab to verify the version of MSP430ware you are using.

2wiki2.png

Now opening the main.cfg under the Project Explorer we can began to graphically configure the peripherals and generate C code that will initialize these peripherals

2wiki3.png

Click on the device overview to bring up the functional block diagram seem below.

Wiki4.png

The blue boxes indicate they are configurable, click on ADC10_B. In the next window then check the “Configure ADC10_B Peripheral” and click on “Power User Mode”. We will enable two GPIO pins (P1.0 and P1.1) for channels 0 and 1. A single conversion with a sequence of channels will be sampled to return the horizontal and vertical values. The rest ofthe settings are shown below.

5adc.png

Now going back to the overall block diagram we can configure the clock module. Which is seen below.

6clock.png

We will be using the SMCLK which is sourced by the DCO. We will now configure the UART by returning to the overall block diagram and clicking on eUSCI_A0: UART, I2C. In the next window then check the “Configure eUSCI_A0 Peripheral” and click on UART Mode, where the settings are shown below.

7uart.png

Next we will go back to the block diagram overview and select the GPIO module. In this module (similar to the others) you have the option to graphically configure or to select register bits. We will click the “Pinout 40-pin VQFN” and the screen below should appear.

Wiki7.png

We will set P1.0 and P1.1 to A0 and A1 for the ADC channels as shown above. Now we are done with our initialization and can build our project. Looking at the main.c file you can see the call to the Grace generated code. If you press F3 over the call to “Grace_init” it will take you to the different peripheral initialization functions where you can see the generated code.

Graceinit.png

Below is an example of the code generated for the eUSCI_A0 module.

EA0.png

Now that our initialization is complete we can write the values read from the analog joystick and display them to the host PC through the UART. We will use a variable called “position” which will take the value of ADCMEM in the ISR and store the values in an array/ After the call to Grace_init we can enable interrupts for the ADC (this could have also been easily done in Grace). Next we will want to write a segment of code to sample the ADC value and store the values in sequence (horizontal, vertical..) in a 1 x n size array that will be transmitted over the UART.

After this storage is done we will need to initialize pointer of type “char”(since the TX buffer for the UART is 8 bits) that points to the beginning of the array. The array will also need to be cast to a char since it was originally declared as an int. For convenience a counter was chosen to determine how many bytes to transmit where the value of the counter is number of how many ADC samples were read.

  • Hint – If you array is 1 x n the value of count should be 2n since each ADC reading takes two samples.

It is important to note that the value of ADCMEM is 16 bits and the UART TX buffer is 8 bits so every two UART transmissions account for one ADC value. A program on the host PC will be used to correctly interpret the incoming data and store it in a .txt file. The terminal program Hterm was used for serial transmission for its ability to translate the raw serial data to either hex/binary/decimal and store to a .txt file.

Below is a screen shot of the serial data that Hterm received. When saving this data it is important to select the drop down area next to save output and select the format you want (hex was chosen for this example).

Hterm.png

The screenshot below shows the serial data received by Hterm in the form of hex numbers.

Input1.png

After a simple host program formats the data, the decimal form of the coordinates will be displayed (horizontal position followed by vertical position).

Printf.png

The out.txt file should correctly match what was displayed on the console.

Out.png

Code

//***************************************************************************************
#include <ti/mcu/msp430/Grace.h>
 
 
unsigned int ADCresult[100];
volatile long position;
int count = 200;
int i,j;
 
 
int main(void)
{
	        Grace_init();                   // Activate Grace-generated configuration
 
	        /* Enable interrupt request */
	     	ADC10B_enableInterrupt(__MSP430_BASEADDRESS_ADC10_B__);
 
	    	/* Fills array in the format {vertical , horizontal, vertical, ...} */
	    	for (i = 0;i<100;i++) {
 
                /* Delays 1ms for new sample */
	    	__delay_cycles(8000000);
 
	    	/* Starts conversion on channels 0 and 1 */
	    	ADC10B_startConversion(__MSP430_BASEADDRESS_ADC10_B__,ADC10B_SEQOFCHANNELS);
 
	      	/* LPM4 with interrupts enabled */
	      	__bis_SR_register(LPM4_bits + GIE);
 
	        __no_operation();
 
	        /* Stores x position followed by y position in a 1xn array */
	        ADCresult[i] = position;
 
	        /* Set breakpoint below to view values in debugger */
	        __no_operation();
	    						}
	        /* Pointer to beginning of array */
	    	char *Ptr = (char*)&ADCresult[0];
 
	        /* Send data over UART */
	        while(count>0) {
 
	    	   eUART_transmitData(__MSP430_BASEADDRESS_EUSCI_A0__,*Ptr);
 
	    	   /* Increments to next element in array and decrements count */
	    	   Ptr++;
	    	   count--;
 
 
	    	    		}
 
 
}
 
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
  switch(__even_in_range(ADC10IV,12))
  {
    case  0: break;                          // No interrupt
    case  2: break;                          // conversion result overflow
    case  4: break;                          // conversion time overflow
    case  6: break;                          // ADC10HI
    case  8: break;                          // ADC10LO
    case 10: break;                          // ADC10IN
    case 12: position = ADC10MEM0;
             __bic_SR_register_on_exit(LPM4_bits);
             break;                          // Clear CPUOFF bit from 0(SR)
    default: break;
  }
}

The program below will reside on the host PC to interpret the incoming data and store it in a .txt file.

#include <stdio.h>
 
#define SAMPLESIZE 100
 
int main() {
    FILE *fop;
    FILE *fcl;
    unsigned int value[SAMPLESIZE];
    int i,j=0;
    int totalsize = SAMPLESIZE;
    unsigned int sum = 0;
 
    fop=fopen("input1.txt","r");
    fcl=fopen("out.txt","w");
 
    // Read in UART values from .txt file
    while (j < 100) {
        fscanf(fop, "%2X ", &value[j]);
        j++;
    }
 
    for(i=0; i< totalsize; i +=2)
    {
    // Swap every two values in the array
    int temp = value[i];
    value[i] = value[i+1];
    value[i+1] = temp;
 
    // Converts two 8 bit values into a 16 bit values and displays and stores (in decimal)
    sum = (value[i] << 8) | (value[i+1] & 0x00FF);
    printf("%02d\n" ,sum);
    fprintf(fcl, "%02d\n", sum);
    }
 
    fclose(fop);
    fclose(fcl);
 
    return 0;
}

References

  1. MSP430FR57xx Family User Guide