Other Parts Discussed in Thread: MSP430FR2355, TIDA-00648, TIDM-01000
Good morning,
I have some issues with the communication between the MCU MSP430FR2355 and the DAC161S997.
My goal is to simply program the current that I want on the DAC output.
For now, I get 2.119 mA on LOOP- (although I asked in the code for 5mA). Pin ERRB is low, so there is an error somewhere...
For testing I use 2 interrupts for reading the registers 0x09 and 0x05 (so I sent commands 0x89 and 0x85).
I tried to send
0x89 0x5555 0x02 0xDEAD (read status and NOP)
and I get on MISO 0x20 0xDEAD 0x89 0x00E1 (that "1" indicates a loop error)
When I send 0x85 0x5555 0xDEAD (read error config and NOP) and
I get on MISO : 0x20 0xDEAD 0x85 0x00F1 (that's OK)
The SPI timings seem correct.
I program the MCU with the "MSP430FR2355 LaunchPad". When the system is only powered up with the launchpad (only the 3V3) , ERRB gets high (so, no error). But when I power the entire system (by LOOP+ / LOOP-) ERRH gets down.
Is there anything I missed or something I can test ?
If it can help, I enclosed below the programs and the schematic. I used the TIDA-00648 and TIDM-01000 as references.
Can anybody help me find the problem ?
I'm a beginner with microcontrollers, it might be a stupid mistake.
Best regards,
Christophe FELDER
----------
#include <stdio.h> #include <msp430.h> #include <intrinsics.h> #include "DAC161.h" volatile int flag_4ma = 0; volatile int flag_20ma = 0; unsigned char DAC_Error_Processing; unsigned char dacStatus = 0; void USCIA1_Init(void); unsigned char USCIA1_SPI_WriteByte (unsigned char data); unsigned char DAC161_Read_Status (void); void DAC161_Write_Regs (unsigned short *writeValues, unsigned char startReg, unsigned char lengthBytes); void Setup_DAC161 (unsigned short errConfig, unsigned short errLow_uA, unsigned short errHigh_uA); void main(void) { volatile int i=0; WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer PM5CTL0 &= ~LOCKLPM5; USCIA1_Init(); P4DIR &= ~BIT0; // Input Pins P4IES |= BIT0; // High to Low Edge P4IFG &= ~0xFF; // Clear any pending interrupts P4IE |= BIT0; // Enable Interrupts P3OUT &= ~BIT7; // Clear P3.7 output latch for a defined power-on state P3DIR |= BIT7; // Set P3.7 to output direction P1DIR &= ~BIT0; // Set P1.0 as input P1IE |= BIT0; P1IES |= BIT0; P1IFG &= ~BIT0; // P1.0 IFG cleared P1DIR &= ~BIT1; // Set P1.1 as input P1IE |= BIT1; P1IES |= BIT1; P1IFG &= ~BIT1; // P1.1 IFG cleared __bis_SR_register(GIE); // Enter LPM0 w/ interrupt Setup_DAC161(DAC161_STD_ERR_CONFIG_MASKED, 3000, 22000); // Configure the DAC161 DAC_Error_Processing = 0; DAC161_Set_Out_Value (5000); //does not work DAC161_Nop(); __delay_cycles(5000); while (1) { if (DAC_Error_Processing) { // Perform DAC ERROR Processing Here DAC_Error_Processing = 0; dacStatus = DAC161_Read_Status(); // Read Status to clear error } } #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { switch(__even_in_range(P1IV,16)) { case 0: break; // No Interrupt case 2: flag_20ma = 1; //interrupt on P1.0 P2OUT &= ~BIT1; //CS DAC = 0 USCIA1_SPI_WriteByte(0x89); //READ STATUS USCIA1_SPI_WriteByte(0x55); USCIA1_SPI_WriteByte(0x55); P2OUT |= BIT1; //CS DAC = 1 DAC161_Nop(); // to read status P1IFG &= ~BIT0; // clear flag break; // P1.0 case 4: // interrupt on P1.1 flag_4ma=1; P2OUT &= ~BIT1; //CS DAC = 0 USCIA1_SPI_WriteByte(0x85); //READ ERR CFG USCIA1_SPI_WriteByte(0x55); USCIA1_SPI_WriteByte(0x55); P2OUT |= BIT1; DAC161_Nop(); P1IFG &= ~BIT1; //CS DAC = 1 break; // P1.1 } } #pragma vector=PORT4_VECTOR __interrupt void Port_4(void) { if (P4IFG & BIT0) { // Has an error from the DAC occurred? (ERRB -> 0) DAC_Error_Processing = 1; } P4IFG = 0; } void USCIA1_Init(void) { P4SEL0 |= BIT1 + BIT2 + BIT3; // Configuration MOSI MISO SCK P2OUT &= ~BIT1; //CS_DAC P2DIR |= BIT1; UCA1CTL1 |= UCSWRST; // Enable SW reset UCA1CTLW0 = UCMST + UCSSEL__SMCLK + UCMSB + UCSYNC + UCSWRST; // SPI Master, 3 wire, synchronous mode UCA1BR0 = 0; // SMCLK/1 = SCLK (1MHz) UCA1BR1 = 0; UCA1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation } unsigned char USCIA1_SPI_WriteByte (unsigned char data) { while (!(UCA1IFG&UCTXIFG)); // USCI_A1 TX buffer ready? UCA1IFG &= ~UCRXIFG; // Clear RX Interrupt flag UCA1TXBUF = data; // Place data in TX Buffer while (!(UCA1IFG & UCRXIFG)); // Wait for end of data receive return ((unsigned char)UCA1RXBUF); // Return the received byte from RX Buffer } unsigned char DAC161_Read_Status (void) { // read dac status unsigned char returnValue[3]; DAC161_Read_Regs (returnValue, DAC161_STATUS_REG, 2); return (returnValue[2]); } void DAC161_Write_Regs (unsigned short *writeValues, unsigned char startReg, unsigned char lengthBytes) { unsigned char outData[3]; outData[0] = DAC161_SPI_WRITE_CMD(startReg); outData[1] = *writeValues >> 8; outData[2] = *writeValues & 0xff; USCIA1_SPI_write_DAC (outData, RcvData, lengthBytes+1); // Add 1 to length for command byte } void Setup_DAC161 (unsigned short errConfig, unsigned short errLow_uA, unsigned short errHigh_uA) { unsigned short errValue; DAC161_Write_Regs (&errConfig, DAC161_ERR_CONFIG_REG, 2); errValue = DAC161_CONVERT_ERR_VALUE(errLow_uA) & 0x7f00; DAC161_Write_Regs (&errValue, DAC161_ERR_LOW_REG, 2); errValue = DAC161_CONVERT_ERR_VALUE(errHigh_uA) & 0xff00; if (errValue < 0x80) errValue = 0x80; DAC161_Write_Regs (&errValue, DAC161_ERR_HIGH_REG, 2); }