I have been trying to get the DAC to trigger an interrupt to the DMA so that there will be as little latency in the data transfer as possible. My current setup is working, but does not produce a desirable result from the output of the DAC as there is a 10us delay between each of the sine waves. The DAC0 output is on CH1, the other channels are irrelevant. I expect that is delay is being created by the way that I am triggering the DMA in software. Any help would be appreciated.
#include <msp430.h> #include <math.h> #include <stdlib.h> //===================================================================================================================================================================== // Global Variables //===================================================================================================================================================================== unsigned char MST_Data_index = 1; unsigned char MST_Data[2]; /** * main.c */ void digital_pot_clt(unsigned int ctl, unsigned int val, unsigned char *ctl1, unsigned char *ctl2) { unsigned int to_convert; unsigned int tmp_val; unsigned int tmp_ctl; unsigned int pot_cmd; //0. Check if the resistance value is greater than 1023. if (val > 1023) { tmp_val = 511; } else { tmp_val = val; } //1. Check the control value. if (ctl <= 6 & ctl >= 0) { tmp_ctl = ctl << 10; } else tmp_ctl = 0; //2. Convert the 16 Bit Control Value to Two 8 Bit Values pot_cmd = tmp_ctl | tmp_val; ctl1[0] = pot_cmd; ctl2[0] = pot_cmd >> 8; } int main(void) { //0. Setup a sin function in memory. unsigned int v[27]; //40kHz v[0] = 2046; v[1] = 2554; v[2] = 3031; v[3] = 3446; v[4] = 3772; v[5] = 3991; v[6] = 4087; v[7] = 4056; v[8] = 3898; v[9] = 3623; v[10] = 3250; v[11] = 2801; v[12] = 2305; v[13] = 1792; v[14] = 1296; v[15] = 846; v[16] = 472; v[17] = 196; v[18] = 37; v[19] = 3; v[20] = 98; v[21] = 315; v[22] = 641; v[23] = 1055; v[24] = 1531; v[25] = 2039; v[25] = 2046; //1. Configure the WDT to stop working. WDTCTL = WDTPW | WDTHOLD; //2. Configure the DAC to, //a. Configure the input range to full scale output. DAC12_0CTL0 = DAC12IR; //b. Configure the DAC reference voltage to AVCC. DAC12_0CTL0 |= DAC12SREF_1; //c. Configure the DAC Amplifier Setting -> Input Buffer: HS/HC & Output Buffer: HS/HC DAC12_0CTL0 |= DAC12AMP_5; //d. Enable Conversion. DAC12_0CTL0 |= DAC12ENC; //e. Turn on Calibration. DAC12_0CTL0 |= DAC12CALON; //f. Select the load trigger for the DAC. //DAC12_0CTL0 |= DAC12LSEL1; //g. Turn on the dac ie. //DAC12IFG will not be set if this is enabled. //DAC12_0CTL0 |= DAC12IE; //3. Configure the DMA controller //a. Source address. __data16_write_addr((unsigned short) &DMA0SA, (unsigned long) &v[0]); //b. Destination Address __data16_write_addr((unsigned short) &DMA0DA, (unsigned short) &DAC12_0DAT); //c. Set the block size. DMA0SZ = 26; //d. Repeated Single Transfer. DMA0CTL = DMADT_5; //e. Source address is incremented. DMA0CTL |= DMASRCINCR_3; //f. Destination address is unchanged. DMA0CTL |= DMADSTINCR_0; //h. Enable DCA Interrupt //DMACTL0 |= DMA0TSEL_25; //g. Enable DMA0 DMA0CTL |= DMAEN; //i. Global Interrupt Enable __bis_SR_register(GIE); //DAC12_0CTL0 = DAC12IFG; //4. SPI Configuration //a. Configure the pins for SPI output //i. Port 8 Pins, //PIN1 (UCA1CLK) //PIN2 (UCA1SIMO) //PIN3 (UCA1SOMI) P8SEL = 0b00001110; P8DIR = 0b00000000; //ii. Port 2 Pins //===PIN2 U10 RST=== //Set the direction. P2DIR = 0b00000100; //Set the pull up resistor (disable). P2REN = 0b00000000; //Set the drive strength (full). P2DS = 0b00000100; //Set the pin function (gpio). P2DS = 0b00000000; P2OUT = BIT2; //===PIN0 U10 SYNC=== //Set the direction. P2DIR |= 0b00000001; //Set the pull up resistor (disable). P2REN |= 0b00000000; //Set the drive strength (full). P2DS |= 0b00000001; //Set the pin function (gpio). P2DS |= 0b00000000; P2OUT |= BIT0; //===PIN1 U10 RDY=== //Set the direction. P2DIR |= 0b00000000; //Set the pull up resistor (enable). P2REN |= 0b00000000; //Set the drive strength (full). P2DS |= 0b00000000; //Set the pin function (gpio). P2DS |= 0b00000000; //iii. Univ. Serial Comm Module (SPI) // **Put state machine in reset** UCA1CTL1 |= UCSWRST; // 3-pin, 8-bit SPI master // Clock polarity high, MSB UCA1CTL0 |= UCMST|UCSYNC|UCCKPL|UCMSB; // SMCLK UCA1CTL1 |= UCSSEL_2; // /2 UCA1BR0 = 0x02; UCA1BR1 = 0 ; // No modulation UCA1MCTL = 0; // **Initialize USCI state machine** UCA1CTL1 &= ~UCSWRST; // Enable USCI_A0 RX,TX interrupt //UCA1IE = UCRXIE; //iv. Setup the SYNC POT input. P2OUT |= 0; //v. Wait for slave to initialize __delay_cycles(100); //vi. Create the POT data. digital_pot_clt(4, 1, &MST_Data[0], &MST_Data[1]); //vii. Send the POT data. while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = MST_Data[MST_Data_index]; // Transmit first character MST_Data_index--; while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = MST_Data[MST_Data_index]; // Transmit first character P2OUT &= BIT2; P2OUT |= 0; //v. Wait for slave to initialize __delay_cycles(100); //vi. Create the POT data. digital_pot_clt(2, 512, &MST_Data[0], &MST_Data[1]); //vii. Send the POT data. while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = MST_Data[MST_Data_index]; // Transmit first character MST_Data_index--; while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = MST_Data[MST_Data_index]; // Transmit first character P2OUT &= BIT2; for(;;) { DMA0CTL |= DMAREQ; } //return 0; }