/****************************************************************************** 版权所有 (C), 2018-2099, Radkil_Std ****************************************************************************** 文 件 名 : led.c 版 本 号 : 初稿 作 者 : Radkil 生成日期 : 2022年12月2日 最近修改 : 功能描述 : io输出相关模块管理 修改历史 : 1.日 期 : 2022年12月2日 作 者 : Radkil 修改内容 : 创建文件 ******************************************************************************/ #include #include #include #include "led.h" #include "rd_thread.h" #include "rd_time.h" /*----------------------------------------------* * 外部变量说明 * *----------------------------------------------*/ /*----------------------------------------------* * 外部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 内部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 全局变量 * *----------------------------------------------*/ /*----------------------------------------------* * 模块级变量 * *----------------------------------------------*/ static rd_slist_t g_sLedListHead = RD_SLIST_OBJECT_INIT(g_sLedListHead); //led对象的链表头结点 static rd_mutex_t g_fpLedCtrl = RD_MUTEX_INITIALIZER; //led控制模块互斥锁 /*----------------------------------------------* * 常量定义 * *----------------------------------------------*/ /*----------------------------------------------* * 宏定义 * *----------------------------------------------*/ static void cbk_LedDefaultCompeleteCallback(rd_led_t *_ptLed) { log_i("Led[%p] is compelete!", _ptLed); } static int rd_LedGetLightArr(rd_led_t *_ptLed, const char *light_mode) { int iRet = RD_SUCCESS; if(NULL == _ptLed || NULL == _ptLed->m_pCbkCtrl) { return RD_INVALUE; } const char *ptr = light_mode; while (*ptr) { if (*ptr == ',') { _ptLed->m_iArrNum++; } ptr++; } if (*(ptr - 1) != ',') { _ptLed->m_iArrNum++; } if (_ptLed->m_iArrNum == 0) { iRet = RD_FAILURE; goto END; } uint32_t *piLightArr = RD_MALLOC(_ptLed->m_iArrNum * sizeof(uint32_t)); if (piLightArr == NULL) { iRet = RD_FAILURE; goto END; } RD_MEMSET(piLightArr, 0, _ptLed->m_iArrNum * sizeof(int)); ptr = light_mode; int i = 0; for (i = 0; i < _ptLed->m_iArrNum; i++) { piLightArr[i] = (uint32_t)atoi(ptr); ptr = strchr(ptr, ','); if (ptr) ptr++; } _ptLed->m_piLightArr = piLightArr; END: return iRet; } int rd_LedStart(rd_led_t *_ptLed) { int iRet = RD_SUCCESS; Rd_MutexLock(&g_fpLedCtrl, __func__, NULL); if(NULL == _ptLed) { goto END; return RD_INVALUE; } if (_ptLed->m_iActive) { iRet = RD_FAILURE; goto END; } if ((_ptLed->m_piLightArr == NULL) || (_ptLed->m_iArrNum == 0)) { iRet = RD_FAILURE; goto END; } _ptLed->m_iArrIndex = 0; _ptLed->m_iLoopCnt = _ptLed->m_iLoopInit; _ptLed->m_iTimeout = Rd_GetTime(); rd_slist_append(&g_sLedListHead, &(_ptLed->m_tSlist)); _ptLed->m_iActive = 1; END: Rd_MutexUnlock(&g_fpLedCtrl, __func__, NULL); return iRet; } int rd_LedStop(rd_led_t *_ptLed) { int iRet = RD_SUCCESS; Rd_MutexLock(&g_fpLedCtrl, __func__, NULL); if(NULL == _ptLed) { goto END; return RD_INVALUE; } if (!_ptLed->m_iActive) { iRet = RD_FAILURE; goto END; } rd_slist_remove(&g_sLedListHead, &(_ptLed->m_tSlist)); _ptLed->m_tSlist.next = NULL; _ptLed->m_iActive = 0; END: Rd_MutexUnlock(&g_fpLedCtrl, __func__, NULL); return iRet; } void rd_LedOn(rd_led_t *_ptLed) { if(NULL != _ptLed && NULL != _ptLed->m_pCbkCtrl) { _ptLed->m_pCbkCtrl(_ptLed->m_pLed_t, _ptLed->m_iActiveLogic); } } void rd_LedOff(rd_led_t *_ptLed) { if(NULL != _ptLed && NULL != _ptLed->m_pCbkCtrl) { _ptLed->m_pCbkCtrl(_ptLed->m_pLed_t, !_ptLed->m_iActiveLogic); } } rd_led_t *rd_LedCreate(int active_logic, const char *light_mode, uint8_t loop_cnt, void (*_pCbkCtrl)(l_led_t *pLed, int _iState), l_led_t *pLed_t) { rd_led_t *_ptLed = (rd_led_t *)RD_MALLOC(sizeof(rd_led_t)); if(NULL == _ptLed || NULL == _pCbkCtrl) { return NULL; } _ptLed->m_iActive = 0; _ptLed->m_pLed_t = pLed_t; _ptLed->m_pCbkCtrl = _pCbkCtrl; _ptLed->m_iActiveLogic = active_logic; _ptLed->m_piLightArr = NULL; _ptLed->m_iArrNum = 0; _ptLed->m_iArrIndex = 0; if (light_mode) { if (rd_LedGetLightArr(_ptLed, light_mode) != RD_SUCCESS) { RD_FREE(_ptLed); return NULL; } } _ptLed->m_iLoopInit = loop_cnt; _ptLed->m_iLoopCnt = _ptLed->m_iLoopInit; _ptLed->m_iTimeout = Rd_GetTime(); _ptLed->m_pCompelete = cbk_LedDefaultCompeleteCallback; rd_slist_init(&(_ptLed->m_tSlist)); _ptLed->m_pCbkCtrl(pLed_t, !active_logic); return _ptLed; } int rd_LedDelete(rd_led_t *_ptLed) { if(NULL == _ptLed) { return RD_INVALUE; } Rd_MutexLock(&g_fpLedCtrl, __func__, NULL); rd_slist_remove(&g_sLedListHead, &(_ptLed->m_tSlist)); _ptLed->m_tSlist.next = NULL; Rd_MutexUnlock(&g_fpLedCtrl, __func__, NULL); if (_ptLed->m_piLightArr) { RD_FREE((int *)_ptLed->m_piLightArr); _ptLed->m_piLightArr = NULL; } RD_FREE(_ptLed); return RD_SUCCESS; } int rd_LedDynamicChangeLightMode(rd_led_t *_ptLed, const char *light_mode, uint8_t loop_cnt) { int iRet = RD_SUCCESS; Rd_MutexLock(&g_fpLedCtrl, __func__, NULL); if(NULL == _ptLed) { goto END; return RD_INVALUE; } if (light_mode) { if (_ptLed->m_piLightArr) { RD_FREE((int *)_ptLed->m_piLightArr); _ptLed->m_piLightArr = NULL; } _ptLed->m_iArrNum = 0; if (rd_LedGetLightArr(_ptLed, light_mode) != RD_SUCCESS) { rd_LedStop(_ptLed); iRet = RD_FAILURE; goto END; } } _ptLed->m_iLoopInit = loop_cnt; _ptLed->m_iArrIndex = 0; _ptLed->m_iLoopCnt = _ptLed->m_iLoopInit; _ptLed->m_iTimeout = Rd_GetTime(); END: Rd_MutexUnlock(&g_fpLedCtrl, __func__, NULL); return iRet; } void rd_LedProcess(void) { rd_slist_t *pNode; rd_slist_t *pN; rd_slist_for_each(pNode, pN, &g_sLedListHead) { rd_led_t *pLed = rd_slist_entry(pNode, rd_led_t, m_tSlist); if (pLed->m_iLoopCnt == 0) { rd_LedStop(pLed); if (pLed->m_pCompelete) { pLed->m_pCompelete(pLed); } pNode = &g_sLedListHead; continue; } Rd_MutexLock(&g_fpLedCtrl, __func__, NULL); REPEAT: if (pLed->m_iArrIndex < pLed->m_iArrNum && NULL != pLed->m_piLightArr) { if (pLed->m_piLightArr[pLed->m_iArrIndex] == 0) { pLed->m_iArrIndex++; goto REPEAT; } if (Rd_GetTime() - pLed->m_iTimeout >= pLed->m_piLightArr[pLed->m_iArrIndex]) { if (pLed->m_iArrIndex % 2) { rd_LedOff(pLed); } else { rd_LedOn(pLed); } pLed->m_iTimeout = Rd_GetTime(); pLed->m_iArrIndex++; } } else { pLed->m_iArrIndex = 0; if (pLed->m_iLoopCnt > 0) { pLed->m_iLoopCnt--; } } Rd_MutexUnlock(&g_fpLedCtrl, __func__, NULL); } }