mirror of
https://github.com/EFeru/hoverboard-sideboard-hack-GD.git
synced 2025-07-27 09:39:33 +00:00
446 lines
13 KiB
C
446 lines
13 KiB
C
/*!
|
|
\file gd32f1x0_slcd.c
|
|
\brief SLCD driver
|
|
*/
|
|
|
|
/*
|
|
Copyright (C) 2017 GigaDevice
|
|
|
|
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
|
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
|
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
|
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
|
*/
|
|
|
|
#ifdef GD32F170_190
|
|
#include "gd32f1x0_slcd.h"
|
|
#include "gd32f1x0_rcu.h"
|
|
|
|
/*!
|
|
\brief SLCD reset
|
|
\param[in] none
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_deinit(void)
|
|
{
|
|
rcu_periph_reset_enable(RCU_SLCDRST);
|
|
rcu_periph_reset_disable(RCU_SLCDRST);
|
|
}
|
|
|
|
/*!
|
|
\brief get the SLCD status flag
|
|
\param[in] slcd_flag: the adc status flag bits
|
|
\arg SLCD_FLAG_ON: SLCD controller on flag
|
|
\arg SLCD_FLAG_SOF: start of frame flag
|
|
\arg SLCD_FLAG_UPR: SLCD data update request flag
|
|
\arg SLCD_FLAG_UPD: update LCDS data done flag
|
|
\arg SLCD_FLAG_VRDY: SLCD voltage ready flag
|
|
\arg SLCD_FLAG_SYN: SLCD CFG register synchronization flag
|
|
\param[out] none
|
|
\retval FlagStatus: SET or RESET
|
|
*/
|
|
FlagStatus slcd_flag_get(uint8_t slcd_flag)
|
|
{
|
|
if(SLCD_STAT & slcd_flag){
|
|
return SET;
|
|
}else{
|
|
return RESET;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief get the SLCD interrupt flag
|
|
\param[in] slcd_interrupt: the adc interrupt flag bits
|
|
\arg SLCD_INT_FLAG_SOF: start of frame interrupt
|
|
\arg SLCD_INT_FLAG_UPD: SLCD update done interrupt
|
|
\param[out] none
|
|
\retval FlagStatus: SET or RESET
|
|
*/
|
|
FlagStatus slcd_interrupt_flag_get(uint8_t slcd_interrupt)
|
|
{
|
|
FlagStatus interrupt_flag = RESET;
|
|
uint32_t state;
|
|
/* check the interrupt bits */
|
|
switch(slcd_interrupt){
|
|
case SLCD_INT_FLAG_SOF:
|
|
state = SLCD_STAT & SLCD_FLAG_SOF;
|
|
if((SLCD_CFG & SLCD_CFG_SOFIE) && state){
|
|
interrupt_flag = SET;
|
|
}
|
|
break;
|
|
case SLCD_INT_FLAG_UPD:
|
|
state = SLCD_STAT & SLCD_FLAG_UPD;
|
|
if((SLCD_CFG & SLCD_CFG_UPDIE) && state){
|
|
interrupt_flag = SET;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return interrupt_flag;
|
|
}
|
|
|
|
/*!
|
|
\brief clear the SLCD flag
|
|
\param[in] slcd_flag: the adc status flag bits
|
|
\arg SLCD_FLAG_SOF: start of frame flag
|
|
\arg SLCD_FLAG_UPD: update LCDS data done flag
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_flag_clear(uint8_t slcd_flag)
|
|
{
|
|
/* check the interrupt bits */
|
|
switch(slcd_flag){
|
|
case SLCD_FLAG_SOF:
|
|
SLCD_STATC |= SLCD_STATC_SOFC;
|
|
break;
|
|
case SLCD_FLAG_UPD:
|
|
SLCD_STATC |= SLCD_STATC_UPDC;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief clear the SLCD interrupt flag
|
|
\param[in] slcd_interrupt: the adc interrupt bits
|
|
\arg SLCD_INT_FLAG_SOF: start of frame interrupt
|
|
\arg SLCD_INT_FLAG_UPD: SLCD update done interrupt
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_interrupt_flag_clear(uint8_t slcd_interrupt)
|
|
{
|
|
/* check the interrupt bits */
|
|
switch(slcd_interrupt){
|
|
case SLCD_INT_FLAG_SOF:
|
|
SLCD_STATC |= SLCD_STATC_SOFC;
|
|
break;
|
|
case SLCD_INT_FLAG_UPD:
|
|
SLCD_STATC |= SLCD_STATC_UPDC;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief the SLCD interrupt config
|
|
\param[in] slcd_interrupt: the adc interrupt bits
|
|
\arg SLCD_INT_SOF: start of frame interrupt
|
|
\arg SLCD_INT_UPD: SLCD update done interrupt
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_interrupt_config(uint8_t slcd_interrupt,ControlStatus newvalue)
|
|
{
|
|
/* ENABLE or DISABLE the interrupt */
|
|
if(newvalue){
|
|
/* select the interrupt source */
|
|
switch(slcd_interrupt){
|
|
case SLCD_INT_SOF:
|
|
SLCD_CFG |= (uint32_t) SLCD_CFG_SOFIE;
|
|
break;
|
|
case SLCD_INT_UPD:
|
|
SLCD_CFG |= (uint32_t) SLCD_CFG_UPDIE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}else{
|
|
switch(slcd_interrupt){
|
|
/* select the interrupt source */
|
|
case SLCD_INT_SOF:
|
|
SLCD_CFG &= (uint32_t)~(SLCD_CFG_SOFIE);
|
|
break;
|
|
case SLCD_INT_UPD:
|
|
SLCD_CFG &= (uint32_t)~(SLCD_CFG_UPDIE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD bias voltage select
|
|
\param[in] bias_voltage: the SLCD voltage bias
|
|
\arg SLCD_BIAS_1_4: 1/4 voltage bias
|
|
\arg SLCD_BIAS_1_2: 1/2 voltage bias
|
|
\arg SLCD_BIAS_1_3: 1/3 voltage bias
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_bias_voltage_select(uint32_t bias_voltage)
|
|
{
|
|
SLCD_CTL &= (uint32_t)~(SLCD_CTL_BIAS);
|
|
SLCD_CTL |= (uint32_t)bias_voltage;
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD duty cycle select
|
|
\param[in] duty: the adc flag bits
|
|
\arg SLCD_DUTY_STATIC: static dutycycle
|
|
\arg SLCD_DUTY_1_2: 1/2 dutycycle
|
|
\arg SLCD_DUTY_1_3: 1/3 dutycycle
|
|
\arg SLCD_DUTY_1_4: 1/4 dutycycle
|
|
\arg SLCD_DUTY_1_6: 1/6 dutycycle
|
|
\arg SLCD_DUTY_1_8: 1/8 dutycycle
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_duty_select(uint32_t duty)
|
|
{
|
|
SLCD_CTL &= (uint32_t)~(SLCD_CTL_DUTY);
|
|
SLCD_CTL |= (uint32_t)duty;
|
|
}
|
|
|
|
/*!
|
|
\brief config the prescaler and the divider of SLCD clock
|
|
fSLCD = finclk/( pow( 2 , PRE )* DIV )
|
|
\param[in] prescaler: the prescaler factor
|
|
\arg SLCD_PRESCALER_1: PRE = 0
|
|
\arg SLCD_PRESCALER_2: PRE = 1
|
|
\arg SLCD_PRESCALER_4: PRE = 2
|
|
\arg SLCD_PRESCALER_8: PRE = 3
|
|
\arg SLCD_PRESCALER_16: PRE = 4
|
|
\arg SLCD_PRESCALER_32: PRE = 5
|
|
\arg SLCD_PRESCALER_64: PRE = 6
|
|
\arg SLCD_PRESCALER_128: PRE = 7
|
|
\arg SLCD_PRESCALER_256: PRE = 8
|
|
\arg SLCD_PRESCALER_512: PRE = 9
|
|
\arg SLCD_PRESCALER_1024: PRE = 10
|
|
\arg SLCD_PRESCALER_2048: PRE = 11
|
|
\arg SLCD_PRESCALER_4096: PRE = 12
|
|
\arg SLCD_PRESCALER_8192: PRE = 13
|
|
\arg SLCD_PRESCALER_16384: PRE = 14
|
|
\arg SLCD_PRESCALER_32768: PRE = 15
|
|
\param[in] divider: the divider factor
|
|
\arg SLCD_DIVIDER_x: x= 16..31 ,DIV = 16..31
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_clock_config(uint32_t prescaler,uint32_t divider)
|
|
{
|
|
uint32_t cfg;
|
|
|
|
/* config the prescaler and the divider */
|
|
cfg = SLCD_CFG;
|
|
cfg &= (uint32_t)~(SLCD_CFG_PSC | SLCD_CFG_DIV);
|
|
cfg |= (uint32_t)(prescaler | divider);
|
|
SLCD_CFG = cfg;
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD blink mode config
|
|
\param[in] mode: the prescaler factor
|
|
\arg SLCD_BLINKMODE_OFF: blink disabled
|
|
\arg SLCD_BLINKMODE_SEG0_COM0: blink enabled on SEG[0], COM[0]
|
|
\arg SLCD_BLINKMODE_SEG0_ALLCOM: blink enabled on SEG[0], all COM
|
|
\arg SLCD_BLINKMODE_ALLSEG_ALLCOM: blink enabled on all SEG and all COM
|
|
\param[in] blink_divider: the divider factor
|
|
\arg SLCD_BLINK_FREQUENCY_DIV8: blink frequency = fSLCD/8
|
|
\arg SLCD_BLINK_FREQUENCY_DIV16: blink frequency = fSLCD/16
|
|
\arg SLCD_BLINK_FREQUENCY_DIV32: blink frequency = fSLCD/32
|
|
\arg SLCD_BLINK_FREQUENCY_DIV64: blink frequency = fSLCD/64
|
|
\arg SLCD_BLINK_FREQUENCY_DIV128: blink frequency = fSLCD/128
|
|
\arg SLCD_BLINK_FREQUENCY_DIV256: blink frequency = fSLCD/256
|
|
\arg SLCD_BLINK_FREQUENCY_DIV512: blink frequency = fSLCD/512
|
|
\arg SLCD_BLINK_FREQUENCY_DIV1024: blink frequency = fSLCD/1024
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_blink_mode_config(uint32_t mode,uint32_t blink_divider)
|
|
{
|
|
SLCD_CFG &= (uint32_t)~(SLCD_CFG_BLKMOD | SLCD_CFG_BLKDIV);
|
|
SLCD_CFG |= (uint32_t)(mode | blink_divider);
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD contrast ratio config
|
|
\param[in] contrast_ratio: specify the VSLCD voltage ,when chosing the internal voltage source
|
|
\arg SLCD_CONTRAST_LEVEL_0: maximum SLCD Voltage = 2.60V
|
|
\arg SLCD_CONTRAST_LEVEL_1: maximum SLCD Voltage = 2.73V
|
|
\arg SLCD_CONTRAST_LEVEL_2: maximum SLCD Voltage = 2.86V
|
|
\arg SLCD_CONTRAST_LEVEL_3: maximum SLCD Voltage = 2.99V
|
|
\arg SLCD_CONTRAST_LEVEL_4: maximum SLCD Voltage = 3.12V
|
|
\arg SLCD_CONTRAST_LEVEL_5: maximum SLCD Voltage = 3.25V
|
|
\arg SLCD_CONTRAST_LEVEL_6: maximum SLCD Voltage = 3.38V
|
|
\arg SLCD_CONTRAST_LEVEL_7: maximum SLCD Voltage = 3.51V
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_contrast_ratio_config(uint32_t contrast_ratio)
|
|
{
|
|
uint32_t cfg;
|
|
|
|
/* config the contrast ratio */
|
|
cfg = SLCD_CFG;
|
|
cfg &= (uint32_t)~(SLCD_CFG_CONR);
|
|
cfg |= (uint32_t)contrast_ratio;
|
|
SLCD_CFG = cfg;
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD dead time duration config
|
|
\param[in] dead_time: configure the length of the dead time between frames
|
|
\arg SLCD_DEADTIME_PERIOD_0: no dead time
|
|
\arg SLCD_DEADTIME_PERIOD_1: 1 phase inserted between couple of frame
|
|
\arg SLCD_DEADTIME_PERIOD_2: 2 phase inserted between couple of frame
|
|
\arg SLCD_DEADTIME_PERIOD_3: 3 phase inserted between couple of frame
|
|
\arg SLCD_DEADTIME_PERIOD_4: 4 phase inserted between couple of frame
|
|
\arg SLCD_DEADTIME_PERIOD_5: 5 phase inserted between couple of frame
|
|
\arg SLCD_DEADTIME_PERIOD_6: 6 phase inserted between couple of frame
|
|
\arg SLCD_DEADTIME_PERIOD_7: 7 phase inserted between couple of frame
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_dead_time_config(uint32_t dead_time)
|
|
{
|
|
uint32_t cfg;
|
|
|
|
/* config dead time duration */
|
|
cfg = SLCD_CFG;
|
|
cfg &= (uint32_t)~(SLCD_CFG_DTD);
|
|
cfg |= (uint32_t)dead_time;
|
|
SLCD_CFG = cfg;
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD pulse on duration config
|
|
\param[in] duration: configure the length of the dead time between frames
|
|
\arg SLCD_PULSEON_DURATION_0: pulse on duration = 0
|
|
\arg SLCD_PULSEON_DURATION_1: pulse on duration = 1*1/fPRE
|
|
\arg SLCD_PULSEON_DURATION_2: pulse on duration = 2*1/fPRE
|
|
\arg SLCD_PULSEON_DURATION_3: pulse on duration = 3*1/fPRE
|
|
\arg SLCD_PULSEON_DURATION_4: pulse on duration = 4*1/fPRE
|
|
\arg SLCD_PULSEON_DURATION_5: pulse on duration = 5*1/fPRE
|
|
\arg SLCD_PULSEON_DURATION_6: pulse on duration = 6*1/fPRE
|
|
\arg SLCD_PULSEON_DURATION_7: pulse on duration = 7*1/fPRE
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_pulse_on_duration_config(uint32_t duration)
|
|
{
|
|
uint32_t cfg;
|
|
|
|
/* config pulse on duration */
|
|
cfg = SLCD_CFG;
|
|
cfg &= (uint32_t)~(SLCD_CFG_PULSE);
|
|
cfg |= (uint32_t)duration;
|
|
SLCD_CFG = cfg;
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD common/segment pad select
|
|
\param[in] NewValue: ENABLE or DISABLE
|
|
\arg ENABLE: LCD_COM[7:4] pad select LCD_SEG[31:28]
|
|
\arg DISABLE: LCD_COM[7:4] pad select LCD_COM[7:4]
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_com_seg_remap(ControlStatus newvalue)
|
|
{
|
|
if( ENABLE == newvalue ){
|
|
SLCD_CTL |= SLCD_CTL_COMS;
|
|
}else{
|
|
SLCD_CTL &= ~(SLCD_CTL_COMS);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD voltage source select
|
|
\param[in] voltage_source: the SLCD voltage source
|
|
\arg SLCD_VOLTAGE_INTERNAL: internal source
|
|
\arg SLCD_VOLTAGE_EXTERNAL: external source (VSLCD pin)
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_voltage_source_select(uint8_t voltage_source)
|
|
{
|
|
if( SLCD_VOLTAGE_EXTERNAL == voltage_source ){
|
|
SLCD_CTL |= SLCD_CTL_VSRC;
|
|
}else{
|
|
SLCD_CTL &= ~(SLCD_CTL_VSRC);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief enable or disable permanent high drive
|
|
\param[in] NewValue: ENABLE or DISABLE
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_high_drive_config(ControlStatus newvalue)
|
|
{
|
|
if( ENABLE == newvalue ){
|
|
SLCD_CFG |= SLCD_CFG_HDEN;
|
|
}else{
|
|
SLCD_CFG &= ~(SLCD_CFG_HDEN);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD voltage source select
|
|
\param[in] data_reg: the SLCD data register
|
|
\arg SLCD_DATA_REG0: SLCD_DATA register 0
|
|
\arg SLCD_DATA_REG1: SLCD_DATA Register 1
|
|
\arg SLCD_DATA_REG2: SLCD_DATA register 2
|
|
\arg SLCD_DATA_REG3: SLCD_DATA Register 3
|
|
\arg SLCD_DATA_REG4: SLCD_DATA register 4
|
|
\arg SLCD_DATA_REG5: SLCD_DATA Register 5
|
|
\arg SLCD_DATA_REG6: SLCD_DATA register 6
|
|
\arg SLCD_DATA_REG7: SLCD_DATA Register 7
|
|
\param[in] data: the data write to the register
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_data_register_write(uint32_t data_reg,uint32_t data)
|
|
{
|
|
volatile uint32_t *pdata;
|
|
|
|
/* point to DATA register */
|
|
pdata = &SLCD_DATA0;
|
|
|
|
/* wtite data word to DATA register */
|
|
*(pdata + data_reg) = (uint32_t)data;
|
|
}
|
|
|
|
/*!
|
|
\brief SLCD data update request
|
|
\param[in] none
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_data_update_request(void)
|
|
{
|
|
SLCD_STAT |= SLCD_STAT_UPRF;
|
|
}
|
|
|
|
/*!
|
|
\brief enable SLCD interface
|
|
\param[in] none
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_enable(void)
|
|
{
|
|
SLCD_CTL |= SLCD_CTL_LCDON;
|
|
}
|
|
|
|
/*!
|
|
\brief disable SLCD interface
|
|
\param[in] none
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void slcd_disable(void)
|
|
{
|
|
SLCD_CTL &= ~(SLCD_CTL_LCDON);
|
|
}
|
|
|
|
#endif /* GD32F170_190 */
|