adc

Dependents:   h7adc

Revision:
2:f480200c8600
Child:
3:1d62b3be52e8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADE7912.cpp	Tue Oct 27 13:23:41 2020 +0000
@@ -0,0 +1,419 @@
+#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)
+{
+    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;
+    }
+}
+
+
+
+void ADE7912_UpdateData(struct ADE7912_Inst *ade)
+{
+    uint8_t buf[14];
+
+    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);
+
+            uint32_t tmp;
+
+            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;
+    }
+}
+
+
+