我主要在 blocking_mode 中使用 I2C、而对于我的应用、我需要使用它 callback_mode。 我希望确保正确实施回调和操作。 我已经修改了 i2ctmp.c 测试代码以使用回调功能。 我的行为是否正确?
/*
* ======== i2ctmp.c ========
*/
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>
/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>
#include <ti/display/Display.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Semaphore.h>
/* Driver configuration */
#include "ti_drivers_config.h"
#define TASKSTACKSIZE 640
/* Temperature result registers */
#define TMP11X_RESULT_REG 0x0000
/* I2C target addresses */
#define TMP11X_BASSENSORS_ADDR 0x48
#define TMP116_LAUNCHPAD_ADDR 0x49
/* Number of supported sensor iterations */
#define TMP_COUNT 2
/*Testiing using the RV3028C7 */
#define DEVICE_ADDRESS 0x52
#define MANFACTURER_ID_REG 0x28
/*
* Data structure containing currently supported I2C TMP sensors.
* Sensors are ordered by descending preference.
*/
static const struct
{
uint8_t address;
uint8_t resultReg;
char *id;
} sensors[TMP_COUNT] = {{TMP11X_BASSENSORS_ADDR, TMP11X_RESULT_REG, "11X"},
{TMP116_LAUNCHPAD_ADDR, TMP11X_RESULT_REG, "116"}};
static uint8_t targetAddress;
static Display_Handle display;
static void i2cErrorHandler(I2C_Transaction *transaction, Display_Handle display);
void someI2CCallbackFunction(I2C_Handle handle, I2C_Transaction *i2cTransaction, bool result);
Semaphore_Handle sem;
Semaphore_Params semParams;
/*
* ======== mainThread ========
*/
void *mainThread(void *arg0)
{
uint16_t sample;
int16_t temperature;
uint8_t txBuffer[1];
uint8_t rxBuffer[1];
int8_t i;
I2C_Handle i2c;
I2C_Params i2cParams;
I2C_Transaction i2cTransaction;
Semaphore_Params_init(&semParams);
sem = Semaphore_create(0, &semParams, NULL); /* Memory allocated in here */
if (sem == NULL) /* Check if the handle is valid */
{
//System_abort("Semaphore could not be created");
;
}
/* Call driver init functions */
Display_init();
GPIO_init();
I2C_init();
/* Configure the LED and if applicable, the TMP_EN pin */
GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
#ifdef CONFIG_GPIO_TMP_EN
GPIO_setConfig(CONFIG_GPIO_TMP_EN, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
/* Allow the sensor to power on */
sleep(1);
#endif
/* Open the UART display for output */
display = Display_open(Display_Type_UART, NULL);
if (display == NULL)
{
while (1) {}
}
/* Turn on user LED */
GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
Display_printf(display, 0, 0, "Starting the i2ctmp example\n");
/* Create I2C for usage */
I2C_Params_init(&i2cParams);
i2cParams.bitRate = I2C_400kHz;
i2cParams.transferMode = I2C_MODE_CALLBACK;
//i2cParams.transferMode = I2C_MODE_BLOCKING;
i2cParams.transferCallbackFxn = someI2CCallbackFunction;
i2c = I2C_open(CONFIG_I2C_TMP, &i2cParams);
if (i2c == NULL)
{
Display_printf(display, 0, 0, "Error Initializing I2C\n");
while (1) {}
}
else
{
Display_printf(display, 0, 0, "I2C Initialized!\n");
}
/*RV3028C7 Testing reading the Manufacterer ID*/
txBuffer[0] = MANFACTURER_ID_REG;
i2cTransaction.targetAddress = DEVICE_ADDRESS;
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.readCount = 1;
while (1) {
uint8_t data = 0;
I2C_transfer(i2c, &i2cTransaction);
data = rxBuffer[0];
Display_printf(display, 0, 0, "Data %2x", data);
//Wait for transfer to complete here
Semaphore_pend(sem, BIOS_WAIT_FOREVER); // the timeout value can be changed
}
I2C_close(i2c);
Display_printf(display, 0, 0, "I2C closed!");
return (NULL);
}
/*
* ======== i2cErrorHandler ========
*/
static void i2cErrorHandler(I2C_Transaction *transaction, Display_Handle display)
{
switch (transaction->status)
{
case I2C_STATUS_TIMEOUT:
Display_printf(display, 0, 0, "I2C transaction timed out!");
break;
case I2C_STATUS_CLOCK_TIMEOUT:
Display_printf(display, 0, 0, "I2C serial clock line timed out!");
break;
case I2C_STATUS_ADDR_NACK:
Display_printf(display,
0,
0,
"I2C target address 0x%x not"
" acknowledged!",
transaction->targetAddress);
break;
case I2C_STATUS_DATA_NACK:
Display_printf(display, 0, 0, "I2C data byte not acknowledged!");
break;
case I2C_STATUS_ARB_LOST:
Display_printf(display, 0, 0, "I2C arbitration to another controller!");
break;
case I2C_STATUS_INCOMPLETE:
Display_printf(display, 0, 0, "I2C transaction returned before completion!");
break;
case I2C_STATUS_BUS_BUSY:
Display_printf(display, 0, 0, "I2C bus is already in use!");
break;
case I2C_STATUS_CANCEL:
Display_printf(display, 0, 0, "I2C transaction cancelled!");
break;
case I2C_STATUS_INVALID_TRANS:
Display_printf(display, 0, 0, "I2C transaction invalid!");
break;
case I2C_STATUS_ERROR:
Display_printf(display, 0, 0, "I2C generic error!");
break;
default:
Display_printf(display, 0, 0, "I2C undefined error case!");
break;
}
}
void someI2CCallbackFunction(I2C_Handle handle, I2C_Transaction *i2cTransaction, bool result) {
if (result) {
// transfer completed successfully
// Data is stored in i2cTransaction
// Notify task that transfer is complete here (semaphore or event)
Semaphore_post(sem);
} else {
// error occurred
}
}