pure sdk for main
This commit is contained in:
@@ -0,0 +1,412 @@
|
||||
/**
|
||||
* @file hgled_v0.c
|
||||
* @author bxd
|
||||
* @brief led
|
||||
* @version
|
||||
* TXW80X
|
||||
* @date 2023-08-02
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "typesdef.h"
|
||||
#include "list.h"
|
||||
#include "errno.h"
|
||||
#include "dev.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/string.h"
|
||||
#include "hal/led.h"
|
||||
#include "dev/led/hgled_v0.h"
|
||||
#include "hgled_v0_hw.h"
|
||||
|
||||
/**********************************************************************************/
|
||||
/* LOW LAYER FUNCTION */
|
||||
/**********************************************************************************/
|
||||
|
||||
static int32 hgled_v0_switch_hal_led_work_mode(enum led_work_mode param) {
|
||||
|
||||
switch (param) {
|
||||
case (LED_WORK_MODE_COMMON_ANODE):
|
||||
return 1;
|
||||
break;
|
||||
case (LED_WORK_MODE_COMMON_CATHODE):
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgled_v0_switch_hal_led_seg_cnt(enum led_seg_cnt param) {
|
||||
|
||||
switch (param) {
|
||||
case (LED_SEG_CNT_1):
|
||||
return 0x10001;
|
||||
break;
|
||||
case (LED_SEG_CNT_2):
|
||||
return 0x20003;
|
||||
break;
|
||||
case (LED_SEG_CNT_3):
|
||||
return 0x30007;
|
||||
break;
|
||||
case (LED_SEG_CNT_4):
|
||||
return 0x4000f;
|
||||
break;
|
||||
case (LED_SEG_CNT_5):
|
||||
return 0x5001f;
|
||||
break;
|
||||
case (LED_SEG_CNT_6):
|
||||
return 0x6003f;
|
||||
break;
|
||||
case (LED_SEG_CNT_7):
|
||||
return 0x7007f;
|
||||
break;
|
||||
case (LED_SEG_CNT_8):
|
||||
return 0x800ff;
|
||||
break;
|
||||
case (LED_SEG_CNT_9):
|
||||
return 0x901ff;
|
||||
break;
|
||||
case (LED_SEG_CNT_10):
|
||||
return 0xa03ff;
|
||||
break;
|
||||
case (LED_SEG_CNT_11):
|
||||
return 0xb07ff;
|
||||
break;
|
||||
case (LED_SEG_CNT_12):
|
||||
return 0xc0fff;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgled_v0_switch_hal_led_com_cnt(enum led_com_cnt param) {
|
||||
|
||||
switch (param) {
|
||||
case (LED_COM_CNT_1):
|
||||
return 0x10001;
|
||||
break;
|
||||
case (LED_COM_CNT_2):
|
||||
return 0x20003;
|
||||
break;
|
||||
case (LED_COM_CNT_3):
|
||||
return 0x30007;
|
||||
break;
|
||||
case (LED_COM_CNT_4):
|
||||
return 0x4000f;
|
||||
break;
|
||||
case (LED_COM_CNT_5):
|
||||
return 0x5001f;
|
||||
break;
|
||||
case (LED_COM_CNT_6):
|
||||
return 0x6003f;
|
||||
break;
|
||||
case (LED_COM_CNT_7):
|
||||
return 0x7007f;
|
||||
break;
|
||||
case (LED_COM_CNT_8):
|
||||
return 0x800ff;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgled_v0_switch_hal_led_irq_flag(enum led_irq_flag param) {
|
||||
|
||||
switch (param) {
|
||||
case (LED_IRQ_FLAG_INT):
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgled_v0_switch_hal_led_ioctl_cmd(enum led_ioctl_cmd param) {
|
||||
|
||||
switch (param) {
|
||||
case (LED_IOCTL_CMD_SET_SCAN_FREQ):
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hgled_v0_enable(struct hgled_v0_hw *p_led) {
|
||||
(p_led)->CON |= LL_LED_CON_EN;
|
||||
}
|
||||
|
||||
static inline void hgled_v0_disable(struct hgled_v0_hw *p_led) {
|
||||
(p_led)->CON &= ~LL_LED_CON_EN;
|
||||
}
|
||||
|
||||
static inline void hgled_v0_clear_interrupt_pending(struct hgled_v0_hw *p_led) {
|
||||
(p_led)->CON |= LL_LED_CON_PENDING_CLR;
|
||||
}
|
||||
|
||||
static inline int32 hgled_v0_set_scan_freq(struct hgled_v0_hw *p_led, uint32 param1, uint32 param2) {
|
||||
(p_led)->TIME = ((p_led)->TIME &~ LL_LED_TIME_CLK_PSC(0xFFF)) | LL_LED_TIME_CLK_PSC(param1);
|
||||
(p_led)->TIME = ((p_led)->TIME &~ LL_LED_TIME_LEN(0xFF )) | LL_LED_TIME_LEN(param2 );
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
/* ATTCH FUNCTION */
|
||||
/**********************************************************************************/
|
||||
|
||||
static int32 hgled_v0_open(struct led_device *led, enum led_work_mode work_mode, enum led_seg_cnt seg_cnt, enum led_com_cnt com_cnt) {
|
||||
|
||||
struct hgled_v0 *dev = (struct hgled_v0 *)led;
|
||||
struct hgled_v0_hw *hw = (struct hgled_v0_hw *)dev->hw;
|
||||
int32 work_mode_to_reg = 0;
|
||||
int32 seg_cnt_to_reg = 0;
|
||||
int32 com_cnt_to_reg = 0;
|
||||
|
||||
|
||||
if (dev->opened) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* hal enum */
|
||||
work_mode_to_reg = hgled_v0_switch_hal_led_work_mode(work_mode);
|
||||
seg_cnt_to_reg = hgled_v0_switch_hal_led_seg_cnt(seg_cnt );
|
||||
com_cnt_to_reg = hgled_v0_switch_hal_led_com_cnt(com_cnt );
|
||||
|
||||
if (((-1) == work_mode_to_reg) ||
|
||||
((-1) == seg_cnt_to_reg ) ||
|
||||
((-1) == com_cnt_to_reg ) ) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
/* pin config */
|
||||
if (pin_func(dev->dev.dev.dev_id , 1) != RET_OK) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
#ifdef TXW80X
|
||||
sysctrl_tk_clk_en();
|
||||
#endif
|
||||
|
||||
|
||||
/* reg config */
|
||||
hw->CON = LL_LED_CON_SEG_EN(seg_cnt_to_reg & 0xFFFF) | \
|
||||
LL_LED_CON_COM_EN(com_cnt_to_reg & 0xFFFF) | \
|
||||
LL_LED_CON_SCAN_SEL(work_mode_to_reg ) | \
|
||||
LL_LED_CON_PENDING_CLR;
|
||||
|
||||
hw->TIME = LL_LED_TIME_CLK_PSC(59) | /* default clk psc */
|
||||
LL_LED_TIME_GRAY(0) |
|
||||
LL_LED_TIME_LEN(99); /* default time len */
|
||||
|
||||
hw->DATA0 = 0x0000;
|
||||
hw->DATA1 = 0x0000;
|
||||
hw->DATA2 = 0x0000;
|
||||
hw->DATA3 = 0x0000;
|
||||
hw->CON |= LL_LED_CON_LOAD_DATA_EN;
|
||||
hw->CON |= LL_LED_CON_EN;
|
||||
|
||||
dev->opened = 1;
|
||||
|
||||
dev->com_cnt = com_cnt_to_reg >> 16;
|
||||
dev->seg_cnt = seg_cnt_to_reg >> 16;
|
||||
dev->tube_type = work_mode;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgled_v0_on(struct led_device *led, uint32 num, enum led_com_cnt pos) {
|
||||
|
||||
struct hgled_v0 *dev = (struct hgled_v0 *)led;
|
||||
struct hgled_v0_hw *hw = (struct hgled_v0_hw *)dev->hw;
|
||||
const uint16 num_tbl[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
|
||||
|
||||
int32 i = 0;
|
||||
uint32 e = 0;
|
||||
uint32 *led_ptr = (uint32 *)(&(hw->DATA0));
|
||||
uint32 data_temp = 0;
|
||||
|
||||
i = hgled_v0_switch_hal_led_com_cnt(pos);
|
||||
|
||||
if ((-1) == i) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
i = (i >> 16);
|
||||
|
||||
if (i > dev->com_cnt) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
i -= 1;
|
||||
|
||||
e = num % 10;
|
||||
|
||||
//update pointer by pos, 16 bits for seg
|
||||
led_ptr = led_ptr + (i/2);
|
||||
|
||||
data_temp = *(led_ptr);
|
||||
|
||||
data_temp = (data_temp &~ (0xFF << (16*(i%2)))) | (num_tbl[e] << (16*(i%2)));
|
||||
|
||||
//write data to show
|
||||
*(led_ptr) = data_temp;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgled_v0_off(struct led_device *led, enum led_com_cnt pos) {
|
||||
|
||||
struct hgled_v0 *dev = (struct hgled_v0 *)led;
|
||||
struct hgled_v0_hw *hw = (struct hgled_v0_hw *)dev->hw;
|
||||
|
||||
int32 i = 0;
|
||||
uint32 *led_ptr = (uint32 *)(&(hw->DATA0));
|
||||
uint32 data_temp = 0;
|
||||
|
||||
i = hgled_v0_switch_hal_led_com_cnt(pos);
|
||||
|
||||
if ((-1) == i) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
i = (i >> 16);
|
||||
|
||||
if (i > dev->com_cnt) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
i -= 1;
|
||||
|
||||
//update pointer by pos, 16 bits for seg
|
||||
led_ptr = led_ptr + (i/2);
|
||||
|
||||
data_temp = *(led_ptr);
|
||||
|
||||
//write 0 to data register for turn off the tube
|
||||
data_temp = (data_temp &~ (0xFF << (16*(i%2))));
|
||||
|
||||
*(led_ptr) = data_temp;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
static int32 hgled_v0_close(struct led_device *led) {
|
||||
|
||||
struct hgled_v0 *dev = (struct hgled_v0 *)led;
|
||||
struct hgled_v0_hw *hw = (struct hgled_v0_hw *)dev->hw;
|
||||
|
||||
if (!dev->opened) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
hgled_v0_disable(hw );
|
||||
irq_disable(dev->irq_num );
|
||||
pin_func(dev->dev.dev.dev_id, 0);
|
||||
|
||||
#ifdef TXW80X
|
||||
sysctrl_tk_clk_dis();
|
||||
#endif
|
||||
|
||||
dev->opened = 0;
|
||||
dev->tube_type = 0;
|
||||
dev->seg_cnt = 0;
|
||||
dev->com_cnt = 0;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgled_v0_ioctl(struct led_device *led, enum led_ioctl_cmd ioctl_cmd, uint32 param1, uint32 param2) {
|
||||
|
||||
int32 ret_val = RET_OK;
|
||||
struct hgled_v0 *dev = (struct hgled_v0 *)led;
|
||||
struct hgled_v0_hw *hw = (struct hgled_v0_hw *)dev->hw;
|
||||
|
||||
switch (ioctl_cmd) {
|
||||
case (LED_IOCTL_CMD_SET_SCAN_FREQ):
|
||||
ret_val = hgled_v0_set_scan_freq(hw, param1, param2);
|
||||
break;
|
||||
default:
|
||||
ret_val = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static void hgled_v0_irq_handler(void *data) {
|
||||
|
||||
struct hgled_v0 *dev = (struct hgled_v0 *)data;
|
||||
struct hgled_v0_hw *hw = (struct hgled_v0_hw *)dev->hw;
|
||||
|
||||
if((hw->CON & LL_LED_CON_PENDING) && (hw->CON & LL_LED_CON_IE)) {
|
||||
hgled_v0_clear_interrupt_pending(hw);
|
||||
|
||||
if (dev->irq_hdl) {
|
||||
dev->irq_hdl(LED_IRQ_FLAG_INT, dev->irq_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgled_v0_request_irq(struct led_device *led, enum led_irq_flag irq_flag, led_irq_hdl irq_hdl, uint32 irq_data) {
|
||||
|
||||
struct hgled_v0 *dev = (struct hgled_v0 *)led;
|
||||
struct hgled_v0_hw *hw = (struct hgled_v0_hw *)dev->hw;
|
||||
|
||||
dev->irq_hdl = irq_hdl;
|
||||
dev->irq_data = irq_data;
|
||||
request_irq(dev->irq_num, hgled_v0_irq_handler, dev);
|
||||
|
||||
if (irq_flag & LED_IRQ_FLAG_INT) {
|
||||
hw->CON |= LL_LED_CON_IE;
|
||||
}
|
||||
|
||||
irq_enable(dev->irq_num);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgled_v0_release_irq(struct led_device *led, enum led_irq_flag irq_flag) {
|
||||
|
||||
struct hgled_v0 *dev = (struct hgled_v0 *)led;
|
||||
struct hgled_v0_hw *hw = (struct hgled_v0_hw *)dev->hw;
|
||||
|
||||
irq_disable(dev->irq_num);
|
||||
hw->CON &= ~ LL_LED_CON_IE;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const struct led_hal_ops led_ops = {
|
||||
.open = hgled_v0_open,
|
||||
.close = hgled_v0_close,
|
||||
.on = hgled_v0_on,
|
||||
.off = hgled_v0_off,
|
||||
.ioctl = hgled_v0_ioctl,
|
||||
.request_irq = hgled_v0_request_irq,
|
||||
.release_irq = hgled_v0_release_irq,
|
||||
};
|
||||
|
||||
int32 hgled_v0_attach(uint32 dev_id, struct hgled_v0 *led) {
|
||||
|
||||
led->opened = 0;
|
||||
led->seg_cnt = 0;
|
||||
led->com_cnt = 0;
|
||||
led->tube_type = 0;
|
||||
led->irq_hdl = NULL;
|
||||
led->irq_data = 0;
|
||||
led->dev.dev.ops =(const struct devobj_ops *)&led_ops;
|
||||
irq_disable(led->irq_num);
|
||||
dev_register(dev_id, (struct dev_obj *)led);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#ifndef _HGLED_V0_HW_H
|
||||
#define _HGLED_V0_HW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* **** **** LED_CON **** **** */
|
||||
|
||||
/* Seg enable
|
||||
*/
|
||||
#define LL_LED_CON_SEG_EN(n) ((uint32)(((uint32)(n)&0x0FFF) << 20))
|
||||
|
||||
/* Com enable
|
||||
*/
|
||||
#define LL_LED_CON_COM_EN(n) ((uint32)(((uint32)(n)&0xFF) << 12))
|
||||
|
||||
/* LED interrupt pending clear
|
||||
*/
|
||||
#define LL_LED_CON_PENDING_CLR ((uint32)(1UL << 5))
|
||||
|
||||
/* LED interrupt pending
|
||||
*/
|
||||
#define LL_LED_CON_PENDING ((uint32)(1UL << 4))
|
||||
|
||||
/* LED interrupt enable
|
||||
*/
|
||||
#define LL_LED_CON_IE ((uint32)(1UL << 3))
|
||||
|
||||
/* LED load data from shadow register
|
||||
*/
|
||||
#define LL_LED_CON_LOAD_DATA_EN ((uint32)(1UL << 2))
|
||||
|
||||
/* LED scan type selcect
|
||||
*/
|
||||
#define LL_LED_CON_SCAN_SEL(n) ((uint32)(((uint32)(n)&0x1) << 1))
|
||||
|
||||
/* LEN enable
|
||||
*/
|
||||
#define LL_LED_CON_EN ((uint32)(1UL << 0))
|
||||
|
||||
|
||||
/* **** **** LED_TIME **** **** */
|
||||
|
||||
/* LED clock prescale
|
||||
*/
|
||||
#define LL_LED_TIME_CLK_PSC(n) ((uint32)(((uint32)(n)&0x0FFF) << 16))
|
||||
|
||||
/* LED gray control
|
||||
*/
|
||||
#define LL_LED_TIME_GRAY(n) ((uint32)(((uint32)(n)&0xFF) << 8))
|
||||
|
||||
/* LED time length
|
||||
*/
|
||||
#define LL_LED_TIME_LEN(n) ((uint32)(((uint32)(n)&0xFF) << 0))
|
||||
|
||||
|
||||
/* **** **** LED_DATA0 **** **** */
|
||||
#define LL_LED_DATA0_COM0(n) ((uint32)(((uint32)(n)&0x0FFF) << 0))
|
||||
#define LL_LED_DATA0_COM1(n) ((uint32)(((uint32)(n)&0x0FFF) << 16))
|
||||
|
||||
|
||||
/* **** **** LED_DATA1 **** **** */
|
||||
#define LL_LED_DATA1_COM2(n) ((uint32)(((uint32)(n)&0x0FFF) << 0))
|
||||
#define LL_LED_DATA1_COM3(n) ((uint32)(((uint32)(n)&0x0FFF) << 16))
|
||||
|
||||
|
||||
/* **** **** LED_DATA2 **** **** */
|
||||
#define LL_LED_DATA2_COM4(n) ((uint32)(((uint32)(n)&0x0FFF) << 0))
|
||||
#define LL_LED_DATA2_COM5(n) ((uint32)(((uint32)(n)&0x0FFF) << 16))
|
||||
|
||||
|
||||
/* **** **** LED_DATA3 **** **** */
|
||||
#define LL_LED_DATA3_COM6(n) ((uint32)(((uint32)(n)&0x0FFF) << 0))
|
||||
#define LL_LED_DATA3_COM7(n) ((uint32)(((uint32)(n)&0x0FFF) << 16))
|
||||
|
||||
|
||||
struct hgled_v0_hw {
|
||||
__IO uint32_t CON;
|
||||
__IO uint32_t TIME;
|
||||
__IO uint32_t DATA0;
|
||||
__IO uint32_t DATA1;
|
||||
__IO uint32_t DATA2;
|
||||
__IO uint32_t DATA3;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGLED_V0_HW_H */
|
||||
Reference in New Issue
Block a user