1

I'm new to the PSoC board and I'm trying to read the x,y,z values from a Digital Compass but I'm having a problem in beginning the Transmission with the compass itself.

I found some Arduino tutorial online here but since PSoC doesn't have the library I can't duplicate the code.

Also I was reading the HMC5883L datasheet here and I'm suppose to write bytes to the compass and obtain the values but I was unable to receive anything. All the values I received are zero which might be caused by reading values from wrong address.

Hoping for your answer soon.

kgangadhar
  • 4,886
  • 5
  • 36
  • 54
Jack Lee
  • 11
  • 5

2 Answers2

2

PSoC is sorta tricky when you are first starting out with it. You need to read over the documentation carefully of both the device you want to talk to and the i2c module itself.

The datasheet for the device you linked states this on page 18:

All bus transactions begin with the master device issuing the start sequence followed by the slave address byte. The address byte contains the slave address; the upper 7 bits (bits7-1), and the Least Significant bit (LSb). The LSb of the address byte designates if the operation is a read (LSb=1) or a write (LSb=0). At the 9 th clock pulse, the receiving slave device will issue the ACK (or NACK). Following these bus events, the master will send data bytes for a write operation, or the slave will clock out data with a read operation. All bus transactions are terminated with the master issuing a stop sequence.

If you use the I2C_MasterWriteBuf function, it wraps all that stuff the HMC's datasheet states above. The start command, dealing with that ack, the data handling, etc. The only thing you need to specify is how to transmit it.

If you refer to PSoC's I2C module datasheet, the MasterWriteBuf function takes in the device address, a pointer to the data you want to send, how many bytes you want to send, and a "mode". It shows what the various transfer modes in the docs.

I2C_MODE_COMPLETE_XFER Perform complete transfer from Start to Stop.
I2C_MODE_REPEAT_START Send Repeat Start instead of Start.
I2C_MODE_NO_STOP Execute transfer without a Stop

The MODE_COMPLETE_XFRE transfer will send the start and stop command for you if I'm not mistaken.

You can "bit-bang" this also if you want but calling directly on the I2C_MasterSendStart, WriteByte, SendStop, etc. But it's just easier to call on their writebuf functions.

Pretty much you need to write your code like follows:

// fill in your data or pass in the buffer of data you want to write 
// if this is contained in a function call. I'm basing this off of HMC's docs
uint8 writeBuffer[3];
uint8 readBuffer[6];
writeBuffer[0] = 0x3C;
writeBuffer[1] = 0x00;
writeBuffer[2] = 0x70;
I2C_MasterWriteBuf(HMC_SLAVE_ADDRESS, &writeBuffer, 3, I2C_MODE_COMPLETE_XFER);
while((I2C_MasterStatus() & I2C_MSTAT_WR_CMPLT) == 0u)
{
    // wait for operation to finish
}

writeBuffer[1] = 0x01;
writeBuffer[2] = 0xA0;
I2C_MasterWriteBuf(HMC_SLAVE_ADDRESS, &writeBuffer, 3, I2C_MODE_COMPLETE_XFER);
// wait for operation to finish

writeBuffer[1] = 0x02;
writeBuffer[2] = 0x00;
I2C_MasterWriteBuf(HMC_SLAVE_ADDRESS, &writeBuffer, 3, I2C_MODE_COMPLETE_XFER);
// wait for operation to finish
CyDelay(6); // docs state 6ms delay before you can start looping around to read

for(;;)
{
    writeBuffer[0] = 0x3D;
    writeBuffer[1] = 0x06;
    I2C_MasterWriteBuf(HMC_SLAVE_ADDRESS, &writeBuffer, 2, I2C_MODE_COMPLETE_XFER);
    // wait for operation to finish

    // Docs don't state any different sort of bus transactions for reads. 
    // I'm assuming it'll be the same as a write
    I2C_MasterReadBuf(HMC_SLAVE_ADDRESS, readBuffer, 6, I2C_MODE_COMPLETE_XFER);  
    // wait for operation to finish, wait on I2C_MSTAT_RD_CMPLT instead of WR_COMPLT  

    // You should have something in readBuffer to work with

    CyDelay(67); // docs state to wait 67ms before reading again
}

I just sorta wrote that off the top of my head. I have no idea if that'll work or not, but I think that should be a good place to start and try. They have I2C example projects to look at also I think.

Another thing to look at so the WriteBuf function doesn't just seem like some magical command, if you right-click on the MasterWriteBuf function and click on "Find Definition" (after you build the project) it'll show you what it's doing.

shaboinkin
  • 171
  • 1
  • 11
0

Following are the samples for I2C read and write operation on PSoC,

simple Write operation:

//Dumpy data values to write 
uint8 writebuffer[3]
writebuffer[0] = 0x23
writebuffer[1] = 0xEF
writebuffer[2] = 0x0F

uint8 I2C_MasterWrite(uint8 slaveAddr, uint8 nbytes)
{
    uint8 volatile status;

    status = I2C_MasterClearStatus();
    if(!(status & I2C_MSTAT_ERR_XFER))
    {
      status = I2C_MasterWriteBuf(slaveAddr, (uint8 *)&writebuffer, nbytes, I2C_MODE_COMPLETE_XFER);
        if(status == I2C_MSTR_NO_ERROR)
        {
            /* wait for write complete and no error */
            do
            {
                status = I2C_MasterStatus();
            } while((status & (I2C_MSTAT_WR_CMPLT | I2C_MSTAT_ERR_XFER)) == 0u);
        }
        else
        {
            /* translate from I2CM_MasterWriteBuf() error output to
            *  I2C_MasterStatus() error output */
            status = I2C_MSTAT_ERR_XFER;
        }
    }

    return status;
}

Read Operation:

void I2C_MasterRead(uint8 slaveaddress, uint8 nbytes)
{
    uint8 volatile status;

    status = I2C_MasterClearStatus();
      if(!(status & I2C_MSTAT_ERR_XFER))
        {
            /* Then do the read */
            status = I2C_MasterClearStatus();
            if(!(status & I2C_MSTAT_ERR_XFER))
            {
                status = I2C_MasterReadBuf(slaveaddress,
                                           (uint8 *)&(readbuffer),
                                           nbytes, I2C_MODE_COMPLETE_XFER);
                if(status == I2C_MSTR_NO_ERROR)
                {
                    /* wait for reading complete and no error */
                    do
                    {
                        status = I2C_MasterStatus();
                    } while((status & (I2C_MSTAT_RD_CMPLT | I2C_MSTAT_ERR_XFER)) == 0u);
                    if(!(status & I2C_MSTAT_ERR_XFER))
                    {
                        /* Decrement all RW bytes in the EZI2C buffer, by different values */
                        for(uint8 i = 0u; i < nbytes; i++)
                        {
                            readbuffer[i] -= (i + 1);
                        }
                    }
                }
                else
                {
                    /* translate from I2C_MasterReadBuf() error output to
                    *  I2C_MasterStatus() error output */
                    status = I2C_MSTAT_ERR_XFER;
                }
            }
        }
        if(status & I2C_MSTAT_ERR_XFER)
        {
            /* add error handler code here */
        }

 }
kgangadhar
  • 4,886
  • 5
  • 36
  • 54