This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TM4C123GH6PM: SPI based Digital Pot

Part Number: TM4C123GH6PM

Tool/software: Code Composer Studio

Hello All,

I am working on SPI based Digital pot ( 10K ) MCP4152103.

I am not able to initializing Pot. could you please tell me if i did anything wrong in the below code.

//*****************************************************************************
//
// Digitalpot.c - Example demonstrating how to configure SSI2 in TI master mode.
//
// Copyright (c) 2010-2017 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
//
// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package.
//
//*****************************************************************************

#include <stdbool.h>
#include <stdint.h>

#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/pwm.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "driverlib/adc.h"
#include "driverlib/timer.h"
#include "math.h"
#include "driverlib/ssi.h"
#include "driverlib/qei.h"

//*****************************************************************************
//
//! \addtogroup ssi_examples_list
//! <h1>TI Master (ti_master)</h1>
//!
//! This example shows how to configure the SSI0 as TI Master.  The code will
//! send three characters on the master Tx then poll the receive FIFO until
//! 3 characters are received on the master Rx.
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - SSI2 peripheral
//! - GPIO Port B peripheral (for SSI2 pins)
//! - SSI2Clk - PB4
//! - SSI2Fss - PB5
//! - SSI2Rx  - PB6
//! - SSI2Tx  - PB7
//!
//! The following UART signals are configured only for displaying console
//! messages for this example.  These are not required for operation of I2C0.
//! - UART0 peripheral
//! - GPIO Port A peripheral (for UART0 pins)
//! - UART0RX - PA0
//! - UART0TX - PA1
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - None.
//
//*****************************************************************************

// DigitalPot Command Byte for Digital Pot Reading and writing.
//
//*****************************************************************************
#define COMMAND_WRITE            0x40
#define COMMAND_READ             0x4C
//*****************************************************************************
//
// Transmit FIFO and Receive FIFO
//
//*****************************************************************************
uint32_t pui32DataTx;
uint32_t pui32DataRx;

//*****************************************************************************
//
// This Function is used to Enable the all peripheral clocks.
// A,B,C,D,E and F
//*****************************************************************************
void InitModules(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
}
//*****************************************************************************
//
// This function sets up UART0 to be used for a console to display information
// as the example is running.
//
//*****************************************************************************
void
InitConsole(void)
{
    //
    // Enable UART0 so that we can configure the clock.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //
    // Configure the pin muxing for UART0 functions on port A0 and A1.
    // This step is not necessary if your part does not support pin muxing.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);

    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    //
    // Select the alternate (UART) function for these pins.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Initialize the UART for console I/O.
    //
    UARTStdioConfig(0, 115200, 16000000);

}
//*****************************************************************************
//
// Configure SSI2 in Master TI mode.  This example will send out 10 bytes of
// data, then wait for 3 bytes of data to come in.  This will all be done using
// the interrupt method.
//
//*****************************************************************************
void
InitSSI2(void)
{
    //
    // The SSI0 peripheral must be enabled for use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);

    //
    //
    // Configure the pin muxing for SSI2 functions on port A2, A3, A4, and A5.
    // This step is not necessary if your part does not support pin muxing.
    // TODO: change this to select the port/pin you are using.
    //

    GPIOPinConfigure(GPIO_PB4_SSI2CLK);
   // GPIOPinConfigure(GPIO_PB5_SSI2FSS);
    GPIOPinConfigure(GPIO_PB6_SSI2RX);
    GPIOPinConfigure(GPIO_PB7_SSI2TX);


    //
    // Configure the GPIO settings for the SSI pins.  This function also gives
    // control of these pins to the SSI hardware.  Consult the data sheet to
    // see which functions are allocated per pin.
    // The pins are assigned as follows:
    //      PB7 - SSI0Tx
    //      PB6 - SSI0Rx
    //      PB5 - SSI0Fss
    //      PB4 - SSI0CLK
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypeSSI(GPIO_PORTB_BASE,GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_4);

    //
    // Configure PB2,PE0,PF0,PA6 pins for digital pot slave select
    //
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_2);
    GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE,GPIO_PIN_0);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_0);
    GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_6);


    //
    // Unlock the PF0 pin
    //
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
    HWREG(GPIO_PORTF_BASE + GPIO_O_AFSEL) |= 0x400;
    HWREG(GPIO_PORTF_BASE + GPIO_O_DEN) |= 0x01;
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;


    //
    // Configure and enable the SSI port for TI master mode.  Use SSI2, system
    // clock supply, master mode, 1MHz SSI frequency, and 8-bit data.
    //
    SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(),SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER,50000, 16);

    //
    // Enable SSI2 module
    //
    SSIEnable(SSI2_BASE);


    //
    // Make Chip select pins as High
    //
    GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2);
    GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_0,GPIO_PIN_0);
    GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_0,GPIO_PIN_0);
    GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,GPIO_PIN_6);


    //
    // Read any residual data from the SSI port.  This makes sure the receive
    // FIFOs are empty, so we don't read any unwanted junk.  This is done here
    // because the TI SSI mode is full-duplex, which allows you to send and
    // receive at the same time.  The SSIDataGetNonBlocking function returns
    // "true" when data was returned, and "false" when no data was returned.
    // The "non-blocking" function checks if there is any data in the receive
    // FIFO and does not "hang" if there isn't.
    //
    while(SSIDataGetNonBlocking(SSI2_BASE, &pui32DataRx))
    {
    }
}

//*****************************************************************************
//
// This function is used to send 16 bit data over SSI2 bus
//
//*****************************************************************************
bool
SSI2_MCP41HV51_Write (uint32_t ulDataTx,uint32_t channel)
{

    uint32_t validity = false;

    pui32DataTx = 0x4200 | (ulDataTx & 0xff);

   // pui32DataTx = ulDataTx;

    switch(channel)
    {

    case 1: GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,~GPIO_PIN_2);
            SysCtlDelay(100);
           // SSIDataPut(SSI2_BASE, 0x0000);
            SSIDataPut(SSI2_BASE, pui32DataTx);
            while(SSIBusy(SSI2_BASE));
            GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2);
            SysCtlDelay(100);
            validity = true;
            break;

    case 2: GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_0,~GPIO_PIN_0);
            SysCtlDelay(100);
            SSIDataPut(SSI2_BASE, pui32DataTx);
            while(SSIBusy(SSI2_BASE));
            GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_0,GPIO_PIN_0);
            SysCtlDelay(100);
            validity = true;
            break;

    case 3: GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_0,~GPIO_PIN_0);
            SysCtlDelay(100);
            SSIDataPut(SSI2_BASE, pui32DataTx);
            while(SSIBusy(SSI2_BASE));
            GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_0,GPIO_PIN_0);
            SysCtlDelay(100);
            validity = true;
            break;

    case 4: GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,~GPIO_PIN_6);
            SysCtlDelay(100);
            SSIDataPut(SSI2_BASE, pui32DataTx);
            while(SSIBusy(SSI2_BASE));
            GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,GPIO_PIN_6);
            SysCtlDelay(100);
            validity = true;
            break;

    default:GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2);
            GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_0,GPIO_PIN_0);
            GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_0,GPIO_PIN_0);
            GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,GPIO_PIN_6);
            validity = false;

    }
    return validity;
}


//*****************************************************************************
//
// Main function entry starts here
//
//*****************************************************************************
int
main(void)
{
    uint32_t Rx_Data[10] = {0};
    uint32_t count = 0;

    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal on your board.
    //

    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
            SYSCTL_XTAL_16MHZ);


    //
    // Set up the serial console to use for displaying messages.
    //
    InitModules();
    InitConsole();
    InitSSI2();

    SSI2_MCP41HV51_Write(0x00,1);
    SysCtlDelay(10000);
    SSI2_MCP41HV51_Write(0xff,1);
    SysCtlDelay(10000);
    while(1)
    {

//        //
//        // Receive command the data from UART to control the Digital pot
//        //
//        while(UARTCharsAvail(UART0_BASE))
//        {
//             Rx_Data[count] = UARTCharGetNonBlocking(UART0_BASE);
//
//             if( Rx_Data[count] == '@')
//             {
//                 uint32_t Channel = Rx_Data[0] - 48;
//                 uint32_t Data =  ((Rx_Data[2] - 48) * 100) +  ((Rx_Data[3] - 48) * 10) + (Rx_Data[4] - 48);
//                 SSI2_MCP41HV51_Write(Data,Channel);
//                 count = 0;
//             }
//             else
//             {
//             count++;
//             }
//        }


        SSI2_MCP41HV51_Write(0x80,1);
        SysCtlDelay(10000);


//        SSI2_MCP41HV51_Write(0x10,2);
//        SysCtlDelay(100);
//
//        SSI2_MCP41HV51_Write(0x20,3);
//        SysCtlDelay(100);
//
//        SSI2_MCP41HV51_Write(0x30,4);
//        SysCtlDelay(100);

    }
}