⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 battery.c

📁 How to detect Battery voltage in DragonBall SZ platform
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "mx1_def.h"



void delay(U32 n)
{
	while(n --);
	return;
}




//
//	GPIO init for Analog Mux control
//
void port_init_mux(void)
{
	//	PA4 (CSI_D0) => Vin = battery enable
	//	PA6 (CSI_D2) => Vin = 1.8V enable
	//	PA8 (CSI_D4) => Vin = 0V enable

//config PA4 for battery input
	* (U32 *)PTA_GIUS |= (0x1 << 4);
	* (U32 *)PTA_OCR1 |= (0x3 << 8);
	* (U32 *)PTA_DDIR |= (0x1 << 4);
	* (U32 *)PTA_GPR  |= (0x1 << 4);
	* (U32 *)PTA_DR   &= ~(0x1 << 4);	//default set low

//config PA6 for 1.8V input
	* (U32 *)PTA_GIUS |= (0x1 << 6);
	* (U32 *)PTA_OCR1 |= (0x3 << 12);
	* (U32 *)PTA_DDIR |= (0x1 << 6);
	* (U32 *)PTA_GPR  |= (0x1 << 6);
	* (U32 *)PTA_DR   &= ~(0x1 << 6);	//default set low

//config PA8 for 0V input
	* (U32 *)PTA_GIUS |= (0x1 << 8);
	* (U32 *)PTA_OCR1 |= (0x3 << 16);
	* (U32 *)PTA_DDIR |= (0x1 << 8);
	* (U32 *)PTA_GPR  |= (0x1 << 8);
	* (U32 *)PTA_DR   &= ~(0x1 << 8);	//default set low

	return;
}


void port_set_battery(U32 level)
{
	if(level)
		* (U32 *)PTA_DR |= (0x1 << 4);	//set
	else
		* (U32 *)PTA_DR &= ~(0x1 << 4);	//clear

	return;
}


void port_set_1800(U32 level)
{
	if(level)
		* (U32 *)PTA_DR |= (0x1 << 6);	//set
	else
		* (U32 *)PTA_DR &= ~(0x1 << 6);	//clear

	return;
}


void port_set_0000(U32 level)
{
	if(level)
		* (U32 *)PTA_DR |= (0x1 << 8);	//set
	else
		* (U32 *)PTA_DR &= ~(0x1 << 8);	//clear

	return;
}



//
//	Init ASP for auto U-ch sampling
//
void Uinit(void)
{
//sample rate control
	U32 DMCNT		= 7;	//decimation count	: 0 - 7
	U32 BIT_SELECT	= 0;	//filter bit select	: 0 - 3
	U32 IDLECNT		= 0;	//idle count		: 0 - 63
	U32 DSCNT		= 0;	//data set up count	: 0 - 15

//ASP init
	* (U32 *)ASP_ACNTLCR |= 0x800000;	//module reset
	* (U32 *)ASP_CLKDIV  |= 8;			//96M / 8 => 12M
	*(U32 *)ASP_ACNTLCR  |= 0x40001;	//BandGap enable
	while(!(* (U32 *)ASP_ISTATR & 0x200));	//wait for BGR

//init for auto U mode
	* (U32 *)ASP_PSMPLRG = (DMCNT << 12) | (BIT_SELECT << 10) | (IDLECNT << 4) | (DSCNT);
	* (U32 *)ASP_ICNTLR  |= 0x13;	//enable PDR / PFFE interrupt
	* (U32 *)ASP_ACNTLCR |= 0x7000;	//auto U mode
	* (U32 *)ASP_ACNTLCR |= 0x2;	//PEN enable	

	return;
}



//
//	Calibration
//
void Calibrate(float * _slope, U32 * _offset)
{
	U32 sample1800, sample0000, dump;
	U32 j;

//select 1800mV input
	port_set_1800(1);
	
//get FIFO data and take mean
	if(* (U32 *)ASP_ISTATR & 0x20)			//clear overflow
		* (U32 *)ASP_ISTATR = 0x20;
	while(!(* (U32 *)ASP_ISTATR & 0x2));	//poll FIFO Full
	for(j = 0, sample1800 = 0; j < 12; j ++)
		sample1800 += * (U32 *)ASP_PADFIFO;
	sample1800 /= 12;

//unselect 1800mV input
	port_set_1800(0);

//select 0V input
	port_set_0000(1);
	
//get FIFO data and take mean
	if(* (U32 *)ASP_ISTATR & 0x20)			//clear overflow
		* (U32 *)ASP_ISTATR = 0x20;
	while(!(* (U32 *)ASP_ISTATR & 0x2));	//poll FIFO Full
	for(j = 0, sample0000 = 0; j < 12; j ++)
		sample0000 += * (U32 *)ASP_PADFIFO;
	sample0000 /= 12;

//unselect 0V input
	port_set_0000(0);

//get slope and offset
	* _slope = (float)(sample1800 - sample0000) / (float)(1800 - 0);
	* _offset = sample0000;

	printf("slope = %f mV-1, offset = %d\n", * _slope, * _offset);

	return;
}



//
//	Read Battery Voltage
//
void ReadBattery(float slope, U32 offset, float scaler)
{
	U32 sample;
	float voltage;
	U32 j;

//select battery input
	port_set_battery(1);
	delay(10000000);
	
//get FIFO data and take mean
	if(* (U32 *)ASP_ISTATR & 0x20)			//clear overflow
		* (U32 *)ASP_ISTATR = 0x20;
	while(!(* (U32 *)ASP_ISTATR & 0x2));	//poll FIFO Full
	for(j = 0, sample = 0; j < 12; j ++)
		sample += * (U32 *)ASP_PADFIFO;
	sample /= 12;

//clear port
	port_set_battery(0);

//interpret Voltage
	if(sample <= offset)	//truncation
		voltage = 0;
	else
		voltage = ((float)(sample - offset) / slope) * scaler;

	printf("voltage = %f, sample = %d\n", voltage, sample);

	return;
}





/*
void ReadBattery1(U32 scaler)
{
	U32 sample1800, sample0000, sample;
	U32 j;
	float slope;
	U32 offset;
	float voltage;

//select 1800mV input
	port_set_battery(0);
	port_set_0000(0);
	port_set_1800(1);
	delay(1000000);

	while(1)
	{
	//check POV
		if(* (U32 *)ASP_ISTATR & 0x20)
			* (U32 *)ASP_ISTATR |= 0x20;
	//check PFF
	//get FIFO data and take mean
		if(* (U32 *)ASP_ISTATR & 0x2)
		{
			sample1800 = 0;
			for(j = 0; j < 12; j ++)
				sample1800 += * (U32 *)ASP_PADFIFO;
			sample1800 /= 12;
			
			break;
		}
	}


//select 0V input
	port_set_battery(0);
	port_set_1800(0);
	port_set_0000(1);
	delay(1000000);

	while(1)
	{
	//check POV
		if(* (U32 *)ASP_ISTATR & 0x20)
			* (U32 *)ASP_ISTATR |= 0x20;
	//check PFF
	//get FIFO data and take mean
		if(* (U32 *)ASP_ISTATR & 0x2)
		{
			sample0000 = 0;
			for(j = 0; j < 12; j ++)
				sample0000 += * (U32 *)ASP_PADFIFO;
			sample0000 /= 12;
			
			break;
		}
	}

//get slope and offset
	slope = (float)(sample1800 - sample0000) / (float)(1800 - 0);
	offset = sample0000;

//select battery input
	port_set_0000(0);
	port_set_1800(0);
	port_set_battery(1);
	delay(1000000);
	
	while(1)
	{
	//check POV
		if(* (U32 *)ASP_ISTATR & 0x20)
			* (U32 *)ASP_ISTATR |= 0x20;
	//check PFF
	//get FIFO data and take mean
		if(* (U32 *)ASP_ISTATR & 0x2)
		{
			sample = 0;
			for(j = 0; j < 12; j ++)
				sample += * (U32 *)ASP_PADFIFO;
			sample /= 12;
			
			break;
		}
	}

//interpret Voltage
	voltage = (float)(sample - offset) / slope;
	voltage *= scaler;
	printf("voltage = %f\n", voltage);

	return;
}
*/











//
//	Entry point
//
void BatteryMain(void)
{
	float slope;
	U32 offset;
	float scaler = 2.5;	//potential divider ratio for battery input

	port_init_mux();

	Uinit();

//	while(1)
//		ReadBattery1(scaler);

	Calibrate(&slope, &offset);
	
	while(1)
		ReadBattery(slope, offset, scaler);


	while(1);
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -