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.

TUSS4440: [Software and Hardware] Not exciting transducer

Part Number: TUSS4440
Other Parts Discussed in Thread: TUSS4470, MSP430F5529, ENERGIA

Hello,

I have been breaking my head over why TUSS4440 is not exciting the transducer, I am not able to spot the issue. The schematics look the following:

I am trying to perform a simple TOF measurement, and convert it to CM based on the examples provided by TI and also here. The frequency on the IO2 pin is set to 200Khz which shows up on the osciloscope, the SPI settings are also default ones.

The code:

// code sources:
// A : msp430_driverlib_2_91_13_01\examples\MSP430F5xx_6xx\usci_a_spi/usci_a_spi_ex1_master.c
// B : TUSS4470 examples\examples\VOUT_ADC_Processing\TUSS44x0_ultrasonic.cpp
// C : msp430_driverlib_2_91_13_01\examples\MSP430F5xx_6xx\adc12_a/adc12_a_ex5_repeatedSingle.c

#include "stdio.h"
#include <stdbool.h>
#include <stdint.h>
#include <avr/sleep.h>
#include <avr/delay.h>
#define F_CPU 5000000UL
// Prototypes
unsigned int BitShiftCombine( unsigned char x_high, unsigned char x_low);
void executeTOFandSample();
void initializeTUSS4440();
void init_GPIO();
void initTimer();
void initClocks();
void initTUSS4470();
void initSPI();
void initADC12();
void initDMA();
uint8_t parity16(unsigned int ino);
void sampleLoop();
uint8_t * tuss44x0_regAddParity(uint8_t addr, uint8_t data);
uint8_t tuss44x0_parity(uint8_t * spi16Val);
void writeRegTUSS4470 (uint8_t address, uint8_t value);

// SPI Variables
#define SPICLK 500000
uint8_t SPIInitReturnValue = 0;

// Clock/UCS variables
uint16_t NMIstatus;
#define LF_CRYSTAL_FREQUENCY_IN_HZ 32768
#define HF_CRYSTAL_FREQUENCY_IN_HZ 4000000
#define MCLK_DESIRED_FREQUENCY 4000000 // 4 MHz
#define MCLK_FLLREF_RATIO MCLK_DESIRED_FREQUENCY / UCS_REFOCLK_FREQUENCY
uint32_t myACLK = 0;
uint32_t mySMCLK = 0;
uint32_t myMCLK = 0;

// TOF Variables
uint8_t sampleSetLoopCount = 0;
bool samplingActive = false;

// ADC variables
#define ADC12_Num_of_Indexes 20
#define ADC12_Num_of_Results 125
volatile uint8_t ADC12_results_index1 = 0;
volatile uint8_t ADC12_results_index2 = 0;
int ADCValuesCounterResults = 0;
int ADCValuesCounterIndex = 0;
volatile uint16_t ADC12_results[ADC12_Num_of_Indexes][ADC12_Num_of_Results] = {};

// DMA variables
#define ANALOG_DMA_CHANNEL DMA_CHANNEL_0
#define ANALOG_INPUT ADC12_A_INPUT_A5
#define ANALOG_MEMORY ADC12_A_MEMORY_0

unsigned int speedOfSound = 0x0157; // default speed of sound through air at room temperature is 343 m/s


void sampleLoop()
{

}

//// Initialization /////

void initializeTUSS4440() {

TCB2_Initialize();
TUSS4440_Initialize(); // initialize SPI communication for ATmega4809 -> TUSS4470
// initTimer(); // initialize timer for 1MHz pulse
// initSPI(); // initialize SPI communication for MSP430 -> TUSS4470
// initADC12(); // initialize ADC12 A/D converter in MSP430F5529
initTUSS4470(); // initialize/configure TUSS4470
}

//// Timer Initialization ////
// PWM timer - generate 1MHz transducer pulses - SMCLK must be 4 MHz

//// ADC Initialization ////
// code source: C

void initADC12() {
// ADC clock source is configured as SMCLK
// SMCLK and MCLK = 4MHZ
// Calculate minimum required sample time
// calculation source: MSP430 User guide section 28.2.5.3 'Sample Timing Considerations'
// The resistance of the source RS and RI affect tsample. The following equation can be used to calculate the
// minimum sampling time tsample for a n-bit conversion, where n equals the bits of resolution:
// t.sample > (RS + RI) * ln(2n+1) * CI + 800 ns
// Substituting the values for RI and CI given above, the equation becomes:
// t.sample > (RS + 1.8 KOhm) * ln(2n+1) * 25 pF + 800 ns
// For example, for 12-bit resolution, if RS is 10 KOhm, t.sample must be greater than 3.46 uS.
// using measurement of 4.2 KOhms output resistance of TUSS4470
// sample > (4.2 Kohm + 1.8 KOhm) * ln(2 ^ (12 + 1)) * 25 + 800ns
// sample > 2.151 us
// minimum sample time = 2.15 uS
// if ADC clock = 4MHZ, 1 cycle = 0.25 uS, a minimum of 9 cycles (2.25 uS) is required to meet minimum sample time of 2.15 us (16 cycles or 3.2 uS is closest driverlib option)

// configure REF (reference voltage) module

}

//// SPI Initialization ////

// code source: A

void initSPI() {

}

//// TUSS4470 Initialization ////

void initTUSS4470()
{
// recommended TUSS4470 register settings from INDUS_REG_USER_MEMSPACE_447-StemincTDCXDCR_Optimized.txt
// e2e.ti.com/.../927400

writeRegTUSS4470(0x10 ,0x5F); // (BPF_CONFIG_1)
writeRegTUSS4470(0x11 ,0x00); // (BPF_CONFIG_2)
writeRegTUSS4470(0x12 ,0x1C); // (DEV_CTRL_1)
writeRegTUSS4470(0x13 ,0xC1); // DEV_CTRL_2)
writeRegTUSS4470(0x14 ,0x00); // (DEV_CTRL_3)
writeRegTUSS4470(0x15 ,0x00); // (DEV_CTRL_4)
writeRegTUSS4470(0x16 ,0x40); // (VDRV_CTRL)
writeRegTUSS4470(0x17 ,0x07); // (ECHO_INT_CONFIG)
writeRegTUSS4470(0x18 ,0x14); // (ZC_CONFIG)
writeRegTUSS4470(0x19 ,0x00); // (XFMR_DRV_LIM)
writeRegTUSS4470(0x1A ,0x08); // (BURST_PULSE)
writeRegTUSS4470(0x1B ,0x02); // (TOF_CONFIG)
writeRegTUSS4470(0x1C ,0x08); // (DEV_STAT)
writeRegTUSS4470(0x1D ,0xB9); // (DEVICE_ID)
writeRegTUSS4470(0x1E ,0x02); // (REV_ID)
writeRegTUSS4470(0x1F ,0x00); // (DEV_TI_UNLOCK)
}

typedef struct {
// hardware stuff that controls SPI mode
// hardware stuff that controls SPI baud rate
uint8_t CTRLAvalue;
uint8_t CTRLBvalue;
} spi0_configuration_t;
// code source: B
//// write register values to TUSS4470 over SPI bus ////
void writeRegTUSS4470 (uint8_t address, uint8_t value) {
uint8_t *regValPtr;
uint8_t tuss4470regWriteArray[2];

regValPtr = tuss44x0_regAddParity(address, value);
tuss4470regWriteArray[0] = *regValPtr;
tuss4470regWriteArray[1] = *(regValPtr + 1); // increment pointer 1 byte


//Enable SPI module
TUSS4440_Initialize();
TUSS4440_Enable();
spi0_configuration_t t;
t.CTRLAvalue = 0;
t.CTRLBvalue = 16000;
TUSS4440_Open(t);
//Wait for slave to initialize
_delay_ms(100);

//USCI_B0 TX buffer ready?
clientSelect();
TUSS4440_WriteByte(tuss4470regWriteArray[0]);
TUSS4440_WriteByte(tuss4470regWriteArray[1]);
clientDeselect();
}

// code source: B
//// Execute Time of Flight and Sample ////
typedef uint16_t adc_result_t;
/* Analog Channel Selection Bits select */


/** Datatype for the result of the ADC conversion */
typedef uint16_t adc_result_t;

void executeTOFandSample() {


writeRegTUSS4470(0x1B, 0x00); // TOF_CONFIG's CMD_TRIGGER to 0
writeRegTUSS4470(0x1B, 0x01); // TOF_CONFIG's CMD_TRIGGER to 1 (enable burst mode)
adc_result_t res;
ADC_MUXPOS_t channel;
channel = ADC_MUXPOS_AIN0_gc;
//channel;
// ADC12 sample and convert
TUSS_ANALOG_INPUT_StartConversion(channel);
TCB2_EnableCaptInterrupt();

_delay_ms(10);
//res = TUSS_ANALOG_INPUT_GetConversion(channel);

// P8OUT |= BIT2; // set pin 8.2 high - for oscilloscope timing tests
//__delay_cycles(40); // 40 cycle delay produces ~ 12 to 14 pulses at 1MHz if SMCLK = 4 MHz
TCB2_DisableCaptInterrupt();
writeRegTUSS4470(0x1B, 0x00); // TOF_CONFIG's CMD_TRIGGER to 0 (disable burst mode)

}

double tofToDistance(unsigned long tofTime)
{
return (tofTime * (speedOfSound * 0.5)) * 0.001;
}

// code source: B
/*------------------------------------------------- tuss44x0_regAddParity -----
| Function tuss44x0_regAddParity
|
| Purpose: Modify addr byte, Calculate Parity bit and return array pointer.
|
| Parameters:
| addr (IN) -- valid register address byte between 0x10 to 0x1E
| data (IN) -- valid register data byte between 0x00 to 0xFF
|
| Returns: none
*-------------------------------------------------------------------*/
uint8_t * tuss44x0_regAddParity(uint8_t addr, uint8_t data)
{
uint8_t regByteArr[2];
regByteArr[0] = (addr & 0x3F) << 1; // shift addr to MSB position
regByteArr[1] = data; // null data byte during read
regByteArr[0] |= tuss44x0_parity(regByteArr); // apply parity bit
return regByteArr;
}

// code source: B
/*------------------------------------------------- tuss44x0_parity -----
| Function tuss44x0_parity
|
| Purpose: Calculates odd parity bit for given SPI data.
|
| Parameters:
| spi16Val (IN) -- 16 bit SPI data byte array
|
| Returns: byte representation of SPI data array element 0's LSB
| containing calculated parity bit value
*-------------------------------------------------------------------*/
uint8_t tuss44x0_parity(uint8_t * spi16Val)
{
// SPI frame comprised of: 1 RW bit, 6 bits for the register address, 1 ODD parity bit for entire SPI frame, 8 bits for data
return parity16(BitShiftCombine(spi16Val[0],spi16Val[1]));
}

// code source: B
/*------------------------------------------------- tuss44x0_parity -----
| Function tuss44x0_parity
|
| Purpose: Determines the number of ones in a given unsigned integer
| to return odd parity bit result.
|
| Parameters:
| ino (IN) -- 16 bit unsigned integer
| Returns: parity bit value
*-------------------------------------------------------------------*/
uint8_t parity16(unsigned int ino)
{
int i = 0;
uint8_t noofones = 0;
for(i = 0; i < 16; i++)
{
if(((ino>>i) & 1) == 1)
{
noofones++;
}
}
// if remainder of one, add one to parity bit field
return ((noofones+1) % 2);
}

// code source: B
/*------------------------------------------------- BitShiftCombine -----
| Function BitShiftCombine
|
| Purpose: Combines two byte values into a single unsigned integer value.
|
| Parameters:
| x_high (IN) -- MSB input byte
| x_low (IN) -- LSB input byte
|
| Returns: unsigned integer of combined MSB and LSB bytes
*-------------------------------------------------------------------*/
unsigned int BitShiftCombine( unsigned char x_high, unsigned char x_low)
{
unsigned int combined;
combined = x_high; // send x_high to rightmost 8 bits
combined = combined<<8; // shift x_high over to leftmost 8 bits
combined |= x_low; // logical OR keeps x_high intact in combined and fills in rightmost 8 bits
return combined;
}

Any help is greatly appreciated!

  • Hello Philip,

    Thank you for the information I will have to review it in case if there is something you may have missed. But just to check you said you have been able to confirm if the IO2 pin is receiving the proper signal on the scope. Have you been able to probe what the output is on OUTA and OUTB after you process a pulse command?

    Best,

    Isaac

  • Hello,

    thank you for your swift response. So the code is easier to debug, i rewrote it to the C++ example from here. This is the code (i could not format it as code, some error pops up):

    // code sources:
    // A : msp430_driverlib_2_91_13_01\examples\MSP430F5xx_6xx\usci_a_spi/usci_a_spi_ex1_master.c
    // B : TUSS4470 examples\examples\VOUT_ADC_Processing\TUSS44x0_ultrasonic.cpp
    // C : msp430_driverlib_2_91_13_01\examples\MSP430F5xx_6xx\adc12_a/adc12_a_ex5_repeatedSingle.c

    #include "stdio.h"
    #include <stdbool.h>
    #include <stdint.h>
    #include <avr/sleep.h>
    #define __DELAY_BACKWARD_COMPATIBLE__
    #include <avr/delay.h>
    #define F_CPU 5000000UL
    // Prototypes
    unsigned int BitShiftCombine( unsigned char x_high, unsigned char x_low);
    void executeTOFandSample();
    void initializeTUSS4440();
    void init_GPIO();
    void initTimer();
    void initClocks();
    void initTUSS4470();
    void initSPI();
    void initADC12();
    void initDMA();
    uint8_t parity16(unsigned int ino);
    void sampleLoop();
    uint8_t * tuss44x0_regAddParity(uint8_t addr, uint8_t data);
    uint8_t tuss44x0_parity(uint8_t * spi16Val);
    void writeRegTUSS4470 (uint8_t address, uint8_t value);
    uint8_t tuss44x0_regRead(uint8_t address);

    // *** GLOBAL VARIABLES ***

    // TOF Configuration Variables
    unsigned int pulseFrequency = 0x28; // default frequency of 40 kHz
    unsigned char recordLength = 0x18; // default record length of 24 ms
    unsigned char burstPulse = 0; // default number of pulses of 0
    unsigned int speedOfSound = 0x0157; // default speed of sound through air at room temperature is 343 m/s

    // Driver Variables
    unsigned char tofMode = 1; // default time of flight mode: 0=listen_only, 1=burst_and_listen
    unsigned char driverType = 0; // default pulse driver generation type: 0=bit_bang, 1= timer_interrupt
    unsigned char IO2_toggleCount = 0; // index counter for the number of times IO2 toggles during interrupt routine
    bool timerBurstDone = false; // flag to indicate timer_interrupt burst is on going or completed
    unsigned char numberOfHalfPulses = 0; // number of pulses multiplied by two

    // VOUT ADC Capture Variables
    bool voutCaptureEnable = true; // enable state of VOUT ADC capture
    unsigned char voutBuf[4095]; // VOUT ADC capture buffer
    unsigned int capturedSamples = 0; // number VOUT ADC samples captured within record length time

    // Echo Interrupt at O4 Variables
    bool o4EchoIntEnable = true; // enable state of echo interrupt capture
    unsigned char o4Trig = 0; // index counter for the number of o4Micros state CHANGE interrupts at pin O4
    const uint8_t o4TrigMax = 0x0A; // maximum allowable number of state CHANGE interrupts at pin O4
    unsigned long o4Micros[0x0A]; // O4 echo interrupt microsecond timer array (one burst, four objects)

    void initializeTUSS4440() {
    TUSS_ANALOG_INPUT_Initialize();
    TCB2_Initialize();
    TUSS4440_Initialize(); // initialize SPI communication for ATmega4809 -> TUSS4440
    tofExecute(200,24,speedOfSound);
    }


    uint8_t tuss44x0_regRead(uint8_t address)
    {
    uint8_t inByteArr[2];
    inByteArr[0] = 0x80 + ((address & 0x3F) << 1); // shift addr to MSB position
    inByteArr[1] = 0x00; // null data byte during read
    inByteArr[0] |= tuss44x0_parity(inByteArr); // apply parity bit
    TUSS4440_Initialize();
    TUSS4440_Enable();
    _delay_ms(100);
    uint8_t outByteArr[2];
    clientSelect();
    TUSS4440_WriteBlock(inByteArr, sizeof(inByteArr));
    TUSS4440_ReadBlock(outByteArr, sizeof(outByteArr));
    clientDeselect();
    return outByteArr[1];
    }

    //// write register values to TUSS4470 over SPI bus ////
    void writeRegTUSS4470 (uint8_t address, uint8_t value) {
    uint8_t *regValPtr;
    uint8_t tuss4470regWriteArray[2];

    regValPtr = tuss44x0_regAddParity(address, value);
    tuss4470regWriteArray[0] = *regValPtr;
    tuss4470regWriteArray[1] = *(regValPtr + 1);
    // increment pointer 1 byte
    uint8_t inByteArr[2];
    inByteArr[0] = (address & 0x3F) << 1; // shift addr to MSB position
    inByteArr[1] = value; // null data byte during read
    inByteArr[0] |= tuss44x0_parity(inByteArr);

    //Enable SPI module
    TUSS4440_Initialize();
    TUSS4440_Enable();
    _delay_ms(100);
    clientSelect();
    TUSS4440_WriteBlock(inByteArr, sizeof(inByteArr));
    clientDeselect();
    }

    // code source: B
    //// Execute Time of Flight and Sample ////
    typedef uint16_t adc_result_t;
    /* Analog Channel Selection Bits select */


    /** Datatype for the result of the ADC conversion */
    typedef uint16_t adc_result_t;

    void tofExecute(unsigned int pF, uint8_t rL, uint8_t tM)
    {
    // read IO_MODE and BURST_PULSE
    uint8_t ioMode = tuss44x0_regRead(0x14) & 0x03; // read DEV_CTRL_3's IO_MODE bits
    burstPulse = tuss44x0_regRead(0x1A) & 0x1F; // read DEV_CTRL_2's BURST_PULSE bits

    // calculate burst period based on frequency
    unsigned int burstPeriodUs = (1 / (pF*0.001)); // convert freq to us


    // when pin O4 Echo Interrupt enabled
    o4Trig = 0;
    memset(o4Micros, 0, sizeof(o4Micros)); // clear receive buffer data
    writeRegTUSS4470(0x1B, 0x00); // TOF_CONFIG's CMD_TRIGGER to 0
    writeRegTUSS4470(0x1B, 0x01); // TOF_CONFIG's CMD_TRIGGER to 1
    drivePhase(tM, burstPeriodUs,burstPulse,ioMode);
    captureADC(rL);
    writeRegTUSS4470(0x1B, 0x00); // TOF_CONFIG's CMD_TRIGGER to 0

    // zero offset echo interrupt timer results
    unsigned long startOfBurst = o4Micros[0];
    for(int i = 0; i < o4Trig; i++)
    {
    o4Micros[i] = o4Micros[i]-startOfBurst;
    }
    }

    /*------------------------------------------------- captureADC -----
    | Function captureADC
    |
    | Purpose: Capture VOUT signal with ADC during TOF command for the
    | duration of the user defined record length.
    |
    | Parameters:
    | delta (IN) -- active TOF record length
    |
    | Returns: none
    *-------------------------------------------------------------------*/
    void captureADC(uint8_t delta)
    {
    ADC_MUXPOS_t channel;
    channel = ADC_MUXPOS_AIN0_gc;
    unsigned int sample = 0;
    uint16_t startMillis = millis(); // capture start time
    while ((millis() - startMillis) < delta) // test whether the record length has elapsed
    {
    if(voutCaptureEnable == true)
    {
    if(sample < sizeof(voutBuf))
    {
    voutBuf[sample++] = TUSS_ANALOG_INPUT_GetConversion(channel);
    }
    }
    }
    capturedSamples = sample;
    }


    /*------------------------------------------------- drivePhase -----
    | Function drivePhase
    |
    | Purpose: Configures the driver of the TOF command execution.
    |
    | Parameters:
    | tM (IN) -- TOF mode for listen (0) or burst (1) operation
    | burstPeriodUs (IN) -- burst period in microseconds
    | burstPulse (IN) -- number of burst pulses
    | ioMode (IN) -- TUSS44x0 IO_MODE 0-3
    |
    | Returns: none
    *-------------------------------------------------------------------*/
    void drivePhase(uint8_t tM, unsigned int burstPeriodUs, uint8_t burstPulse, uint8_t ioMode)
    {
    timerBurstDone = false;
    if(tM = 0x01)
    {
    //noInterrupts(); // disable interrupts
    if(ioMode != 2)
    {
    burstBitBang(burstPeriodUs,burstPulse);
    }
    else
    {
    //burstBitBangDual(burstPeriodUs,burstPulse);
    }
    //interrupts(); // re enable interrupts
    timerBurstDone = true;
    }
    }
    #include "./mcc_generated_files/include/pin_manager.h"
    void burstBitBang(unsigned int bPU, uint8_t nP)
    {
    unsigned int bPUHalf = bPU * 0.5;
    //bPUHalf -= 3; // compensate delay delta for digitalWrite for MSP430F5529 at 16 MHz which requires 3us
    int nPPlus = nP + 1;
    if(!(bPU==0))
    {
    for(int i = 0; i < nPPlus; i++)
    {
    PB4_SetLow();
    _delay_ms(bPUHalf);
    PB4_SetHigh();
    _delay_ms(bPUHalf);
    }
    }
    else
    {
    // println("Warning: BURST_PULSE = 0");
    }
    }

    void executeTOFandSample() {


    writeRegTUSS4470(0x1B, 0x00); // TOF_CONFIG's CMD_TRIGGER to 0
    writeRegTUSS4470(0x1B, 0x01); // TOF_CONFIG's CMD_TRIGGER to 1 (enable burst mode)
    adc_result_t res;
    ADC_MUXPOS_t channel;
    channel = ADC_MUXPOS_AIN0_gc;
    //channel;
    // ADC12 sample and convert
    TUSS_ANALOG_INPUT_StartConversion(channel);
    TCB2_EnableCaptInterrupt();

    _delay_ms(10);
    //res = TUSS_ANALOG_INPUT_GetConversion(channel);

    // P8OUT |= BIT2; // set pin 8.2 high - for oscilloscope timing tests
    //__delay_cycles(40); // 40 cycle delay produces ~ 12 to 14 pulses at 1MHz if SMCLK = 4 MHz
    TCB2_DisableCaptInterrupt();
    writeRegTUSS4470(0x1B, 0x00); // TOF_CONFIG's CMD_TRIGGER to 0 (disable burst mode)

    }

    double tofToDistance(unsigned long tofTime)
    {
    return (tofTime * (speedOfSound * 0.5)) * 0.001;
    }

    // code source: B
    /*------------------------------------------------- tuss44x0_regAddParity -----
    | Function tuss44x0_regAddParity
    |
    | Purpose: Modify addr byte, Calculate Parity bit and return array pointer.
    |
    | Parameters:
    | addr (IN) -- valid register address byte between 0x10 to 0x1E
    | data (IN) -- valid register data byte between 0x00 to 0xFF
    |
    | Returns: none
    *-------------------------------------------------------------------*/
    uint8_t * tuss44x0_regAddParity(uint8_t addr, uint8_t data)
    {
    uint8_t regByteArr[2];
    regByteArr[0] = (addr & 0x3F) << 1; // shift addr to MSB position
    regByteArr[1] = data; // null data byte during read
    regByteArr[0] |= tuss44x0_parity(regByteArr); // apply parity bit
    return regByteArr;
    }

    // code source: B
    /*------------------------------------------------- tuss44x0_parity -----
    | Function tuss44x0_parity
    |
    | Purpose: Calculates odd parity bit for given SPI data.
    |
    | Parameters:
    | spi16Val (IN) -- 16 bit SPI data byte array
    |
    | Returns: byte representation of SPI data array element 0's LSB
    | containing calculated parity bit value
    *-------------------------------------------------------------------*/
    uint8_t tuss44x0_parity(uint8_t * spi16Val)
    {
    // SPI frame comprised of: 1 RW bit, 6 bits for the register address, 1 ODD parity bit for entire SPI frame, 8 bits for data
    return parity16(BitShiftCombine(spi16Val[0],spi16Val[1]));
    }

    // code source: B
    /*------------------------------------------------- tuss44x0_parity -----
    | Function tuss44x0_parity
    |
    | Purpose: Determines the number of ones in a given unsigned integer
    | to return odd parity bit result.
    |
    | Parameters:
    | ino (IN) -- 16 bit unsigned integer
    | Returns: parity bit value
    *-------------------------------------------------------------------*/
    uint8_t parity16(unsigned int ino)
    {
    int i = 0;
    uint8_t noofones = 0;
    for(i = 0; i < 16; i++)
    {
    if(((ino>>i) & 1) == 1)
    {
    noofones++;
    }
    }
    // if remainder of one, add one to parity bit field
    return ((noofones+1) % 2);
    }

    // code source: B
    /*------------------------------------------------- BitShiftCombine -----
    | Function BitShiftCombine
    |
    | Purpose: Combines two byte values into a single unsigned integer value.
    |
    | Parameters:
    | x_high (IN) -- MSB input byte
    | x_low (IN) -- LSB input byte
    |
    | Returns: unsigned integer of combined MSB and LSB bytes
    *-------------------------------------------------------------------*/
    unsigned int BitShiftCombine( unsigned char x_high, unsigned char x_low)
    {
    unsigned int combined;
    combined = x_high; // send x_high to rightmost 8 bits
    combined = combined<<8; // shift x_high over to leftmost 8 bits
    combined |= x_low; // logical OR keeps x_high intact in combined and fills in rightmost 8 bits
    return combined;
    }

    The PB2 pin is the IO2 pin on TUSS, it is correctly being triggered. There is no signal on the OUTA and OUTB pins, and the code hangs on this method, as it awaits some input:

    adc_result_t TUSS_ANALOG_INPUT_GetConversion(adc_0_channel_t channel)
    {
    adc_result_t res;

    TUSS_ANALOG_INPUT_StartConversion(channel);
    while (!TUSS_ANALOG_INPUT_IsConversionDone());
    res = TUSS_ANALOG_INPUT_GetConversionResult();
    ADC0.INTFLAGS = ADC_RESRDY_bm;
    return res;
    }

  • Hello Philip,

    Sorry for the error, do you know what error message it generates so that I may report it to the team so that we may get that fixed?

    So you have confirmed that IO2 is being generated by the MCU? You should see a square wave being generated as an output at the frequency equivalent to the operating frequency of your transducer. Have you monitored the VDRV_READY bit to see if the capacitor in the device has charged and reached the required level?

    Are you using the MSP430F5529 as an MCU for your project? Or are you using a different microcontroller?

    Best,

    Isaac

  • My setup is the following: ATmega4809, a voltage translator and TUSS4440 is being driven by 20V on the VPWR pin, the VDRV pin is not being driven after starting the burst

    That is correct, the osciloscope is showing the IO2 on TUSS4440 being driven the proper amount of times, there is no movement on the OUTA/OUTB pins. While reading the 0x1C register (7.6.1.12 DEV_STAT Register (Address = 0x1C) [reset = 0x0]) I am receiving this value: 10111001. As I understand it, this means that the VDRV pin has the correct voltage but there is a CRC error. What should be the next step to be able to find where the issue lays? This is the method used to read the register:

    uint8_t tuss44x0_regRead(uint8_t address)
    {
        uint8_t inByteArr[2];
        inByteArr[0] = 0x80 + ((address & 0x3F) << 1); // shift addr to MSB position
        inByteArr[1] = 0x00;                        // null data byte during read
        inByteArr[0] |= tuss44x0_parity(inByteArr); // apply parity bit
        TUSS4440_Initialize();
        TUSS4440_Enable();
        _delay_ms(100);
        uint8_t outByteArr[2];
        clientSelect();
        TUSS4440_WriteBlock(inByteArr, sizeof(inByteArr));
        TUSS4440_ReadBlock(outByteArr, sizeof(outByteArr));
        clientDeselect();
        return outByteArr[1];
    }
    

    Also, what is the best way to find a solution? Is it through posting to the forum, or is it possible to write someone a detailed e-mail?

  • Hello Philip,

    Unfortunately I cannot check much of your code since there are functions missing from what you have disclosed, but from what I can tell the initial portions follow the Energia code so they should work appropriately. I checked the registers on an operational device to verify what value I was getting on my device, oddly enough I was getting similar value but it seems like that is the same value for the Device ID. Can you read a couple of other registers in order to ensure that the value you are seeing at 0X1C is the correct value? Try to read the device ID or other known registers to verify operation. (Keep in mind that this is a register read off of a TUSS4470 since I do not have a TUSS4440 at hand at the moment, you should see a 0x99 when reading register 0x1D).

    The best way to get questions answered is through the forum, if for some reason you have detailed information that you would like not to disclose on the forum feel free to friend me and we can take through messages privately.

    Best,

    Isaac

  • mre.zipHello Isaac,

    thank you so much for your swift response! 

    Unfortunately I cannot check much of your code since there are functions missing from what you have disclosed

    sorry for that, I thought in this part of the code there might be an obvious issue! I will provide a minimal reproducible example in the zip file attached to this post. I would be more than thankful if you could check it against your TUSS4470 if thats possible.

    Those are the current readings from my register:

    No. Register Value
    1 0x10 10100001
    2 0x11 10100010
    4 0x12 10100100
    5 0x13 10100111
    6 0x14 10101000
    7 0x15 10101011
    8 0x16 10101101
    9 0x17 10101110
    10 0x18 10110000
    11 0x19 10110011
    12 0x1A 10110101
    13 0x1B 10110110
    14 0x1C 10110110
    15 0x1D 10111010
    16 0x1E 10111100

    Please tell me what else I can provide you so we can pin down where the issue is. The IO2 is properly driven, 20V is being applied to the device. I am using a 200kHz transducer, the INN capacitor is 21 uF, the FLT is 31.83 uF. I do not see anything on the OUTB/OUTA and VDRV pins. I am not sure how to debug the TUSS4440 further.

  • Hello Philip,

    Thanks for the files, I will look through them to see if I can find the issue, but there definitely seems to be an error in reading the register because the value for the device ID is not correct (register 0x1D should be yielding a value of 10011001). My belief is that the problem is most likely in the code so I will take a look at that for you just give me some time to review.

    On another note the values you are using for your capacitors a 200kHz transducer and IO2 being driven at the same frequency are  significantly high, if you look at table 21 of the datasheet it gives you the formula to follow for your transducer frequency I obtained a value of 3.18nF for C_FLT and C_INN I obtained 21.22nF. You can also refer to this thread here if you are curious about other values: e2e.ti.com/.../boostxl-tuss4440-missing-documentation-to-set-frequency

    Best,

    Isaac

  • Hello Isaac,

    thank you so much for pointing my mistake in my calculations! I exchanged the capacitors!

    I hope you will be able to find the issue that is not allowing to correctly communicate with the device through SPI! 

  • Hello Philip,

    Glad we were able to get those corrected! I have not had a chance to look through the code yet to see if there is an error but I will get back to you soon.

    Best,

    Isaac

  • Hi Isaac,

    is there anything I could do to help you? Any more code snippets, register settings?

  • Hello Philip,

    Sorry for the delay, I have had some other issues come up that took up a lot of time but I should have a chance to review this week. I should have more info by Wednesday by end of day.

    Best,

    Isaac

  • Hello Philip,

    I took a look at your code and I could not find an issue as to why the register values were being written incorrectly or read incorrectly, have you tried probing with a logic analyzer just to inspect the packet when they are being written or read to make sure they are transmitted correctly? I would check this for you but I do not have an Arduino to test the code on.

    Best,

    Isaac