Ver código fonte

feat: 蓝牙命令
adc模块
风扇速度管理

kindring 1 ano atrás
pai
commit
dc40fd70d5

+ 5 - 0
ble-light.uvprojx

@@ -492,6 +492,11 @@
               <FileType>1</FileType>
               <FilePath>.\src\control\btn.c</FilePath>
             </File>
+            <File>
+              <FileName>readAdc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\src\control\readAdc.c</FilePath>
+            </File>
             
           </Files>
         </Group>

+ 6 - 6
components/driver/adc/adc.c

@@ -523,7 +523,7 @@ static void hal_adc_load_calibration_value(void)
 float hal_adc_value_cal(adc_CH_t ch,uint16_t* buf, uint32_t size, uint8_t high_resol, uint8_t diff_mode)
 {
     uint32_t i;
-		int adc_sum = 0;
+	int adc_sum = 0;
     float result = 0.0;
 	
     for (i = 0; i < size; i++) {
@@ -532,13 +532,13 @@ float hal_adc_value_cal(adc_CH_t ch,uint16_t* buf, uint32_t size, uint8_t high_r
   
     hal_adc_load_calibration_value();  
     result = ((float)adc_sum)/size;
-  
-    if((adc_cal_postive!=0xfff)&&(adc_cal_negtive!=0xfff)){
-        float delta = ((int)(adc_cal_postive-adc_cal_negtive))/2.0;
+	
+    if((adc_cal_postive!=0xfff) && (adc_cal_negtive!=0xfff)){
+        float delta = ((int)(adc_cal_postive - adc_cal_negtive))/2.0;
         if(ch&0x01)
         {
-            result = (diff_mode) ? ((result-2048-delta)*2/(adc_cal_postive+adc_cal_negtive)) 
-            : ((result+delta) /(adc_cal_postive+adc_cal_negtive));
+            result = (diff_mode) ? ((result - 2048 - delta) * 2 / (adc_cal_postive + adc_cal_negtive)) 
+            : ((result + delta) / (adc_cal_postive + adc_cal_negtive));
         }
         else
         {

+ 1 - 1
src/OSAL_wrist.c

@@ -32,7 +32,7 @@
 #include "light.h"
 
 /* adc */
-#include "adc.h"
+#include "readAdc.h"
 
 /* Application */
 #include "app_wrist.h"

+ 82 - 1
src/app_wrist.c

@@ -18,6 +18,9 @@
 #include "log.h"
 #include "ll.h"
 
+#include "adc.h"
+
+
 #include "light.h"
 #include "app_wrist.h"
 #include "wrist_service.h"
@@ -235,6 +238,82 @@ static void getPinState(){
 	LOG("---------------------------------\n");
 }
 
+void test_adc_evt(adc_Evt_t* pev){
+    int i = 0;
+    LOG("test_adc_evt\n");
+    if(pev->type == HAL_ADC_EVT_DATA){
+        LOG("HAL_ADC_EVT_DATA\n");
+    }
+    // typedef struct _adc_Evt_t{
+    //     int       type;
+    //     adc_CH_t  ch;
+    //     uint16_t* data;
+    //     uint8_t   size; //word size
+    // }adc_Evt_t;
+    LOG("adc event type:%d ch:%d\n", pev->type, pev->ch);
+    // 输出adc数据
+    LOG("[adc data] size:%d value: ", pev->size);
+    for(i = 0; i < pev->size; i++){
+        LOG("%02x", pev->data[i]);
+    }
+    LOG("\n");
+    uint16 adc_buf[6][64];
+    osal_memcpy(adc_buf[pev->ch-2], pev->data, 2*(pev->size));
+
+
+    // 输出adcbuf数据
+    for(i = 0; i < 6; i++){
+        LOG("adc_buf[%d]: ", i);
+        for(int j = 0; j < 64; j++){
+            LOG("%02x", adc_buf[i][j]);
+        }
+        LOG("\n");
+    }
+
+    float value = 0;
+    static uint8_t channel_done_flag = 0;
+    channel_done_flag |= BIT(pev->ch);
+    for(i=2;i<8;i++)
+    {
+        if(channel_done_flag & BIT(i))
+		{
+        // is_high_resolution = (adc_cfg.is_high_resolution & BIT(i))?TRUE:FALSE;
+            // is_differential_mode = (adc_cfg.is_differential_mode & BIT(i))?TRUE:FALSE;
+            LOG("PEV: %d %d %d\n", i, pev->size, pev->data[0]);
+            value = hal_adc_value_cal((adc_CH_t)i, adc_buf[i-2], pev->size, TRUE, FALSE);
+            // 最终电压值 
+            if(i<7)
+            {
+                LOG("P%d %d mv val: %d mv V: %d",(i+9),(int)(value*1000), (int)(value * 1000 * 4), (int)(value*1000) * 4 * 12);
+                // 输出电压值 V 12倍 浮点数
+                LOG("[BATT]: %dmV", (int)(value*1000) * 4 * 13);
+            } else
+            {
+                LOG("P%d %d mv ",(20),(int)(value*1000));
+            }
+        }
+    }	
+    // getPinState();
+}
+void test_adc_read(){
+   LOG("[test_adc_read] read Read Adc");
+   hal_adc_init();
+    GPIO_Pin_e controlPin = P34;
+   GPIO_Pin_e adcPin = P14;
+   adc_Cfg_t adc_cfg = {
+        .channel = ADC_BIT(ADC_CH2P_P14),
+        .is_continue_mode = FALSE,
+        .is_differential_mode = FALSE,
+        .is_high_resolution = TRUE,
+    };
+   
+    // 注册adc
+    hal_adc_config_channel(adc_cfg, test_adc_evt);
+    LOG("hal_adc_config_channel end\n");
+    hal_adc_start();
+}
+
+
 void appWristInit( uint8 task_id)
 {
     AppWrist_TaskID = task_id;
@@ -315,6 +394,9 @@ void appWristInit( uint8 task_id)
     LOG("temp_set end\n");
     // light_set(10, 0, NULL);
     LOG("appWristInit end\n");
+    // test_adc_read();
+    // 注册定时器. 持续读取数据
+    // osal_start_reload_timer( AppWrist_TaskID, TIMER_LIGHT_EVT, 2000);
 }
 
 // 事件处理器
@@ -351,7 +433,6 @@ uint16 appWristProcEvt( uint8 task_id, uint16 events )
     if ( events & TIMER_LIGHT_EVT )
     {
         LOG("TIMER_LIGHT_EVT\n");
-        getPinState();
         return ( events ^ TIMER_LIGHT_EVT );
     }
      return 0;

+ 16 - 11
src/control/readAdc.c

@@ -164,13 +164,13 @@ static void adc_evt(adc_Evt_t* pev)
 {
 	float value = 0;
 	int i = 0;
-	bool is_high_resolution = FALSE;
+	bool is_high_resolution = TRUE;
 	bool is_differential_mode = FALSE;
 		
 	if((pev->type != HAL_ADC_EVT_DATA) || (pev->ch < 2))
 		return;
 		
-	osal_memcpy(adc_debug[pev->ch-2],pev->data,2*(pev->size));
+	osal_memcpy(adc_debug[pev->ch-2], pev->data, 2*(pev->size));
 	channel_done_flag |= BIT(pev->ch);		
 		
 	if(channel_done_flag == adc_cfg.channel)
@@ -179,9 +179,10 @@ static void adc_evt(adc_Evt_t* pev)
 		{
 			if(channel_done_flag & BIT(i))
 			{
-				is_high_resolution = (adc_cfg.is_high_resolution & BIT(i))?TRUE:FALSE;
-				is_differential_mode = (adc_cfg.is_differential_mode & BIT(i))?TRUE:FALSE;
-				value = hal_adc_value_cal((adc_CH_t)i,adc_debug[i-2], pev->size, is_high_resolution,is_differential_mode);
+				// is_high_resolution = (adc_cfg.is_high_resolution & BIT(i))?TRUE:FALSE;
+				// is_differential_mode = (adc_cfg.is_differential_mode & BIT(i))?TRUE:FALSE;
+				LOG("PEV: %d %d %d\n", i, pev->size, pev->data[0]);
+				value = hal_adc_value_cal((adc_CH_t)i, adc_debug[i-2], pev->size, FALSE, is_differential_mode);
 				
 				if(i<7)
 					LOG("P%d %d mv ",(i+9),(int)(value*1000));
@@ -204,8 +205,8 @@ static void adcMeasureTask( void )
 {
 	// 1. config adc channel
 	int ret;
-	bool batt_mode = FALSE;
-	uint8_t batt_ch = ADC_CH3P_P20;
+	bool batt_mode = TRUE;
+	uint8_t batt_ch = ADC_CH2P_P14;
 	GPIO_Pin_e pin;
 	
 	if(FALSE == batt_mode)
@@ -216,13 +217,17 @@ static void adcMeasureTask( void )
 	{
 		if((((1 << batt_ch) & adc_cfg.channel) == 0) || (adc_cfg.is_differential_mode != 0x00))			
 			return;
-
-		pin = s_pinmap[batt_ch];		
-		hal_gpio_cfg_analog_io(pin,Bit_DISABLE);
+		LOG("batt_mode\n");
+		// 拉高 p34 脚的电压, 配置为输出
+		hal_gpio_pull_set(P34, STRONG_PULL_UP);
+		
+		pin = s_pinmap[batt_ch];	
+		hal_gpio_cfg_analog_io(pin, Bit_DISABLE);
 		hal_gpio_write(pin, 1);		
 
 		ret = hal_adc_config_channel(adc_cfg, adc_evt);
-		hal_gpio_cfg_analog_io(pin,Bit_DISABLE);	
+		hal_gpio_cfg_analog_io(pin, Bit_DISABLE);	
+
 	}	
 	
 	//LOG("REG_IO_CONTROL:%x\n",*REG_IO_CONTROL);

+ 115 - 4
src/light.c

@@ -27,12 +27,15 @@ int light_ch_set(uint8_t ch, uint16_t val){
     return ret;
 }
 
-
-
-
-// 计算 冷暖光的亮度值
+/**
+ * 计算并调节冷暖光以及风扇的pwm通道值
+ * 
+*/
 uint8_t comLightVal(){
     int light_val = light_data.light, temp_val = light_data.temp;
+    uint8 fan_speed = light_data.fan;
+    // 设备是否关闭
+    bool isClose = !light_data.open;
     if(light_val > 100){
         light_val = 100;
     }
@@ -55,25 +58,69 @@ uint8_t comLightVal(){
     int tmp_cold_val = _light_total - tmp_warm_val;
     int warm_val = light_val * tmp_warm_val / 100;
     int cold_val = light_val * tmp_cold_val / 100;
+    // 如果色温偏冷, 且亮度小于特定值,则需要将暖色温进行一定补偿, 防止暖色温灯光过暗, 造成色温偏冷
+    if(temp_val < TEMP_MIN + TEMP_OFFSET 
+    && warm_val < WARM_LIGHT_MIN 
+    && temp_val != TEMP_MIN
+    && light_val >= LIGHT_MIN){
+        warm_val = WARM_LIGHT_MIN + 1;
+    }
+    // 如果色温偏暖, 且亮度小于特定值,则需要将冷色温进行一定补偿, 防止冷色温灯光过暗, 造成色温偏暖
+    if(temp_val > TEMP_MAX - TEMP_OFFSET 
+    && cold_val < COLD_LIGHT_MIN 
+    && temp_val != TEMP_MIN
+    && light_val >= LIGHT_MIN){
+        cold_val = COLD_LIGHT_MIN + 1;
+    }
+    
+    
     LOG("[comLightVal] light: %d temp: %d warm_val %d, cold_val %d \n", light_val, temp_val, warm_val, cold_val);
     
     if(light_data.mode == LIGHT_MODE_FULL){
         // 全亮模式
         warm_val = light_val * _light_total / 100;
         cold_val = light_val * _light_total / 100;
+        fan_speed = 100;
     }
 
 
+
+    // 冷暖灯光小于最低值直接关闭灯光通道
+    if(warm_val < WARM_LIGHT_MIN && cold_val < COLD_LIGHT_MIN){
+        isClose = true;
+    }
+
+    
     if(!light_data.open){
         // 设备已经关闭, 设置为 0
+        isClose = true;
+    }
+
+
+    if (isClose)
+    {
+        // 关闭灯光
         warm_val = 0;
         cold_val = 0;
+        fan_speed = 0;
     }
 
+
     light_ch_set(WARM_CH, warm_val);
     light_ch_set(COLD_CH, cold_val);
 
+   
 
+    // 设置风扇
+    if (fan_speed > 0)
+    {   
+        pwm_open(FAN_CH, GPIO_FAN);
+        light_ch_set(FAN_CH, fan_speed);
+    }else{
+        // 关闭风扇
+        pwm_close(FAN_CH);
+    }
+    
     return 0;
 }
 
@@ -294,7 +341,26 @@ uint16 light_set(uint8 val, uint8_t sn , uint8 *res){
     if(val > 100){
         val = 100;
     }
+    
+    // 只在亮度减少时进行检测
+    if (val < light_data.light && val < LIGHT_MIN)
+    {
+        LOG("[light_set] val is too small, set to 0\n");
+        val = 0;
+    }
+
     light_data.light = val;
+    // 亮度大于特定值时, 直接将风扇速度与灯同步
+    if(val > FAN_LIGHT_MIN)
+    {
+        light_data.fan = val;
+    } else 
+    {
+        // 亮度小于特定值时, 风扇速度为 30
+        light_data.fan = 0;
+    }
+
+
     comLightVal();
     uint8 data[1] = {val};
     uint16 resLen = 0;
@@ -348,6 +414,39 @@ uint16 temp_set(int temp, uint8_t sn , uint8 *res){
     return resLen;
 }
 
+/**
+ * 风扇速度调节
+*/
+uint16 FAN_SET(uint8 fanSpeed, uint8_t sn , uint8 *res){
+    if(fanSpeed > 100){
+        fanSpeed = 100;
+    }
+    light_data.fan = fanSpeed;
+    comLightVal();
+    uint8 data[1] = {fanSpeed};
+    uint16 resLen = 0;
+    if(res == NULL)
+    {
+        uint8 *_res = osal_mem_alloc(CMD_HEADER_LEN + 1);
+        resLen = comCmdResCode(CMD_FAN, sn, data, 1, _res);
+        if(notify_callback != NULL){
+            notify_callback(_res, resLen);
+        }
+        osal_mem_free(_res);
+    }else{
+        resLen = comCmdResCode(CMD_FAN, sn, data, 1, res);
+    }
+    // 输出hex数据
+    LOG("[FAN_SET] res: ");
+    for (int i = 0; i < resLen; i++)
+    {
+        LOG("%02x ", res[i]);
+    }
+    LOG("\n");
+    
+    return resLen;
+}
+
 /**
  * led 模式切换
 */
@@ -506,10 +605,22 @@ void light_init(uint8 taskId){
         return ;
     }
 
+
+    ret = pwm_light_init(FAN_CH, GPIO_FAN, 0,  100, 5, PWM_CLK_DIV_128);
+    if(ret != 0){
+        LOG("[light_init] pwm_FAN_init FAN failed  %d \n", ret);
+        return ;
+    }
+
+
+
     // 读取保存的数据
     read_light_data();
     // 拉低 warm2 与 cold2 的电平
 
+
+    // 拉高 p34 脚的电压, 配置为输出
+	hal_gpio_pull_set(GPIO_BATT_CH, STRONG_PULL_UP);
     // hal_gpio_pull_set(GPIO_WARM2, PULL_DOWN);
     // hal_gpio_pull_set(GPIO_COLD2, PULL_DOWN);
 }

+ 19 - 3
src/light.h

@@ -8,32 +8,48 @@
 #define LIGHT_EVT_SAVE_DATA 0x0010
 
 // 保存数据等待时间 秒
-#define SAVE_DATA_WAIT_TIME 5
+#define SAVE_DATA_WAIT_TIME 3
 
 // 暖光 pwm脚
 #define GPIO_WARM P18
 #define GPIO_WARM2 P15
 #define WARM_CH 0
+// 暖光最小亮度值
+#define WARM_LIGHT_MIN 5
 // 冷光 pwm脚
 #define GPIO_COLD P20
 #define GPIO_COLD2 P31
 #define COLD_CH 1
+// 冷光最小亮度值
+#define COLD_LIGHT_MIN 5
 
 // 风扇 pwm
-#define GPIO_FAN P23
+#define GPIO_FAN P3
+#define FAN_CH 2
+// 风扇启用亮度值 (灯光亮度大于该值时启用风扇)
+#define FAN_LIGHT_MIN 30
 
 // 亮度分级 0~100 翻 100倍
 #define TOTAl_LEVEL 100
 // 亮度更改步长
 #define LIGHT_STEP 5
+// 亮度最低值
+#define LIGHT_MIN 8
+
 #define TEMP_MIN 2700
 #define TEMP_MAX 6500
+// 色温便宜值
+#define TEMP_OFFSET 500
 // 色温更改步长
 #define TEMP_STEP 50
 
 
+
 // adc 电源监测脚
-#define GPIO_POWER P28
+#define GPIO_POWER P14
+// 电压检测控制脚
+#define GPIO_BATT_CH P34
+// adc 电源监测通道
 
 // 工作模式
 // 默认工作模式

+ 56 - 9
src/pwm_light/pwm_light.c

@@ -9,11 +9,11 @@ const uint8_t max_pwm_light = 5;
 uint8_t pwm_light_len = 0;
 // 申请5个通道的内存
 pwm_t pwm_light_chann_list[max_pwm_light] = {
-    {PWM_CH0, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16},
-    {PWM_CH1, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16},
-    {PWM_CH2, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16},
-    {PWM_CH3, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16},
-    {PWM_CH5, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16},
+    {PWM_CH0, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16, GPIO_DUMMY},
+    {PWM_CH1, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16, GPIO_DUMMY},
+    {PWM_CH2, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16, GPIO_DUMMY},
+    {PWM_CH3, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16, GPIO_DUMMY},
+    {PWM_CH5, GPIO_DUMMY, 0, 100, 5, PWM_CLK_DIV_16, GPIO_DUMMY},
 };
 
 // 刷新指定 pwm 引脚
@@ -29,17 +29,15 @@ int pwm_light_reflash(int i)
     
     hal_pwm_close_channel(pwm->pwm_ch);
     hal_pwm_destroy(pwm->pwm_ch);
-
+    
     hal_pwm_stop();
 
     hal_gpio_pin_init(pwm->pin, IE);
     hal_gpio_pull_set(pwm->pin, WEAK_PULL_UP);
-
     hal_pwm_init(pwm->pwm_ch, pwm->div, PWM_CNT_UP, PWM_POLARITY_FALLING);
-
     hal_pwm_set_count_val(pwm->pwm_ch, pwm->val, pwm->total);
-
     hal_pwm_open_channel(pwm->pwm_ch, pwm->pin);
+    
     hal_pwm_start();
     return 0;
 }
@@ -189,3 +187,52 @@ int pwm_light_set_div(uint8_t ch, PWM_CLK_DIV_e div)
 
     return 0;
 }
+
+
+int pwm_close(uint8_t ch)
+{
+    LOG("pwm_close %d\n", ch);
+    pwm_t *pwm;
+    // 判断 ch 是否合法
+    CHECK_PWM_CH
+    
+    // 获取 pwm
+    pwm = &pwm_light_chann_list[ch];
+
+    hal_pwm_close_channel(pwm->pwm_ch);
+    hal_pwm_destroy(pwm->pwm_ch);
+    hal_gpio_pin_init(pwm->pin, OEN);
+    hal_gpio_pull_set(pwm->pin, PULL_DOWN);
+
+    // 关闭 pwm
+    pwm->pin = GPIO_DUMMY;
+
+    pwm_reflash_all();
+    return 0;
+}
+
+
+int pwm_open(uint8_t ch , GPIO_Pin_e pin)
+{
+    LOG("pwm_open %d\n", ch);
+    pwm_t *pwm;
+    // 判断 ch 是否合法
+    CHECK_PWM_CH
+
+    // 获取 pwm
+    pwm = &pwm_light_chann_list[ch];
+    if (pin == GPIO_DUMMY)
+    {
+        LOG("pwm ReOpen error %d\n", ch);
+        return -1;
+    }
+    if (pwm->pin == pin)
+    {
+        LOG("pwm open error %d is started\n", ch);
+        return -2;
+    }
+    
+    pwm->pin = pin;
+    pwm_light_reflash(ch);
+    return 0;
+}

+ 3 - 1
src/pwm_light/pwm_light.h

@@ -18,6 +18,7 @@ typedef struct pwm_t {
     uint32_t total;// 总量 0-100
     uint32_t step;// 步长 5
     PWM_CLK_DIV_e div;// pwm时钟分频
+    GPIO_Pin_e old_pin;// 旧引脚
 } pwm_t;
 
 // pwm结构体数组 不定长 最大5个
@@ -77,5 +78,6 @@ extern int pwm_light_set_val(uint8_t ch , uint32_t val);
 */
 extern int pwm_light_set_div(uint8_t ch , PWM_CLK_DIV_e div);
 
-
+extern int pwm_open(uint8_t ch, GPIO_Pin_e pin);
+extern int pwm_close(uint8_t ch);
 #endif