/** * \brief Application entry point for PWM with PDC example. * * Outputs a PWM on LED1 & LED2 & LED3 to makes it fade in repeatedly. * Channel #0, #1, #2 are linked together as synchronous channels, so they have * the same source clock, the same period, the same alignment and * are started together. The update of the duty cycle values is made * automatically by the Peripheral DMA Controller (PDC). * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t i; uint8_t key; int32_t numkey; /* Disable watchdog */ WDT_Disable( WDT ) ; /* Output example information */ printf("-- PWM with PDC Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); /* PIO configuration */ PIO_Configure(pins, PIO_LISTSIZE(pins)); /* Enable PWMC peripheral clock */ PMC_EnablePeripheral(ID_PWM); /* Set clock A to run at PWM_FREQUENCY * MAX_DUTY_CYCLE (clock B is not used) */ PWMC_ConfigureClocks(PWM_FREQUENCY * MAX_DUTY_CYCLE, 0, BOARD_MCK); /* Configure PWMC channel for LED0 (left-aligned, enable dead time generator) */ PWMC_ConfigureChannelExt( PWM, CHANNEL_PWM_LED0, /* channel */ PWM_CMR_CPRE_CKA, /* prescaler */ 0, /* alignment */ 0, /* polarity */ 0, /* countEventSelect */ PWM_CMR_DTE, /* DTEnable */ 0, /* DTHInverte */ 0 ); /* DTLInverte */ PWMC_SetPeriod(PWM, CHANNEL_PWM_LED0, MAX_DUTY_CYCLE); PWMC_SetDutyCycle(PWM, CHANNEL_PWM_LED0, MIN_DUTY_CYCLE); PWMC_SetDeadTime(PWM, CHANNEL_PWM_LED0, 5, 5); /* Configure PWMC channel for LED1 */ PWMC_ConfigureChannelExt( PWM, CHANNEL_PWM_LED1, /* channel */ PWM_CMR_CPRE_CKA, /* prescaler */ 0, /* alignment */ 0, /* polarity */ 0, /* countEventSelect */ 0, /* DTEnable */ 0, /* DTHInverte */ 0 ); /* DTLInverte */ PWMC_SetPeriod(PWM, CHANNEL_PWM_LED1, MAX_DUTY_CYCLE); PWMC_SetDutyCycle(PWM, CHANNEL_PWM_LED1, MIN_DUTY_CYCLE); /* Configure PWMC channel for LED2 */ PWMC_ConfigureChannelExt( PWM, CHANNEL_PWM_LED2, /* channel */ PWM_CMR_CPRE_CKA, /* prescaler */ 0, /* alignment */ 0, /* polarity */ 0, /* countEventSelect */ 0, /* DTEnable */ 0, /* DTHInverte */ 0 ); /* DTLInverte */ PWMC_SetPeriod(PWM, CHANNEL_PWM_LED2, MAX_DUTY_CYCLE); PWMC_SetDutyCycle(PWM, CHANNEL_PWM_LED2, MIN_DUTY_CYCLE); /* Set synchronous channels, update mode = 2 */ PWMC_ConfigureSyncChannel(PWM, (1 << CHANNEL_PWM_LED0) | (1 << CHANNEL_PWM_LED1) | (1 << CHANNEL_PWM_LED2), PWM_SCM_UPDM_MODE2, // (PWMC) Automatic write of data and automatic trigger of the update 0, 0); /* Set Synchronous channel update period value */ PWMC_SetSyncChannelUpdatePeriod(PWM, PWM_SCUP_UPR(0xF)); /* Configure interrupt for PDC transfer */ NVIC_DisableIRQ(PWM_IRQn); NVIC_ClearPendingIRQ(PWM_IRQn); NVIC_SetPriority(PWM_IRQn, 0); NVIC_EnableIRQ(PWM_IRQn); PWMC_EnableIt(PWM, 0, PWM_IER2_ENDTX); /* Set override value to 1 on PWMH0, others is 0. */ PWMC_SetOverrideValue(PWM, PWM_OOV_OOVH0); /* Fill duty cycle buffer for channel #0, #1 and #2 */ /* For Channel #0, #1, #2 duty cycle are from MIN_DUTY_CYCLE to MAX_DUTY_CYCLE */ for (i = 0; i < DUTY_BUFFER_LENGTH/3; i++) { dutyBuffer[i*3] = (i + MIN_DUTY_CYCLE); dutyBuffer[i*3+1] = (i + MIN_DUTY_CYCLE); dutyBuffer[i*3+2] = (i + MIN_DUTY_CYCLE); } /* Define the PDC transfer */ PWMC_WriteBuffer(PWM, dutyBuffer, DUTY_BUFFER_LENGTH); /* Enable syncronous channels by enable channel #0 */ PWMC_EnableChannel(PWM, CHANNEL_PWM_LED0); while (1) { _DisplayMenu(); key = UART_GetChar(); switch (key) { case 'u': printf("Input update period between %d to %d.\n\r", 0, PWM_SCUP_UPR_Msk); numkey = _GetNumkey2Digit(); if(numkey <= PWM_SCUP_UPR_Msk) { /* Set synchronous channel update period value */ PWMC_SetSyncChannelUpdatePeriod(PWM, numkey); printf("Done\n\r"); } else { printf("Invalid input\n\r"); } break; case 'd': printf("Input dead time for channel #0 between %d to %d.\n\r", MIN_DUTY_CYCLE, MAX_DUTY_CYCLE); numkey = _GetNumkey2Digit(); if(numkey >= MIN_DUTY_CYCLE && numkey <= MAX_DUTY_CYCLE) { /* Set synchronous channel update period value */ PWMC_SetDeadTime(PWM, CHANNEL_PWM_LED0, numkey, numkey); /* Update synchronous channel */ PWMC_SetSyncChannelUpdateUnlock(PWM); printf("Done\n\r"); } else { printf("Invalid input\n\r"); } break; case 'o': printf("0: Disable override output on channel #0\n\r"); printf("1: Enable override output on channel #0\n\r"); key = UART_GetChar(); if (key == '1') { PWMC_EnableOverrideOutput(PWM, PWM_OSSUPD_OSSUPH0 | PWM_OSSUPD_OSSUPL0, 1); printf("Done\n\r"); } else if (key == '0') { PWMC_DisableOverrideOutput(PWM, PWM_OSSUPD_OSSUPH0 | PWM_OSSUPD_OSSUPL0, 1); printf("Done\n\r"); } break; default: printf("Invalid input\n\r"); break; } } }
/** * \brief Application entry point for PWM with PDC example. * * Outputs a PWM on LED1. * Channel #0 is configured as synchronous channels. * The update of the duty cycle values is made automatically by the Peripheral DMA Controller. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t i; /* Disable watchdog */ WDT_Disable( WDT ) ; /* Enable I and D cache */ SCB_EnableICache(); SCB_EnableDCache(); /* Output example information */ printf("-- PWM with DMA Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); /* PIO configuration */ PIO_Configure(pinPwm, PIO_LISTSIZE(pinPwm)); for (i= 0; i< DUTY_BUFFER_LENGTH; i++) dwDutys[i] = i/2; /* Enable PWMC peripheral clock */ PMC_EnablePeripheral(ID_PWM0); /* Configure interrupt for PWM transfer */ NVIC_DisableIRQ(PWM0_IRQn); NVIC_ClearPendingIRQ(PWM0_IRQn); NVIC_SetPriority(PWM0_IRQn, 0); /* Configure DMA channel for PWM transfer */ _ConfigureDma(); /* Set clock A to run at PWM_FREQUENCY * MAX_DUTY_CYCLE (clock B is not used) */ PWMC_ConfigureClocks(PWM0, PWM_FREQUENCY * MAX_DUTY_CYCLE , 0, BOARD_MCK); /* Configure PWMC channel for LED0 (left-aligned, enable dead time generator) */ PWMC_ConfigureChannel( PWM0, 0, /* channel */ PWM_CMR_CPRE_CLKA, /* prescaler, CLKA */ 0, /* alignment */ 0 /* polarity */ ); PWMC_ConfigureSyncChannel(PWM0, (1 << CHANNEL_PWM_LED0), /* Define the synchronous channels by the bits SYNCx */ PWM_SCM_UPDM_MODE2, /* Select the manual write of duty-cycle values and the automatic update by setting the field UPDM to 鈥�1鈥� */ 0, 0); /* Configure channel 0 period */ PWMC_SetPeriod(PWM0, 0, DUTY_BUFFER_LENGTH); /* Configure channel 0 duty cycle */ PWMC_SetDutyCycle(PWM0, 0, MIN_DUTY_CYCLE); /* Define the update period by the field UPR in the PWM_SCUP register*/ PWMC_SetSyncChannelUpdatePeriod(PWM0, 8); /* Enable the synchronous channels by writing CHID0 in the PWM_ENA register */ PWMC_EnableChannel(PWM0, 0); /* Enable PWM interrupt */ PWMC_EnableIt(PWM0, 0, PWM_IER2_WRDY); NVIC_EnableIRQ(PWM0_IRQn); _PwmDmaTransfer(); while(1); }
/*------------------------------------------------------------------------------ Name: configurePWMC parameters: - description: initializes the PWM controller ------------------------------------------------------------------------------*/ void BldcControl::configurePWMC(void) { uint32_t clka = 0; /* clock A not used */ uint32_t clkb = 0; /* clock B not used */ uint32_t mck = MCK_CLOCK_42MHZ; uint16_t duty = 0; uint16_t deadTime; pwmPeriod = MCK_CLOCK_42MHZ / this->periphery->Pwm.pwmSwFrq; deadTime = (uint16_t)(pwmPeriod * (DEAD_TIME * this->periphery->Pwm.pwmSwFrq * 2)); /* disable all 3 channels */ PWMC_DisableChannel(PWM, this->periphery->Pwm.pwmChU); PWMC_DisableChannel(PWM, this->periphery->Pwm.pwmChV); PWMC_DisableChannel(PWM, this->periphery->Pwm.pwmChW); PWMC_ConfigureClocks(clka, clkb, mck); /* initialize all 3 channels */ PWMC_ConfigureChannelExt(PWM, this->periphery->Pwm.pwmChU, /* channel ID */ PWM_CMR_CPRE_MCK, /* use main clock */ PWM_CMR_CALG, /* center alligned */ 0, /* polarity low level */ 0, /* event counter = 0 */ PWM_CMR_DTE, /* enable dead time */ 0, /* no inversion of dead time H */ 0); /* no inversion of dead time L */ PWMC_ConfigureChannelExt(PWM, this->periphery->Pwm.pwmChV, /* channel ID */ PWM_CMR_CPRE_MCK, PWM_CMR_CALG, /* center alligned */ 0, /* polarity low level */ 0, /* event counter = 0 */ PWM_CMR_DTE, /* enable dead time */ 0, /* no inversion of dead time H */ 0); /* no inversion of dead time L */ PWMC_ConfigureChannelExt(PWM, this->periphery->Pwm.pwmChW, /* channel ID */ PWM_CMR_CPRE_MCK, PWM_CMR_CALG, /* center alligned */ 0, /* polarity low level */ 0, /* event counter = 0 */ PWM_CMR_DTE, /* enable dead time */ 0, /* no inversion of dead time H */ 0); /* no inversion of dead time L */ PWMC_ConfigureSyncChannel(PWM, PWM_SCM_SYNC0|PWM_SCM_SYNC1|PWM_SCM_SYNC2, PWM_SCM_UPDM_MODE0, PWM_SCM_PTRM, PWM_SCM_PTRCS(0)) ; /* set periods */ PWMC_SetPeriod(PWM, this->periphery->Pwm.pwmChU, pwmPeriod); PWMC_SetPeriod(PWM, this->periphery->Pwm.pwmChV, pwmPeriod); PWMC_SetPeriod(PWM, this->periphery->Pwm.pwmChW, pwmPeriod); /* set duty cycles */ PWMC_SetDutyCycle(PWM, this->periphery->Pwm.pwmChU, duty); PWMC_SetDutyCycle(PWM, this->periphery->Pwm.pwmChV, duty); PWMC_SetDutyCycle(PWM, this->periphery->Pwm.pwmChW, duty); /* set dead times */ PWMC_SetDeadTime(PWM, this->periphery->Pwm.pwmChU, deadTime, deadTime); PWMC_SetDeadTime(PWM, this->periphery->Pwm.pwmChV, deadTime, deadTime); PWMC_SetDeadTime(PWM, this->periphery->Pwm.pwmChW, deadTime, deadTime); /* set overwrites to 0 */ PWMC_SetOverrideValue(PWM, 0); /* set event for ADC trigger */ PWM->PWM_CMP[this->periphery->Pwm.pwmChU].PWM_CMPM |= PWM_CMPM_CEN | /* enable */ PWM_CMPM_CTR(0) | /* each period */ PWM_CMPM_CPR(0); PWM->PWM_CMP[this->periphery->Pwm.pwmChU].PWM_CMPV = pwmPeriod/2; /* set trigger */ PWM->PWM_ELMR[0] |= PWM_ELMR_CSEL0; /* enable event line 0 */ }