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.

Sending Digital signal to specified GPIO pin

Other Parts Discussed in Thread: TM4C123GH6PGE

For my application with the TM4C123GH6PGE, I am sampling data from the ADC, doing digital filtering using the CMSIS library and then I want to output the digital data onto a GPIO pin to be used in an external DAC.  

How would I configure the pin for writing continuous data to it?  

The data being processed from the DSP library outputs a float value so I assume that for the DAC to work it would need to be an integer.  

  • Hello Brandon,

    Information needed here would be how many pins do the DAC need for sending the data?

    How is the DAC expecting the continuous data, is there a clock, load pin and  a timing diagram would be useful

    Regards

    Amit

  • Brandon Autrey said:
    DSP library outputs a float value so I assume that for the DAC to work it would need to be an integer.

    In addition to the good guidance passed by friend Amit - has any DAC - by any maker - at any time - supported the resolution demanded by a, "float?"  Thus - your generation of a float forces (necessary) added processing to massage said float value into the best match to the DAC's resolution.  (i.e. "float to nearest integer conversion" most always required)

    DACs range in resolution (today/usually) from 8 to 14 bits with 12 bits best matching your MCU's ADC.  (although I'd not quite, "bet the farm" on any MCU's 3 lsb - thus a 10 bit DAC should serve nicely)  Suspect an I2C or SPI based DAC will avoid the necessity/burden of, "10 data lines + strobes" signal transfer - between MCU & DAC. 

    And - simplest for you if chosen DAC includes a buffered output - saving you the cost/size of adding an op-amp to "beef up" an often ill-fated, high impedance, DAC output.  C'est tres facile - mais oui, mon ami...

  • Sorry for the very vague question.  I talked to my teammate and we are using a AD5660 DAC.  This has a 3 wire serial interface that is compatible with SPI, QSPI, and MICROWIRE.  It includes a buffered amplifier output and 16 bits of resolution.  

    I tried to get the SSI working on the by connecting to another Tiva C Series board.  I used SSI mode 1 with the pins PF0 to PF3.  

    Tx -> Rx

    Clk -> Clk

    Fss -> Fss

    But nothing was being received.  I looked at the FIFO register (SSI_DR) during debug mode using breakpoints, and it showed as all 0's.  If I'm sending data through the Tx pin, shouldn't it copy the value it send to this register and then send it out the pin?  So therefore it should read the value I am about to send.  

    I pasted all the relevant code below.  Is there anything you can suggest to me to fix this?

    It seems as though this post is describing the exact problem I'm having, but has no solution: http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/309096.aspx

    /*
     * Sends data to the external DAC
     * Uses example code from spi_master.c in TivaWare Examples
     */
    void initSPI() {
    
    	//
    	// The SSI1 peripheral must be enabled for use.
    	//
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
    
    	//
    	// For this example SSI1 is used with PortF[0:3].  The actual port and pins
    	// used may be different on your part, consult the data sheet for more
    	// information.  GPIO port F needs to be enabled so these pins can be used.
    	//
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    
    	//
    	// Configure the pin muxing for SSI1 functions on port 0 - 3.
    	// This step is not necessary if your part does not support pin muxing.
    	//
    	GPIOPinConfigure(GPIO_PF2_SSI1CLK);
    	GPIOPinConfigure(GPIO_PF3_SSI1FSS);
    	GPIOPinConfigure(GPIO_PF0_SSI1RX);
    	GPIOPinConfigure(GPIO_PF1_SSI1TX);
    
    	//
    	// 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:
    	//	PF0 - SSI1Rx
    	//	PF1 - SSI1TX
    	// 	PF2 - SSI1Ck
    	//	PF3 - SSI1Fss
    	GPIOPinTypeSSI(GPIO_PORTF_BASE,
    			GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    
    	//
    	// Configure and enable the SSI port for SPI master mode.  Use SSI1,
    	// system clock supply, idle clock level low and active low clock in
    	// freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.
    	// For SPI mode, you can set the polarity of the SSI clock when the SSI
    	// unit is idle.  You can also configure what clock edge you want to
    	// capture data on.  Please reference the datasheet for more information on
    	// the different SPI modes.
    
    	// \param ui32Base specifies the SSI module base address.
    	// \param ui32SSIClk is the rate of the clock supplied to the SSI module.
    	// \param ui32Protocol specifies the data transfer protocol.
    	// \param ui32Mode specifies the mode of operation.
    	// \param ui32BitRate specifies the clock rate.
    	// \param ui32DataWidth specifies number of bits transferred per frame.
    	//
    	SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
    			SSI_MODE_MASTER, 1000000, 8);
    
    	//
    	// Enable the SSI1 module.
    	//
    	SSIEnable(SSI1_BASE);
    }
    
    int main(void) {
    initConsole();
    	initSPI();
    
    	uint32_t pui32DataTx[NUM_SSI_DATA];
    	uint32_t ui32Index;
    
    	//
    	// Initialize the data to send.
    	//
    	pui32DataTx[0] = 's';
    	pui32DataTx[1] = 'p';
    	pui32DataTx[2] = 'i';
    	//continuously send and receive by SPI
    	while (1) {
    
    		//
    		// Send 3 bytes of data.
    		//
    		for (ui32Index = 0; ui32Index < NUM_SSI_DATA; ui32Index++) {
    			//
    			// Display the data that SSI is transferring.
    			//
    
    			//UARTprintf("\nSent: \n");
    			//UARTprintf("'%c' ", pui32DataTx[ui32Index]);
    
    			//
    			// Send the data using the "blocking" put function.  This function
    			// will wait until there is room in the send FIFO before returning.
    			// This allows you to assure that all the data you send makes it into
    			// the send FIFO.
    			//
    	        SSIDataPut(SSI1_BASE, pui32DataTx[ui32Index]);
    
    			//
    			// Wait until SSI1 is done transferring all the data in the transmit FIFO.
    			//
    			while (SSIBusy(SSI1_BASE)) {
    			}
    		}
    
    		SysCtlDelay(SysCtlClockGet() / 3);
    		
    	}

  • Hello Brandon,

    Did you check the physcial pins for Transmission from the SSI master and does the TX, CS and CLK toggle when you write to the SSIDATA Register?

    Regards

    Amit

  • Brandon Autrey said:
     I used SSI mode 1 with the pins PF0 to PF3.  

    Note always defaulting/dreaded PF0 - once more - welcoming a relatively new user.  Good read of the GPIO Section of your MCU manual will reveal the MCU's default management of PF0 to be "outside" your expectations.  Further read and some time here - this forum - will detail the "how/why" of PF0 massage away from default NMI - which precludes its use as you intend.

    Don't know why a 16 b DAC is in play.  Your MCU ADC should yield a solid 9 bits - 3 lsb (this/other MCUs) always bit unstable/suspect.  So DAC appears very much "over-kill" unless other factors intrude which have yet to arrive - this thread.

  • I was able to get the SSI modules working.  The code above actually does work but only for sending.  In order to receive the values you must use a register interrupt.  

    The 16-bit DAC was used because of a previous design where we used a 16-bit external ADC.  But in order to simplify the project, we just went with the on-board ADC which has 12-bits resolution.  And we did not bother to change the DAC.  However the 16-bit DAC requires a 24-bit input shift register.  The SPI modules on the TM4C123G chip can only send 16-bit frames at max.  Therefore this DAC is incompatible with our device.  The AD5620 (12-bit) and AD5640 (14-bit) both require a 16-bit input shift register so these should work.  

    I'm not really asking for any help anymore, I'm just updating my solution in case it is helpful for anyone else.  

  • Hello Brandon,

    The interesting thing about uC is the amount of flexibility it provides. In consideration to the last post, you can still use the 24-bit DAC. Configure the SPI in 12-bit word mode and instead of the CS coming from the SPI, control it through a GPIO.

    Before sending/receiving 24-bit, make the GPIO low, then write the 12-bit data 2 times and read the SSI Data register 2 times. Then make the GPIO high for CS to be deasserted. The SW can then join the 2x12 bit transfers into a single 24-bit value.

    Regards

    Amit

  • So I will be using a GPIO in place of the FSS (or control signal) and controlling when this signal goes high and low manually? 

    "write the 12-bit data 2 times and read the SSI Data register 2 times" I'm confused on what you mean with this?  If I write the 12-bit data two times, I assume the data will be put in two different entries in the transmit FIFO.  The transmit FIFO is 16-bit wide and 8 locations deep.  How does reading data supposed to send it?

    "The SW can then join the 2x12 bit transfers into a single 24-bit value."  I assume SW stands for software.  Do you mean that on the DAC it will convert the two 12-bit transfers into one 24-bit?

  • Hello Brandon,

    Yes, FSS Control is via GPIO Now.

    When the code writes the data two times, the SSI Transmitter serialized and sends the data out till the FIFO is not empty. At the same time the SSI Receiver samples the data on RX Line 2 times in increments of 12 bits and writes the two 12 bits into the FIFO. Hence the relieve FIFO will have two entries of 12 bit each. Reading the same and using shift-OR operation.

    Also SW stands for Software

    E,g,

    SSIDataGet(SSI0_BASE,&upperword);

    SSIDataGet(SSI0_BASE),&lowerword;

    finalword = (upperword << 12) | lowerword;

    Regards

    Amit