adc
Diff: ADE7912.cpp
- Revision:
- 2:f480200c8600
- Child:
- 3:1d62b3be52e8
diff -r 5796bdddf29c -r f480200c8600 ADE7912.cpp --- /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; + } +} + + +