123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- #include "include.h"
- #include "led.h"
- #if LED_DISP_EN
- #define TRACE_EN 0
- #if TRACE_EN
- #define TRACE(...) printf(__VA_ARGS__)
- #define TRACE_R(...) print_r(__VA_ARGS__)
- #else
- #define TRACE(...)
- #define TRACE_R(...)
- #endif // TRACE_EN
- typedef struct {
- u32 tick_inst;
- u32 tick_off;
- u8 rled_sta; //红灯 亮-灭控制
- u8 bled_sta; //蓝灯 亮-灭控制
- u16 unit; //50ms单位 (范围:1~255)
- u16 circle;
- bool lowbat;
- } led_cb_t;
- led_cb_t led_sync AT(.buf.led);
- led_cb_t led_cb AT(.buf.led);
- led_cb_t led_lb AT(.buf.led); //low battery
- void m_led2_port_init(gpio_t *g, bool ext_res);
- void m_port_2led_scan(gpio_t *g);
- void led_cfg_port_init(gpio_t *g);
- void led_cfg_set_onoff(gpio_t *g, bool onoff);
- AT(.com_text.led_disp)
- void led_scan(void)
- {
- led_cb_t *s;
- u32 tickn = TICKN_GET();
- if (!is_led_scan_enable()) {
- return;
- }
- #if HLW_UI
- #if ONE_LED_EN
- s = &led_cb;
- //s = &led_lb;
- #else
- s = (led_cb.lowbat)? &led_lb : &led_cb;
- #endif // ONE_LED_EN
- #else
- s = (led_cb.lowbat)? &led_lb : &led_cb;
- #endif // HLW_UI
- if(s->unit == 0) {
- if (RLED_LOWBAT_FOLLOW_EN) {
- if(led_cb.lowbat){
- led_cb.lowbat = false;
- }
- }
- return;
- }
- u32 tickdiff = TICK_SUB(tickn, s->tick_inst);
- if(tickdiff < TICK_MAX_DELAY && s->unit != 0) {
- if(tickdiff % s->unit == 0) {
- u8 bcnt = tickdiff/s->unit;
- // GPIOBSET = BIT(4);
- // my_spi_putc(0x22);
- // my_spi_putc(bcnt);
- // GPIOBCLR = BIT(4);
- if (s->bled_sta & BIT(bcnt)) {
- bled_set_on();
- } else {
- bled_set_off();
- }
- if (s->rled_sta & BIT(bcnt)) {
- rled_set_on();
- } else {
- rled_set_off();
- }
- if(bcnt >= 7) {
- s->tick_inst = TICK_ADD(s->tick_inst, s->circle);
- if(s->circle == 0) { //只亮一次
- s->unit = 0;
- }
- }
- }
- }
- }
- AT(.text.led_disp.set) ALIGNED(256)
- void led_set_sta_do(led_cfg_t *sta, led_cb_t *s, bool local)
- {
- tws_time_t time;
- memset(&time, 0, sizeof(tws_time_t));
- TICK_TIME_GET(&time, 200); //200ms后开始显示
- if(local) {
- time.tickoff = 0;
- }
- GLOBAL_INT_DISABLE();
- s->rled_sta = sta->redpat;
- s->bled_sta = sta->bluepat;
- s->unit = sta->unit * 50;
- if (sta->cycle == 0xff) {
- s->circle = 0;
- } else {
- s->circle = s->unit * 8 + sta->cycle * 50;
- }
- s->tick_inst = TICK_ADD(time.tickn, time.tickoff);
- s->tick_off = time.tickoff;
- GLOBAL_INT_RESTORE();
- }
- AT(.text.led_disp.set)
- bool led_sta_is_change(const led_cfg_t *sta, const led_cb_t *s)
- {
- if(sta->cycle != 0xff
- && s->rled_sta == sta->redpat
- && s->bled_sta == sta->bluepat
- && s->unit == sta->unit * 50) {
- return false;
- }
- return true;
- }
- //获取LED当前设置的状态
- AT(.com_text.led_disp)
- u8 get_led_sta(u32 type)
- {
- if (type) {
- return led_cb.rled_sta;
- } else {
- return led_cb.bled_sta;
- }
- }
- AT(.com_text.led_disp)
- void led_cfg_set_on(gpio_t *g)
- {
- led_cfg_set_onoff(g, 1);
- }
- AT(.com_text.led_disp)
- void led_cfg_set_off(gpio_t *g)
- {
- led_cfg_set_onoff(g, 0);
- }
- #if USER_ADKEY_MUX_LED
- AT(.text.led_disp)
- void led_mux_cfg_port_init(gpio_t *g)
- {
- if ((g == NULL) || (g->sfr == NULL)) {
- return;
- }
- g->type = 2; //ADKEY_MUX
- led_cfg_port_init(g);
- }
- #endif // USER_ADKEY_MUX_LED
- #if LED_PWR_EN
- //一个IO口推两个LED灯
- void led2_port_init(gpio_t *g)
- {
- m_led2_port_init(g, !xcfg_cb.port_2led_resless_en);
- }
- //每ms扫描一次
- AT(.com_text.led_disp)
- void port_2led_scan(void)
- {
- if ((!sys_cb.port2led_en)) {
- return;
- }
- m_port_2led_scan(&bled_gpio);
- }
- //1个IO推两个灯,充电状态下不进sleep,否则充电灯异常。
- AT(.sleep_text.led)
- bool port_2led_is_sleep_en(void)
- {
- if ((sys_cb.port2led_en) && (CHARGE_DC_IN())) {
- return false;
- }
- return true;
- }
- #endif // LED_PWR_EN
- AT(.com_text.led_disp)
- void bled_set_off(void)
- {
- if (!sys_cb.charge_bled_flag) { //充满状态优先控制
- LED_SET_OFF();
- }
- }
- AT(.com_text.led_disp)
- void bled_set_on(void)
- {
- if (!sys_cb.charge_bled_flag) { //充满状态优先控制
- LED_SET_ON();
- }
- }
- AT(.com_text.led_disp)
- void rled_set_off(void)
- {
- if (!sys_cb.charge_sta) { //充电状态优先控制
- LED_PWR_SET_OFF();
- }
- }
- AT(.com_text.led_disp)
- void rled_set_on(void)
- {
- if (!sys_cb.charge_sta) { //充电状态优先控制
- LED_PWR_SET_ON();
- }
- }
- AT(.text.led_disp)
- void led_init(void)
- {
- LED_INIT();
- LED_PWR_INIT();
- memset(&led_sync, 0, sizeof(led_sync));
- memset(&led_cb, 0, sizeof(led_cb));
- memset(&led_lb, 0, sizeof(led_lb));
- }
- //蓝灯灭
- AT(.text.led_disp)
- void led_off(void)
- {
- led_cb.bled_sta = 0x00;
- bled_set_off();
- }
- //蓝灯亮
- AT(.text.led_disp)
- void led_on(void)
- {
- led_cb.bled_sta = 0xff;
- bled_set_on();
- }
- AT(.text.led_disp)
- void rled_on(void)
- {
- led_cb.rled_sta = 0xff;
- rled_set_on();
- }
- AT(.text.led_disp)
- void rled_off(void)
- {
- led_cb.rled_sta = 0x00;
- rled_set_off();
- }
- //拔出充电红灯灭
- AT(.charge_text.det)
- void charge_led_off(void)
- {
- LED_PWR_SET_OFF();
- }
- //充电红灯亮
- AT(.charge_text.det)
- void charge_led_on(void)
- {
- led_cb.bled_sta = 0x00; //充电关蓝灯亮红灯
- LED_SET_OFF();
- LED_PWR_SET_ON();
- }
- //充满蓝灯常亮
- AT(.charge_text.det)
- void charge_bled_on(void)
- {
- LED_SET_ON();
- }
- void led_set_sta_lowbat(const led_cfg_t *cfg)
- {
- led_cfg_t sta;
- memcpy(&sta, cfg, sizeof(sta));
- #if HLW_UI
- if(led_sta_is_change(&sta, &led_cb)) {
- rled_set_off();
- bled_set_off();
- led_set_sta_do(&sta, &led_cb, true);
- }
- #else
- if(led_sta_is_change(&sta, &led_lb)) {
- rled_set_off();
- bled_set_off();
- led_set_sta_do(&sta, &led_lb, true);
- }
- #endif // HLW_UI
- }
- void led_set_sta_normal(const led_cfg_t *cfg)
- {
- led_cfg_t sta;
- memcpy(&sta, cfg, sizeof(sta));
- if(led_sta_is_change(&sta, &led_cb)) {
- if(!led_cb.lowbat) {
- rled_set_off();
- bled_set_off();
- }
- led_set_sta_do(&sta, &led_cb, true);
- TRACE("led_normal: circle=%x, uint=%x, tick=%x(%x), (%02x,%02x)\n", led_cb.circle, led_cb.unit, led_cb.tick_inst, 0, led_cb.bled_sta, led_cb.rled_sta);
- }
- }
- #if (LED_LOWBAT_EN || RLED_LOWBAT_FOLLOW_EN)
- void led_lowbat_do(void);
- void led_lowbat_follow_do(void);
- AT(.text.led_disp.lowbat)
- void led_lowbat(void)
- {
- if (!led_cb.lowbat) {
- led_lowbat_do();
- led_cb.lowbat = true;
- }
- }
- AT(.text.led_disp.lowbat) ALIGNED(128)
- void led_lowbat_recover(void)
- {
- if(led_cb.lowbat){
- GLOBAL_INT_DISABLE();
- rled_set_off();
- bled_set_off();
- led_cb.lowbat = false;
- GLOBAL_INT_RESTORE();
- }
- }
- AT(.text.led_disp.lowbat)
- void led_lowbat_follow_warning(void)
- {
- #if HLW_UI
- //if(!led_cb.lowbat)
- //{
- led_lowbat_do();
- led_cb.lowbat = true;
- //}
- #else
- if (!led_cb.lowbat) {
- led_lowbat_follow();
- led_cb.lowbat = true;
- }
- #endif // HLW_UI
- }
- #endif // LED_LOWBAT_EN
- #if BT_TWS_EN
- ALIGNED(128)
- void led_get_sync_info(uint8_t *buf)
- {
- uint32_t tick_diff;
- tws_time_t time;
- TICK_TIME_GET(&time, 0);
- GLOBAL_INT_DISABLE();
- tick_diff = TICK_SUB(time.tickoff, led_sync.tick_off);
- led_sync.tick_inst = TICK_ADD(led_sync.tick_inst, tick_diff);
- led_sync.tick_off = time.tickoff;
- memcpy(buf, &led_sync, 14);
- GLOBAL_INT_RESTORE();
- TRACE("led_get: circle=%x, uint=%x, inst=%x, (%02x,%02x)\n", led_sync.circle, led_sync.unit, led_sync.tick_inst, led_sync.bled_sta, led_sync.rled_sta);
- }
- ALIGNED(256)
- void led_set_sync_sta(led_cb_t *p, uint32_t tickoff)
- {
- uint32_t tick_inst, diff;
- tws_time_t time;
- tick_inst = TICK_SUB(p->tick_inst, tickoff);
- if(led_cb.circle != 0
- && p->circle == led_cb.circle
- && p->rled_sta == led_cb.rled_sta
- && p->bled_sta == led_cb.bled_sta
- && p->unit == led_cb.unit) {
- diff = TICK_SUB(led_cb.tick_inst, tick_inst);
- if(diff % led_cb.circle == 0) {
- return;
- }
- TRACE("led_miss: %x, %x, %x, %x\n", led_cb.tick_inst, tick_inst, diff, led_cb.circle);
- }
- if(!led_cb.lowbat) {
- rled_set_off();
- bled_set_off();
- }
- TICK_TIME_GET(&time, 0);
- if(p->circle != 0 && TICK_GEQ(time.tickn, tick_inst)) {
- diff = TICK_SUB(time.tickn, tick_inst);
- diff -= (diff % p->circle);
- tick_inst = TICK_ADD(tick_inst, diff);
- }
- GLOBAL_INT_DISABLE();
- memcpy(&led_cb, p, 14);
- led_cb.tick_inst = tick_inst;
- GLOBAL_INT_RESTORE();
- TRACE("led_set: circle=%x, uint=%x, tick=%x(%x), (%02x,%02x)\n", led_cb.circle, led_cb.unit, led_cb.tick_inst, time.tickn, led_cb.bled_sta, led_cb.rled_sta);
- }
- void led_cal_sync_info(const led_cfg_t *cfg)
- {
- led_cfg_t sta;
- memcpy(&sta, cfg, sizeof(sta));
- if(led_sta_is_change(&sta, &led_sync)) {
- led_set_sta_do(&sta, &led_sync, false);
- TRACE("led_cal: circle=%x, uint=%x, inst=%x, (%02x,%02x)\n", led_sync.circle, led_sync.unit, led_sync.tick_inst, led_sync.bled_sta, led_sync.rled_sta);
- }
- }
- //回调函数,本地设置LED状态
- void tws_local_set_ledsta(uint8_t *buf)
- {
- led_cb_t *p = (led_cb_t *)buf;
- led_set_sync_sta(p, p->tick_off);
- }
- //回调函数,远端设置LED状态
- void tws_remote_set_ledsta(uint8_t *buf)
- {
- led_cb_t *p = (led_cb_t *)buf;
- if(bt_nor_is_connected()) {
- tws_time_t time;
- TICK_TIME_GET(&time, 0);
- memcpy(&led_sync, p, 14);
- led_sync.tick_off = time.tickoff;
- led_set_sync_sta(p, time.tickoff);
- }
- }
- #endif // BT_TWS_EN
- #endif
|