LPS mod

lib_L6470DC.cpp

Committer:
jsanchez
Date:
2022-05-02
Revision:
7:2ff9788e2827
Parent:
6:7ca2eef852fd

File content as of revision 7:2ff9788e2827:

#include "mbed.h"
#include "lib_L6470DC.h"

////////////////////////////////////////////////////////////////////////////////
//                              CONSTRUCTOR                                   //
////////////////////////////////////////////////////////////////////////////////

L6470DC::L6470DC(int nMax, PinName mosi, PinName miso, PinName sclk, PinName cs):m_spi(mosi, miso, sclk),m_cs(cs), nMotMax(nMax)
{
    m_cs = 1;
    m_spi.format(8,3);
    m_spi.frequency(5000000);
}

////////////////////////////////////////////////////////////////////////////////
//                              BASICS_FUNC                                   //
////////////////////////////////////////////////////////////////////////////////

unsigned char L6470DC::send(unsigned char nMOT,unsigned char temp)
{
    unsigned char temp0;
    int i;
    m_cs = 0;
    for (i = nMotMax - 1; i >= 0; i--) {
        if(i==nMOT) temp =(unsigned char) m_spi.write(temp);
        else temp0 =(unsigned char) m_spi.write(0x00);
    }

    m_cs = 1;
    wait_us(1);
    return(temp);
}

void L6470DC::send_bytes(unsigned char nMOT,unsigned char temp[],int i)
{
    while(0 < i--) {
        temp[i] = send(nMOT,temp[i]);
    }
}

void L6470DC::NOP(unsigned char nMOT)
{
    send(nMOT,0x00);
}

void L6470DC::SetParam(unsigned char nMOT,L6470_Register param,int value)
{
    int length,address;

    switch(param) {
        case ABS_POS:
            length  = LEN_ABS_POS;
            address = ADD_ABS_POS;
            break;
        case EL_POS:
            length  = LEN_EL_POS;
            address = ADD_EL_POS;
            break;
        case MARK:
            length  = LEN_MARK;
            address = ADD_MARK;
            break;
        case SPEED:
            length  = LEN_SPEED;
            address = ADD_SPEED;
            break;
        case ACC:
            length  = LEN_ACC;
            address = ADD_ACC;
            break;
        case DEC:
            length  = LEN_DEC;
            address = ADD_DEC;
            break;
        case MAX_SPEED:
            length  = LEN_MAX_SPEED;
            address = ADD_MAX_SPEED;
            break;
        case MIN_SPEED:
            length  = LEN_MIN_SPEED;
            address = ADD_MIN_SPEED;
            break;
        case KVAL_HOLD:
            length  = LEN_KVAL_HOLD;
            address = ADD_KVAL_HOLD;
            break;
        case KVAL_RUN:
            length  = LEN_KVAL_RUN;
            address = ADD_KVAL_RUN;
            break;
        case KVAL_ACC:
            length  = LEN_KVAL_ACC;
            address = ADD_KVAL_ACC;
            break;
        case KVAL_DEC:
            length  = LEN_KVAL_DEC;
            address = ADD_KVAL_DEC;
            break;
        case INT_SPD:
            length  = LEN_INT_SPD;
            address = ADD_INT_SPD;
            break;
        case ST_SLP:
            length  = LEN_ST_SLP;
            address = ADD_ST_SLP;
            break;
        case FN_SLP_ACC:
            length  = LEN_FN_SLP_ACC;
            address = ADD_FN_SLP_ACC;
            break;
        case FN_SLP_DEC:
            length  = LEN_FN_SLP_DEC;
            address = ADD_FN_SLP_DEC;
            break;
        case K_THERA:
            length  = LEN_K_THERA;
            address = ADD_K_THERA;
            break;
        case ADC_OUT:
            length  = LEN_ADC_OUT;
            address = ADD_ADC_OUT;
            break;
        case OCR_TH:
            length  = LEN_OCR_TH;
            address = ADD_OCR_TH;
            break;
        case STALL_TH:
            length  = LEN_STALL_TH;
            address = ADD_STALL_TH;
            break;
        case FS_SPD:
            length  = LEN_FS_SPD;
            address = ADD_FS_SPD;
            break;
        case STEP_MODE:
            length  = LEN_STEP_MODE;
            address = ADD_STEP_MODE;
            break;
        case ARARM_FN:
            length  = LEN_ARARM_FN;
            address = ADD_ARARM_FN;
            break;
        case CONFIG:
            length  = LEN_CONFIG;
            address = ADD_CONFIG;
            break;
        case STATUS:
            length  = LEN_STATUS;
            address = ADD_STATUS;
            break;
        default:
            length  = 0;
            address = 0;
            break;

    }

    int n = length/8;
    int m = length%8;
    if(m==0) {
        unsigned char temp[n+1];
        temp[n] = 0x00|(unsigned char)(address);
        while(0 < n--) {
            temp[n]=(unsigned char) (value >> 8*n)&0xFF;
        }
        send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
    } else {
        unsigned char temp[n+2];
        temp[n+1] = 0x00|(unsigned char)(address);
        temp[n] =(unsigned char) (value >> 8*n)&~(0xff<<m);
        while(0 < n--) {
            temp[n]=(unsigned char) (value >> 8*n)&0xFF;
        }
        send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
    }
}

int L6470DC::GetParam(unsigned char nMOT,L6470_Register param)
{
    int value = 0;
    int length,address;
    switch(param) {
        case ABS_POS:
            length  = LEN_ABS_POS;
            address = ADD_ABS_POS;
            break;
        case EL_POS:
            length  = LEN_EL_POS;
            address = ADD_EL_POS;
            break;
        case MARK:
            length  = LEN_MARK;
            address = ADD_MARK;
            break;
        case SPEED:
            length  = LEN_SPEED;
            address = ADD_SPEED;
            break;
        case ACC:
            length  = LEN_ACC;
            address = ADD_ACC;
            break;
        case DEC:
            length  = LEN_DEC;
            address = ADD_DEC;
            break;
        case MAX_SPEED:
            length  = LEN_MAX_SPEED;
            address = ADD_MAX_SPEED;
            break;
        case MIN_SPEED:
            length  = LEN_MIN_SPEED;
            address = ADD_MIN_SPEED;
            break;
        case KVAL_HOLD:
            length  = LEN_KVAL_HOLD;
            address = ADD_KVAL_HOLD;
            break;
        case KVAL_RUN:
            length  = LEN_KVAL_RUN;
            address = ADD_KVAL_RUN;
            break;
        case KVAL_ACC:
            length  = LEN_KVAL_ACC;
            address = ADD_KVAL_ACC;
            break;
        case KVAL_DEC:
            length  = LEN_KVAL_DEC;
            address = ADD_KVAL_DEC;
            break;
        case INT_SPD:
            length  = LEN_INT_SPD;
            address = ADD_INT_SPD;
            break;
        case ST_SLP:
            length  = LEN_ST_SLP;
            address = ADD_ST_SLP;
            break;
        case FN_SLP_ACC:
            length  = LEN_FN_SLP_ACC;
            address = ADD_FN_SLP_ACC;
            break;
        case FN_SLP_DEC:
            length  = LEN_FN_SLP_DEC;
            address = ADD_FN_SLP_DEC;
            break;
        case K_THERA:
            length  = LEN_K_THERA;
            address = ADD_K_THERA;
            break;
        case ADC_OUT:
            length  = LEN_ADC_OUT;
            address = ADD_ADC_OUT;
            break;
        case OCR_TH:
            length  = LEN_OCR_TH;
            address = ADD_OCR_TH;
            break;
        case STALL_TH:
            length  = LEN_STALL_TH;
            address = ADD_STALL_TH;
            break;
        case FS_SPD:
            length  = LEN_FS_SPD;
            address = ADD_FS_SPD;
            break;
        case STEP_MODE:
            length  = LEN_STEP_MODE;
            address = ADD_STEP_MODE;
            break;
        case ARARM_FN:
            length  = LEN_ARARM_FN;
            address = ADD_ARARM_FN;
            break;
        case CONFIG:
            length  = LEN_CONFIG;
            address = ADD_CONFIG;
            break;
        case STATUS:
            length  = LEN_STATUS;
            address = ADD_STATUS;
            break;
        default:
            length  = 0;
            address = 0;
            break;

    }

    int n = length/8;
    int m = length%8;
    if(m==0) {
        unsigned char temp[n+1];
        for(int i = 0; i < n+1; i++) {
            temp[i]=0;
        }
        temp[n] = 0x20|(unsigned char)(address);
        send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
        while(0 < n--) {
            value |= (int)temp[n] << 8*n;
        }
    } else {
        n++;
        unsigned char temp[n+1];
        for(int i = 0; i < n+2; i++) {
            temp[i]=0;
        }
        temp[n] = 0x20|(unsigned char)(address);
        send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
        while(0 < n--) {
            value |= (int)temp[n] << 8*n;
        }
    }

    return(value);
}



void L6470DC::Run(unsigned char nMOT,unsigned char dir,float spd)
{
    unsigned char temp[4];
    int tmp_spd = L6470_Step_s_2_Speed(spd);
    temp[3] = 0x50|dir;
    temp[2] = (unsigned char) (tmp_spd >> 16)&0x0F;
    temp[1] = (unsigned char) (tmp_spd >>  8)&0xFF;
    temp[0] = (unsigned char) (tmp_spd >>  0)&0xFF;
    send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
}

void L6470DC::StepClock(unsigned char nMOT,unsigned char dir)
{
    send(nMOT,0x58|dir);
}

void L6470DC::Move(unsigned char nMOT,unsigned char dir,int n_step)
{
    unsigned char temp[4];
    temp[3] = 0x40|dir;
    temp[2] = (unsigned char) (n_step >> 16)&0x3F;
    temp[1] = (unsigned char) (n_step >>  8)&0xFF;
    temp[0] = (unsigned char) (n_step >>  0)&0xFF;
    send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
}

void L6470DC::GoTo(unsigned char nMOT,int abs_pos)
{
    unsigned char temp[4];
    temp[3] = 0x60;
    temp[2] = (unsigned char) (abs_pos >> 16)&0x3F;
    temp[1] = (unsigned char) (abs_pos >>  8)&0xFF;
    temp[0] = (unsigned char) (abs_pos >>  0)&0xFF;
    send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
}

void L6470DC::GoTo_DIR(unsigned char nMOT,unsigned char dir,int abs_pos)
{
    unsigned char temp[4];
    temp[3] = 0x68|dir;
    temp[2] = (unsigned char) (abs_pos >> 16)&0x3F;
    temp[1] = (unsigned char) (abs_pos >>  8)&0xFF;
    temp[0] = (unsigned char) (abs_pos >>  0)&0xFF;
    send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
}

void L6470DC::GoUntil(unsigned char nMOT,unsigned char act,unsigned char dir,int spd)
{
    unsigned char temp[4];
    temp[3] = 0x82|(act << 3)|dir;
    temp[2] = (unsigned char) (spd >> 16)&0x0F;
    temp[1] = (unsigned char) (spd >>  8)&0xFF;
    temp[0] = (unsigned char) (spd >>  0)&0xFF;
    send_bytes(nMOT,temp,sizeof temp/sizeof temp[0]);
}

void L6470DC::ReleaseSW(unsigned char nMOT,unsigned char act,unsigned char dir)
{
    send(nMOT,0x92|(act << 3)|dir);
}

void L6470DC::GoHome(unsigned char nMOT)
{
    send(nMOT,0x70);
}

void L6470DC::GoMark(unsigned char nMOT)
{
    send(nMOT,0x78);
}

void L6470DC::ResetPos(unsigned char nMOT)
{
    send(nMOT,0xD8);
}

void L6470DC::ResetDevice(unsigned char nMOT)
{
    send(nMOT,0xC0);
}

void L6470DC::SoftStop(unsigned char nMOT)
{
    send(nMOT,0xB0);
}

void L6470DC::HardStop(unsigned char nMOT)
{
    send(nMOT,0xB8);
}


void L6470DC::SoftHiZ(unsigned char nMOT)
{
    send(nMOT,0xA0);
}

void L6470DC::HardHiZ(unsigned char nMOT)
{
    send(nMOT,0xA8);
}

////////////////////////////////////////////////////////////////////////////////
//                             ADVANCED_FUNC                                  //
////////////////////////////////////////////////////////////////////////////////

void L6470DC::Config(unsigned char nMOT, L6470_MotorConf *conf)
{
    L6470_MotorConf *MotorParameterData = (L6470_MotorConf *) conf;
    StepperMotorRegister MotorRegister;

    ResetDevice(nMOT);

    MotorRegister.ACC = L6470_Step_s2_2_Acc(MotorParameterData->acc);
    MotorRegister.DEC = L6470_Step_s2_2_Dec(MotorParameterData->dec);
    MotorRegister.MAX_SPEED = L6470_Step_s_2_MaxSpeed(MotorParameterData->maxspeed);
    MotorRegister.MIN_SPEED = L6470_Step_s_2_MinSpeed(MotorParameterData->minspeed);
    MotorRegister.FS_SPD = L6470_Step_s_2_FsSpd(MotorParameterData->fsspd);
    MotorRegister.KVAL_HOLD = (uint8_t)((float)((float)(MotorParameterData->kvalhold * 256) / (MotorParameterData->motorvoltage)));
    MotorRegister.KVAL_RUN = (uint8_t)((float)((float)(MotorParameterData->kvalrun * 256) / (MotorParameterData->motorvoltage)));
    MotorRegister.KVAL_ACC = (uint8_t)((float)((float)(MotorParameterData->kvalacc * 256) / (MotorParameterData->motorvoltage)));
    MotorRegister.KVAL_DEC = (uint8_t)((float)((float)(MotorParameterData->kvaldec * 256) / (MotorParameterData->motorvoltage)));
    MotorRegister.INT_SPEED = L6470_Step_s_2_IntSpeed(MotorParameterData->intspeed);
    MotorRegister.ST_SLP = L6470_s_Step_2_StSlp(MotorParameterData->stslp);
    MotorRegister.FN_SLP_ACC = L6470_s_Step_2_FnSlpAcc(MotorParameterData->fnslpacc);
    MotorRegister.FN_SLP_DEC = L6470_s_Step_2_FnSlpDec(MotorParameterData->fnslpdec);
    MotorRegister.K_THERM = MotorParameterData->kterm;
    MotorRegister.OCD_TH = L6470_mA_2_OcdTh(MotorParameterData->ocdth);
    MotorRegister.STALL_TH = L6470_mA_2_StallTh(MotorParameterData->stallth);
    MotorRegister.ALARM_EN = MotorParameterData->alarmen;
    MotorRegister.CONFIG = MotorParameterData->config;
    MotorRegister.STEP_MODE = MotorParameterData->step_sel;

    /* Write the L6470 registers with the prepared data */
    SetParam(nMOT, ACC, MotorRegister.ACC);
    SetParam(nMOT, DEC, MotorRegister.DEC);
    SetParam(nMOT, MAX_SPEED, MotorRegister.MAX_SPEED);
    SetParam(nMOT, MIN_SPEED, MotorRegister.MIN_SPEED);
    SetParam(nMOT, FS_SPD, MotorRegister.FS_SPD);
    SetParam(nMOT, KVAL_HOLD, MotorRegister.KVAL_HOLD);
    SetParam(nMOT, KVAL_RUN, MotorRegister.KVAL_RUN);
    SetParam(nMOT, KVAL_ACC, MotorRegister.KVAL_ACC);
    SetParam(nMOT, KVAL_DEC, MotorRegister.KVAL_DEC);
    SetParam(nMOT, INT_SPD, MotorRegister.INT_SPEED);
    SetParam(nMOT, ST_SLP, MotorRegister.ST_SLP);
    SetParam(nMOT, FN_SLP_ACC, MotorRegister.FN_SLP_ACC);
    SetParam(nMOT, FN_SLP_DEC, MotorRegister.FN_SLP_DEC);
    SetParam(nMOT, K_THERA, MotorRegister.K_THERM);
    SetParam(nMOT, OCR_TH, MotorRegister.OCD_TH);
    SetParam(nMOT, STALL_TH, MotorRegister.STALL_TH);
    SetParam(nMOT, STEP_MODE, MotorRegister.STEP_MODE);
    SetParam(nMOT, ARARM_FN, MotorRegister.ALARM_EN);
    SetParam(nMOT, CONFIG, MotorRegister.CONFIG);
}

////////////////////////////////////////////////////////////////////////////////

int L6470DC::GetPosition(int nMOT)
{
    return L6470_AbsPos_2_Position(GetParam(nMOT, ABS_POS));
}

int L6470DC::GetMark(int nMOT)
{
    return L6470_AbsPos_2_Position(GetParam(nMOT, MARK));
}

int L6470DC::GetSpeed(int nMOT)
{
    return L6470_Speed_2_Step_s(GetParam(nMOT, SPEED));
}

int L6470DC::GetStatus(int nMOT, FlagId_t FlagId)
{
    int status = GetParam(nMOT, STATUS);
    int ack = -1;

    switch(FlagId) {
        case MOT_STATUS_ID:
            ack = status & (3 << MOT_STATUS_ID);
            return ack >> MOT_STATUS_ID;
            break;

        default :
            ack = status & (1 << FlagId);
            return ack >> FlagId;
            break;
    }
}

void L6470DC::SetHome(int nMOT)
{
    ResetPos(nMOT);
}

void L6470DC::SetMaxSpeed(int nMOT, int speed)
{
    SetParam(nMOT, MAX_SPEED, L6470_Step_s_2_MaxSpeed(speed));
}

void L6470DC::SetMark(int nMOT, int mark)
{
    SetParam(nMOT, MARK, L6470_Position_2_AbsPos(mark));
}


////////////////////////////////////////////////////////////////////////////////
//                              CONVERSIONS                                   //
////////////////////////////////////////////////////////////////////////////////

int32_t L6470DC::L6470_AbsPos_2_Position(uint32_t AbsPos)
{

    if (AbsPos > L6470_MAX_POSITION)
        return (AbsPos - (L6470_POSITION_RANGE + 1));
    else

        return AbsPos;
}

uint32_t L6470DC::L6470_Position_2_AbsPos(int32_t Position)
{
    if ((Position >= 0) && (Position <= L6470_MAX_POSITION))
        return Position;
    else {
        if ((Position >= L6470_MIN_POSITION) && (Position < 0))
            return (Position + (L6470_POSITION_RANGE + 1));
        else
            return (L6470_POSITION_RANGE + 1);        // OVF
    }
}

float L6470DC::L6470_Speed_2_Step_s(uint32_t Speed)
{
    return (Speed * ((float)14.9012e-3));
}

uint32_t L6470DC::L6470_Step_s_2_Speed(float Step_s)
{
    //if (Step_s <= (L6470_MAX_SPEED * ((float)14.9012e-3)))
    return (uint32_t)(Step_s / ((float)14.9012e-3));
    //else
    //return 0;
}

float L6470DC::L6470_Acc_2_Step_s2(uint16_t Acc)
{
    if (Acc <= L6470_MAX_ACC)
        return (Acc * ((float)1.4552e1));
    else
        return 0;
}

uint16_t L6470DC::L6470_Step_s2_2_Acc(float Step_s2)
{
    if (Step_s2 <= (L6470_MAX_ACC * ((float)1.4552e1)))
        return (uint16_t)(Step_s2 / ((float)1.4552e1));
    else
        return 0;
}

float L6470DC::L6470_Dec_2_Step_s2(uint16_t Dec)
{
    if (Dec <= L6470_MAX_DEC)
        return (Dec * ((float)1.4552e1));
    else
        return 0;
}

uint16_t L6470DC::L6470_Step_s2_2_Dec(float Step_s2)
{
    if (Step_s2 <= (L6470_MAX_DEC * ((float)1.4552e1)))
        return (uint16_t)(Step_s2 / ((float)1.4552e1));
    else
        return 0;
}

float L6470DC::L6470_MaxSpeed_2_Step_s(uint16_t MaxSpeed)
{
    if (MaxSpeed <= L6470_MAX_MAX_SPEED)
        return (MaxSpeed * ((float)15.2588));
    else
        return 0;
}

uint16_t L6470DC::L6470_Step_s_2_MaxSpeed(float Step_s)
{
    if (Step_s <= (L6470_MAX_MAX_SPEED * ((float)15.2588)))
        return (uint16_t)(Step_s / ((float)15.2588));
    else
        return 0;
}

float L6470DC::L6470_MinSpeed_2_Step_s(uint16_t MinSpeed)
{
    if (MinSpeed <= L6470_MAX_MIN_SPEED)
        return (MinSpeed * ((float)238.4186e-3));
    else
        return 0;
}

uint16_t L6470DC::L6470_Step_s_2_MinSpeed(float Step_s)
{
    if (Step_s <= (L6470_MAX_MIN_SPEED * ((float)238.4186e-3)))
        return (uint16_t)(Step_s / ((float)238.4186e-3));
    else
        return 0;
}

float L6470DC::L6470_FsSpd_2_Step_s(uint16_t FsSpd)
{
    if (FsSpd <= L6470_MAX_FS_SPD)
        return ((FsSpd+0.5) * ((float)15.25));
    else
        return 0;
}

uint16_t L6470DC::L6470_Step_s_2_FsSpd(float Step_s)
{
    if (Step_s <= ((L6470_MAX_FS_SPD+0.5) * ((float)15.25)))
        return (uint16_t)((float)(Step_s / ((float)15.25)) - (float)0.5);
    else
        return 0;
}

float L6470DC::L6470_IntSpeed_2_Step_s(uint16_t IntSpeed)
{
    if (IntSpeed <= L6470_MAX_INT_SPEED)
        return (IntSpeed * ((float)59.6046e-3));
    else
        return 0;
}

uint16_t L6470DC::L6470_Step_s_2_IntSpeed(float Step_s)
{
    if (Step_s <= (L6470_MAX_INT_SPEED * ((float)59.6046e-3)))
        return (uint16_t)(Step_s / ((float)59.6046e-3));
    else
        return 0;
}

float L6470DC::L6470_StSlp_2_s_Step(uint8_t StSlp)
{
    return (StSlp * ((float)1.5686e-5));
}

uint8_t L6470DC::L6470_s_Step_2_StSlp(float s_Step)
{
    if (s_Step <= (L6470_MAX_ST_SLP * ((float)1.5686e-5)))
        return (uint8_t)(s_Step / ((float)1.5686e-5));
    else
        return 0;
}

float L6470DC::L6470_FnSlpAcc_2_s_Step(uint8_t FnSlpAcc)
{
    return (FnSlpAcc * ((float)1.5686e-5));
}

uint8_t L6470DC::L6470_s_Step_2_FnSlpAcc(float s_Step)
{
    if (s_Step <= (L6470_MAX_FN_SLP_ACC * ((float)1.5686e-5)))
        return (uint8_t)(s_Step / ((float)1.5686e-5));
    else
        return 0;
}

float L6470DC::L6470_FnSlpDec_2_s_Step(uint8_t FnSlpDec)
{
    return (FnSlpDec * ((float)1.5686e-5));
}


uint8_t L6470DC::L6470_s_Step_2_FnSlpDec(float s_Step)
{
    if (s_Step <= (L6470_MAX_FN_SLP_DEC * ((float)1.5686e-5)))
        return (uint8_t)(s_Step / ((float)1.5686e-5));
    else
        return 0;
}

float L6470DC::L6470_OcdTh_2_mA(uint8_t OcdTh)
{
    if (OcdTh <= L6470_MAX_OCD_TH)
        return ((OcdTh+1) * ((float)375));
    else
        return 0;
}

uint8_t L6470DC::L6470_mA_2_OcdTh(float mA)
{
    float result, decimal;

    if (mA <= ((L6470_MAX_OCD_TH+1) * ((float)375))) {
        result = (mA / ((float)375));
        decimal = result - (uint8_t)result;

        if (decimal < (float)0.5)
            return ((uint8_t)result - 1);
        else
            return ((uint8_t)result);
    } else
        return 0;
}

float L6470DC::L6470_StallTh_2_mA(uint8_t StallTh)
{
    if (StallTh <= L6470_MAX_STALL_TH)
        return ((StallTh+1) * ((float)31.25));
    else
        return 0;   // Warning
}

uint8_t L6470DC::L6470_mA_2_StallTh(float mA)
{
    float result, decimal;

    if (mA <= ((L6470_MAX_STALL_TH+1) * ((float)31.25))) {
        result = (mA / ((float)31.25));
        decimal = result - (uint8_t)result;

        if (decimal < (float)0.5)
            return ((uint8_t)result - 1);
        else
            return ((uint8_t)result);
    } else
        return 0;
}