Post Go back to editing

Serial port communication with HMC1190LP6GE using FT2232D and D2XX library

Hello,

I am trying to write my own software to control HMC1190LP6GE evaluation board.

I use C language together with D2XX library for the FT2232D chip that is on my USB interface PCB that was included in the kit.

So far my simple code is able to find that the board is present, get its basic info including a serial number and also open and close the device handle (see attachment, this code is working fine). 

What I would try to do next is to understand what is the flow of writing/reading from the HMC1190LP6GE registers described in details in the mixer's datasheet. For a start I would like e.g. to read REG 0 register that should return me the Chip ID number.

Could anybody share some sample lines of code to help me get started?

main.c.zip
Parents
  • Hi,

    For some time i have been trying to communicate with HMC1190A Eval Board with a simple C program and FTDI D2XX library. After following the HMC1190A datasheet time diagrams i succeeded in reading the REG 00 value (C7701A). My happiness lasted only for a short while because when i tried to read any other READ ONLY register, like REG 13, i got always C7701A again and again

    method pasted below called as:

    SPI_ReadAddr(ftHandle, ftStatus, 0, 10, &OutputBuffer, dwNumBytesToSend, dwNumBytesSent, &InputBuffer, dwNumBytesToRead, dwNumBytesRead);

    gives the following result:

    Read data index 0 = C7

    Read data index 1 = 70

    Read data index 2 = 1A

    Read data index 3 = 00

    Read data index 4 = 00

    Read data index 5 = 00

    Read data index 6 = 00

    Read data index 7 = 00

    Read data index 8 = 00

    Read data index 9 = 00

    The problem is that it gives the same result no matter what address i give. Can anybody spot what i am doing wrong?

    I give you the link to my main.c file if you want to give it a try: Dropbox - hmc1190A_comm.zip 

    //this routine is used to read data from HMC1190A register at the given address
    BOOL SPI_ReadAddr(FT_HANDLE ftHandle, FT_STATUS ftStatus
    , BYTE address, int NumBytesToReadFromAddress, BYTE *OutputBuffer, int dwNumBytesToSend, int dwNumBytesSent, BYTE *InputBuffer, int dwNumBytesToRead, int dwNumBytesRead) {

     

    // (a.) The Master (host), on the first 24 falling edges of SCLK places 24-bit data, d23:d0, MSB first, on SDI
    // as shown in Figure 73. d23:d5 should be set to zero. d4:d0 = address of the register to be READ on
    // the next cycle.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    OutputBuffer[dwNumBytesToSend++] = 2;
    OutputBuffer[dwNumBytesToSend++] = 0;

    OutputBuffer[dwNumBytesToSend++] = 0;
    OutputBuffer[dwNumBytesToSend++] = 0;
    OutputBuffer[dwNumBytesToSend++] = address;

     

    // clear SEN (according to timing diagram on datasheet page 43)
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x0';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // (c.) Master places 5-bit register address , r4:r0, (the READ ADDRESS register),
    // MSB first, on the next 5 falling edges of SCK (25-29). r4:r0=00000.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
    OutputBuffer[dwNumBytesToSend++] = 4;
    OutputBuffer[dwNumBytesToSend++] = address;

    // (e.) Master places 3-bit chip address, a2:a0, MSB first, on the next 3 falling
    // edges of SCK (30-32). Chip address is always ‘000’b.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
    OutputBuffer[dwNumBytesToSend++] = 2;
    OutputBuffer[dwNumBytesToSend++] = 0;

     

    // SET SEN (according to timing diagram on datasheet page 43)
    // (g.) Master asserts SEN after the 32nd rising edge of SCK.
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x8';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // CLEAR SEN after a0 on SDI
    // (i. ) Master clears SEN to complete the the address transfer of the two part READ cycle
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x0';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // SET SEN (according to timing diagram on datasheet page 43)
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x8';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // (k.) Master places the same SDI data as the previous cycle on the next 32 falling edges of SCK.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    OutputBuffer[dwNumBytesToSend++] = 2;
    OutputBuffer[dwNumBytesToSend++] = 0;

    OutputBuffer[dwNumBytesToSend++] = 0;
    OutputBuffer[dwNumBytesToSend++] = 0;
    OutputBuffer[dwNumBytesToSend++] = address;

    // clear SEN (according to timing diagram on datasheet page 43, bottom diagram)
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x0';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // 5 bits of address and 3 bits chip address `000`.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
    OutputBuffer[dwNumBytesToSend++] = 4;
    OutputBuffer[dwNumBytesToSend++] = address;
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
    OutputBuffer[dwNumBytesToSend++] = 2;
    OutputBuffer[dwNumBytesToSend++] = 0;

     

    // SET SEN
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x8';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // clock in
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_IN;
    OutputBuffer[dwNumBytesToSend++] = NumBytesToReadFromAddress-1;
    OutputBuffer[dwNumBytesToSend++] = 0;

     

    //send out MPSSE command to MPSSE engine
    ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
    dwNumBytesToSend = 0; //Clear output buffer

    do {

       ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);
       // Get the number of bytes in the device input buffer
    } while ((dwNumBytesToRead == 0) && (ftStatus == FT_OK));

     

    ftStatus = FT_Read(ftHandle, InputBuffer, dwNumBytesToRead, &dwNumBytesRead);//Read 2 bytes from device receive buffer

    for(int j = 0; j < dwNumBytesToRead; j++) {
       printf("Read data index %d = %02X\n", j, InputBuffer[j]);
    }
    printf("\n");
    sleep(1);
    return ftStatus;
    }

    ```

Reply
  • Hi,

    For some time i have been trying to communicate with HMC1190A Eval Board with a simple C program and FTDI D2XX library. After following the HMC1190A datasheet time diagrams i succeeded in reading the REG 00 value (C7701A). My happiness lasted only for a short while because when i tried to read any other READ ONLY register, like REG 13, i got always C7701A again and again

    method pasted below called as:

    SPI_ReadAddr(ftHandle, ftStatus, 0, 10, &OutputBuffer, dwNumBytesToSend, dwNumBytesSent, &InputBuffer, dwNumBytesToRead, dwNumBytesRead);

    gives the following result:

    Read data index 0 = C7

    Read data index 1 = 70

    Read data index 2 = 1A

    Read data index 3 = 00

    Read data index 4 = 00

    Read data index 5 = 00

    Read data index 6 = 00

    Read data index 7 = 00

    Read data index 8 = 00

    Read data index 9 = 00

    The problem is that it gives the same result no matter what address i give. Can anybody spot what i am doing wrong?

    I give you the link to my main.c file if you want to give it a try: Dropbox - hmc1190A_comm.zip 

    //this routine is used to read data from HMC1190A register at the given address
    BOOL SPI_ReadAddr(FT_HANDLE ftHandle, FT_STATUS ftStatus
    , BYTE address, int NumBytesToReadFromAddress, BYTE *OutputBuffer, int dwNumBytesToSend, int dwNumBytesSent, BYTE *InputBuffer, int dwNumBytesToRead, int dwNumBytesRead) {

     

    // (a.) The Master (host), on the first 24 falling edges of SCLK places 24-bit data, d23:d0, MSB first, on SDI
    // as shown in Figure 73. d23:d5 should be set to zero. d4:d0 = address of the register to be READ on
    // the next cycle.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    OutputBuffer[dwNumBytesToSend++] = 2;
    OutputBuffer[dwNumBytesToSend++] = 0;

    OutputBuffer[dwNumBytesToSend++] = 0;
    OutputBuffer[dwNumBytesToSend++] = 0;
    OutputBuffer[dwNumBytesToSend++] = address;

     

    // clear SEN (according to timing diagram on datasheet page 43)
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x0';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // (c.) Master places 5-bit register address , r4:r0, (the READ ADDRESS register),
    // MSB first, on the next 5 falling edges of SCK (25-29). r4:r0=00000.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
    OutputBuffer[dwNumBytesToSend++] = 4;
    OutputBuffer[dwNumBytesToSend++] = address;

    // (e.) Master places 3-bit chip address, a2:a0, MSB first, on the next 3 falling
    // edges of SCK (30-32). Chip address is always ‘000’b.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
    OutputBuffer[dwNumBytesToSend++] = 2;
    OutputBuffer[dwNumBytesToSend++] = 0;

     

    // SET SEN (according to timing diagram on datasheet page 43)
    // (g.) Master asserts SEN after the 32nd rising edge of SCK.
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x8';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // CLEAR SEN after a0 on SDI
    // (i. ) Master clears SEN to complete the the address transfer of the two part READ cycle
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x0';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // SET SEN (according to timing diagram on datasheet page 43)
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x8';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // (k.) Master places the same SDI data as the previous cycle on the next 32 falling edges of SCK.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    OutputBuffer[dwNumBytesToSend++] = 2;
    OutputBuffer[dwNumBytesToSend++] = 0;

    OutputBuffer[dwNumBytesToSend++] = 0;
    OutputBuffer[dwNumBytesToSend++] = 0;
    OutputBuffer[dwNumBytesToSend++] = address;

    // clear SEN (according to timing diagram on datasheet page 43, bottom diagram)
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x0';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // 5 bits of address and 3 bits chip address `000`.
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
    OutputBuffer[dwNumBytesToSend++] = 4;
    OutputBuffer[dwNumBytesToSend++] = address;
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BIT_OUT;
    OutputBuffer[dwNumBytesToSend++] = 2;
    OutputBuffer[dwNumBytesToSend++] = 0;

     

    // SET SEN
    OutputBuffer[dwNumBytesToSend++] = '\x80';
    OutputBuffer[dwNumBytesToSend++] = '\x8';
    OutputBuffer[dwNumBytesToSend++] = '\xB';

     

    // clock in
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_IN;
    OutputBuffer[dwNumBytesToSend++] = NumBytesToReadFromAddress-1;
    OutputBuffer[dwNumBytesToSend++] = 0;

     

    //send out MPSSE command to MPSSE engine
    ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
    dwNumBytesToSend = 0; //Clear output buffer

    do {

       ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead);
       // Get the number of bytes in the device input buffer
    } while ((dwNumBytesToRead == 0) && (ftStatus == FT_OK));

     

    ftStatus = FT_Read(ftHandle, InputBuffer, dwNumBytesToRead, &dwNumBytesRead);//Read 2 bytes from device receive buffer

    for(int j = 0; j < dwNumBytesToRead; j++) {
       printf("Read data index %d = %02X\n", j, InputBuffer[j]);
    }
    printf("\n");
    sleep(1);
    return ftStatus;
    }

    ```

Children
No Data