void pwmout_write(pwmout_t *obj, float value) { // Stop timer for setting clock again TMRB_SetRunState(obj->channel, TMRB_STOP); // values outside this range will be saturated to 0.0f or 1.0f // Disable flip-flop reverse trigger when leading_timing and trailing_timing are duplicated if (value <= 0.0f) { value = 0; FFStruct.FlipflopCtrl = TMRB_FLIPFLOP_CLEAR; FFStruct.FlipflopReverseTrg = TMRB_DISABLE_FLIPFLOP; } else if (value >= 1.0f) { value = 1; FFStruct.FlipflopCtrl = TMRB_FLIPFLOP_SET; FFStruct.FlipflopReverseTrg = TMRB_DISABLE_FLIPFLOP; } else { FFStruct.FlipflopCtrl = TMRB_FLIPFLOP_CLEAR; FFStruct.FlipflopReverseTrg = (TMRB_FLIPFLOP_MATCH_TRAILING | TMRB_FLIPFLOP_MATCH_LEADING); } TMRB_SetFlipFlop(obj->channel, &FFStruct); if (obj->period > 0.7) { value = 1; //TMPM46B duty cycle should be < 700ms, above 700ms fixed 50% duty cycle } // Store the new leading_timing value obj->leading_timing = obj->trailing_timing - (uint16_t)(obj->trailing_timing * value); // Setting TBxRG0 register TMRB_ChangeLeadingTiming(obj->channel, obj->leading_timing); TMRB_SetRunState(obj->channel, TMRB_RUN); }
void pwmout_write(pwmout_t *obj, float value) { TMRB_FFOutputTypeDef FFStruct; // Stop timer for setting clock again TMRB_SetRunState(obj->channel, TMRB_STOP); // values outside this range will be saturated to 0.0f or 1.0f // Disable flip-flop reverse trigger when leading_timing and trailing_timing are duplicated if (value <= 0.0f) { value = 0; FFStruct.FlipflopCtrl = TMRB_FLIPFLOP_CLEAR; FFStruct.FlipflopReverseTrg = TMRB_DISABLE_FLIPFLOP; TMRB_SetFlipFlop(obj->channel, &FFStruct); } else if (value >= 1.0f) { value = 1; FFStruct.FlipflopCtrl = TMRB_FLIPFLOP_SET; FFStruct.FlipflopReverseTrg = TMRB_DISABLE_FLIPFLOP; TMRB_SetFlipFlop(obj->channel, &FFStruct); } else { FFStruct.FlipflopCtrl = TMRB_FLIPFLOP_CLEAR; FFStruct.FlipflopReverseTrg = TMRB_FLIPFLOP_MATCH_TRAILINGTIMING | TMRB_FLIPFLOP_MATCH_LEADINGTIMING; TMRB_SetFlipFlop(obj->channel, &FFStruct); } // Store the new leading_timing value obj->leading_timing = obj->trailing_timing - (uint16_t)(obj->trailing_timing * value); // Setting TBxRG0 register TMRB_ChangeLeadingTiming(obj->channel, obj->leading_timing); TMRB_SetRunState(obj->channel, TMRB_RUN); }
// Set the PWM period, keeping the duty cycle the same. void pwmout_period_us(pwmout_t *obj, int us) { float seconds = 0; uint32_t cycles = 0; int ClkDiv = 0; int i = 0; float duty_cycle = 0; uint32_t clk_freq = 0; seconds = (float)((us) / 1000000.0f); obj->period = seconds; if (obj->period > 0.7) { clk_freq = (CLOCK_FREQUENCY / 2); } else { clk_freq = CLOCK_FREQUENCY; } // Select highest timer resolution for (i = 0; i < 7; ++i) { cycles = (int)((clk_freq / prescale_tbl[i]) * seconds); if (cycles <= MAX_COUNTER_16B) { ClkDiv = i + 1; // range 1:6 break; } else { cycles = MAX_COUNTER_16B; ClkDiv = 7; } } // Stops and clear count operation TMRB_SetRunState(obj->channel, TMRB_STOP); // Restore the duty-cycle duty_cycle = (float)((obj->trailing_timing - obj->leading_timing) / obj->trailing_timing); obj->trailing_timing = cycles; obj->leading_timing = ((cycles)- (uint16_t)(cycles * duty_cycle)); // Change the source clock division and period m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = ClkDiv; m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; m_tmrb.TrailingTiming = obj->trailing_timing; m_tmrb.LeadingTiming = obj->leading_timing; FFStruct.FlipflopCtrl = TMRB_FLIPFLOP_SET; FFStruct.FlipflopReverseTrg = (TMRB_FLIPFLOP_MATCH_TRAILING | TMRB_FLIPFLOP_MATCH_LEADING); // Enable channel TMRB_Enable(obj->channel); // Disable double buffering TMRB_SetDoubleBuf(obj->channel, DISABLE, TMRB_WRITE_REG_SEPARATE); // Init timer function TMRB_Init(obj->channel, &m_tmrb); // Enable double buffering TMRB_SetDoubleBuf(obj->channel, ENABLE, TMRB_WRITE_REG_SEPARATE); TMRB_SetFlipFlop(obj->channel, &FFStruct); // Start timer function TMRB_SetRunState(obj->channel, TMRB_RUN); }
/** * @brief TMRB_PPG demo * @param None * @retval None */ void Example_TimerPpg(void) { uint8_t Rate = 0U; uint32_t Duty[5] = { 0x8CAU, 0x753U, 0x4E2U, 0x271U, 0xFAU }; /* duty: 10%, 25%, 50%, 75%, 90% */ uint8_t keyvalue; TMRB_InitTypeDef m_tmrb; TMRB_FFOutputTypeDef PPGFFInital; GPIO_SetInput(KEYPORT, GPIO_BIT_0); /* set KEY port to input */ /* Set PF1 as TB7OUT for PPG output */ GPIO_SetOutput(GPIO_PF, GPIO_BIT_1); GPIO_EnableFuncReg(GPIO_PF, GPIO_FUNC_REG_1, GPIO_BIT_1); GPIO_SetPullUp(GPIO_PF, GPIO_BIT_1, ENABLE); m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = TMRB_CLK_DIV_8; m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; m_tmrb.Cycle = TMRB7TIME; /* T = 250us */ m_tmrb.Duty = Duty[Rate]; PPGFFInital.FlipflopCtrl = TMRB_FLIPFLOP_CLEAR; PPGFFInital.FlipflopReverseTrg = TMRB_FLIPFLOP_MATCH_CYCLE | TMRB_FLIPFLOP_MATCH_DUTY; TMRB_Enable(TSB_TB7); TMRB_Init(TSB_TB7, &m_tmrb); TMRB_SetFlipFlop(TSB_TB7, &PPGFFInital); TMRB_SetDoubleBuf(TSB_TB7, ENABLE, TMRB_WRITE_REG_SEPARATE); /* enable double buffer */ TMRB_SetRunState(TSB_TB7, TMRB_RUN); do { /* wait if key is pressed */ keyvalue = GPIO_ReadDataBit(KEYPORT, GPIO_BIT_0); } while (GPIO_BIT_VALUE_1 == keyvalue); delay(0xFFFU); /* noise cancel */ while (1) { do { /* wait if key is released */ keyvalue = GPIO_ReadDataBit(KEYPORT, GPIO_BIT_0); } while (GPIO_BIT_VALUE_0 == keyvalue); delay(0xFFFU); /* noise cancel */ Rate++; if (Rate >= DUTYMAX) { /* change duty rate */ Rate = DUTYINIT; } else { /* Do nothing */ } TMRB_ChangeDuty(TSB_TB7, Duty[Rate]); /* change duty rate */ do { /* wait if key is pressed */ keyvalue = GPIO_ReadDataBit(KEYPORT, GPIO_BIT_0); } while (GPIO_BIT_VALUE_1 == keyvalue); delay(0xFFFU); /* noise cancel */ } }
/** * @brief The main function of TMRB_PPG demo * @param None * @retval None */ void Example_TMRB_PPG(void) { uint32_t Duty[5] = { 0x1194U, 0xEA6U, 0x9C4U, 0x4E2U, 0x1F4U }; /* duty: 10%, 25%, 50%, 75%, 90% */ uint8_t keyvalue; TMRB_InitTypeDef m_tmrb; TMRB_FFOutputTypeDef PPGFFInital; /* LCD & switch initialization */ LCD_Configuration(); SW_Init(); /* Set PA5 as TB6OUT for PPG output */ GPIO_SetOutput(GPIO_PA, GPIO_BIT_5); GPIO_EnableFuncReg(GPIO_PA, GPIO_FUNC_REG_2, GPIO_BIT_5); m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = TMRB_CLK_DIV_8; m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; m_tmrb.Cycle = TMRB6TIME; /* T = 500us */ m_tmrb.Duty = Duty[Rate]; PPGFFInital.FlipflopCtrl = TMRB_FLIPFLOP_CLEAR; PPGFFInital.FlipflopReverseTrg = TMRB_FLIPFLOP_MATCH_CYCLE | TMRB_FLIPFLOP_MATCH_DUTY; TMRB_Enable(TSB_TB6); TMRB_Init(TSB_TB6, &m_tmrb); TMRB_SetFlipFlop(TSB_TB6, &PPGFFInital); TMRB_SetDoubleBuf(TSB_TB6, ENABLE, TMRB_WRITE_REG_SEPARATE); /* enable double buffer */ TMRB_SetRunState(TSB_TB6, TMRB_RUN); do { /* Handle the condition that start with the SW0 is high*/ keyvalue = GPIO_ReadDataBit(KEYPORT, GPIO_BIT_0); duty_display(); } while (GPIO_BIT_VALUE_1 == keyvalue); delay(0xFFFFU); /* noise cancel */ while (1) { do { keyvalue = GPIO_ReadDataBit(KEYPORT, GPIO_BIT_0); /* display when switch is low */ duty_display(); } while (GPIO_BIT_VALUE_0 == keyvalue); delay(0xFFFFU); /* noise cancel */ Rate++; if (Rate >= DUTYMAX) { /* change duty rate */ Rate = DUTYINIT; } else { /* Do nothing */ } TMRB_ChangeDuty(TSB_TB6, Duty[Rate]); do { keyvalue = GPIO_ReadDataBit(KEYPORT, GPIO_BIT_0); /* display when switch is high */ duty_display(); } while (GPIO_BIT_VALUE_1 == keyvalue); delay(0xFFFFU); /* noise cancel */ } }
void pwmout_free(pwmout_t *obj) { // Stops and clear count operation TMRB_SetRunState(obj->channel, TMRB_STOP); pwmout_write(obj,0); obj->pin = NC; obj->channel = NULL; obj->trailing_timing = 0; obj->leading_timing = 0; obj->divisor = 0; }
void pwmout_free(pwmout_t *obj) { // Stops and clear count operation TMRB_SetRunState(obj->channel, TMRB_STOP); pwmout_write(obj,0); obj->channel = NULL; obj->trailing_timing = 0; obj->leading_timing = 0; obj->divisor = 0; TMRB_SetIdleMode(TSB_TB0, ENABLE); }
// Set the PWM period, keeping the duty cycle the same. void pwmout_period_us(pwmout_t *obj, int us) { float seconds = 0; int cycles = 0; uint32_t clkdiv = 0; float duty_cycle = 0; TMRB_InitTypeDef m_tmrb; seconds = (float)((us) / 1000000.0f); obj->period = seconds; MBED_ASSERT(obj->channel != NULL); // Select highest timer resolution for (int i = 0; i < 7; ++i) { cycles = (int)((CLOCK_FREQUENCY / prescale_tbl[i]) * seconds); if (cycles <= MAX_COUNTER_16B) { clkdiv = i + 1; // range 1:7 break; } } // Stop timer for setting clock again TMRB_SetRunState(obj->channel, TMRB_STOP); // Restore the duty-cycle duty_cycle = (float)(obj->trailing_timing - obj->leading_timing) / obj->trailing_timing; obj->trailing_timing = cycles; obj->leading_timing = (cycles - (uint16_t)(cycles * duty_cycle)); // Change the source clock division and period m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = clkdiv; m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; m_tmrb.TrailingTiming = obj->trailing_timing; m_tmrb.LeadingTiming = obj->leading_timing; //Init timer function TMRB_Init(obj->channel, &m_tmrb); //Start timer function TMRB_SetRunState(obj->channel, TMRB_RUN); }
void TB0_LED(void) { TSB_PM_DATA_PM4 = 1; TSB_PM_CR_PM4C = 1; myTMRB.Mode = TMRB_INTERVAL_TIMER; myTMRB.ClkDiv = TMRB_CLK_DIV_8; myTMRB.Cycle = TMRB_PERIOD; /* Specific value depends on system clock */ myTMRB.UpCntCtrl = TMRB_AUTO_CLEAR; myTMRB.Duty = TMRB_PERIOD / 2U; /* Specific value depends on system clock */ TMRB_Enable(TSB_TB0); TMRB_Init(TSB_TB0, &myTMRB); TMRB_SetRunState(TSB_TB0, TMRB_RUN); NVIC_EnableIRQ(INTTB0_IRQn); while (1) { /* Do nothing */ } }
/** * @brief TMRB_TIMER demo * @param None * @retval None */ void Example_TimerTimer (void) { TMRB_InitTypeDef m_tmrb; m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = TMRB_CLK_DIV_8; m_tmrb.Cycle = TMRB_1MS; /* periodic time is 1ms */ m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; m_tmrb.Duty = TMRB_1MS; /* periodic time is 1ms */ TMRB_Enable(TSB_TB0); TMRB_Init(TSB_TB0, &m_tmrb); NVIC_EnableIRQ(INTTB00_IRQn); TMRB_SetRunState(TSB_TB0, TMRB_RUN); while (1) { /* Do nothing */ } }
void TB0_print(void) { TMRB_InitTypeDef myTMRB; WDT_Disable(); UART_Configuration(UART0); UART_Print(UART0, "This is a TIMER example!\n\r\n\r"); myTMRB.Mode = TMRB_INTERVAL_TIMER; myTMRB.ClkDiv = TMRB_CLK_DIV_8; myTMRB.Cycle = TMRB_1ms; /* Specific value depends on system clock */ myTMRB.UpCntCtrl = TMRB_AUTO_CLEAR; myTMRB.Duty = TMRB_1ms / 2U; /* Specific value depends on system clock */ TMRB_Enable(TSB_TB0); TMRB_Init(TSB_TB0, &myTMRB); TMRB_SetRunState(TSB_TB0, TMRB_RUN); NVIC_EnableIRQ(INTTB0_IRQn); while (1) { /* Do nothing */ } }
/******************************************************************************* * Function Name : DAC_Demo * Description : DAC_Demo function * Input : None. * Return : None. *******************************************************************************/ void DAC_Demo(void) { DAC_InitTypeDef InitStruct; TMRB_InitTypeDef m_tmrb; /* DA0 Config */ DAC_Start(TSB_DA0); InitStruct.DACClear = DAC_CLEAR; InitStruct.PostTime = 15U; InitStruct.PreTime = 8U; InitStruct.Offset = DAC_0DIV8_VDD; InitStruct.AmpSel = DAC_1DIV4_VDD; InitStruct.TrgSel = DAC_TRG_TMRB2; InitStruct.TrgFunc = DAC_TRG_ENABLE; InitStruct.DMAFunc = DAC_DMA_DISABLE; InitStruct.Wave = DAC_TRIANGLE_WAVE; DAC_Init(TSB_DA0, &InitStruct); DAC_SetOutputCode(TSB_DA0,0x3FFU); /*TMRB Config*/ m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = TMRB_CLK_DIV_8; m_tmrb.Cycle = TMRB_DAC; m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; m_tmrb.Duty = TMRB_DAC; TMRB_Enable(TSB_TB2); TMRB_Init(TSB_TB2, &m_tmrb); NVIC_EnableIRQ(INTTB2_IRQn); TMRB_SetRunState(TSB_TB2, TMRB_RUN); while(1){ } }
/*int main(void)*/ void TMRB_PPG(void) { uint8_t Rate = 0U; uint32_t Duty[5] = { 0x384U, 0x2EEU, 0x1F4U, 0xFAU, 0x64U }; /* duty: 10%, 25%, 50%, 75%, 90% */ TMRB_InitTypeDef m_tmrb; TMRB_FFOutputTypeDef PPGFFInital; /* Set PG0 as TB0OUT for PPG output */ TSB_PG->CR |= 0x01; TSB_PG->FR1 |= 0x01; m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = TMRB_CLK_DIV_8; m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; m_tmrb.Cycle = TMRB0TIME; /* T = 1ms */ m_tmrb.Duty = Duty[Rate]; PPGFFInital.FlipflopCtrl = TMRB_FLIPFLOP_CLEAR; PPGFFInital.FlipflopReverseTrg = TMRB_FLIPFLOP_MATCH_CYCLE | TMRB_FLIPFLOP_MATCH_DUTY; TMRB_Enable(TSB_TB0); TMRB_Init(TSB_TB0, &m_tmrb); TMRB_SetFlipFlop(TSB_TB0, &PPGFFInital); TMRB_SetDoubleBuf(TSB_TB0, ENABLE); /* enable double buffer */ TMRB_SetRunState(TSB_TB0, TMRB_RUN); while (1) { /* change duty rate */ delay(); if (Rate++ >= DUTYMAX) { Rate = DUTYINIT; } TMRB_ChangeDuty(TSB_TB0, Duty[Rate]); } }
void TMRB_TIMER(void) { TMRB_InitTypeDef m_tmrb; CG_InitSystem(); /* CG_SetSystem */ GPIO_SetOutput(GPIO_PA,0xFFU); GPIO_WriteData(GPIO_PA,0xFFU); /* LED initialize */ LedOff(LED1 | LED2 | LED3 | LED4); m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = TMRB_CLK_DIV_8; m_tmrb.Cycle = TMRB_1MS; /* periodic time is 1ms */ m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; m_tmrb.Duty = TMRB_1MS; /* periodic time is 1ms */ TMRB_Enable(TSB_TB0); TMRB_Init(TSB_TB0, &m_tmrb); NVIC_EnableIRQ(INTTB0_IRQn); TMRB_SetRunState(TSB_TB0, TMRB_RUN); while (1) { /* Do nothing */ } }
void pwmout_init(pwmout_t *obj, PinName pin) { uint16_t counter = 0; TMRB_FFOutputTypeDef FFStruct; TMRB_InitTypeDef m_tmrb; // Determine the pwm channel PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); //Assert input is valid MBED_ASSERT(pwm != (PWMName)NC); // Enable clock supply to TB0 CG_SetFcPeriphA(CG_FC_PERIPH_TMRB0_3, ENABLE); CG_SetFcPeriphA(CG_FC_PERIPH_TMRB4_6, ENABLE); switch (pwm) { case PWM_0: obj->channel = TSB_TB0; break; case PWM_1: obj->channel = TSB_TB1; break; case PWM_2: obj->channel = TSB_TB2; break; case PWM_3: obj->channel = TSB_TB3; break; case PWM_4: obj->channel = TSB_TB4; break; case PWM_5: obj->channel = TSB_TB5; CG_SetFcPeriphA(CG_FC_PERIPH_PORTJ, ENABLE); break; case PWM_6: obj->channel = TSB_TB6; CG_SetFcPeriphA(CG_FC_PERIPH_PORTJ, ENABLE); break; default: obj->channel = NULL; return; } // Set pin function as PWM pinmap_pinout(pin, PinMap_PWM); obj->pin = pin; obj->period = DEFAULT_PERIOD; // Enable channel TMRB_Enable(obj->channel); // Stops and clear count operation TMRB_SetRunState(obj->channel, TMRB_STOP); // Disables double buffering TMRB_SetDoubleBuf(obj->channel, DISABLE); // Set default period = 20ms, duty cycle = 0 obj->divisor = DEFAULT_CLOCK_DIVISION; counter = (uint16_t)((DEFAULT_PERIOD * CLOCK_FREQUENCY) / obj->divisor); // Init timer variable for using PPG mode m_tmrb.Mode = TMRB_INTERVAL_TIMER; m_tmrb.ClkDiv = TMRB_CLK_DIV_32; m_tmrb.UpCntCtrl = TMRB_AUTO_CLEAR; // clear UC when matching value m_tmrb.TrailingTiming = counter; // period = 20ms m_tmrb.LeadingTiming = counter; // duty cycle = 0% // Init timer function TMRB_Init(obj->channel, &m_tmrb); obj->trailing_timing = counter; obj->leading_timing = counter; // Enable double buffering TMRB_SetDoubleBuf(obj->channel, ENABLE); // Setting to TBxFF0 reverse trigger FFStruct.FlipflopCtrl = TMRB_FLIPFLOP_CLEAR; FFStruct.FlipflopReverseTrg = TMRB_FLIPFLOP_MATCH_TRAILINGTIMING | TMRB_FLIPFLOP_MATCH_LEADINGTIMING; TMRB_SetFlipFlop(obj->channel, &FFStruct); // Start count operation TMRB_SetRunState(obj->channel, TMRB_RUN); }