2020-02-07 14:57:44 +01:00

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 */