FastPWM clone

Device/FastPWM_KSDK.cpp

Committer:
blaze
Date:
2019-10-30
Revision:
35:d6c2b73d71f5
Parent:
33:2ca2e47f9650

File content as of revision 35:d6c2b73d71f5:

#if defined(TARGET_KPSDK_MCUS)

#include "FastPWM.h"
#include "fsl_ftm.h"


#define PWM_CNV              (*(((fastpwm_struct*)fast_obj)->CnV))  
#define PWM_MOD              (*(((fastpwm_struct*)fast_obj)->MOD))  
#define PWM_SC               (*(((fastpwm_struct*)fast_obj)->SC))  
#define PWM_SYNC             (*(((fastpwm_struct*)fast_obj)->SYNC))  

typedef struct  {
    __IO uint32_t *CnV;
    __IO uint32_t *MOD;
    __IO uint32_t *SC;
    __IO uint32_t *SYNC;
} fastpwm_struct;

static uint32_t pwm_prescaler;
static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS;

void FastPWM::initFastPWM( void ) {
    fast_obj = malloc(sizeof(fastpwm_struct));
    bits = 16;

    pwm_prescaler = SystemCoreClock / CLOCK_GetFreq(kCLOCK_BusClk);;

    unsigned int ch_n = (_pwm.pwm_name & 0xF);
    FTM_Type *ftm = ftm_addrs[_pwm.pwm_name >> TPM_SHIFT];
    
    ((fastpwm_struct*)fast_obj)->CnV = &ftm->CONTROLS[ch_n].CnV;
    ((fastpwm_struct*)fast_obj)->MOD = &ftm->MOD;
    ((fastpwm_struct*)fast_obj)->SC = &ftm->SC;
    ((fastpwm_struct*)fast_obj)->SYNC = &ftm->SYNC;
    
    //Do not clear counter when writing new value, set end of period as loading value
    ftm->SYNCONF &= ~FTM_SYNCONF_SWRSTCNT_MASK;
    ftm->SYNC |= FTM_SYNC_CNTMAX_MASK;
}

void FastPWM::pulsewidth_ticks( uint32_t ticks ) {
    PWM_CNV = ticks;
    PWM_SYNC |= FTM_SYNC_SWSYNC_MASK;
}

void FastPWM::period_ticks( uint32_t ticks ) {
    PWM_MOD = ticks - 1;
    PWM_SYNC |= FTM_SYNC_SWSYNC_MASK;  
}

uint32_t FastPWM::getPeriod( void ) {
    return PWM_MOD + 1;
}

uint32_t FastPWM::setPrescaler(uint32_t reqScale) {
 
    uint32_t prescalers[] = {1, 2, 4, 8, 16, 32, 64, 128};
    
    for (int i = 0; i<8; i++)
         prescalers[i] = prescalers[i] * pwm_prescaler;
    
    //If prescaler is 0, return current one
    if (reqScale == 0)
        return (prescalers[(PWM_SC) & 0x07]);
    
    uint32_t retval = 0;
    char bin;
    
    for (bin = 0; bin<8; bin++) {
        retval = prescalers[bin];
        if (retval >= reqScale)
            break;
    }
    if (bin == 8)
        bin = 7;
    
    //Clear lower 5 bits, write new value:
    char clockbits = PWM_SC & (3<<3);
    
    //For some reason clearing them takes some effort
    while ((PWM_SC & 0x1F) != 0)
        PWM_SC &= ~0x1F;
        
    
    PWM_SC = bin + clockbits;
    return retval;   
}
#endif