Initial import of NFC GNSS SDK project
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
#include "plat_types.h"
|
||||
//#include "plat_basic_api.h"
|
||||
//#include "ui_log_api.h"
|
||||
|
||||
#include "__regs_pwm.h"
|
||||
|
||||
//#include "clock_api.h"
|
||||
|
||||
struct pwm_ctl {
|
||||
unsigned int pwm_cr; /*address*/
|
||||
unsigned int pwm_dcr;
|
||||
unsigned int pwm_pcr;
|
||||
|
||||
unsigned long clk_freq;
|
||||
};
|
||||
|
||||
static struct pwm_ctl pwm[4];
|
||||
|
||||
/**
|
||||
How to get the PV(The value of after scaled clock cycles per cycle/T):
|
||||
InputClockT * ('PV(The value of before scaled clock cycles per cycle)) = PWM_T
|
||||
'PV = PWM_T / InputClockT
|
||||
= PWM_T * InputClockF
|
||||
PV = 'PV /(prescale + 1) -1
|
||||
|
||||
How to get the prescale:
|
||||
Because the internal clock period counter is 10-bit, to avoid overun. We can use the prescale.
|
||||
prescale real value = ('PV - 1(if > 1024, then need prescale)) / 1024
|
||||
|
||||
How to get the Duty cycle:
|
||||
Duty cycle = (PV(the cycles per T) + 1) * ratio(Duty time/PWM_T)
|
||||
|
||||
*/
|
||||
static int __pwm_set_para(struct pwm_ctl *p, int period_ns, int duty_ns)
|
||||
{
|
||||
unsigned long period_cycles, prescale, pv, dc;
|
||||
unsigned long long clk_freq;
|
||||
|
||||
clk_freq = p->clk_freq;
|
||||
clk_freq = clk_freq * period_ns;
|
||||
clk_freq = clk_freq / (1*1000*1000*1000);
|
||||
|
||||
period_cycles = clk_freq;
|
||||
|
||||
if (period_cycles < 1)
|
||||
period_cycles = 1;
|
||||
|
||||
prescale = (period_cycles - 1) / 1024;
|
||||
|
||||
pv = period_cycles / (prescale + 1) - 1;
|
||||
|
||||
if (prescale > 63) {
|
||||
raw_uart_log("clock and period are too large, Both prescale is overun!\n\r");
|
||||
return -1;
|
||||
}
|
||||
if (duty_ns == period_ns)
|
||||
dc = BIT_FD;
|
||||
else
|
||||
dc = (pv + 1) * duty_ns / period_ns;
|
||||
|
||||
/* NOTE: the clock to PWM has to be enabled first
|
||||
* before writing to the registers
|
||||
*/
|
||||
//__pwm_enable(p);
|
||||
|
||||
raw_uart_log("prescale = 0x%x, dc = 0x%x, pv = 0x%x\n\r", prescale, dc, pv);
|
||||
CHIP_REG_OR(p->pwm_cr, prescale);
|
||||
write32(p->pwm_dcr, dc);
|
||||
write32(p->pwm_pcr, pv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void pwm_shutdow_mode(struct pwm_ctl *p, int is_graceful_down)
|
||||
{
|
||||
//unsigned int addr;
|
||||
if (is_graceful_down) {
|
||||
CHIP_REG_AND(p->pwm_cr, ~BIT_SD);
|
||||
} else {
|
||||
CHIP_REG_OR(p->pwm_cr, BIT_SD);
|
||||
}
|
||||
}
|
||||
|
||||
/*Only support port 0, 1, 2, 3*/
|
||||
int pwm_start_work(int port, int period_ns, int duty_ns)
|
||||
{
|
||||
if (port > 3)
|
||||
return -1;
|
||||
return __pwm_set_para(&pwm[port], period_ns, duty_ns);
|
||||
}
|
||||
|
||||
/*Only support port 0, 1, 2, 3*/
|
||||
int pwm_set_shutdown_mode(int port, int is_graceful_down)
|
||||
{
|
||||
if (port > 3)
|
||||
return -1;
|
||||
|
||||
pwm_shutdow_mode(&pwm[port], is_graceful_down);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Only support port 0, 1, 2, 3*/
|
||||
int pwm_disable(int port)
|
||||
{
|
||||
if (port > 3)
|
||||
return -1;
|
||||
|
||||
write32((APBC_PWM0_CLK_RST + port * 4), 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Only support port 0, 1, 2, 3*/
|
||||
int pwm_enable(int port,unsigned long clk_freq)
|
||||
{
|
||||
if (port > 3)
|
||||
return -1;
|
||||
if(clk_freq == 12800000)
|
||||
write32((APBC_PWM0_CLK_RST + port * 4),0x3 | (PWM_13M <<4));
|
||||
else
|
||||
write32((APBC_PWM0_CLK_RST + port * 4),0x3 | (PWM_32K <<4));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void pwm_module_init(int port, unsigned long clk_freq)
|
||||
{
|
||||
//unsigned long long clk_freq;
|
||||
|
||||
if (port >= ARR_SIZE(pwm)) {
|
||||
raw_uart_log("pwm_module_init wrong: port = %d\n\r",port);
|
||||
return;
|
||||
}
|
||||
|
||||
//clk_freq = pwm_clksource_select(clk_id);
|
||||
raw_uart_log("pwm clock frequency is %d\n",clk_freq);
|
||||
|
||||
pwm[port].pwm_cr = REG_PWM0_PWM_CRx + port * 0x400;
|
||||
pwm[port].pwm_dcr= REG_PWM0_PWM_DCR + port * 0x400;
|
||||
pwm[port].pwm_pcr= REG_PWM0_PWM_PCR + port * 0x400;
|
||||
pwm[port].clk_freq = clk_freq;
|
||||
pwm_enable(port,clk_freq);
|
||||
}
|
||||
Reference in New Issue
Block a user