diff --git a/Module/lsm6dsl/lsm6dsl_app.c b/Module/lsm6dsl/lsm6dsl_app.c index 8eee0a7..4f598fd 100644 --- a/Module/lsm6dsl/lsm6dsl_app.c +++ b/Module/lsm6dsl/lsm6dsl_app.c @@ -1,4 +1,4 @@ - + /* Includes ------------------------------------------------------------------*/ #include "lsm6dsl_app.h" #include "lsm6dsl_reg.h" @@ -13,31 +13,24 @@ dev_ctx_t dev_ctx; static bool InitFlag; -#define ACC_CVTTIME (20 * 1000) -#define ACC_COLL_CNT_MAX 6 -#define ACC_FIFO_WATERMASK (ACC_COLL_CNT_MAX * 6) //采集一秒数æ�® -#define TX_BUF_DIM 1000 +#define ACC_COLL_CNT_MAX 4 //ÿ×鯽¾ùÑù±¾Êý,Êä³öËÙÂÊ=ODR/4=13Hz +#define ACC_FIFO_WATERMASK (ACC_COLL_CNT_MAX * 6) //FIFOˮӡ:4×é ¡Á (3ÍÓÂÝ+3¼ÓËÙ¶È)=24 #define BOOT_TIME 15 //ms typedef enum { Acc_Idle, - Acc_Start, - Acc_Get_Data, - Acc_Wait_GetData, - Acc_Go_Bypass, + Acc_Get_Data, //Á¬Ðø²É¼¯ÔËÐÐÖÐ }AccStatusType_m; static AccStatusType_m acc_status; static uint32_t acc_cvttime; static bool Lsm6dslWaterMarkFullIntFlag; static bool Lsm6dslWakeupIntFlag; +static uint16_t Lsm6dslIntWatchdog; //ÎÞÊý¾Ý¿´ÃŹ·¼ÆÊý(1ms) +static bool Lsm6dslRecoverReq; //×Ô»Ö¸´ÇëÇó(1msÖÃλ,Ö÷Ñ­»·Ö´ÐÐ) -static int16_t data_raw_acceleration[3]; -static int16_t data_raw_angular_rate[3]; -static int16_t data_raw_temperature; static float acceleration_mg[3][ACC_COLL_CNT_MAX]; static float angular_rate_mdps[3][ACC_COLL_CNT_MAX]; -static float temperature_degC; static uint8_t whoamI, rst; @@ -60,6 +53,57 @@ static void platform_read(uint8_t reg, uint8_t *bufp, uint32_t len) I2C_MasterReadData(M0P_I2C0, Selve_Add, reg, bufp, len); } +/***************************************************************************************** +* º¯ÊýÃû³Æ: Lsm6dsl_Config +* ¹¦ÄÜÃèÊö: LSM6DSL¼Ä´æÆ÷ÅäÖÃ,ÅäÖÃÍê³Éºó¿ªÆôÁ¬Ðø²É¼¯(³£¿ª,²»½øÈëµÍ¹¦ºÄ) +* ²Î Êý: ÎÞ +* ·µ »Ø Öµ: ÎÞ +*****************************************************************************************/ +static void Lsm6dsl_Config(void) +{ + /* Restore default configuration */ + lsm6dsl_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lsm6dsl_reset_get(&dev_ctx, &rst); + } while (rst); + + /* ¸ßÐÔÄÜģʽ(´«¸ÐÆ÷³£¿ª,ÔëÉù×îµÍ) */ + lsm6dsl_xl_power_mode_set(&dev_ctx, LSM6DSL_XL_HIGH_PERFORMANCE); + lsm6dsl_gy_power_mode_set(&dev_ctx, LSM6DSL_GY_HIGH_PERFORMANCE); + /* Enable Block Data Update */ + lsm6dsl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE); + /* Set full scale */ + lsm6dsl_xl_full_scale_set(&dev_ctx, LSM6DSL_2g); + lsm6dsl_gy_full_scale_set(&dev_ctx, LSM6DSL_500dps); + /* Configure filtering chain(No aux interface) */ + /* Accelerometer - analog filter */ + lsm6dsl_xl_filter_analog_set(&dev_ctx, LSM6DSL_XL_ANA_BW_400Hz); + /* Accelerometer - LPF1 + LPF2 path */ + lsm6dsl_xl_lp2_bandwidth_set(&dev_ctx, LSM6DSL_XL_LOW_NOISE_LP_ODR_DIV_9); + /* Gyroscope - filtering chain */ + lsm6dsl_gy_band_pass_set(&dev_ctx, LSM6DSL_HP_260mHz_LP1_STRONG); + + /* FIFO:Á¬ÐøÁ÷ģʽ,´æÂúˮӡ´¥·¢Öжϵ«²»Í£²É */ + lsm6dsl_fifo_xl_batch_set(&dev_ctx, LSM6DSL_FIFO_XL_NO_DEC); //fifo¼ÓËÙ¶ÈдÈëÆµÂÊÉèÖà + lsm6dsl_fifo_gy_batch_set(&dev_ctx, LSM6DSL_FIFO_GY_NO_DEC); //fifoÍÓÂÝÒÇдÈëÆµÂÊÉèÖà + lsm6dsl_fifo_data_rate_set(&dev_ctx, LSM6DSL_FIFO_52Hz); //FIFO ODRÑ¡Ôñ,Óë´«¸ÐÆ÷ODRÒ»Ö + lsm6dsl_fifo_watermark_set(&dev_ctx, ACC_FIFO_WATERMASK); //FIFOˮӡµçƽÉèÖÃ,4×éÊý¾Ý + lsm6dsl_fifo_stop_on_wtm_set(&dev_ctx, 0); //´æÂúˮӡºó¼ÌÐø²É¼¯,²»Í£ + lsm6dsl_block_data_update_set(&dev_ctx, 1); //fifoģʽctrl3_c bdu±ØÐëΪ1 + lsm6dsl_auto_increment_set(&dev_ctx, 1); //fifoģʽctrl3_c if_inc±ØÐëΪ1 + + /* ÖжÏ1:FIFOˮӡãÐÖµÖÐ¶Ï */ + lsm6dsl_int1_route_t int1val ={0, 0, 0}; + int1val.int1_fth = 1; //FIFO´æ´¢´ïµ½Ë®Ó¡Éî¶Èʱ´¥·¢ + lsm6dsl_pin_int1_route_set(&dev_ctx, int1val); + + /* ×îºó¿ªÆôODRºÍFIFOÁ¬ÐøÄ£Ê½,±£Ö¤ÏÈÅäÖúó²ÉÑù */ + lsm6dsl_fifo_mode_set(&dev_ctx, LSM6DSL_STREAM_MODE); + lsm6dsl_xl_data_rate_set(&dev_ctx, LSM6DSL_XL_ODR_52Hz); + lsm6dsl_gy_data_rate_set(&dev_ctx, LSM6DSL_GY_ODR_52Hz); +} + static void Lsm6dsl_Init(void) { /* Initialize mems driver interface */ @@ -72,7 +116,7 @@ static void Lsm6dsl_Init(void) whoamI = 0; lsm6dsl_device_id_get(&dev_ctx, &whoamI); acc_cvttime = 100; - while(whoamI != LSM6DSL_ID){ + while(whoamI != LSM6DSL_ID){ if(acc_cvttime <= 0){ DBG_LOG("LSM6DS INIT Err...\r\n"); /*manage here device not found */ InitFlag = false; @@ -80,104 +124,49 @@ static void Lsm6dsl_Init(void) } } - /* Restore default configuration */ - lsm6dsl_reset_set(&dev_ctx, PROPERTY_ENABLE); - - do { - lsm6dsl_reset_get(&dev_ctx, &rst); - } while (rst); - - lsm6dsl_xl_power_mode_set(&dev_ctx, LSM6DSL_XL_NORMAL); - /* Enable Block Data Update */ - lsm6dsl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE); - /* Set Output Data Rate */ - lsm6dsl_xl_data_rate_set(&dev_ctx, LSM6DSL_XL_ODR_12Hz5); - lsm6dsl_gy_data_rate_set(&dev_ctx, LSM6DSL_GY_ODR_12Hz5); - //lsm6dsl_gy_data_rate_set(&left_dev_ctx, LSM6DSL_GY_ODR_OFF); //关闭地ç£� - /* Set full scale */ - lsm6dsl_xl_full_scale_set(&dev_ctx, LSM6DSL_2g); - lsm6dsl_gy_full_scale_set(&dev_ctx, LSM6DSL_2000dps); - /* Configure filtering chain(No aux interface) */ - /* Accelerometer - analog filter */ - lsm6dsl_xl_filter_analog_set(&dev_ctx, LSM6DSL_XL_ANA_BW_400Hz); - /* Accelerometer - LPF1 path ( LPF2 not used )*/ - /*lsm6dsl_xl_lp1_bandwidth_set(&left_dev_ctx, LSM6DSL_XL_LP1_ODR_DIV_4);*/ - /* Accelerometer - LPF1 + LPF2 path */ - lsm6dsl_xl_lp2_bandwidth_set(&dev_ctx, LSM6DSL_XL_LOW_NOISE_LP_ODR_DIV_9); - /* Accelerometer - High Pass / Slope path */ - /*lsm6dsl_xl_reference_mode_set(&left_dev_ctx, PROPERTY_DISABLE);*/ - /*lsm6dsl_xl_hp_bandwidth_set(&left_dev_ctx, LSM6DSL_XL_HP_ODR_DIV_100);*/ - /* Gyroscope - filtering chain */ - lsm6dsl_gy_band_pass_set(&dev_ctx, LSM6DSL_HP_260mHz_LP1_STRONG); - - //fifo模å¼�设置 - lsm6dsl_fifo_xl_batch_set(&dev_ctx, LSM6DSL_FIFO_XL_NO_DEC);//fifo加速度写入频率设置 - lsm6dsl_fifo_gy_batch_set(&dev_ctx, LSM6DSL_FIFO_GY_NO_DEC);//fifo陀螺仪写入频率设置 - lsm6dsl_fifo_data_rate_set(&dev_ctx, LSM6DSL_FIFO_12Hz5);//FIFO ODR选择 - - //中断1设置,watermark full中断 - lsm6dsl_int1_route_t int1val ={0, 0, 0}; - int1val.int1_full_flag = 1; //开阀值中断,fifo存储到缓存深度时触å�‘ - lsm6dsl_pin_int1_route_set(&dev_ctx, int1val); - lsm6dsl_fifo_watermark_set(&dev_ctx, ACC_FIFO_WATERMASK);//FIFOæ°´å�°ç”µå¹³è®¾ç½®ï¼Œé˜ˆå€¼è®¾ç½®ï¼Œç¼“存深度 - lsm6dsl_fifo_stop_on_wtm_set(&dev_ctx, 1);//fifo缓存深度存满时,ä¸�å†�存储 - //lsm6dsl_fifo_xl_gy_8bit_format_set(&left_dev_ctx, 1);//在FIFO中为XL和陀螺å�¯ç”¨MSByte记忆,缓存宽度 - lsm6dsl_block_data_update_set(&dev_ctx, 1); //fifo模å¼�ctrl3_c bdu必须为1,直到读å�–MSBå’ŒLSBå�Žæ‰�更新输出寄存器 - lsm6dsl_auto_increment_set(&dev_ctx, 1); //fifo模å¼�ctrl3_c if_inc必须为1,通过串行接å�£(I2C或SPI)进行多字节访问时自动增加寄存器地å�€ã€‚ - lsm6dsl_ctrl3_c_t ctrl3_c; - platform_read(LSM6DSL_CTRL3_C, (uint8_t *)&ctrl3_c, 1); - //lsm6dsl_fifo_mode_set(&dev_ctx, LSM6DSL_FIFO_MODE); - - //中断2设置,唤醒中断 -// uint8_t temp = 0x90; //唤醒中断 -// platform_write(LSM6DSL_TAP_CFG, &temp, 1); -// temp = 0; -// platform_write(LSM6DSL_WAKE_UP_DUR, &temp, 1); -// lsm6dsl_wkup_threshold_set(&left_dev_ctx, 0x20); -// lsm6dsl_int2_route_t int2val ={0, 0, 0}; -// int2val.int2_wu = 1; -// lsm6dsl_pin_int2_route_set(&left_dev_ctx, int2val); + Lsm6dsl_Config(); if(InitFlag == false){ - DBG_LOG("LSM6DS INIT OK...\r\n"); + DBG_LOG("LSM6DS INIT OK...\r\n"); InitFlag = true; - } + } } extern void Lsm6dDataProcessCallBack(float *Acc, float *Gy); static void Acc_IntHandler(void) { uint16_t DiffFifo; + uint16_t Sets; + uint8_t Cnt; + uint8_t Slot; + uint16_t i; AccGyData_t AccGy; - AccData_t Acc; - float VectorG; float AverageAcc[XYZ], AverageGy[XYZ]; - + lsm6dsl_fifo_data_level_get(&dev_ctx, &DiffFifo); - if(DiffFifo == 0) { + if(DiffFifo < ACC_FIFO_WATERMASK) { return; } - - if(DiffFifo > ACC_FIFO_WATERMASK) - DiffFifo = ACC_FIFO_WATERMASK; - for(int i = 0; i < DiffFifo / 6; i++) { + + Sets = DiffFifo / 6; + for(i = 0; i < Sets; i++) { lsm6dsl_fifo_raw_data_get(&dev_ctx, (uint8_t *)&AccGy, sizeof(AccGy)); - angular_rate_mdps[X][i] = lsm6dsl_from_fs2000dps_to_mdps(AccGy.GyX); - angular_rate_mdps[Y][i] = lsm6dsl_from_fs2000dps_to_mdps(AccGy.GyY); - angular_rate_mdps[Z][i] = lsm6dsl_from_fs2000dps_to_mdps(AccGy.GyZ); - acceleration_mg[X][i] = lsm6dsl_from_fs2g_to_mg(AccGy.AccX); - acceleration_mg[Y][i] = lsm6dsl_from_fs2g_to_mg(AccGy.AccY); - acceleration_mg[Z][i] = lsm6dsl_from_fs2g_to_mg(AccGy.AccZ); + Slot = i % ACC_COLL_CNT_MAX; //»·Ðλº´æ,ʼÖÕ±£Áô×îÐÂACC_COLL_CNT_MAX×é + angular_rate_mdps[X][Slot] = lsm6dsl_from_fs500dps_to_mdps(AccGy.GyX); + angular_rate_mdps[Y][Slot] = lsm6dsl_from_fs500dps_to_mdps(AccGy.GyY); + angular_rate_mdps[Z][Slot] = lsm6dsl_from_fs500dps_to_mdps(AccGy.GyZ); + acceleration_mg[X][Slot] = lsm6dsl_from_fs2g_to_mg(AccGy.AccX); + acceleration_mg[Y][Slot] = lsm6dsl_from_fs2g_to_mg(AccGy.AccY); + acceleration_mg[Z][Slot] = lsm6dsl_from_fs2g_to_mg(AccGy.AccZ); } - AverageGy[X] = IntFilter_Float(angular_rate_mdps[0], DiffFifo / 6, 2); - AverageGy[Y] = IntFilter_Float(angular_rate_mdps[1], DiffFifo / 6, 2); - AverageGy[Z] = IntFilter_Float(angular_rate_mdps[2], DiffFifo / 6, 2); - AverageAcc[X] = IntFilter_Float(acceleration_mg[0], DiffFifo / 6, 2); - AverageAcc[Y] = IntFilter_Float(acceleration_mg[1], DiffFifo / 6, 2); - AverageAcc[Z] = IntFilter_Float(acceleration_mg[2], DiffFifo / 6, 2); + Cnt = (Sets >= ACC_COLL_CNT_MAX) ? ACC_COLL_CNT_MAX : (uint8_t)Sets; + AverageGy[X] = IntFilter_Float(angular_rate_mdps[0], Cnt, 0); + AverageGy[Y] = IntFilter_Float(angular_rate_mdps[1], Cnt, 0); + AverageGy[Z] = IntFilter_Float(angular_rate_mdps[2], Cnt, 0); + AverageAcc[X] = IntFilter_Float(acceleration_mg[0], Cnt, 0); + AverageAcc[Y] = IntFilter_Float(acceleration_mg[1], Cnt, 0); + AverageAcc[Z] = IntFilter_Float(acceleration_mg[2], Cnt, 0); Lsm6dDataProcessCallBack(AverageAcc, AverageGy); - - acc_status = Acc_Go_Bypass; } static void ReadWakeUpIntStatus(void) @@ -192,43 +181,19 @@ static void ReadWakeUpIntStatus(void) void Lsm6dslLoopHandler(void) { ReadWakeUpIntStatus(); - switch(acc_status) - { - case Acc_Idle: - break; - - case Acc_Start: - if(acc_cvttime > 0) - break; - lsm6dsl_fifo_mode_set(&dev_ctx, LSM6DSL_FIFO_MODE); - acc_status = Acc_Get_Data; - acc_cvttime = ACC_CVTTIME; - break; - - case Acc_Get_Data: - acc_cvttime = 1000; - acc_status = Acc_Wait_GetData; - break; - - case Acc_Wait_GetData: - if(acc_cvttime <= 0){ - acc_status = Acc_Go_Bypass; - } - else if(Lsm6dslWaterMarkFullIntFlag) { - Lsm6dslWaterMarkFullIntFlag = false; - uint8_t wtm_flag; - lsm6dsl_fifo_wtm_flag_get(&dev_ctx, &wtm_flag); - Acc_IntHandler(); - acc_status = Acc_Go_Bypass; - } - break; - - case Acc_Go_Bypass: - lsm6dsl_fifo_mode_set(&dev_ctx, LSM6DSL_BYPASS_MODE); - Lsm6dsStop(); - acc_status = Acc_Idle; - acc_cvttime = 1; - break; + if(acc_status != Acc_Get_Data) { + return; + } + if(Lsm6dslRecoverReq) { + Lsm6dslRecoverReq = false; + Lsm6dsl_Config(); //1ÃëÎÞˮӡÖжÏ,ÖØÐÂÅäÖÃFIFO/ODR×Ô»Ö¸´ + Lsm6dslIntWatchdog = 0; + return; + } + if(Lsm6dslWaterMarkFullIntFlag) { + Lsm6dslWaterMarkFullIntFlag = false; + Lsm6dslIntWatchdog = 0; + Acc_IntHandler(); } } @@ -236,6 +201,17 @@ void Lsm6dsl1mSRoutine(void) { if(acc_cvttime > 0) acc_cvttime--; + if(acc_status == Acc_Get_Data) { + if(Lsm6dslIntWatchdog < 2000) + Lsm6dslIntWatchdog++; + if(Lsm6dslIntWatchdog >= 1000) { //Á¬Ðø1ÃëÎÞFIFOˮӡÖÐ¶Ï + Lsm6dslIntWatchdog = 0; + Lsm6dslRecoverReq = true; + } + } + else { + Lsm6dslIntWatchdog = 0; + } } void Lsm6dslInit(void) @@ -245,15 +221,19 @@ void Lsm6dslInit(void) void Lsm6dsStart(void) { - Lsm6dsl_Init(); - acc_status = Acc_Start; + if(acc_status == Acc_Get_Data) { + return; //ÒÑÔÚÁ¬Ðø²É¼¯,²»Öظ´ÅäÖà + } + Lsm6dsl_Init(); //ÅäÖüĴæÆ÷²¢¿ªÆôÁ¬Ðø²É¼¯ + acc_status = Acc_Get_Data; } void Lsm6dsStop(void) { + lsm6dsl_fifo_mode_set(&dev_ctx, LSM6DSL_BYPASS_MODE); + lsm6dsl_fifo_data_rate_set(&dev_ctx, LSM6DSL_FIFO_DISABLE); lsm6dsl_xl_data_rate_set(&dev_ctx, LSM6DSL_XL_ODR_OFF); lsm6dsl_gy_data_rate_set(&dev_ctx, LSM6DSL_GY_ODR_OFF); - lsm6dsl_fifo_data_rate_set(&dev_ctx, LSM6DSL_FIFO_DISABLE); acc_status = Acc_Idle; } diff --git a/Module/mmc5983/mmc5983.c b/Module/mmc5983/mmc5983.c index 4d6bb9f..fff6dfd 100644 --- a/Module/mmc5983/mmc5983.c +++ b/Module/mmc5983/mmc5983.c @@ -1,14 +1,21 @@ -#include "main.h" +#include "main.h" #include "mmc5983.h" #include "UartDebug.h" #include "i2c.h" #include "Algorithm.h" -static int32_t max_in[XYZ]; -static int32_t min_in[XYZ]; +#define MAG_AVG_CNT 2 //æ¯�2个样本平å�‡è¾“出1次,输出速率=20Hz/2=10Hz +#define MAG_POLL_MS 20 //测é‡�完æˆ�标志轮询周期,与20Hz测é‡�周期一致 +#define MAG_POLL_FAIL_MAX 5 //连续5次(100ms)轮询无数æ�®åˆ™é‡�写é…�置自æ�¢å¤� + static bool InitFlag; static bool MMC5983IntFlag; static MMC5983Var_t MMC5983Var; +static int32_t mag_array[XYZ][MAG_AVG_CNT]; +static uint8_t magcnt; +static uint8_t PollFailCnt; + +extern void MmcDataProcessCallBack(float *Mag); /***************************************************************************************** * 函数å��ç§°: MMC5983_Write_Reg @@ -50,19 +57,24 @@ static bool MMC5983_Read_Buffer(uint8_t reg, void *buffer, uint8_t len) } /***************************************************************************************** -* 函数å��ç§°: MMC5983StartCov -* 功能æ��è¿°: MMC5983å¼€å�¯è¿žç»­è½¬æ�¢ +* 函数å��ç§°: MMC5983StartContinuous +* 功能æ��è¿°: MMC5983å¼€å�¯20Hz连续转æ�¢(常开,ä¸�进入低功耗) * å�‚ æ•°: æ—  * è¿” 回 值: æ—  *****************************************************************************************/ -static void MMC5983StartCov(void) +static void MMC5983StartContinuous(void) { + MMC5983RegCtrl0 Ctrl0Reg; MMC5983RegCtrl2 Ctrl2Reg; //å¼€å�¯/关闭连续转æ�¢ + Ctrl0Reg.Byte = 0x00; + Ctrl0Reg.Bit.Auto_SR_en = 1; //自动SET/RESET,消除温漂零场漂移 + Ctrl0Reg.Bit.NT_meas_done_en = 1; //测é‡�完æˆ�中断使能(Stop会清CTRL0,å�¯åŠ¨æ—¶å¿…é¡»é‡�写) + MMC5983_Write_Reg(MMC5983_CTRL_0, Ctrl0Reg.Byte); Ctrl2Reg.Byte = 0x00; - Ctrl2Reg.Bit.Cm_freq = 0x04; + Ctrl2Reg.Bit.Cm_freq = 0x03; //011=20Hz连续测é‡� Ctrl2Reg.Bit.Cmm_en = 1; //连续设1,å�•次设0 - Ctrl2Reg.Bit.Prd_set = 3; - Ctrl2Reg.Bit.En_prd_set = 1; //连续设1,å�•次设0 + Ctrl2Reg.Bit.Prd_set = 3; //æ¯�100次测é‡�自动SET一次,消除温漂 + Ctrl2Reg.Bit.En_prd_set = 1; MMC5983_Write_Reg(MMC5983_CTRL_2, Ctrl2Reg.Byte); } @@ -75,54 +87,49 @@ static void MMC5983StartCov(void) static void MMC5983_Init(void) { uint8_t id; - + id = MMC5983_Read_Reg(MMC5983_ID); //DBG_LOG("MMC5983 id=0x%x\r\n",id); MMC5983Var.MMC5983Delay1mSCnt = 100; while(id != 0x30){ if(MMC5983Var.MMC5983Delay1mSCnt <= 0) { - DBG_LOG("LEFT MMC5983 INIT Err...\r\n"); + DBG_LOG("MMC5983 INIT Err...\r\n"); InitFlag = false; return; } } - + MMC5983RegCtrl1 Ctrl1Reg; Ctrl1Reg.Byte = 0x00; Ctrl1Reg.Bit.SW_RST = 1; MMC5983_Write_Reg(MMC5983_CTRL_1, Ctrl1Reg.Byte); MMC5983Delay(15); - - MMC5983RegCtrl2 Ctrl2Reg; //å¼€å�¯/关闭连续转æ�¢ + + MMC5983RegCtrl2 Ctrl2Reg; //连续模å¼�在StartContinuous中开å�¯ Ctrl2Reg.Byte = 0x00; - Ctrl2Reg.Bit.Cm_freq = 0x04; - Ctrl2Reg.Bit.Cmm_en = 0; //连续设1,å�•次设0 - Ctrl2Reg.Bit.Prd_set = 3; - Ctrl2Reg.Bit.En_prd_set = 0; //连续设1,å�•次设0 MMC5983_Write_Reg(MMC5983_CTRL_2, Ctrl2Reg.Byte); - + MMC5983RegCtrl3 Ctrl3Reg; Ctrl3Reg.Byte = 0x00; Ctrl3Reg.Bit.St_enm = 1; Ctrl3Reg.Bit.St_enp = 1; MMC5983_Write_Reg(MMC5983_CTRL_3, Ctrl3Reg.Byte); - + MMC5983RegCtrl0 Ctrl0Reg; Ctrl0Reg.Byte = 0x00; - Ctrl0Reg.Bit.TM_M = 1; - Ctrl0Reg.Bit.Auto_SR_en = 1; - Ctrl0Reg.Bit.NT_meas_done_en = 1; + Ctrl0Reg.Bit.Auto_SR_en = 1; //自动SET/RESET,消除温漂零场漂移 + Ctrl0Reg.Bit.NT_meas_done_en = 1; //测é‡�完æˆ�中断使能 MMC5983_Write_Reg(MMC5983_CTRL_0, Ctrl0Reg.Byte); - + if(InitFlag == false){ - DBG_LOG("MMC5983 INIT OK...\r\n"); + DBG_LOG("MMC5983 INIT OK...\r\n"); InitFlag = true; } } /***************************************************************************************** * 函数å��ç§°: MMC5983_Read -* 功能æ��è¿°: MMC5983读å�–原始数æ�® +* 功能æ��è¿°: MMC5983读å�–原始数æ�®(18bit) * å�‚ æ•°: MagAdcX Xè½´æ•°æ�® MagAdcY Yè½´æ•°æ�® MagAdcZ Zè½´æ•°æ�® @@ -131,7 +138,7 @@ static void MMC5983_Init(void) static bool MMC5983_Read(int32_t *MagAdcX, int32_t *MagAdcY, int32_t *MagAdcZ) { static uint8_t buff[7]; - + if (MMC5983_Read_Buffer(MMC5983_X_OUT_H, buff, 7) == false) return false; @@ -151,125 +158,114 @@ void MMC5983_Get_Mag(float *mag) { if(mag == NULL) return; - + float ADVal[XYZ]; - - ADVal[X] = MMC5983Var.Mag_Original[X] - 131072.0f; - ADVal[Y] = MMC5983Var.Mag_Original[Y] - 131072.0f; - ADVal[Z] = MMC5983Var.Mag_Original[Z] - 131072.0f; - + + ADVal[X] = MMC5983Var.Mag_Original[X] - 131072.0f; + ADVal[Y] = MMC5983Var.Mag_Original[Y] - 131072.0f; + ADVal[Z] = MMC5983Var.Mag_Original[Z] - 131072.0f; + mag[0] = (float) (ADVal[X] * MMC5983_MAG_SCALE_18BIT); mag[1] = (float) (ADVal[Y] * MMC5983_MAG_SCALE_18BIT); mag[2] = (float) (ADVal[Z] * MMC5983_MAG_SCALE_18BIT); } /***************************************************************************************** -* 函数å��ç§°: MMC5983LoopHandler -* 功能æ��è¿°: MMC5983循环处ç�†å‡½æ•° +* 函数å��ç§°: MMC5983MeasDoneProcess +* 功能æ��è¿°: å�•次测é‡�完æˆ�处ç�†:读å�–样本ã€�清除中断é”�å­˜,凑够MAG_AVG_CNT个样本å�Žå¹³å�‡è¾“出 +* å�‚ æ•°: æ—  +* è¿” 回 值: æ—  +*****************************************************************************************/ +static void MMC5983MeasDoneProcess(void) +{ + MMC5983Var.MMC5983Delay1mSCnt = MAG_POLL_MS; + if(MMC5983_Read(&mag_array[X][magcnt], &mag_array[Y][magcnt], &mag_array[Z][magcnt])){ + magcnt++; + } + MMC5983_Write_Reg(MMC5983_STATUS, 0x01); //写1清Meas_M_Done,释放INTé”�å­˜,下次测é‡�产生新上å�‡æ²¿ + if(magcnt >= MAG_AVG_CNT){ + MMC5983Var.Mag_Original[X] = AverageFilter_32t(mag_array[X], magcnt); + MMC5983Var.Mag_Original[Y] = AverageFilter_32t(mag_array[Y], magcnt); + MMC5983Var.Mag_Original[Z] = AverageFilter_32t(mag_array[Z], magcnt); + magcnt = 0; + MMC5983_Get_Mag(MMC5983Var.Mag); + MmcDataProcessCallBack(MMC5983Var.Mag); + } +} + +/***************************************************************************************** +* 函数å��ç§°: MMC5983LoopHandler +* 功能æ��è¿°: MMC5983循环处ç�†å‡½æ•°,20Hz连续采样,2样本平å�‡å�Ž10Hz输出 * å�‚ æ•°: æ—  * è¿” 回 值: æ—  *****************************************************************************************/ -extern void MmcDataProcessCallBack(float *Mag); void MMC5983LoopHandler(void) { - static int32_t mag_array[XYZ][10]; - static uint8_t magcnt; - static uint8_t TimeOutMagcnt; - switch(MMC5983Var.Status) { case MMC5983_STATUS_IDLE:{ break;} - + case MMC5983_STATUS_START:{ - for(int i = 0; i < 10; i++) { - mag_array[X][i] = 0; - mag_array[Y][i] = 0; - mag_array[Z][i] = 0; - } - magcnt = 0; - TimeOutMagcnt = 0; - memset(&MMC5983Var, NULL, sizeof(MMC5983Var)); - MMC5983Var.Status = MMC5983_STATUS_DELAY; - break;} - - case MMC5983_STATUS_DELAY:{ - MMC5983StartRead(); - MMC5983Var.MMC5983Delay1mSCnt = 50; - MMC5983Var.Status = MMC5983_STATUS_WAIT_DELAY; - break;} - - case MMC5983_STATUS_WAIT_DELAY:{ - if(MMC5983Var.MMC5983Delay1mSCnt <= 0){ - MMC5983Var.Status = MMC5983_STATUS_READ; + if(!InitFlag){ + MMC5983_Init(); + if(!InitFlag){ + MMC5983Var.Status = MMC5983_STATUS_IDLE; + break; + } } - break;} - - case MMC5983_STATUS_READ:{ - MMC5983Var.MMC5983Delay1mSCnt = 50; + magcnt = 0; + PollFailCnt = 0; + MMC5983StartContinuous(); //å¼€å�¯20Hz连续测é‡� + MMC5983Var.MMC5983Delay1mSCnt = MAG_POLL_MS; MMC5983Var.Status = MMC5983_STATUS_WAIT_READ; break;} - - case MMC5983_STATUS_WAIT_READ:{ - if(MMC5983Var.MMC5983Delay1mSCnt <= 0){ - MMC5983Var.Status = MMC5983_STATUS_DELAY; - TimeOutMagcnt++; - } + + case MMC5983_STATUS_WAIT_READ:{ if(MMC5983IntFlag == true){ MMC5983IntFlag = false; - MMC5983_Read(&mag_array[X][magcnt], &mag_array[Y][magcnt], &mag_array[Z][magcnt]); - magcnt++; - MMC5983Var.Status = MMC5983_STATUS_DELAY; + PollFailCnt = 0; + MMC5983MeasDoneProcess(); //INT触å�‘,ç«‹å�³è¯»æ•° } - if(TimeOutMagcnt >= 10){ - TimeOutMagcnt = 0; - if(magcnt > 0){ - MMC5983Var.Mag_Original[X] = AverageFilter_32t(mag_array[X], magcnt); - MMC5983Var.Mag_Original[Y] = AverageFilter_32t(mag_array[Y], magcnt); - MMC5983Var.Mag_Original[Z] = AverageFilter_32t(mag_array[Z], magcnt); - magcnt = 0; - MMC5983_Get_Mag(MMC5983Var.Mag); - MmcDataProcessCallBack(MMC5983Var.Mag); - MMC5983Var.Status = MMC5983_STATUS_STOP; + else if(MMC5983Var.MMC5983Delay1mSCnt <= 0){ + uint8_t StatusReg; + MMC5983Var.MMC5983Delay1mSCnt = MAG_POLL_MS; //20ms轮询一次测é‡�完æˆ�标志 + StatusReg = MMC5983_Read_Reg(MMC5983_STATUS); + if((StatusReg & 0x01) != 0){ //Meas_M_Done=1,测é‡�完æˆ� + PollFailCnt = 0; + MMC5983MeasDoneProcess(); } else{ - MMC5983Var.Status = MMC5983_STATUS_STOP; -// DBG_LOG("LEFT MMC5983 TimeOut...\r\n"); + PollFailCnt++; + if(PollFailCnt >= MAG_POLL_FAIL_MAX){ + PollFailCnt = 0; + MMC5983StartContinuous(); //连续无数æ�®,é‡�写é…�置自æ�¢å¤� + } } } - if(magcnt >= 10){ - MMC5983Var.Mag_Original[X] = AverageFilter_32t(mag_array[X], magcnt); - MMC5983Var.Mag_Original[Y] = AverageFilter_32t(mag_array[Y], magcnt); - MMC5983Var.Mag_Original[Z] = AverageFilter_32t(mag_array[Z], magcnt); - magcnt = 0; - MMC5983_Get_Mag(MMC5983Var.Mag); - MmcDataProcessCallBack(MMC5983Var.Mag); - MMC5983Var.Status = MMC5983_STATUS_STOP; - } break;} - + case MMC5983_STATUS_STOP:{ MMC5983Stop(); MMC5983Var.Status = MMC5983_STATUS_IDLE; - //MMC5983Var.Status = MMC5983_STATUS_START;//æŒ�续工作 break;} } } /***************************************************************************************** -* 函数å��ç§°: LeftMMC59831mSRoutine +* 函数å��ç§°: MMC59831mSRoutine * 功能æ��è¿°: MMC59831ms时基循环处ç�†å‡½æ•° * å�‚ æ•°: æ—  * è¿” 回 值: æ—  *****************************************************************************************/ void MMC59831mSRoutine(void) { - if(MMC5983Var.MMC5983Delay1mSCnt > 0) + if(MMC5983Var.MMC5983Delay1mSCnt > 0) MMC5983Var.MMC5983Delay1mSCnt--; } /***************************************************************************************** -* 函数å��ç§°: LeftMMC5983Init +* 函数å��ç§°: MMC5983Init * 功能æ��è¿°: MMC5983åˆ�始化 * å�‚ æ•°: æ—  * è¿” 回 值: æ—  @@ -280,58 +276,52 @@ void MMC5983Init(void) MMC5983_Init(); return; } - + MMC5983Var.Status = MMC5983_STATUS_START; } /***************************************************************************************** -* 函数å��ç§°: LeftMMC5983Start -* 功能æ��è¿°: MMC5983å�¯åЍ +* 函数å��ç§°: MMC5983Start +* 功能æ��è¿°: MMC5983å�¯åЍ(幂等,å·²è¿�行则直接返回) * å�‚ æ•°: æ—  * è¿” 回 值: æ—  *****************************************************************************************/ void MMC5983Start(void) { + if(MMC5983Var.Status == MMC5983_STATUS_WAIT_READ){ + return; //已在连续采样,ä¸�é‡�å¤�é…�ç½® + } if(!InitFlag){ MMC5983_Init(); - return; + if(!InitFlag){ + return; + } } - + MMC5983Var.Status = MMC5983_STATUS_START; } -/***************************************************************************************** -* 函数å��ç§°: LeftMMC5983StartRead -* 功能æ��è¿°: MMC5983å�¯åŠ¨è¯»å�– -* å�‚ æ•°: æ—  -* è¿” 回 值: æ—  -*****************************************************************************************/ -void MMC5983StartRead(void) -{ - MMC5983_Init();//读å�–æ—¶é‡�æ–°åˆ�始化 -} - /***************************************************************************************** * 函数å��ç§°: MMC5983Stop -* 功能æ��è¿°: MMC5983å�œæ­¢ +* 功能æ��è¿°: MMC5983å�œæ­¢(关闭连续转æ�¢) * å�‚ æ•°: æ—  * è¿” 回 值: æ—  *****************************************************************************************/ void MMC5983Stop(void) -{ +{ + MMC5983RegCtrl2 Ctrl2Reg; + Ctrl2Reg.Byte = 0x00; + MMC5983_Write_Reg(MMC5983_CTRL_2, Ctrl2Reg.Byte); //Cmm_en=0,关闭连续转æ�¢ + MMC5983RegCtrl0 Ctrl0Reg; Ctrl0Reg.Byte = 0x00; MMC5983_Write_Reg(MMC5983_CTRL_0, Ctrl0Reg.Byte); - - MMC5983RegStatus StatusReg; - StatusReg.Byte = MMC5983_Read_Reg(MMC5983_STATUS); - if(StatusReg.Bit.Meas_M_Done == 1){ - MMC5983_Write_Reg(MMC5983_STATUS, StatusReg.Byte); - } + + MMC5983Var.Status = MMC5983_STATUS_IDLE; } /***************************************************************************************** -* 函数å��ç§°: LeftMMC5983IntCallBack +* 函数å��ç§°: MMC5983IntCallBack * 功能æ��è¿°: MMC5983中断回调 * å�‚ æ•°: æ—  * è¿” 回 值: æ—  @@ -340,4 +330,3 @@ void MMC5983IntCallBack(void) { MMC5983IntFlag = true; } - diff --git a/Module/mmc5983/mmc5983.h b/Module/mmc5983/mmc5983.h index 9023e88..7e9a085 100644 --- a/Module/mmc5983/mmc5983.h +++ b/Module/mmc5983/mmc5983.h @@ -103,9 +103,6 @@ typedef union { typedef enum{ MMC5983_STATUS_IDLE, MMC5983_STATUS_START, - MMC5983_STATUS_DELAY, - MMC5983_STATUS_WAIT_DELAY, - MMC5983_STATUS_READ, MMC5983_STATUS_WAIT_READ, MMC5983_STATUS_STOP, }MMC5983Status_m; @@ -129,7 +126,6 @@ void MMC5983Calib(void); void MMC5983GetADValue(int32_t *Mag); void MMC5983_Get_Mag(float *mag); MMC5983Status_m GetMMC5983Status(void); -void MMC5983StartRead(void); bool GetMMC5983CalibStatus(void); #endif diff --git a/driver/src/i2c.c b/driver/src/i2c.c index bf3453f..ec54ed9 100644 --- a/driver/src/i2c.c +++ b/driver/src/i2c.c @@ -66,11 +66,11 @@ /** ****************************************************************************** - ** \brief I2C设置波特率é…�置寄存器 + ** \brief I2CÉèÖò¨ÌØÂÊÅäÖüĴæÆ÷ ** - ** \param [in] u8Tm 波特率é…�置值 + ** \param [in] u8Tm ²¨ÌØÂÊÅäÖÃÖµ ** - ** \retval enRet æˆ�功或失败 + ** \retval enRet ³É¹¦»òʧ°Ü ** ******************************************************************************/ en_result_t I2C_SetBaud(M0P_I2C_TypeDef* I2Cx, uint8_t u8Tm) @@ -84,11 +84,11 @@ } /** ****************************************************************************** - ** \brief I2C功能设置相关函数 + ** \brief I2C¹¦ÄÜÉèÖÃÏà¹Øº¯Êý ** - ** \param [in] enFunc功能å�‚æ•° + ** \param [in] enFunc¹¦ÄܲÎÊý ** - ** \retval enRet æˆ�功或失败 + ** \retval enRet ³É¹¦»òʧ°Ü ** ******************************************************************************/ en_result_t I2C_SetFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc) @@ -102,11 +102,11 @@ en_result_t I2C_SetFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc) } /** ****************************************************************************** - ** \brief I2C功能清除相关函数 + ** \brief I2C¹¦ÄÜÇå³ýÏà¹Øº¯Êý ** - ** \param [in] enFunc功能å�‚æ•° + ** \param [in] enFunc¹¦ÄܲÎÊý ** - ** \retval enRet æˆ�功或失败 + ** \retval enRet ³É¹¦»òʧ°Ü ** ******************************************************************************/ en_result_t I2C_ClearFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc) @@ -120,11 +120,11 @@ en_result_t I2C_SetFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc) } /** ****************************************************************************** - ** \brief I2C获å�–中断标记函数 + ** \brief I2C»ñÈ¡Öжϱê¼Çº¯Êý ** - ** \param æ—  + ** \param ÎÞ ** - ** \retval bIrq中断标记 + ** \retval bIrqÖжϱê¼Ç ** ******************************************************************************/ boolean_t I2C_GetIrq(M0P_I2C_TypeDef* I2Cx) @@ -140,11 +140,11 @@ boolean_t I2C_GetIrq(M0P_I2C_TypeDef* I2Cx) } /** ****************************************************************************** - ** \brief I2C清除中断标记函数 + ** \brief I2CÇå³ýÖжϱê¼Çº¯Êý ** - ** \param æ—  + ** \param ÎÞ ** - ** \retval bIrq中断标记 + ** \retval bIrqÖжϱê¼Ç ** ******************************************************************************/ en_result_t I2C_ClearIrq(M0P_I2C_TypeDef* I2Cx) @@ -158,11 +158,11 @@ en_result_t I2C_ClearIrq(M0P_I2C_TypeDef* I2Cx) } /** ****************************************************************************** - ** \brief I2C获å�–相关状æ€� + ** \brief I2C»ñÈ¡Ïà¹Ø×´Ì¬ ** - ** \param æ—  + ** \param ÎÞ ** - ** \retval I2C状æ€� + ** \retval I2C״̬ ** ******************************************************************************/ uint8_t I2C_GetState(M0P_I2C_TypeDef* I2Cx) @@ -176,11 +176,11 @@ uint8_t I2C_GetState(M0P_I2C_TypeDef* I2Cx) /** ****************************************************************************** - ** \brief 字节数æ�®å†™å‡½æ•° + ** \brief ×Ö½ÚÊý¾Ýдº¯Êý ** - ** \param u8Data写数æ�® + ** \param u8DataдÊý¾Ý ** - ** \retval 写数æ�®æ˜¯å�¦æˆ�功 + ** \retval дÊý¾ÝÊÇ·ñ³É¹¦ ** ******************************************************************************/ en_result_t I2C_WriteByte(M0P_I2C_TypeDef* I2Cx, uint8_t u8Data) @@ -194,11 +194,11 @@ en_result_t I2C_WriteByte(M0P_I2C_TypeDef* I2Cx, uint8_t u8Data) } /** ****************************************************************************** - ** \brief 字节数æ�®è¯»å‡½æ•° + ** \brief ×Ö½ÚÊý¾Ý¶Áº¯Êý ** - ** \param æ—  + ** \param ÎÞ ** - ** \retval 读å�–æ•°æ�® + ** \retval ¶ÁÈ¡Êý¾Ý ** ******************************************************************************/ uint8_t I2C_ReadByte(M0P_I2C_TypeDef* I2Cx) @@ -212,11 +212,11 @@ uint8_t I2C_ReadByte(M0P_I2C_TypeDef* I2Cx) /** ****************************************************************************** - ** \brief I2C模å�—åˆ�始化 + ** \brief I2CÄ£¿é³õʼ»¯ ** - ** \param pstcI2CCfgåˆ�始化é…�置结构体 + ** \param pstcI2CCfg³õʼ»¯ÅäÖýṹÌå ** - ** \retval åˆ�始化是å�¦æˆ�功 + ** \retval ³õʼ»¯ÊÇ·ñ³É¹¦ ** ******************************************************************************/ en_result_t I2C_Init(M0P_I2C_TypeDef* I2Cx, stc_i2c_cfg_t *pstcI2CCfg) @@ -265,71 +265,89 @@ en_result_t I2C_Init(M0P_I2C_TypeDef* I2Cx, stc_i2c_cfg_t *pstcI2CCfg) } /** ****************************************************************************** - ** \brief I2C模å�—接收指定长度函数 + ** \brief I2CÄ£¿é½ÓÊÕÖ¸¶¨³¤¶Èº¯Êý ** - ** \param u8SlaveAddr从机设备地å�€ï¼Œu8Addr从机内存地å�€ï¼Œpu8Data读数æ�®å­˜æ”¾ç¼“存,u32Len读数æ�®é•¿åº¦ + ** \param u8SlaveAddr´Ó»úÉ豸µØÖ·£¬u8Addr´Ó»úÄÚ´æµØÖ·£¬pu8Data¶ÁÊý¾Ý´æ·Å»º´æ£¬u32Len¶ÁÊý¾Ý³¤¶È ** - ** \retval 读数æ�®æ˜¯å�¦æˆ�功 + ** \retval ¶ÁÊý¾ÝÊÇ·ñ³É¹¦ ** ******************************************************************************/ - boolean_t I2C_MasterReadData(M0P_I2C_TypeDef* I2CX,uint8_t u8SlaveAddr,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len) + #define I2C_WAIT_TIMEOUT 20000u ///< µ¥²½µÈ´ý³¬Ê±¼ÆÊý,·ÀÖ¹×ÜÏß¿¨ËÀµ¼ÖÂϵͳËÀÑ­»· +#define I2C_READ_PASS_MAX 200u ///< ¶Á´«Êä״̬»ú×î´óÑ­»·´ÎÊý(48×Ö½ÚFIFO¶ÁÔ¼Ðè120´Î) +#define I2C_WRITE_PASS_MAX 64u ///< д´«Êä״̬»ú×î´óÑ­»·´ÎÊý + +boolean_t I2C_MasterReadData(M0P_I2C_TypeDef* I2CX,uint8_t u8SlaveAddr,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len) { boolean_t enRet = FALSE; uint8_t u8i=0,u8State; - - I2C_SetFunc(I2CX,I2cStart_En);//开始 - + uint32_t u32Wait = 0; + uint16_t u16Pass = 0; + + I2C_SetFunc(I2CX,I2cStart_En);//¿ªÊ¼ + while(1) { - while(0 == I2C_GetIrq(I2CX))//获å�–中断标记函数 - {;} - u8State = I2C_GetState(I2CX);//获å�–i2c相关状æ€� + while(0 == I2C_GetIrq(I2CX))//»ñÈ¡Öжϱê¼Çº¯Êý + { + if(++u32Wait >= I2C_WAIT_TIMEOUT) ///< µÈ´ý³¬Ê±,×ÜÏßÒì³£ + { + I2C_SetFunc(I2CX,I2cStop_En); ///< ³¢ÊÔ·¢ËÍÍ£Ö¹Ìõ¼þÊÍ·Å×ÜÏß + return FALSE; + } + } + u32Wait = 0; + if(++u16Pass >= I2C_READ_PASS_MAX) ///< ״̬»úÖØÊÔ³¬ÏÞ(³ÖÐøNACKµÈ),·ÅÆú±¾´Î´«Êä + { + I2C_SetFunc(I2CX,I2cStop_En); + return FALSE; + } + u8State = I2C_GetState(I2CX);//»ñÈ¡i2cÏà¹Ø×´Ì¬ switch(u8State) { - case 0x08: ///< 主设备å�‘总线已å�‘出了一个起始æ�¡ä»¶ + case 0x08: ///< Ö÷É豸Ïò×ÜÏßÒÑ·¢³öÁËÒ»¸öÆðʼÌõ¼þ I2C_ClearFunc(I2CX,I2cStart_En); I2C_WriteByte(I2CX,(u8SlaveAddr << 1)); break; - case 0x18: ///< 主设备å�‘总线已å�‘出了一个从设备地å�€ï¼ˆå†™æ–¹å�‘)并且接收到从设备的应答 - I2C_WriteByte(I2CX,u8Addr); ///< å�‘é€�从机内存地å�€ + case 0x18: ///< Ö÷É豸Ïò×ÜÏßÒÑ·¢³öÁËÒ»¸ö´ÓÉ豸µØÖ·£¨Ð´·½Ïò£©²¢ÇÒ½ÓÊÕµ½´ÓÉ豸µÄÓ¦´ð + I2C_WriteByte(I2CX,u8Addr); ///< ·¢ËÍ´Ó»úÄÚ´æµØÖ· break; - case 0x28: ///< å·²å�‘é€�æ•°æ�®ï¼ŒæŽ¥æ”¶åˆ°ACK, 此处是已å�‘é€�从机内存地å�€u8Addr并接收到ACK - I2C_SetFunc(I2CX,I2cStart_En); ///< å�‘é€�é‡�å¤�èµ·å§‹æ�¡ä»¶ + case 0x28: ///< ÒÑ·¢ËÍÊý¾Ý£¬½ÓÊÕµ½ACK, ´Ë´¦ÊÇÒÑ·¢ËÍ´Ó»úÄÚ´æµØÖ·u8Addr²¢½ÓÊÕµ½ACK + I2C_SetFunc(I2CX,I2cStart_En); ///< ·¢ËÍÖØ¸´ÆðʼÌõ¼þ break; - case 0x10: ///< 主设备å�‘总线已å�‘出了一个é‡�å¤�的起始æ�¡ä»¶ + case 0x10: ///< Ö÷É豸Ïò×ÜÏßÒÑ·¢³öÁËÒ»¸öÖØ¸´µÄÆðʼÌõ¼þ I2C_ClearFunc(I2CX,I2cStart_En); - I2C_WriteByte(I2CX,(u8SlaveAddr << 1) | 0x01);///< å�‘é€�SLA+R,开始从从机读å�–æ•°æ�® + I2C_WriteByte(I2CX,(u8SlaveAddr << 1) | 0x01);///< ·¢ËÍSLA+R£¬¿ªÊ¼´Ó´Ó»ú¶ÁÈ¡Êý¾Ý break; - case 0x40: ///< å·²å�‘é€�SLA+R,并接收到ACK + case 0x40: ///< ÒÑ·¢ËÍSLA+R£¬²¢½ÓÊÕµ½ACK if(u32Len>1) { - I2C_SetFunc(I2CX,I2cAck_En); ///< 使能主机应答功能 + I2C_SetFunc(I2CX,I2cAck_En); ///< ʹÄÜÖ÷»úÓ¦´ð¹¦ÄÜ } break; - case 0x50: ///< 已接收数æ�®å­—节,并已返回ACKä¿¡å�· + case 0x50: ///< ÒѽÓÊÕÊý¾Ý×Ö½Ú£¬²¢ÒÑ·µ»ØACKÐźŠpu8Data[u8i++] = I2C_ReadByte(I2CX); if(u8i==u32Len-1) { - I2C_ClearFunc(I2CX,I2cAck_En); ///< 已接收到倒数第二个字节,关闭ACK应答功能 + I2C_ClearFunc(I2CX,I2cAck_En); ///< ÒѽÓÊÕµ½µ¹ÊýµÚ¶þ¸ö×Ö½Ú£¬¹Ø±ÕACKÓ¦´ð¹¦ÄÜ } break; - case 0x58: ///< 已接收到最å�Žä¸€ä¸ªæ•°æ�®ï¼ŒNACK已返回 + case 0x58: ///< ÒѽÓÊÕµ½×îºóÒ»¸öÊý¾Ý£¬NACKÒÑ·µ»Ø pu8Data[u8i++] = I2C_ReadByte(I2CX); - I2C_SetFunc(I2CX,I2cStop_En); ///< å�‘é€�å�œæ­¢æ�¡ä»¶ + I2C_SetFunc(I2CX,I2cStop_En); ///< ·¢ËÍÍ£Ö¹Ìõ¼þ break; - case 0x38: ///< 在å�‘é€�地å�€æˆ–æ•°æ�®æ—¶ï¼Œä»²è£�丢失 - I2C_SetFunc(I2CX,I2cStart_En); ///< 当总线空闲时å�‘èµ·èµ·å§‹æ�¡ä»¶ + case 0x38: ///< ÔÚ·¢Ë͵ØÖ·»òÊý¾Ýʱ£¬ÖٲöªÊ§ + I2C_SetFunc(I2CX,I2cStart_En); ///< µ±×ÜÏß¿ÕÏÐʱ·¢ÆðÆðʼÌõ¼þ break; - case 0x48: ///< å�‘é€�SLA+Rå�Žï¼Œæ”¶åˆ°ä¸€ä¸ªNACK - I2C_SetFunc(I2CX,I2cStop_En); ///< å�‘é€�å�œæ­¢æ�¡ä»¶ - I2C_SetFunc(I2CX,I2cStart_En); ///< å�‘é€�èµ·å§‹æ�¡ä»¶ + case 0x48: ///< ·¢ËÍSLA+Rºó£¬ÊÕµ½Ò»¸öNACK + I2C_SetFunc(I2CX,I2cStop_En); ///< ·¢ËÍÍ£Ö¹Ìõ¼þ + I2C_SetFunc(I2CX,I2cStart_En); ///< ·¢ËÍÆðʼÌõ¼þ break; default: - I2C_SetFunc(I2CX,I2cStart_En); ///< 其他错误状æ€�,é‡�æ–°å�‘é€�èµ·å§‹æ�¡ä»¶ + I2C_SetFunc(I2CX,I2cStart_En); ///< ÆäËû´íÎó״̬£¬ÖØÐ·¢ËÍÆðʼÌõ¼þ break; } - I2C_ClearIrq(I2CX); ///< 清除中断状æ€�标志ä½� - if(u8i==u32Len) ///< æ•°æ�®å…¨éƒ¨è¯»å�–完æˆ�,跳出while循环 + I2C_ClearIrq(I2CX); ///< Çå³ýÖжÏ״̬±ê־λ + if(u8i==u32Len) ///< Êý¾ÝÈ«²¿¶ÁÈ¡Íê³É£¬Ìø³öwhileÑ­»· { break; } @@ -339,60 +357,76 @@ en_result_t I2C_Init(M0P_I2C_TypeDef* I2Cx, stc_i2c_cfg_t *pstcI2CCfg) } /** ****************************************************************************** - ** \brief I2C模å�—主机å�‘é€�指定长度函数 + ** \brief I2CÄ£¿éÖ÷»ú·¢ËÍÖ¸¶¨³¤¶Èº¯Êý ** - ** \param u8SlaveAddr从机设备地å�€ï¼Œu8Addr从机内存地å�€ï¼Œpu8Data写数æ�®ï¼Œu32Len写数æ�®é•¿åº¦ + ** \param u8SlaveAddr´Ó»úÉ豸µØÖ·£¬u8Addr´Ó»úÄÚ´æµØÖ·£¬pu8DataдÊý¾Ý£¬u32LenдÊý¾Ý³¤¶È ** - ** \retval 写数æ�®æ˜¯å�¦æˆ�功 + ** \retval дÊý¾ÝÊÇ·ñ³É¹¦ ** ******************************************************************************/ boolean_t I2C_MasterWriteData(M0P_I2C_TypeDef* I2CX,uint8_t u8SlaveAddr,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len) { boolean_t enRet = FALSE; uint8_t u8i=0,u8State, u8Flag=FALSE; + uint32_t u32Wait = 0; + uint16_t u16Pass = 0; I2C_SetFunc(I2CX,I2cStart_En); while(1) { while(0 == I2C_GetIrq(I2CX)) - {;} + { + if(++u32Wait >= I2C_WAIT_TIMEOUT) ///< µÈ´ý³¬Ê±,×ÜÏßÒì³£ + { + I2C_SetFunc(I2CX,I2cStop_En); ///< ³¢ÊÔ·¢ËÍÍ£Ö¹Ìõ¼þÊÍ·Å×ÜÏß + return FALSE; + } + } + u32Wait = 0; + if(++u16Pass >= I2C_WRITE_PASS_MAX) ///< ״̬»úÖØÊÔ³¬ÏÞ(³ÖÐøNACKµÈ),·ÅÆú±¾´Î´«Êä + { + I2C_SetFunc(I2CX,I2cStop_En); + return FALSE; + } u8State = I2C_GetState(I2CX); switch(u8State) { - case 0x08: ///< å·²å�‘é€�èµ·å§‹æ�¡ä»¶ + case 0x08: ///< ÒÑ·¢ËÍÆðʼÌõ¼þ I2C_ClearFunc(I2CX,I2cStart_En); - I2C_WriteByte(I2CX,(u8SlaveAddr << 1)); ///< 从设备地å�€å�‘é€� + I2C_WriteByte(I2CX,(u8SlaveAddr << 1)); ///< ´ÓÉ豸µØÖ··¢ËÍ break; - case 0x18: ///< å·²å�‘é€�SLA+W,并接收到ACK - I2C_WriteByte(I2CX,u8Addr); ///< 从设备内存地å�€å�‘é€� + case 0x18: ///< ÒÑ·¢ËÍSLA+W£¬²¢½ÓÊÕµ½ACK + I2C_WriteByte(I2CX,u8Addr); ///< ´ÓÉ豸ÄÚ´æµØÖ··¢ËÍ break; - case 0x28: ///< 上一次å�‘é€�æ•°æ�®å�ŽæŽ¥æ”¶åˆ°ACK + case 0x28: ///< ÉÏÒ»´Î·¢ËÍÊý¾Ýºó½ÓÊÕµ½ACK if (u8i < u32Len) { - I2C_WriteByte(I2CX,pu8Data[u8i++]); ///< ç»§ç»­å�‘é€�æ•°æ�® + I2C_WriteByte(I2CX,pu8Data[u8i++]); ///< ¼ÌÐø·¢ËÍÊý¾Ý }else { - I2C_SetFunc(I2CX,I2cStop_En); ///< 出å�œæ­¢æ�¡ä»¶ + I2C_SetFunc(I2CX,I2cStop_En); ///< ³öÍ£Ö¹Ìõ¼þ u8Flag = TRUE; + enRet = TRUE; ///< È«²¿Êý¾Ý·¢ËÍÍê³É } break; - case 0x38: ///< 上一次在SLA+读或写时丢失仲è£� - I2C_SetFunc(I2CX,I2cStart_En); ///< 当I2C总线空闲时å�‘é€�èµ·å§‹æ�¡ä»¶ + case 0x38: ///< ÉÏÒ»´ÎÔÚSLA+¶Á»òдʱ¶ªÊ§Öٲà + I2C_SetFunc(I2CX,I2cStart_En); ///< µ±I2C×ÜÏß¿ÕÏÐʱ·¢ËÍÆðʼÌõ¼þ break; - case 0x30: ///< å·²å�‘é€�I2Cx_DATA中的数æ�®ï¼Œæ”¶åˆ°NACK,将传输一个STOPæ�¡ä»¶ - I2C_SetFunc(I2CX,I2cStop_En); ///< å�‘é€�å�œæ­¢æ�¡ä»¶ + case 0x30: ///< ÒÑ·¢ËÍI2Cx_DATAÖеÄÊý¾Ý£¬ÊÕµ½NACK£¬½«´«ÊäÒ»¸öSTOPÌõ¼þ + I2C_SetFunc(I2CX,I2cStop_En); ///< ·¢ËÍÍ£Ö¹Ìõ¼þ + u8Flag = TRUE; + enRet = FALSE; ///< ´Ó»úNACK,±¾´Î´«Êäʧ°Ü break; default: break; } - I2C_ClearIrq(I2CX); ///< 清除中断状æ€�标志ä½� - - if(u8Flag == TRUE) ///< æ•°æ�®å�‘é€�完æˆ� - { + I2C_ClearIrq(I2CX); ///< Çå³ýÖжÏ״̬±ê־λ + + if(u8Flag == TRUE) ///< Êý¾Ý·¢ËÍÍê³É + { break; } } - enRet = TRUE; return enRet; } //@} // I2cGroup diff --git a/source/src/main.c b/source/src/main.c index ce36362..33f7193 100644 --- a/source/src/main.c +++ b/source/src/main.c @@ -235,20 +235,21 @@ static void ReadDataLoopHandler(void) break;} case READDATA_STATUS_UPDAING:{ - DATA_DBG_LOG("<------------ Sensor Data Updaing ------------> \r\n"); - App.UpdateOk = false; + //æŒ�续采集模å¼�下UpdateOkä¸�在å�¯åŠ¨æ—¶æ¸…é›¶:上一轮数æ�®ä»�有效,拿到新数æ�®å�Žæ‰�覆盖 + //å�¦åˆ™åœ¨ä¸¤è½®æ•°æ�®çš„é—´éš™(约100ms)键入up/coll会误报"Device data is not ready" Lsm6dsStart(); MMC5983Start(); App.ReadData1mSDelayCnt = 2000; App.RDStatus = READDATA_STATUS_WAIT_UPDAING; break;} - + case READDATA_STATUS_WAIT_UPDAING:{ if(App.ReadData1mSDelayCnt <= 0){ if(App.AccRead_EndFlag == false) - DATA_DBG_LOG("Lsm6dsl Get Data TimeOut...\r\n"); + DATA_DBG_LOG("Lsm6dsl Get Data TimeOut...\r\n"); if(App.MagRead_EndFlag == false) DATA_DBG_LOG("MMC5983 Get Data TimeOut...\r\n"); + App.UpdateOk = false; //è¶…æ—¶:æ•°æ�®ä¸�å�¯ä¿¡ App.RDStatus = READDATA_STATUS_DATA_HANDLE; } else if(App.MagRead_EndFlag == true @@ -256,22 +257,20 @@ static void ReadDataLoopHandler(void) App.RDStatus = READDATA_STATUS_DATA_HANDLE; } break;} - + case READDATA_STATUS_DATA_HANDLE:{ if(App.MagRead_EndFlag == false || App.AccRead_EndFlag == false){ - DATA_DBG_LOG("<------------ Sensor Data Upda End ------------> \r\n"); - App.RDStatus = READDATA_STATUS_IDLE; - App.UpdateOk = false; + //有传感器超时未出数:回到采集状æ€�æŒ�ç»­é‡�试(å�¯åŠ¨å‡½æ•°å¹‚ç­‰,ä¸�会é‡�å¤�åˆ�始化) + App.RDStatus = READDATA_STATUS_UPDAING; break; } App.MagRead_EndFlag = false; App.AccRead_EndFlag = false; - + IMU_Update(0, App.Sensor.acce, App.Sensor.mag, &App.AHRSData.Rad, &App.AHRSData.Deg); App.ConvertedData.Pitch = (int16_t)(App.AHRSData.Deg.pitch * 10); App.ConvertedData.Roll = (int16_t)(App.AHRSData.Deg.roll * 10); App.ConvertedData.Yaw = (int16_t)(App.AHRSData.Deg.yaw * 10); - DATA_DBG_LOG("PitchAngle:%06.1f, RollAngle:%06.1f, YawAngle:%06.1f\r\n",App.AHRSData.Deg.pitch, App.AHRSData.Deg.roll, App.AHRSData.Deg.yaw); if(SGCP.MasterCaliOk == true) { @@ -317,9 +316,9 @@ static void ReadDataLoopHandler(void) #endif memcpy(LocalDataPack, &SGCP.DevData.LaserTracing, sizeof(LocalDataPack)); - DATA_DBG_LOG("<------------ Sensor Data Upda End ------------> \r\n"); + //DATA_DBG_LOG("<------------ Sensor Data Upda End ------------> \r\n"); //10Hz循环打å�°ä¼šé˜»å¡ž9600调试串å�£,å±�蔽 //App.RDStatus = READDATA_STATUS_UPDAING;//æŒ�续工作 - App.RDStatus = READDATA_STATUS_IDLE; + App.RDStatus = READDATA_STATUS_UPDAING;//æŒ�续采集,å§¿æ€�æ•°æ�®ä¿�æŒ�10Hzæ›´æ–°(上传网关节å¥�ä¸�å�˜,ä»�ç”±UploadFlag定时器控制) App.UpdateOk = true; break;} } @@ -352,6 +351,34 @@ bool IsFullPowerTime(void) return false; } +/***************************************************************************************** +* 函数å��ç§°: LoraPowerHandler +* 功能æ��è¿°: LoRa按需供电管ç�†(设备为主动上报模å¼�): +* 仅在与网关通信期间(GWStatusé�žIDLE,å�«æ³¨å†Œ/上传/ä¿¡å�·æŸ¥è¯¢/激光å“�应)å¼€å�¯LoRa接收, +* 通信结æ�Ÿå›žåˆ°IDLEç«‹å�³ä¼‘眠LoRa,平时ä¸�耗电。 +* å�•片机/加速度/地ç£�ä¸�å�—å½±å“�,ä¿�æŒ�æŒ�续采集。 +* å�‚ æ•°: æ—  +* è¿” 回 值: æ—  +*****************************************************************************************/ +static void LoraPowerHandler(void) +{ + static bool LoraPowerOn = true; //开机BspInit已开å�¯,åˆ�值true + bool NeedLora; + + NeedLora = (SGCP.GWStatus != GW_STATUS_IDLE); + + if(NeedLora == true && LoraPowerOn == false) { + LoraPowerOn = true; + Sx1276LoRaWakeup(); //进入接收模å¼� + LORAIntEnable(); //å¼€å�¯LORA中断 + } + else if(NeedLora == false && LoraPowerOn == true) { + LoraPowerOn = false; + LORAIntDisable(); //关闭LORA中断 + Sx1276LoRaSleep(); //LoRa休眠,平时ä¸�耗电 + } +} + static void AppLoopHandler(void) { switch(App.Status) { @@ -393,14 +420,16 @@ static void AppLoopHandler(void) SGCP.GWStatus = GW_STATUS_LOGIN;//注册 App.Status = APP_STATUS_WAIT_LOGIN; } - else if(SGCP.TimingAcquisition == true && App.RDStatus == READDATA_STATUS_IDLE)//设备数æ�®èŽ·å�– - { + else if(SGCP.TimingAcquisition == true)//设备数æ�®èŽ·å�–(æŒ�续采集模å¼�下RDStatus常驻é�žIDLE,采集请求视为已被满足) + { + SGCP.TimingAcquisition = false; + if(App.RDStatus == READDATA_STATUS_IDLE){ PrintfMess(); - SGCP.TimingAcquisition = false; App.RDStatus = READDATA_STATUS_UPDAING; App.Status = APP_STATUS_ACTION; App.TD1mSDelayCnt = 1000; } + } else if(SGCP.LoginOk == true && App.UploadFlag == true && SGCP.GWStatus == GW_STATUS_IDLE && App.UpdateOk == true) { PrintfMess(); @@ -561,6 +590,7 @@ int32_t main(void) //09 00 01 00 00 00 while (1) { + LoraPowerHandler();//LoRa按需供电:通信时开,平时休眠 #if(USE_VBAT_AD == 1) ADCLoopHandler(); #endif