/* IST8310 地磁传感器。 */ /* Includes ----------------------------------------------------------------- */ #include "ist8310.h" #include #include #include #include "bsp\delay.h" #include "bsp\gpio.h" #include "bsp\i2c.h" /* Private define ----------------------------------------------------------- */ #define IST8310_WAI (0x00) #define IST8310_STAT1 (0x02) #define IST8310_DATAXL (0x03) #define IST8310_STAT2 (0x09) #define IST8310_CNTL1 (0x0A) #define IST8310_CNTL2 (0x0B) #define IST8310_STR (0x0C) #define IST8310_TEMPL (0x1C) #define IST8310_TEMPH (0x1D) #define IST8310_AVGCNTL (0x41) #define IST8310_PDCNTL (0x42) #define IST8310_CHIP_ID (0x10) #define IST8310_IIC_ADDRESS (0x0E << 1) #define IST8310_LEN_RX_BUFF (6) /* Private macro ------------------------------------------------------------ */ #define IST8310_SET() \ HAL_GPIO_WritePin(CMPS_RST_GPIO_Port, CMPS_RST_Pin, GPIO_PIN_SET) #define IST8310_RESET() \ HAL_GPIO_WritePin(CMPS_RST_GPIO_Port, CMPS_RST_Pin, GPIO_PIN_RESET) /* Private typedef ---------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */ uint8_t ist8310_rxbuf[IST8310_LEN_RX_BUFF]; static osThreadId_t thread_alert; static bool inited = false; /* Private function -------------------------------------------------------- */ static void IST8310_WriteSingle(uint8_t reg, uint8_t data) { HAL_I2C_Mem_Write(BSP_I2C_GetHandle(BSP_I2C_COMP), IST8310_IIC_ADDRESS, reg, I2C_MEMADD_SIZE_8BIT, &data, 1, 100); } static uint8_t IST8310_ReadSingle(uint8_t reg) { uint8_t buf = 0; HAL_I2C_Mem_Read(BSP_I2C_GetHandle(BSP_I2C_COMP), IST8310_IIC_ADDRESS, reg, I2C_MEMADD_SIZE_8BIT, &buf, 1, 100); return buf; } static void IST8310_Read(uint8_t reg, uint8_t *data, uint8_t len) { if (data == NULL) return; HAL_I2C_Mem_Read_DMA(BSP_I2C_GetHandle(BSP_I2C_COMP), IST8310_IIC_ADDRESS, reg, I2C_MEMADD_SIZE_8BIT, data, len); } static void IST8310_MemRxCpltCallback(void) { osThreadFlagsSet(thread_alert, SIGNAL_IST8310_MAGN_RAW_REDY); } static void IST8310_IntCallback(void) { osThreadFlagsSet(thread_alert, SIGNAL_IST8310_MAGN_NEW_DATA); } /* Exported functions ------------------------------------------------------- */ int8_t IST8310_Init(IST8310_t *ist8310, const IST8310_Cali_t *cali) { if (ist8310 == NULL) return DEVICE_ERR_NULL; if (cali == NULL) return DEVICE_ERR_NULL; if (inited) return DEVICE_ERR_INITED; if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL; ist8310->cali = cali; IST8310_RESET(); BSP_Delay(50); IST8310_SET(); BSP_Delay(50); if (IST8310_ReadSingle(IST8310_WAI) != IST8310_CHIP_ID) return DEVICE_ERR_NO_DEV; BSP_GPIO_DisableIRQ(CMPS_INT_Pin); BSP_I2C_RegisterCallback(BSP_I2C_COMP, HAL_I2C_MEM_RX_CPLT_CB, IST8310_MemRxCpltCallback); BSP_GPIO_RegisterCallback(CMPS_INT_Pin, IST8310_IntCallback); /* Init. */ /* 0x00: Stand-By mode. 0x01: Single measurement mode. */ /* 0x08: Data ready function enable. DRDY signal active low*/ IST8310_WriteSingle(IST8310_CNTL2, 0x08); IST8310_WriteSingle(IST8310_AVGCNTL, 0x09); IST8310_WriteSingle(IST8310_PDCNTL, 0xC0); IST8310_WriteSingle(IST8310_CNTL1, 0x0B); BSP_Delay(10); inited = true; BSP_GPIO_EnableIRQ(CMPS_INT_Pin); return DEVICE_OK; } bool IST8310_WaitNew(uint32_t timeout) { return (osThreadFlagsWait(SIGNAL_IST8310_MAGN_NEW_DATA, osFlagsWaitAll, timeout) == SIGNAL_IST8310_MAGN_NEW_DATA); } int8_t IST8310_StartDmaRecv() { IST8310_Read(IST8310_DATAXL, ist8310_rxbuf, IST8310_LEN_RX_BUFF); return DEVICE_OK; } uint32_t IST8310_WaitDmaCplt() { return osThreadFlagsWait(SIGNAL_IST8310_MAGN_RAW_REDY, osFlagsWaitAll, osWaitForever); } int8_t IST8310_Parse(IST8310_t *ist8310) { if (ist8310 == NULL) return DEVICE_ERR_NULL; #if 1 /* Magn -> T */ int16_t raw_x, raw_y, raw_z; memcpy(&raw_x, ist8310_rxbuf + 0, sizeof(raw_x)); memcpy(&raw_y, ist8310_rxbuf + 2, sizeof(raw_y)); memcpy(&raw_z, ist8310_rxbuf + 4, sizeof(raw_z)); ist8310->magn.x = (float)raw_x; ist8310->magn.y = (float)raw_y; ist8310->magn.z = (float)-raw_z; #else const int16_t *raw_x = (int16_t *)(ist8310_rxbuf + 0); const int16_t *raw_y = (int16_t *)(ist8310_rxbuf + 2); const int16_t *raw_z = (int16_t *)(ist8310_rxbuf + 4); ist8310->magn.x = (float)*raw_x; ist8310->magn.y = (float)*raw_y; ist8310->magn.z = -(float)*raw_z; #endif ist8310->magn.x *= 3.0f / 20.0f; ist8310->magn.y *= 3.0f / 20.0f; ist8310->magn.z *= 3.0f / 20.0f; ist8310->magn.x = (ist8310->magn.x - ist8310->cali->magn_offset.x) * ist8310->cali->magn_scale.x; ist8310->magn.y = (ist8310->magn.y - ist8310->cali->magn_offset.y) * ist8310->cali->magn_scale.y; ist8310->magn.z = (ist8310->magn.z - ist8310->cali->magn_offset.y) * ist8310->cali->magn_scale.z; return DEVICE_OK; }