Installing an MQX driver - i2c

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Installing an MQX driver - i2c

1,173 Views
Cdn_aye
Senior Contributor I

The doc set says that the i2c driver if enabled in the user_config.h file, may be installed in the BSP or application code. I can't see how to do either. When I do an install for cw10.1, mqx, 51jm128 as per the doc set and source files using

    _mcf51xx_i2c_polled_install("i2c0:", &_bsp_i2c0_init);

I get compile errors following on the next line of code. The address of the init structure is &_bsp_i2c0_init, and is from the board specific source file init_i2c.c, in that file we can see the structure. I added this to the build but still get errors. I tried moving the structure declaration to the function and get errors in compiling.

 

At this point we can't even get the app to compile. I have gone through the eeprom demo but that doesn't do it for us. I don't see how to change the structures and we need lower level api access as well for accelerometers and gyros.

 

I have read through all the doc sets and forums but can't find anything on installing drivers other than general guide lines and references.

 

Any starting point would be appreciated. Thanks

0 Kudos
3 Replies

477 Views
Cdn_aye
Senior Contributor I

This is the code I have for sending reading a character from the MMA7455 i2c accelerometer. I need to do the usual which is to send the slave address wait for the ACK, then send the register start address in the MMA7455 to read from. This all works under CW6.3 without MQX, I can't get the driver to work under CW10.1 and MQX.

 

The write hangs and I am not sure if the IO_IOCTL_I2C_SET_DESTINATION_ADDRESS is sent out by the driver or not since I always get a 0 on the read result and a read buffer of zeros. We need to read 20 characters to verify the device. If we implement a fwrite the code just hangs, probably waiting on an ACK.

 

There is something wrong with the basic concept but I can't figure it out from the example code. Any help would be appreciated.

 

/*FUNCTION*-----------------------------------------------------------------------------------------
(((((((((((((((((((((((((((((((((( I2C_Task )))))))))))))))))))))))))))))))))))
----------------------------------------------------------------------------------------------------
    vFn_i2c_test        test driver fcn

    Input Parameter:    void
    Return Type:        none
   
    Notes:
--------------------------------------------------------------------------------------------------*/
void I2C_task(uint_32)
{
MQX_FILE_PTR                    fd;
uint_32                         param, result;
I2C_STATISTICS_STRUCT           stats;
uchar_ptr                       recv_buffer;
uint8                           buffer[30];
    /* Allocate receive buffer */
    recv_buffer = _mem_alloc_zero (RECV_BUFFER_SIZE);

    if (recv_buffer == NULL){
       printf ("ERROR getting receive buffer!\n");
       _task_block ();
    }
   
    /* Open the I2C driver */        
    fd = fopen ("i2c0:", NULL);
    if (fd == NULL){
       printf ("ERROR opening the I2C driver!\n");
       _time_delay (200L);
       _mqx_exit (1L);
    }
   
    /* Test ioctl commands */
    param = 100000;
    if (I2C_OK != ioctl (fd, IO_IOCTL_I2C_SET_BAUD, &param)){       // Set current baud rate to param
       printf ("ERROR\n");
    }

    if (I2C_OK != ioctl (fd, IO_IOCTL_I2C_SET_MASTER_MODE, NULL)){  // printf ("Set master mode ... ");
       printf ("OK\n");
    }

    param = 0x69;                                                       // slave address of accelerometer
    if (I2C_OK != ioctl (fd, IO_IOCTL_I2C_SET_STATION_ADDRESS, &param)){ // printf ("Set destination address to 0x%02x ... ", param);
       printf ("ERROR\n");
    }

    param = 0x00;
    if (I2C_OK != ioctl (fd, IO_IOCTL_I2C_SET_DESTINATION_ADDRESS, &param)){  // printf ("Set destination address to 0x%02x ... ", param);
       printf ("ERROR\n");
    }

        /* Test request 1 byte, read 1 byte */
    param = 20;
    if (I2C_OK != ioctl (fd, IO_IOCTL_I2C_SET_RX_REQUEST, &param)){     // printf ("Test request 1 byte, read 1 byte ... ");
       printf ("\n  ERROR during set rx request\n");
    }
    result = fread (&buffer, 1, 1, fd);
   
    if (I2C_OK != ioctl (fd, IO_IOCTL_FLUSH_OUTPUT, &param)){
       printf ("\n  ERROR during flush\n");
    }
   
    if (I2C_OK != ioctl (fd, IO_IOCTL_I2C_STOP, NULL)){
       printf ("\n  ERROR during stop\n");
    }
       
    _task_block();

}

0 Kudos

477 Views
easybreather
Contributor II

Hi Robert,

I might suggest a couple of options - given I've recently shared your pain with MQX & I2C!
First: get an O'Scope on your SDA & SCL lines. This gives you that warm fuzzy feeling you are really connected to something

Second: read the manual (I found one online here http://www.jameco.com/Jameco/Products/ProdDS/2109667.pdf) and it does describe the I2C protocol. Is your HW setting CS high so I2C is enabled?

third: remember it's 7 bit device addressing...

fourth, write the code so that the initialisation ends, you STOP the device (pretty important)!

fifth: when you write a packet to the device do you see the data transferred on the O'scope... oh I mentioned that already :smileywink:

sixth: does it work in polling or interupt mod?

 

Lemme know if you get it working - and then if you can use the Interrupts!

477 Views
MarkP_
Contributor V

Hi Robert,

Probably the reason is that the fwrite call is missing.

There is an example in file Freescale MQX 3.7\mqx\examples\i2c\eeprom_int.c in function i2c_read_eeprom_interrupt().

I modified that to read/write IO-expander, it works OK.

~Mark