Beispiel #1
0
//=========================================================================
__myevic__ void SetPWMClock()
{
	uint32_t clk;

	if ( gFlags.pwm_pll )
	{
		clk = CLK_CLKSEL2_PWM0SEL_PLL;
		PWMCycles = CLK_GetPLLClockFreq() / BBC_PWM_FREQ;
	}
	else
	{
		clk = CLK_CLKSEL2_PWM0SEL_PCLK0;
		PWMCycles = CLK_GetPCLK0Freq() / BBC_PWM_FREQ;
	}

	MaxDuty		= PWMCycles - 1;
	MinBuck		= PWMCycles / 48;
	MaxBoost	= PWMCycles / 12;
	ProbeDuty	= PWMCycles / 8;
	BoostWindow	= PWMCycles / 19;

#define MaxBuck  MaxDuty
#define MinBoost MaxDuty

	if ( ISCUBO200 || ISRX200S || ISRX23 || ISRX300 )
	{
		MaxDuty = 95 * PWMCycles / 100;
	}

	CLK_EnableModuleClock( PWM0_MODULE );
	CLK_SetModuleClock( PWM0_MODULE, clk, 0 );
	SYS_ResetModule( PWM0_RST );
}
Beispiel #2
0
/**
  * @brief  This function make USCI_SPI module be ready to transfer.
  *         By default, the USCI_SPI transfer sequence is MSB first, the slave selection
  *         signal is active low and the automatic slave select function is disabled. In
  *         Slave mode, the u32BusClock must be NULL and the USCI_SPI clock
  *         divider setting will be 0.
  * @param[in]  uspi The pointer of the specified USCI_SPI module.
  * @param[in]  u32MasterSlave Decide the USCI_SPI module is operating in master mode or in slave mode. Valid values are:
  *                    - \ref USPI_SLAVE
  *                    - \ref USPI_MASTER
  * @param[in]  u32SPIMode Decide the transfer timing. Valid values are:
  *                    - \ref USPI_MODE_0
  *                    - \ref USPI_MODE_1
  *                    - \ref USPI_MODE_2
  *                    - \ref USPI_MODE_3
  * @param[in]  u32DataWidth The data width of a USCI_SPI transaction.
  * @param[in]  u32BusClock The expected frequency of USCI_SPI bus clock in Hz.
  * @return Actual frequency of USCI_SPI peripheral clock.
  */
uint32_t USPI_Open(USPI_T *uspi, uint32_t u32MasterSlave, uint32_t u32SPIMode,  uint32_t u32DataWidth, uint32_t u32BusClock)
{
    uint32_t u32ClkDiv = 0ul;
    uint32_t u32Pclk;
    uint32_t u32UspiClk = 0ul;

    if(uspi == (USPI_T *)USPI0) {
        u32Pclk = CLK_GetPCLK0Freq();
    } else {
        u32Pclk = CLK_GetPCLK1Freq();
    }

    if(u32BusClock != 0ul) {
        u32ClkDiv = (uint32_t) ((((((u32Pclk/2ul)*10ul)/(u32BusClock))+5ul)/10ul)-1ul); /* Compute proper divider for USCI_SPI clock */
    } else {}

    /* Enable USCI_SPI protocol */
    uspi->CTL &= ~USPI_CTL_FUNMODE_Msk;
    uspi->CTL = 1ul << USPI_CTL_FUNMODE_Pos;

    /* Data format configuration */
    if(u32DataWidth == 16ul) {
        u32DataWidth = 0ul;
    } else {}
    uspi->LINECTL &= ~USPI_LINECTL_DWIDTH_Msk;
    uspi->LINECTL |= (u32DataWidth << USPI_LINECTL_DWIDTH_Pos);

    /* MSB data format */
    uspi->LINECTL &= ~USPI_LINECTL_LSB_Msk;

    /* Set slave selection signal active low */
    if(u32MasterSlave == USPI_MASTER) {
        uspi->LINECTL |= USPI_LINECTL_CTLOINV_Msk;
    } else {
        uspi->CTLIN0 |= USPI_CTLIN0_ININV_Msk;
    }

    /* Set operating mode and transfer timing */
    uspi->PROTCTL &= ~(USPI_PROTCTL_SCLKMODE_Msk | USPI_PROTCTL_AUTOSS_Msk | USPI_PROTCTL_SLAVE_Msk);
    uspi->PROTCTL |= (u32MasterSlave | u32SPIMode);

    /* Set USCI_SPI bus clock */
    uspi->BRGEN &= ~USPI_BRGEN_CLKDIV_Msk;
    uspi->BRGEN |=  (u32ClkDiv << USPI_BRGEN_CLKDIV_Pos);
    uspi->PROTCTL |=  USPI_PROTCTL_PROTEN_Msk;

    if(u32BusClock != 0ul) {
        u32UspiClk = (uint32_t)( u32Pclk / ((u32ClkDiv+1ul)<<1) );
    } else {}

    return u32UspiClk;
}
Beispiel #3
0
/**
  * @brief Get the actual frequency of USCI_SPI bus clock. Only available in Master mode.
  * @param[in]  uspi The pointer of the specified USCI_SPI module.
  * @return Actual USCI_SPI bus clock frequency.
  */
uint32_t USPI_GetBusClock(USPI_T *uspi)
{
    uint32_t u32BusClk;
    uint32_t u32ClkDiv;

    u32ClkDiv = (uspi->BRGEN & USPI_BRGEN_CLKDIV_Msk) >> USPI_BRGEN_CLKDIV_Pos;

    if(uspi == USPI0) {
        u32BusClk = (uint32_t)( CLK_GetPCLK0Freq() / ((u32ClkDiv+1ul)<<1) );
    } else {
        u32BusClk = (uint32_t)( CLK_GetPCLK1Freq() / ((u32ClkDiv+1ul)<<1) );
    }

    return u32BusClk;
}
Beispiel #4
0
/**
  * @brief Set the USCI_SPI bus clock. Only available in Master mode.
  * @param[in]  uspi The pointer of the specified USCI_SPI module.
  * @param[in]  u32BusClock The expected frequency of USCI_SPI bus clock.
  * @return Actual frequency of USCI_SPI peripheral clock.
  */
uint32_t USPI_SetBusClock(USPI_T *uspi, uint32_t u32BusClock)
{
    uint32_t u32ClkDiv;
    uint32_t u32Pclk;

    if(uspi == USPI0) {
        u32Pclk = CLK_GetPCLK0Freq();
    } else {
        u32Pclk = CLK_GetPCLK1Freq();
    }

    u32ClkDiv = (uint32_t) ((((((u32Pclk/2ul)*10ul)/(u32BusClock))+5ul)/10ul)-1ul); /* Compute proper divider for USCI_SPI clock */

    /* Set USCI_SPI bus clock */
    uspi->BRGEN &= ~USPI_BRGEN_CLKDIV_Msk;
    uspi->BRGEN |=  (u32ClkDiv << USPI_BRGEN_CLKDIV_Pos);

    return ( u32Pclk / ((u32ClkDiv+1ul)<<1) );
}
Beispiel #5
0
/**
 * @brief Configure BPWM capture and get the nearest unit time.
 * @param[in] bpwm The pointer of the specified BPWM module
 *                - BPWM0 : BPWM Group 0
 *                - BPWM1 : BPWM Group 1
 * @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
 * @param[in] u32UnitTimeNsec The unit time of counter
 * @param[in] u32CaptureEdge The condition to latch the counter. This parameter is not used
 * @return The nearest unit time in nano second.
 * @details This function is used to Configure BPWM capture and get the nearest unit time.
 */
uint32_t BPWM_ConfigCaptureChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32UnitTimeNsec, uint32_t u32CaptureEdge)
{
    uint32_t u32Src;
    uint32_t u32PWMClockSrc;
    uint32_t u32NearestUnitTimeNsec;
    uint16_t u16Prescale = 1U, u16CNR = 0xFFFFU;

    if(bpwm == BPWM0) {
        u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk;
    } else { /* (bpwm == BPWM1) */
        u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk;
    }

    if(u32Src == 0U) {
        /* clock source is from PLL clock */
        u32PWMClockSrc = CLK_GetPLLClockFreq();
    } else {
        /* clock source is from PCLK */
        SystemCoreClockUpdate();
        if(bpwm == BPWM0) {
            u32PWMClockSrc = CLK_GetPCLK0Freq();
        } else {/* (bpwm == BPWM1) */
            u32PWMClockSrc = CLK_GetPCLK1Freq();
        }
    }

    u32PWMClockSrc /= 1000UL;
    for(u16Prescale = 1U; u16Prescale <= 0x1000U; u16Prescale++) {
        uint32_t u32Exit = 0U;
        u32NearestUnitTimeNsec = (1000000UL * u16Prescale) / u32PWMClockSrc;
        if(u32NearestUnitTimeNsec < u32UnitTimeNsec) {
            if (u16Prescale == 0x1000U) { /* limit to the maximum unit time(nano second) */
                u32Exit = 1U;
            } else {
                u32Exit = 0U;
            }
            if (!(1000000UL * (u16Prescale + 1UL) > (u32NearestUnitTimeNsec * u32PWMClockSrc))) {
                u32Exit = 1U;
            } else {
                u32Exit = 0U;
            }
        } else {
            u32Exit = 1U;
        }
        if (u32Exit == 1U) {
            break;
        } else {}
    }

    /* convert to real register value */
    /* all channels share a prescaler */
    u16Prescale -= 1U;
    BPWM_SET_PRESCALER(bpwm, u32ChannelNum, u16Prescale);

    /* set BPWM to down count type(edge aligned) */
    (bpwm)->CTL1 = (1UL);

    BPWM_SET_CNR(bpwm, u32ChannelNum, u16CNR);

    return (u32NearestUnitTimeNsec);
}
Beispiel #6
0
/**
 * @brief This function Configure BPWM generator and get the nearest frequency in edge aligned auto-reload mode
 * @param[in] bpwm The pointer of the specified BPWM module
 *                - BPWM0 : BPWM Group 0
 *                - BPWM1 : BPWM Group 1
 * @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
 * @param[in] u32Frequency Target generator frequency
 * @param[in] u32DutyCycle Target generator duty cycle percentage. Valid range are between 0 ~ 100. 10 means 10%, 20 means 20%...
 * @return Nearest frequency clock in nano second
 * @note Since all channels shares a prescaler. Call this API to configure BPWM frequency may affect
 *       existing frequency of other channel.
 */
uint32_t BPWM_ConfigOutputChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle)
{
    uint32_t u32Src;
    uint32_t u32PWMClockSrc;
    uint32_t i;
    uint32_t u32Prescale = 1U, u32CNR = 0xFFFFU;

    if(bpwm == BPWM0) {
        u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk;
    } else { /* (bpwm == BPWM1) */
        u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk;
    }

    if(u32Src == 0U) {
        /* clock source is from PLL clock */
        u32PWMClockSrc = CLK_GetPLLClockFreq();
    } else {
        /* clock source is from PCLK */
        SystemCoreClockUpdate();
        if(bpwm == BPWM0) {
            u32PWMClockSrc = CLK_GetPCLK0Freq();
        } else { /* (bpwm == BPWM1) */
            u32PWMClockSrc = CLK_GetPCLK1Freq();
        }
    }

    for(u32Prescale = 1U; u32Prescale < 0xFFFU; u32Prescale++) { /* prescale could be 0~0xFFF */
        i = (u32PWMClockSrc / u32Frequency) / u32Prescale;
        /* If target value is larger than CNR, need to use a larger prescaler */
        if(i < (0x10000U)) {
            u32CNR = i;
            break;
        }
    }
    /* Store return value here 'cos we're gonna change u16Prescale & u16CNR to the real value to fill into register */
    i = u32PWMClockSrc / (u32Prescale * u32CNR);

    /* convert to real register value */
    /* all channels share a prescaler */
    u32Prescale -= 1U;
    BPWM_SET_PRESCALER(bpwm, u32ChannelNum, u32Prescale);
    /* set BPWM to down count type(edge aligned) */
    (bpwm)->CTL1 = (1UL);

    u32CNR -= 1U;
    BPWM_SET_CNR(bpwm, u32ChannelNum, u32CNR);
    if(u32DutyCycle) {
        BPWM_SET_CMR(bpwm, u32ChannelNum, u32DutyCycle * (u32CNR + 1UL) / 100UL - 1UL);
        (bpwm)->WGCTL0 &= ~((BPWM_WGCTL0_PRDPCTLn_Msk | BPWM_WGCTL0_ZPCTLn_Msk) << (u32ChannelNum * 2U));
        (bpwm)->WGCTL0 |= (BPWM_OUTPUT_LOW << ((u32ChannelNum * (2U)) + (uint32_t)BPWM_WGCTL0_PRDPCTLn_Pos));
        (bpwm)->WGCTL1 &= ~((BPWM_WGCTL1_CMPDCTLn_Msk | BPWM_WGCTL1_CMPUCTLn_Msk) << (u32ChannelNum * 2U));
        (bpwm)->WGCTL1 |= (BPWM_OUTPUT_HIGH << (u32ChannelNum * (2U) + (uint32_t)BPWM_WGCTL1_CMPDCTLn_Pos));
    } else {
        BPWM_SET_CMR(bpwm, u32ChannelNum, 0U);
        (bpwm)->WGCTL0 &= ~((BPWM_WGCTL0_PRDPCTLn_Msk | BPWM_WGCTL0_ZPCTLn_Msk) << (u32ChannelNum * 2U));
        (bpwm)->WGCTL0 |= (BPWM_OUTPUT_LOW << (u32ChannelNum * 2U + (uint32_t)BPWM_WGCTL0_ZPCTLn_Pos));
        (bpwm)->WGCTL1 &= ~((BPWM_WGCTL1_CMPDCTLn_Msk | BPWM_WGCTL1_CMPUCTLn_Msk) << (u32ChannelNum * 2U));
        (bpwm)->WGCTL1 |= (BPWM_OUTPUT_HIGH << (u32ChannelNum * 2U + (uint32_t)BPWM_WGCTL1_CMPDCTLn_Pos));
    }

    return(i);
}