/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file yunhorn_sts_lamp_bar.c * * @author Yunhorn (r) Technology Limited Application Team * * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * ****************************************************************************** * @attention * * Copyright (c) 2022 Yunhorn Technology Limited. * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ #include "main.h" #include "dma.h" #include "tim.h" #include "string.h" #include "sys_app.h" #include "stm32_systime.h" #include "sts_lamp_bar.h" #include "yunhorn_sts_sensors.h" #define ONE_PULSE (36) #define ZERO_PULSE (20) #define LED_DATA_LEN (24) #define WS2812B_DATA_LEN (LED_DATA_LEN * (STS_LAMP_BAR_LED_NUM+4)) #define DEFAULT_LUMINANCE_LEVEL (20) #define RESET_PULSE (10) //(80) TO FIX DARK_COLOR AND SM2 typedef struct ws2812b_e { uint16_t head[3]; uint16_t GRB[24*STS_LAMP_BAR_LED_NUM]; uint16_t tail; } WS2812B_FrameTypeDef; volatile WS2812B_FrameTypeDef rgb_buf = { .head[0] = 0, .head[1] = 0, .head[2] = 0, .tail = 0 }; uint8_t color_rgb[8][3] = { //STS_COLOR R G B MAPPING TABLE {0,0,0},{0,1,0},{1,0,0},{0,0,1},{1,1,0},{1,0,1},{0,1,1},{1,1,1} }; extern volatile uint8_t sts_service_mask; extern volatile uint8_t sts_work_mode; volatile uint8_t sts_reed_hall_ext_int = 0; volatile uint8_t sts_status_color = STS_DARK; volatile uint8_t sts_lamp_bar_color = STS_GREEN; //puColor volatile uint8_t sts_cloud_netcolor = STS_GREEN; //netColor extern volatile uint8_t sts_occupancy_status; extern volatile uint8_t sts_reed_hall_result, sts_emergency_button_pushed; // inital 0 = close volatile uint8_t sts_hall1_read=0,sts_hall2_read=0; // Above hall1_read == reed_hall_result, hall2_read == emergency_button extern volatile uint8_t sts_reed_hall_1_result, sts_reed_hall_2_result; extern volatile uint8_t sts_tof_result_changed_flag; extern volatile uint8_t sts_rss_result_changed_flag, sts_hall1_changed_flag, sts_hall2_changed_flag, sts_reed_hall_changed_flag; extern volatile uint8_t sts_rss_result; extern volatile uint8_t sts_rss_2nd_result; //2nd RSS sensor status extern volatile uint8_t sts_tof_result; //extern volatile uint8_t last_sts_reed_hall_result = 2; //Initial state, not 0, not 1 volatile uint8_t last_lamp_bar_color; extern volatile uint8_t sts_presence_fall_detection; extern volatile float sts_presence_rss_distance; extern volatile uint8_t sensor_data_ready; extern SysTime_t mems_event_time; extern volatile uint32_t event_start_time, event_stop_time; uint8_t luminance_level = DEFAULT_LUMINANCE_LEVEL; void STS_Lamp_Bar_Set_Dark(void) { for (uint8_t i=0; i< STS_LAMP_BAR_LED_NUM; i++) { STS_WS2812B_Set_RGB(0x00,0x00,0x00,i); } //STS_WS2812B_Refresh(); } void STS_WS2812B_Refresh(void) { HAL_TIM_PWM_Start_DMA(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL, (uint32_t *)&rgb_buf, (RESET_PULSE+WS2812B_DATA_LEN+1)); //HAL_TIM_PWM_Start_IT(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL); } void STS_Lamp_Bar_Init(void) { if (sts_service_mask == STS_SERVICE_MASK_L0) { STS_Lamp_Bar_Set_STS_RGB_Color(STS_GREEN, luminance_level); //STS_WS2812B_Refresh(); HAL_Delay(200); STS_Lamp_Bar_Set_STS_RGB_Color(STS_RED, luminance_level); //STS_WS2812B_Refresh(); HAL_Delay(200); STS_Lamp_Bar_Set_STS_RGB_Color(STS_BLUE, luminance_level); //STS_WS2812B_Refresh(); HAL_Delay(200); } } //marquee scoller void STS_Lamp_Bar_Scoller(uint8_t color, uint8_t luminance_level) { STS_Lamp_Bar_Set_Dark(); for(uint8_t i = 0; i<(STS_LAMP_BAR_LED_NUM+1); i++) { //if (sts_service_mask < STS_SERVICE_MASK_L1) // STS_WS2812B_Refresh(); HAL_Delay(60); if (i < STS_LAMP_BAR_LED_NUM) { STS_WS2812B_Set_RGB(color_rgb[color][0]*luminance_level,color_rgb[color][1]*luminance_level, color_rgb[color][2]*luminance_level, i); } } HAL_Delay(10); //if (sts_service_mask == STS_SERVICE_MASK_L0) { // STS_WS2812B_Refresh(); //} } void STS_WS2812B_Set_RGB(uint8_t R, uint8_t G, uint8_t B, uint8_t idx) { if (idx < STS_LAMP_BAR_LED_NUM) { for (uint8_t j = 0; j < 8; j ++) { rgb_buf.GRB[idx*24+j] = (G&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; rgb_buf.GRB[idx*24+8+j] = (R&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; rgb_buf.GRB[idx*24+16+j] = (B&(0X80)>>j)? ONE_PULSE : ZERO_PULSE; } } // CHANGED AT 2023-05-10 if (sts_service_mask == STS_SERVICE_MASK_L0) { STS_WS2812B_Refresh(); } } void STS_Lamp_Bar_Set_RGB_Color(uint8_t red, uint8_t green, uint8_t blue ) { HAL_Delay(1); for(uint8_t i = 0; i < STS_LAMP_BAR_LED_NUM; i++) { for (uint8_t j = 0; j < 8; j ++) { rgb_buf.GRB[i*24+j] = (green&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; rgb_buf.GRB[i*24+8+j] = (red&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; rgb_buf.GRB[i*24+16+j] = (blue&(0x80)>>j)? ONE_PULSE : ZERO_PULSE; } } if (sts_service_mask == STS_SERVICE_MASK_L0) { STS_WS2812B_Refresh(); } } void STS_Lamp_Bar_Refresh(void) { STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); } void STS_Lamp_Bar_Set_STS_RGB_Color(uint8_t sts_lamp_color, uint8_t luminance_level) { uint8_t lum = luminance_level; STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, 0x0); switch (sts_lamp_color) { case STS_DARK: STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, 0x0); break; case STS_GREEN: STS_Lamp_Bar_Set_RGB_Color(0x0, lum, 0x0); break; case STS_RED: STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, 0x0); break; case STS_BLUE: STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, lum); break; case STS_YELLOW: STS_Lamp_Bar_Set_RGB_Color(lum, lum, 0x0); break; case STS_PINK: STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, lum); break; case STS_CYAN: STS_Lamp_Bar_Set_RGB_Color(0x0, lum, lum); break; case STS_WHITE: STS_Lamp_Bar_Set_RGB_Color(lum, lum, lum); break; case STS_RED_BLUE: STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, 0x0); HAL_Delay(300); STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, lum); HAL_Delay(300); break; } } void STS_Reed_Hall_Working(void) { } void STS_Combined_Status_Processing(void) { mems_event_time = SysTimeGetMcuTime(); if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_1_result == STS_Status_Door_Close)|| (sts_reed_hall_2_result == STS_Status_Door_Close) || (sts_tof_result == STS_RESULT_PRESENCE)) { if (event_start_time == 0) { event_start_time = mems_event_time.Seconds; event_stop_time = 0; APP_LOG(TS_OFF, VLEVEL_M, "\r\n Event Started at %6u Seconds \r\n", event_start_time); } } else if ((sts_rss_result != STS_RESULT_MOTION) || (sts_reed_hall_1_result != STS_Status_Door_Close)|| (sts_reed_hall_2_result != STS_Status_Door_Close) || (sts_tof_result != STS_RESULT_PRESENCE)) { if (event_stop_time ==0) { event_stop_time = mems_event_time.Seconds; event_start_time = 0; APP_LOG(TS_OFF, VLEVEL_M, "\r\n Event Stop at %6u Seconds \r\n", event_stop_time); } } switch (sts_work_mode) { case STS_NETWORK_MODE: sts_status_color = sts_cloud_netcolor; break; case STS_WIRED_MODE: // NO LAMP BAR FOR THOSE WATER LEAKAGE SENSOR OR SOAP CAPACITY SENSORS sts_status_color = STS_DARK; #ifdef STS_M1 sts_water_leakage_result = (sts_reed_hall_result == STS_Status_Door_Open )?STS_RESULT_WATER_LEAKAGE_YES:STS_RESULT_WATER_LEAKAGE_NO; sts_water_leakage_changed_flag = 1; #endif break; case STS_REEDSWITCH_MODE: sts_status_color = (sts_reed_hall_result == STS_Status_Door_Open )? STS_GREEN: STS_RED; break; case STS_RSS_MODE: if (sts_rss_result == STS_RESULT_NO_MOTION){ sts_status_color = STS_GREEN; } else if ((sts_rss_result == STS_RESULT_MOTION)) { sts_status_color = STS_RED; } break; case STS_DUAL_MODE: if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_1_result == STS_Status_Door_Open )&& (sts_reed_hall_2_result == STS_Status_Door_Open )) { sts_status_color = STS_GREEN; } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_1_result == STS_Status_Door_Close )||(sts_reed_hall_2_result == STS_Status_Door_Close )) { sts_status_color = STS_RED; //if (sts_reed_hall_2_result == STS_Status_Door_Close ) { // sts_status_color = STS_RED_BLUE; //} } break; case STS_REMOTE_REED_RSS_MODE: if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_result == STS_Status_Door_Open )) { sts_status_color = STS_GREEN; } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close )) { sts_status_color = STS_RED; } break; case STS_DUAL_RSS_MODE: if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_rss_2nd_result == STS_RESULT_NO_MOTION)) { sts_status_color = STS_GREEN; } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_rss_2nd_result == STS_RESULT_MOTION)) { sts_status_color = STS_RED; } break; case STS_TOF_RSS_MODE: if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_tof_result == STS_RESULT_NO_PRESENCE)){ sts_status_color = STS_GREEN; } else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_tof_result == STS_RESULT_PRESENCE)) { sts_status_color = STS_RED; } break; // TO-DO LIST *********************************************************** case STS_TOF_DISTANCE_MODE: if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { sts_status_color = STS_GREEN; } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { sts_status_color = STS_RED; } break; case STS_TOF_PRESENCE_MODE: if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { sts_status_color = STS_GREEN; } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { sts_status_color = STS_RED; } break; case STS_TOF_IN_OUT_MODE: if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) { sts_status_color = STS_GREEN; } else if ((sts_tof_result == STS_RESULT_PRESENCE)) { sts_status_color = STS_RED; } break; // TO-DO LIST *********************************************************** default: break; } #if 0 if (sts_status_color == STS_RED_BLUE) { //STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); STS_Lamp_Bar_Set_STS_RGB_Color(STS_RED, luminance_level); HAL_Delay(100); STS_Lamp_Bar_Set_STS_RGB_Color(STS_BLUE, luminance_level); HAL_Delay(100); STS_Lamp_Bar_Set_STS_RGB_Color(STS_RED_BLUE, luminance_level); } #endif if ((sts_work_mode == STS_WIRED_MODE) || (sts_service_mask > STS_SERVICE_MASK_L0)) { sts_status_color = STS_DARK; sts_lamp_bar_color = STS_DARK; last_lamp_bar_color = STS_DARK; STS_Lamp_Bar_Set_Dark(); } else { //if ((last_lamp_bar_color != sts_status_color)) { sts_lamp_bar_color = ((sts_service_mask == STS_SERVICE_MASK_L0)? sts_status_color:STS_DARK); STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); if ((sts_service_mask == STS_SERVICE_MASK_L0) || (sts_lamp_bar_color == STS_DARK)) { // STS_WS2812B_Refresh(); } last_lamp_bar_color = sts_lamp_bar_color; } } STS_Lamp_Bar_Refresh(); #if 1 //if ((sts_rss_result_changed_flag)|| (sts_reed_hall_changed_flag) || (sts_tof_result_changed_flag) || (sts_water_leakage_changed_flag)) { sts_rss_result_changed_flag =0; sts_reed_hall_changed_flag =0; sts_tof_result_changed_flag =0; #ifdef STS_M1 sts_water_leakage_changed_flag=0; #endif sensor_data_ready = 1; STS_PRESENCE_SENSOR_Prepare_Send_Data(); } #endif } void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { __HAL_TIM_SetCompare(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL,0); HAL_TIM_PWM_Stop_DMA(&STS_LAMP_BAR_HTIM,STS_LAMP_BAR_TIM_CHANNEL); } void STS_Lamp_Bar_Self_Test_Simple(void) { uint8_t color=0, luminance_level=10; APP_LOG(TS_OFF, VLEVEL_M, "\r\n [#1] RGB Space Lumianance Level Testing Start\r\n"); for (color=STS_GREEN; color <= STS_RED_BLUE; color++) { luminance_level = 10; do { STS_Lamp_Bar_Set_STS_RGB_Color(color, luminance_level); HAL_Delay(50); luminance_level += 20; } while (luminance_level < 99); //STS_Lamp_Bar_Set_Dark(); } APP_LOG(TS_OFF, VLEVEL_M, "\r\n [#1] RGB Space Lumianance Level Testing Finished\r\n"); } void STS_Lamp_Bar_Self_Test(void) { uint8_t color=0, luminance_level=10; APP_LOG(TS_OFF, VLEVEL_M, "\r\n YunHorn STS Indicative Lamp Self Test\r\n"); STS_Lamp_Bar_Self_Test_Simple(); APP_LOG(TS_OFF, VLEVEL_H, "\r\n [#2] Scoller Testing\r\n"); for (color = STS_GREEN; color <= STS_RED_BLUE; color++) { STS_Lamp_Bar_Scoller(color, luminance_level); } STS_Lamp_Bar_Set_Dark(); APP_LOG(TS_OFF, VLEVEL_M, "\r\n [##] YunHorn STS Indicative Lamp Self Test Finished\r\n"); if ((sts_work_mode == STS_WIRED_MODE) ) { STS_Lamp_Bar_Set_Dark(); } else { STS_Lamp_Bar_Set_STS_RGB_Color(STS_GREEN, luminance_level); } } void sts_rgb_unit_test(void) { APP_LOG(TS_OFF, VLEVEL_L, "\r\n STS Lamp Bar Init...\r\n"); STS_Lamp_Bar_Set_Dark(); STS_Lamp_Bar_Full_Color_Gradient(); STS_Lamp_Bar_Self_Test(); do { for (uint8_t i=0; i<9; i++) { APP_LOG(TS_OFF, VLEVEL_L, "\r\n STS Lamp Bar color = %d...\r\n", i); STS_Lamp_Bar_Set_STS_RGB_Color(i, luminance_level); STS_Combined_Status_Processing(); HAL_Delay(6000); STS_Lamp_Bar_Set_Dark(); } } while(1); }