adc

Dependents:   h7adc

ADE7912.cpp

Committer:
yuliyasm
Date:
2020-10-28
Revision:
3:1d62b3be52e8
Parent:
2:f480200c8600

File content as of revision 3:1d62b3be52e8:

#include "ADE7912.h"
#include "communication.h"
#include "stm32h7xx_hal.h"



uint8_t spiPackageTransmited = 0;
uint8_t spiPackageReceived = 0;



void ADE7912_WriteToReg(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, uint8_t addr, uint8_t *buf, uint8_t length);
void ADE7912_ReadFromReg(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, uint8_t addr, uint8_t *buf, uint8_t length);
uint8_t ADE7912_ReadADCVersionFromReg(struct ADE7912_Inst *ade, enum ADE7912_Phases phase);
uint8_t ADE7912_ReadTemposFromReg(struct ADE7912_Inst *ade, enum ADE7912_Phases phase);
//void ADE7912_InitEXTIForDReady(struct ADE7912_Inst *ade, GPIO_TypeDef *port, uint16_t pin);



void ADE7912_WriteToReg(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, uint8_t addr, uint8_t *buf, uint8_t length)
{
	HAL_GPIO_WritePin(ade->CS_ports[phase], ade->CS_pins[phase], GPIO_PIN_RESET);
	
	uint8_t addrBuf = addr | ADE7912_WRITE_MODE;
	WriteToRegisterBySPI(ade->spi, addrBuf, buf, length);
	
	HAL_GPIO_WritePin(ade->CS_ports[phase], ade->CS_pins[phase], GPIO_PIN_SET);
}



void ADE7912_ReadFromReg(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, uint8_t addr, uint8_t *buf, uint8_t length)
{
	HAL_GPIO_WritePin(ade->CS_ports[phase], ade->CS_pins[phase], GPIO_PIN_RESET);
	
	uint8_t addrBuf = addr | ADE7912_READ_MODE;
	ReadFromRegisterBySPI(ade->spi, addrBuf, buf, length);

	HAL_GPIO_WritePin(ade->CS_ports[phase], ade->CS_pins[phase], GPIO_PIN_SET);
}



//void ADE7912_InitEXTIForDReady(struct ADE7912_Inst *ade, GPIO_TypeDef *port, uint16_t pin)
//{
//	ade->DReadyPort = port;
//	ade->DReadyPin = pin;
//	
//	switch (pin)
//	{
//		case GPIO_PIN_0:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_1:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_2:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_3:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_4:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_5:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_6:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_7:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_8:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_9:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_10:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_11:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_12:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_13:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_14:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//		case GPIO_PIN_15:
//			ade->EXTIinterrupt = EXTI15_10_IRQn;
//		break;
//	}
//	
//	GPIO_InitTypeDef GPIO_InitStruct = {0};

//  /* GPIO Ports Clock Enable */
//  __HAL_RCC_GPIOA_CLK_ENABLE();

//  /*Configure GPIO pin : PA11 */
//  GPIO_InitStruct.Pin = pin;
//  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
//  GPIO_InitStruct.Pull = GPIO_NOPULL;
//  HAL_GPIO_Init(port, &GPIO_InitStruct);

//  /* EXTI interrupt init*/
//	
//	
//	
//	
//  HAL_NVIC_SetPriority(EXTIinterrupt, 0, 0);
//  HAL_NVIC_EnableIRQ(EXTIinterrupt);
//}



struct ADE7912_Inst* New_ADE7912(SPI_HandleTypeDef *spi)
{
	struct ADE7912_Inst *ade = (struct ADE7912_Inst *)malloc(sizeof(struct ADE7912_Inst));
	ade->spi = spi;
	for(int phase = 0; phase < 4; phase += 1)
	{
		ade->CS_pins[phase] = NULL;
		ade->CS_ports[phase] = GPIOA;
		ade->phasesData[phase] = NULL;
		ade->phasesEnable[phase] = 0;
	}
	return ade;
}



void ADE7912_PhaseInit(struct ADE7912_Inst *ade, struct ADE7912_Phase_Settings *settings, enum ADE7912_Phases phase)
{
	ade->CS_ports[phase] = settings->CS_port;
	ade->CS_pins[phase] = settings->CS_pin;

	ade->phasesData[phase] = (struct ADE7912_BrushRead_Data *)malloc(sizeof(struct ADE7912_BrushRead_Data));
	ade->phasesData[phase]->V1WV = 0;
	ade->phasesData[phase]->V2WV = 0;
	ade->phasesData[phase]->IWV = 0;
	ade->phasesData[phase]->ADC_CRC = 0;
	ade->phasesData[phase]->STATUS0 = 0;
	ade->phasesData[phase]->CNT_SNAPSHOT = 0;
	
	ADE7912_ResetPhase(ade, phase);
	
	ade->version[phase] = ADE7912_ReadADCVersionFromReg(ade, phase);
	
	ADE7912_SetDataUpdateFreq(ade, phase, settings->freq);
	
	ADE7912_SetPwrConverterEnabled(ade, phase, 1);
	
	ADE7912_SetTempEnabled(ade, phase, 0);
	
	ADE7912_SetBandwidth(ade, phase, settings->bandwidth);
	
	ade->tempGain[phase] = settings->bandwidth == BW_3K3HZ ? ADE7912_TEMPGAIN_WITH_3K3_BW : ADE7912_TEMPGAIN_WITH_2K_BW;
	
	ADE7912_SetCLKOUTFunctionality(ade, phase, settings->clkoutFunc);
	
	uint32_t tmp;
	tmp = ADE7912_ReadTemposFromReg(ade, phase) << 11;
	//if (tmp & 0x00040000) tmp = ~(~(tmp - 1) | 0x0007FFFF) + 1;
	ade->tempos[phase] = ADE7912_TEMPGAIN_WITH_3K3_BW * (float)tmp;
	
	ADE7912_EnablePhase(ade, phase);
	
}



void ADE7912_EnablePhase(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	ade->phasesEnable[phase] = 1;
}



void ADE7912_DisablePhase(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	ade->phasesEnable[phase] = 0;
}

void ADE7912_ResetPhase(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	// Software reset start
	uint8_t buf;
	ADE7912_ReadFromReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1);
	
	buf |= ADE7912_CONFIG_BIT_SWRST;
	ADE7912_WriteToReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1);
	
	// Wait for reset finished
	while (1)
	{
		uint8_t buf;
		ADE7912_ReadFromReg(ade, phase, ADE7912_STATUS0_REG_ADDRESS, &buf, 1); 
		
		if (~buf & ADE7912_STATUS0_BIT_RESET_ON) break;
	}
}

uint8_t buf[14];
			uint32_t tmp;

void ADE7912_UpdateData(struct ADE7912_Inst *ade)
{

	
	for(int phase = 0; phase < 4; phase += 1)
	{
		if (ade->phasesEnable[phase])
		{
			ADE7912_ReadFromReg(ade, static_cast<ADE7912_Phases>(phase), ADE7912_BRUSH_READ_MODE, buf, 14);
			

			
			tmp = (buf[0] << 16) | (buf[1] << 8) | buf[2];
			if (tmp > 0x007FFFFF) tmp |= 0xFF000000; 
			ade->phasesData[phase]->IWV = (int32_t)tmp;
			
			tmp = (buf[3] << 16) | (buf[4] << 8) | buf[5];
			if (tmp > 0x007FFFFF) tmp |= 0xFF000000; 
			ade->phasesData[phase]->V1WV = (int32_t)tmp;
			
			tmp = (buf[6] << 16) | (buf[7] << 8) | buf[8];
			if (tmp > 0x007FFFFF) tmp |= 0xFF000000; 
			ade->phasesData[phase]->V2WV = (int32_t)tmp;
			
			ade->phasesData[phase]->ADC_CRC = (buf[9] << 8) | buf[10];
			ade->phasesData[phase]->STATUS0 = buf[11];
			ade->phasesData[phase]->CNT_SNAPSHOT = (buf[12] << 8) | buf[13];
		}
	}
}



int ADE7912_BrrushReadData(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, struct ADE7912_BrushRead_Data *data)
{
	if (ade->phasesEnable[phase]) 
	{
		data->IWV = ade->phasesData[phase]->IWV;
		data->V1WV = ade->phasesData[phase]->V1WV;
		data->V2WV = ade->phasesData[phase]->V2WV;
		data->ADC_CRC = ade->phasesData[phase]->ADC_CRC;
		data->STATUS0 = ade->phasesData[phase]->STATUS0;
		data->CNT_SNAPSHOT = ade->phasesData[phase]->CNT_SNAPSHOT;
		
		return 0;
	} else return 1;
}



void ADE7912_SetDataUpdateFreq(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, enum ADE7912_DataUpdateFreq freq)
{
	
	uint8_t buf;
	ADE7912_ReadFromReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
	
	HAL_Delay(1);
	
	buf &= (uint8_t)~ADE7912_CONFIG_ADC_FREQ;
	switch(freq)
	{
		case F_8KHZ:
			buf |= ADE7912_CONFIG_ADC_FREQ_8K;
		break;
		case F_4KHZ:
			buf |= ADE7912_CONFIG_ADC_FREQ_4K;
		break;
		case F_2KHZ:
			buf |= ADE7912_CONFIG_ADC_FREQ_2K;
		break;
		case F_1KHZ:
			buf |= ADE7912_CONFIG_ADC_FREQ_1K;
		break;
	}
	ADE7912_WriteToReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
}



uint8_t ADE7912_ReadADCVersionFromReg(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	uint8_t buf;
	ADE7912_ReadFromReg(ade, phase, ADE7912_STATUS1_REG_ADDRESS, &buf, 1); 
	
	return buf & ADE7912_STATUS1_BIT_VERSION;
}



uint8_t ADE7912_ReadTemposFromReg(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	uint8_t buf;
	ADE7912_ReadFromReg(ade, phase, ADE7912_TEMPOS_REG_ADDRESS, &buf, 1); 
	
	return buf;
}



void ADE7912_SetPwrConverterEnabled(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, bool enabled)
{
	uint8_t buf;
	ADE7912_ReadFromReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
	
	HAL_Delay(1);
	
	buf &= (uint8_t)~ADE7912_CONFIG_BIT_PWRDWNENB;
	buf |= enabled ? ADE7912_CONFIG_BIT_PWRDWNENB : 0;
	ADE7912_WriteToReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
}



void ADE7912_SetTempEnabled(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, bool enabled)
{
	uint8_t buf;
	ADE7912_ReadFromReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
	
	HAL_Delay(1);
	
	buf &= (uint8_t)~ADE7912_CONFIG_BIT_TEMPENB;
	buf |= enabled ? ADE7912_CONFIG_BIT_TEMPENB : 0;
	ADE7912_WriteToReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
}



void ADE7912_SetBandwidth(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, enum ADE7912_Bandwidths bandwidth)
{
	uint8_t buf;
	ADE7912_ReadFromReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
	
	HAL_Delay(1);
	
	buf &= (uint8_t)~ADE7912_CONFIG_BIT_BW;
	switch(bandwidth)
	{
		case BW_3K3HZ:
			buf |= 0;
		break;
		case BW_2KHZ:
			buf |= ADE7912_CONFIG_BIT_BW;
		break;
	}
	ADE7912_WriteToReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
}



void ADE7912_LockConfigurationRegisters(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	uint8_t buf = 0xCA;
	ADE7912_WriteToReg(ade, phase, ADE7912_LOCK_REG_ADDRESS, &buf, 1); 
}



void ADE7912_UnlockConfigurationRegisters(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	uint8_t buf = 0x9C;
	ADE7912_WriteToReg(ade, phase, ADE7912_LOCK_REG_ADDRESS, &buf, 1); 
}



void ADE7912_SetCLKOUTFunctionality(struct ADE7912_Inst *ade, enum ADE7912_Phases phase, enum ADE7912_CLKOUT_Functionality functionality)
{
	uint8_t buf;
	ADE7912_ReadFromReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
	
	HAL_Delay(1);
	
	buf &= (uint8_t)~ADE7912_CONFIG_BIT_CLKOUTENB;
	switch(functionality)
	{
		case CLKOUT:
			buf |= ADE7912_CONFIG_BIT_CLKOUTENB;
		break;
		case DREADY:
			buf |= 0;
		break;
	}
	ADE7912_WriteToReg(ade, phase, ADE7912_CONFIG_REG_ADDRESS, &buf, 1); 
}



uint8_t ADE7912_GetADCVersion(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	return ade->version[phase];
}



float ADE7912_GetVoltage(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	if (ade->phasesEnable[phase] == 1) 
	{
		return ade->phasesData[phase]->V1WV * ADE7912_VWV_TRANSLATE_COEF;
	} else {
		return 0;
	}
}



float ADE7912_GetCurrent(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	if (ade->phasesEnable[phase] == 1) 
	{
		return ade->phasesData[phase]->IWV * ADE7912_IWV_TRANSLATE_COEF;
	} else {
		return 0;
	}
}



float ADE7912_GetTemp(struct ADE7912_Inst *ade, enum ADE7912_Phases phase)
{
	if (ade->phasesEnable[phase] == 1) 
	{
		return ade->tempGain[phase] * (float)ade->phasesData[phase]->V2WV - ade->tempos[phase] - ADE7912_CONST_TEMPOS;
	} else {
		return 0;
	}
}