adc
ADE7912.cpp
- Committer:
- yuliyasm
- Date:
- 2020-10-27
- Revision:
- 2:f480200c8600
- Child:
- 3:1d62b3be52e8
File content as of revision 2:f480200c8600:
#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; } }