<commit_before>// This software is part of OpenMono, see http://developer.openmono.com
// and is available under the MIT license, see LICENSE.txt

#include "act8600_power_system.h"
#include <mono.h>
#include <mbed_error.h>
#include <project.h>

using namespace mono::power;

ACT8600PowerSystem::ACT8600PowerSystem() :
    i2c(NC, NC),
    powerInterrupt(InterruptPin, PullUp)
{
    //powerInterrupt.DeactivateUntilHandled();
    enableFaultMask();
    powerInterrupt.fall<ACT8600PowerSystem>(this, &ACT8600PowerSystem::powerInterruptHandler);
}

uint8_t ACT8600PowerSystem::SystemStatus()
{
    uint8_t data = 0x00;
    if (!readRegister(SYS, &data))
        error("Could not get SystemStatus, I2C failed\n\r");
    
    return data;
}

IPowerSubSystem::ChargeState ACT8600PowerSystem::ChargeStatus()
{
    uint8_t data = 0x00;
    if (!readRegister(APCH_4, &data))
        error("Failed to read APCH 4 register, I2C failed\n\r");
    
    ACTChargeState state = (ACTChargeState) ((data >> 4) & 0x03);

    switch (state) {
        case PRECONDITION:
            return CHARGE_PRECONDITION;
            break;
        case FAST_CHARGE:
            return CHARGE_FAST;
            break;
        case END_OF_CHARGE:
            return CHARGE_ENDED;
            break;
        case SUSPENDED:
            return CHARGE_SUSPENDED;
            break;
        default:
            return UNKNOWN;
            break;
    }
}

bool ACT8600PowerSystem::PowerFencePeriperals()
{
    uint8_t data = 0x00;
    if (!readRegister(REG1_EXT, &data))
    {
        debug("could not read from power chip");
        return false;
    }
    
    debug("REG1: 0x%x\n\r",data);
    return data & ENABLE ? false : true;
}


void ACT8600PowerSystem::powerOffUnused()
{
    bool success = true;
    success &= writeRegister(REG2_EXT, (uint8_t)(0x00 | (~ENABLE)));
    uint8_t reg = 0;
    readRegister(REG2_EXT, &reg);
    debug("reg2: 0x%x\n\r",reg);
    
    success &= writeRegister(REG3_EXT, (uint8_t)(0x00 | (~ENABLE)));
    readRegister(REG3_EXT, &reg);
    debug("reg3: 0x%x\n\r",reg);
    
    success &= writeRegister(REG4_EXT, (uint8_t)(0x00 | (~ENABLE)));
    readRegister(REG4_EXT, &reg);
    debug("reg4: 0x%x\n\r",reg);
    
    success &= writeRegister(REG5_EXT, (uint8_t)(0x00 | (~ENABLE)));
    readRegister(REG5_EXT, &reg);
    debug("reg5: 0x%x\n\r",reg);
    
    success &= writeRegister(REG6_EXT, (uint8_t)(0x00 | (~ENABLE)));
    readRegister(REG6_EXT, &reg);
    debug("reg6: 0x%x\n\r",reg);
    
    success &= writeRegister(REG7_EXT, (uint8_t)(0x00 | (~ENABLE)));
    readRegister(REG7_EXT, &reg);
    debug("reg7: 0x%x\n\r",reg);
    
    success &= writeRegister(REG8_EXT, (uint8_t)(0x00 | (~ENABLE)));
    readRegister(REG8_EXT, &reg);
    debug("reg8: 0x%x\n\r",reg);
    
    readRegister(REG910, &reg);
    debug("reg9: 0x%x\n\r",reg);
    
    readRegister(REG1_EXT, &reg);
    debug("reg1: 0x%x\n\r",reg);
    
    if (!success)
    {
        debug("Failed to set unused power regs!\n\r");
    }
}

void ACT8600PowerSystem::setPowerFence(bool active)
{
    debug("set power fence: %i\n\r",active);
    setPowerFencePeripherals(active);
}

bool ACT8600PowerSystem::IsPowerFenced()
{
    return PowerFencePeriperals();
}

void ACT8600PowerSystem::setPowerFencePeripherals(bool off)
{
    bool success;
    if (off)
        success = writeRegister(REG1_EXT, 0x00 & (~ENABLE));
    else
        success = writeRegister(REG1_EXT, 0x00 | ENABLE);
    
    if (!success)
    {
        debug("failed to set power fence!\n\r");
    }
}

bool ACT8600PowerSystem::setUSBOTGPower(bool on)
{
    writeRegister(OTG, on?ONQ1:0x00);
    uint8_t otg = 0;
    bool ok = readRegister(OTG, &otg);
    
    if (!on && ok)
        return true;
    else if (!on)
        return false;
    
    if (ok && otg & Q1OK)
    {
        return true;
    }
    else
        return false;
}

bool ACT8600PowerSystem::USBOTGPower()
{
    uint8_t otg = 0x00;
    readRegister(OTG, &otg);
    
    return (otg & Q1OK) ? true : false;
}

uint8_t ACT8600PowerSystem::USBOTG()
{
    uint8_t otg = 0x00;
    readRegister(OTG, &otg);
    return otg;
}

/// POWER SYSTEM METHODS

void ACT8600PowerSystem::onSystemPowerOnReset()
{
    //Set output voltage on OUT5 to 3.3V - to power MCU input supply the same as VSYS
    //writeRegister(REG5, VOLTAGE_SELECTION & V3_3);
    powerInterrupt.fall<ACT8600PowerSystem>(this, &ACT8600PowerSystem::powerInterruptHandler);
}

void ACT8600PowerSystem::onSystemEnterSleep()
{
    
}

void ACT8600PowerSystem::onSystemWakeFromSleep()
{
    
}

/// MARK: Protected Methods


void ACT8600PowerSystem::enableFaultMask()
{
    uint8_t data = 0;
    if (!readRegister(REG1_EXT, &data))
    {
        debug("set could not set fault mask");
        return;
    }

    if (!writeRegister(REG1_EXT, data | FAULT_MASK_CONTROL))
    {
        debug("set could not set fault mask 2");
        return;
    }

    readRegister(REG1_EXT, &data);
    debug("REG1 EXT: 0x%X\n\r",data);
}

void ACT8600PowerSystem::powerInterruptHandler()
{

    uint8_t data = 0x00;
    if (!readRegister(REG1_EXT, &data))
    {
        debug("FATAL: could not read from power chip");
        setPowerFence(true);
        return;
    }

    if ((data & ENABLE) != 0 && (data & POWER_OK_STATUS) == 0)
    {
        //there is a fault on 3V3 power rail - turn it off!
        setPowerFence(true);

        // sad weeping beep
        uint8_t orgPeriod = PWM_ReadPeriod();

        for (int i=1; i<256; i++) {<commit_msg>power subsystem less verbose<commit_after>// This software is part of OpenMono, see http://developer.openmono.com
// and is available under the MIT license, see LICENSE.txt

#include "act8600_power_system.h"
#include <mono.h>
#include <mbed_error.h>
#include <project.h>

using namespace mono::power;

ACT8600PowerSystem::ACT8600PowerSystem() :
    i2c(NC, NC),
    powerInterrupt(InterruptPin, PullUp)
{
    enableFaultMask();
    powerInterrupt.fall<ACT8600PowerSystem>(this, &ACT8600PowerSystem::powerInterruptHandler);
}

uint8_t ACT8600PowerSystem::SystemStatus()
{
    uint8_t data = 0x00;
    if (!readRegister(SYS, &data))
        error("Could not get SystemStatus, I2C failed\n\r");
    
    return data;
}

IPowerSubSystem::ChargeState ACT8600PowerSystem::ChargeStatus()
{
    uint8_t data = 0x00;
    if (!readRegister(APCH_4, &data))
        error("Failed to read APCH 4 register, I2C failed\n\r");
    
    ACTChargeState state = (ACTChargeState) ((data >> 4) & 0x03);

    switch (state) {
        case PRECONDITION:
            return CHARGE_PRECONDITION;
            break;
        case FAST_CHARGE:
            return CHARGE_FAST;
            break;
        case END_OF_CHARGE:
            return CHARGE_ENDED;
            break;
        case SUSPENDED:
            return CHARGE_SUSPENDED;
            break;
        default:
            return UNKNOWN;
            break;
    }
}

bool ACT8600PowerSystem::PowerFencePeriperals()
{
    uint8_t data = 0x00;
    if (!readRegister(REG1_EXT, &data))
    {
        debug("could not read from power chip");
        return false;
    }

    return data & ENABLE ? false : true;
}


void ACT8600PowerSystem::powerOffUnused()
{
    bool success = true;
    success &= writeRegister(REG2_EXT, (uint8_t)(0x00 | (~ENABLE)));
    
    success &= writeRegister(REG3_EXT, (uint8_t)(0x00 | (~ENABLE)));
    
    success &= writeRegister(REG4_EXT, (uint8_t)(0x00 | (~ENABLE)));
    
    success &= writeRegister(REG5_EXT, (uint8_t)(0x00 | (~ENABLE)));
    
    success &= writeRegister(REG6_EXT, (uint8_t)(0x00 | (~ENABLE)));
    
    success &= writeRegister(REG7_EXT, (uint8_t)(0x00 | (~ENABLE)));
    
    success &= writeRegister(REG8_EXT, (uint8_t)(0x00 | (~ENABLE)));
    
    if (!success)
    {
        debug("Failed to set unused power regs!\n\r");
    }
}

void ACT8600PowerSystem::setPowerFence(bool active)
{
    setPowerFencePeripherals(active);
}

bool ACT8600PowerSystem::IsPowerFenced()
{
    return PowerFencePeriperals();
}

void ACT8600PowerSystem::setPowerFencePeripherals(bool off)
{
    bool success;
    if (off)
        success = writeRegister(REG1_EXT, 0x00 & (~ENABLE));
    else
        success = writeRegister(REG1_EXT, 0x00 | ENABLE);
    
    if (!success)
    {
        debug("failed to set power fence!\n\r");
    }
}

bool ACT8600PowerSystem::setUSBOTGPower(bool on)
{
    writeRegister(OTG, on?ONQ1:0x00);
    uint8_t otg = 0;
    bool ok = readRegister(OTG, &otg);
    
    if (!on && ok)
        return true;
    else if (!on)
        return false;
    
    if (ok && otg & Q1OK)
    {
        return true;
    }
    else
        return false;
}

bool ACT8600PowerSystem::USBOTGPower()
{
    uint8_t otg = 0x00;
    readRegister(OTG, &otg);
    
    return (otg & Q1OK) ? true : false;
}

uint8_t ACT8600PowerSystem::USBOTG()
{
    uint8_t otg = 0x00;
    readRegister(OTG, &otg);
    return otg;
}

/// MARK: POWER AWARE SYSTEM METHODS

void ACT8600PowerSystem::onSystemPowerOnReset()
{
    //Set output voltage on OUT5 to 3.3V - to power MCU input supply the same as VSYS
    //writeRegister(REG5, VOLTAGE_SELECTION & V3_3);
}

void ACT8600PowerSystem::onSystemEnterSleep()
{
    
}

void ACT8600PowerSystem::onSystemWakeFromSleep()
{
    
}

/// MARK: Protected Methods


void ACT8600PowerSystem::enableFaultMask()
{
    uint8_t data = 0;
    if (!readRegister(REG1_EXT, &data))
    {
        debug("set could not set fault mask");
        return;
    }

    if (!writeRegister(REG1_EXT, data | FAULT_MASK_CONTROL))
    {
        debug("set could not set fault mask 2");
        return;
    }
}

void ACT8600PowerSystem::powerInterruptHandler()
{

    uint8_t data = 0x00;
    if (!readRegister(REG1_EXT, &data))
    {
        debug("FATAL: could not read from power chip");
        setPowerFence(true);
        return;
    }

    if ((data & ENABLE) != 0 && (data & POWER_OK_STATUS) == 0)
    {
        //there is a fault on 3V3 power rail - turn it off!
        setPowerFence(true);

        // sad weeping beep
        uint8_t orgPeriod = PWM_ReadPeriod();

        for (int i=1; i<256; i++) {
{'fraction_non_alphanumeric': 0.12790236157967852, 'fraction_numerical': 0.04167493550307601, 'mean_word_length': 2.8337771015595283, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1646957', 'n_tokens_mistral': 3815, 'n_tokens_neox': 3589, 'n_words': 760}