我主要在 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 } }