adc

Dependents:   h7adc

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;
    }
}