Three phase bridge control

Dependents:   BLDC_control BLDC_RPM_meter

ThreePhaseBridge.cpp

Committer:
acracan
Date:
2014-07-08
Revision:
1:ba7889accd61
Parent:
0:a129854eb4b6

File content as of revision 1:ba7889accd61:

#include "ThreePhaseBridge.h"

int8_t ThreePhaseBridge::stateOrder[6] =  {3, 1, 5, 4, 6, 2};

ThreePhaseBridge::ThreePhaseBridge(
    PinName sw1PinName, PinName sw2PinName, PinName sw3PinName,
    PinName sw4PinName, PinName sw5PinName, PinName sw6PinName,
    ThreePhaseBridge::ActiveState activeState
) : sw1(sw1PinName), sw3(sw3PinName), sw5(sw5PinName),
    sw2(sw2PinName), sw4(sw4PinName), sw6(sw6PinName),
    activeState(activeState)
{
    highSide[0] = &sw1;
    highSide[1] = &sw3;
    highSide[2] = &sw5;
    lowSide[0] = &sw2;
    lowSide[1] = &sw4;
    lowSide[2] = &sw6;
    switchesState = activeState == ActiveLow ? 63 : 0;
    setSwitchesState(0);
    m_state = 0; stateIndex = 5;
    period(10e-6);
    pulsewidth(15e-6);
}

void ThreePhaseBridge::period(double seconds)
{
    pwmPeriod = seconds;
    pwmPulseWidthOff = activeState == ActiveLow ? pwmPeriod * 1.1 : 0.0;
    sw1.period(seconds);
    sw3.period(seconds);
    sw5.period(seconds);
}

void ThreePhaseBridge::pulsewidth(double seconds)
{
    if (activeState == ActiveHigh)
        pwmPulseWidth = seconds;
    else
        pwmPulseWidth = pwmPeriod - seconds;
    switch (m_state) {
        case 1:
        case 5:
            sw1.pulsewidth(pwmPulseWidth);
        break;
        case 2:
        case 3:
            sw3.pulsewidth(pwmPulseWidth);
        break;
        case 4:
        case 6:
            sw5.pulsewidth(pwmPulseWidth);
        break;
    };        
}
void ThreePhaseBridge::setHighSideSwitchState(int8_t sw, ThreePhaseBridge::SwitchState state)
{
    state == On ? highSide[sw]->pulsewidth(pwmPulseWidth)
                : highSide[sw]->pulsewidth(pwmPulseWidthOff);
}

void ThreePhaseBridge::setLowSideSwitchState(int8_t sw, ThreePhaseBridge::SwitchState state)
{
    state == On ? *lowSide[sw] = (activeState == ActiveLow ? 0 : 1)
                : *lowSide[sw] = (activeState == ActiveLow ? 1 : 0);
}

void ThreePhaseBridge::setSwitchesState(uint8_t newState)
{
    uint8_t turnOff = ~(newState & switchesState) & switchesState;
    uint8_t turnOffLow = turnOff & 7;
    uint8_t turnOffHigh = turnOff >> 3;
    uint8_t turnOn = newState & ~switchesState;
    uint8_t turnOnLow = turnOn & 7;
    uint8_t turnOnHigh = turnOn >> 3;
    for (uint8_t i = 0; i < 3; i++) {
        if (turnOffLow & (1 << i))
            setLowSideSwitchState(i, Off);
        if (turnOffHigh & (1 << i))
            setHighSideSwitchState(i, Off);
    }
    for (uint8_t i = 0; i < 3; i++) {
        if (turnOnLow & (1 << i))
        {
            setLowSideSwitchState(i, On);
        }
        if (turnOnHigh & (1 << i))
            setHighSideSwitchState(i, On);        
    }
    switchesState = newState;
}
    
void ThreePhaseBridge::setState(int8_t newState)
{
    switch (newState) {
        case 1:
            setSwitchesState(SW1 | SW6);
        break;
        case 2:
            setSwitchesState(SW3 | SW2);
        break;
        case 3:
            setSwitchesState(SW3 | SW6);
        break;
        case 4:
            setSwitchesState(SW5 | SW4);
        break;
        case 5:
            setSwitchesState(SW1 | SW4);
        break;
        case 6:
            setSwitchesState(SW5 | SW2);
        break;
        default:
            setSwitchesState(0);
        break;
    }
    m_state = newState;
}

void ThreePhaseBridge::spin(ThreePhaseBridge::SpinDirection dir)
{
    stateIndex = (6 + stateIndex + dir) % 6;
    setState(stateOrder[stateIndex]);        
}

void ThreePhaseBridge::stop()
{
    setState(0);
}

void ThreePhaseBridge::overflow(void (*fptr)(void))
{
    if (fptr) {
        NVIC_SetVector(TPM0_IRQn, (uint32_t)fptr);
        NVIC_EnableIRQ(TPM0_IRQn);
    }
}