void imu_startblink(void) { imu_leds_on(true); Pin pins[] = {PINS_IMU_LED}; for(uint8_t i = 0; i < 6; i++) { pins[i].type = PIO_OUTPUT_1; } PIO_Configure(pins, PIO_LISTSIZE(pins)); for(uint8_t i = 0; i < 41; i++) { TC0->TC_CHANNEL[0].TC_RA = blink_lookup[i]; TC0->TC_CHANNEL[1].TC_RA = blink_lookup[i]; TC0->TC_CHANNEL[2].TC_RB = blink_lookup[i]; PWMC_SetDutyCycle(PWM, 3, blink_lookup[40-i]); SLEEP_MS(6); } for(uint8_t i = 0; i < 41; i++) { TC0->TC_CHANNEL[0].TC_RA = blink_lookup[40-i]; TC0->TC_CHANNEL[1].TC_RA = blink_lookup[40-i]; TC0->TC_CHANNEL[2].TC_RB = blink_lookup[40-i]; PWMC_SetDutyCycle(PWM, 3, blink_lookup[i]); SLEEP_MS(6); } for(uint8_t i = 0; i < 41; i++) { TC0->TC_CHANNEL[0].TC_RA = blink_lookup[i]; TC0->TC_CHANNEL[1].TC_RA = blink_lookup[i]; TC0->TC_CHANNEL[2].TC_RB = blink_lookup[i]; PWMC_SetDutyCycle(PWM, 3, blink_lookup[40-i]); SLEEP_MS(6); } imu_leds_on(false); }
/** * \brief ILI9488 Hardware Initialization for SPI/SMC LCD. */ static void _ILI9488_Spi_HW_Initialize(void) { /* Pin configurations */ PIO_Configure(&lcd_spi_reset_pin, 1); PIO_Configure(&lcd_spi_cds_pin, 1); PIO_Configure(lcd_pins, PIO_LISTSIZE(lcd_pins)); PIO_Configure(&lcd_spi_pwm_pin, 1); /* Enable PWM peripheral clock */ PMC_EnablePeripheral(ID_PWM0); PMC_EnablePeripheral(ID_SPI0); /* Set clock A and clock B */ // set for 14.11 KHz for CABC control //mode = PWM_CLK_PREB(0x0A) | (PWM_CLK_DIVB(110)) | //PWM_CLK_PREA(0x0A) | (PWM_CLK_DIVA(110)); PWMC_ConfigureClocks(PWM0, 14200, 0, BOARD_MCK); /* Configure PWM channel 1 for LED0 */ PWMC_DisableChannel(PWM0, CHANNEL_PWM_LCD); PWMC_ConfigureChannel(PWM0, CHANNEL_PWM_LCD, PWM_CMR_CPRE_CLKA, 0, PWM_CMR_CPOL); PWMC_SetPeriod(PWM0, CHANNEL_PWM_LCD, 16); PWMC_SetDutyCycle(PWM0, CHANNEL_PWM_LCD, 8); PWMC_EnableChannel(PWM0, CHANNEL_PWM_LCD); SPI_Configure(ILI9488_SPI, ID_SPI0, (SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS(SMC_EBI_LCD_CS))); SPI_ConfigureNPCS(ILI9488_SPI, SMC_EBI_LCD_CS, SPI_CSR_CPOL | SPI_CSR_BITS_8_BIT | SPI_DLYBS(6, BOARD_MCK) | SPI_DLYBCT(100, BOARD_MCK) | SPI_SCBR(20000000, BOARD_MCK)); SPI_Enable(ILI9488_SPI); }
static void ILI9488_InitInterface(void) { PIO_Configure(ILI9488_Reset, PIO_LISTSIZE(ILI9488_Reset)); PIO_Configure(spi_pins, PIO_LISTSIZE(spi_pins)); PIO_Configure(ILI9488_Pwm, PIO_LISTSIZE(ILI9488_Pwm)); /* Enable PWM peripheral clock */ PMC_EnablePeripheral(ID_PWM0); /* Set clock A and clock B */ // set for 14.11 KHz for CABC control // mode = PWM_CLK_PREB(0x0A) | (PWM_CLK_DIVB(110)) | // PWM_CLK_PREA(0x0A) | (PWM_CLK_DIVA(110)); PWMC_ConfigureClocks(PWM0, 14200, 0, BOARD_MCK); /* Configure PWM channel 1 for LED0 */ PWMC_DisableChannel(PWM0, CHANNEL_PWM_LCD); PWMC_ConfigureChannel(PWM0, CHANNEL_PWM_LCD, PWM_CMR_CPRE_CLKA,0,PWM_CMR_CPOL); PWMC_SetPeriod(PWM0, CHANNEL_PWM_LCD, 16); PWMC_SetDutyCycle(PWM0, CHANNEL_PWM_LCD, 8); PWMC_EnableChannel(PWM0, CHANNEL_PWM_LCD); SPI_Configure(ILI9488, ILI9488_ID, (SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS( ILI9488_cs ))); SPI_ConfigureNPCS( ILI9488, ILI9488_cs, SPI_CSR_CPOL | SPI_CSR_BITS_9_BIT | SPI_DLYBS(100, BOARD_MCK) | SPI_DLYBCT(100, BOARD_MCK) | SPI_SCBR( 35000000, BOARD_MCK) ) ; SPI_Enable(ILI9488); }
void LCDD_SpiSetBacklight (uint32_t level) { /* Ensure valid level */ level = (level < 1) ? 1 : level; level = (level > 16) ? 16 : level; PWMC_SetDutyCycle(PWM0, CHANNEL_PWM_LCD, level); }
//////////////////////////////////////////////////////////////////////////////// // Konfiguracja 4-rech kana��w PWM dla silnik�w //////////////////////////////////////////////////////////////////////////////// void PWM_Configure() { //wlaczenie zegara dla pwm PMC_EnablePeripheral(AT91C_ID_PWMC); // AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PWMC ); PWMC_ConfigureChannel(0, 0x6 << 0, 0x1 << 8, 0x1 << 9 | 0x0 << 10); // PWMC_ConfigureChannel(1, 0x6 << 0, 0x1 << 8, 0x1 << 9 | 0x0 << 10); // PWMC_ConfigureChannel(2, 0x6 << 0, 0x1 << 8, 0x1 << 9 | 0x0 << 10); // PWMC_ConfigureChannel(3, 0x6 << 0, 0x1 << 8, 0x1 << 9 | 0x0 << 10); // //wylaczenie wszystkich kanalow przed zmiana konfiguracji // AT91C_BASE_PWMC->PWMC_DIS = (AT91C_PWMC_CHID0 | AT91C_PWMC_CHID1 | AT91C_PWMC_CHID2 | AT91C_PWMC_CHID3); // // //oczekiwanie na wy��czenie wszystkich kanalow // while(AT91C_BASE_PWMC->PWMC_SR & (AT91C_PWMC_CHID0 | AT91C_PWMC_CHID1 | AT91C_PWMC_CHID2 | AT91C_PWMC_CHID3) ); // // //KONFIGURACJA TRYBU PRACY // // - prescaler = MCK/64 // // - alligment = center // // - polarity = high // // - update = duty // AT91C_BASE_PWMC->PWMC_CH[0].PWMC_CMR = (0x6 << 0 | 0x1 << 8 | 0x1 << 9 | 0x0 << 10); // AT91C_BASE_PWMC->PWMC_CH[1].PWMC_CMR = (0x6 << 0 | 0x1 << 8 | 0x1 << 9 | 0x0 << 10); // AT91C_BASE_PWMC->PWMC_CH[2].PWMC_CMR = (0x6 << 0 | 0x1 << 8 | 0x1 << 9 | 0x0 << 10); // AT91C_BASE_PWMC->PWMC_CH[3].PWMC_CMR = (0x6 << 0 | 0x1 << 8 | 0x1 << 9 | 0x0 << 10); // // rozdzielczosc = 255 PWMC_SetPeriod(0, 255); // PWMC_SetPeriod(1, 255); // PWMC_SetPeriod(2, 255); // PWMC_SetPeriod(3, 255); // AT91C_BASE_PWMC->PWMC_CH[0].PWMC_CPRDR = 256; // AT91C_BASE_PWMC->PWMC_CH[1].PWMC_CPRDR = 256; // AT91C_BASE_PWMC->PWMC_CH[2].PWMC_CPRDR = 256; // AT91C_BASE_PWMC->PWMC_CH[3].PWMC_CPRDR = 256; // wypelnienie poczatkowe = 1 PWMC_SetDutyCycle(0, 1); // PWMC_SetDutyCycle(1, 1); // PWMC_SetDutyCycle(2, 1); // PWMC_SetDutyCycle(3, 1); // AT91C_BASE_PWMC->PWMC_CH[0].PWMC_CDTYR = 2; // AT91C_BASE_PWMC->PWMC_CH[1].PWMC_CDTYR = 2; // AT91C_BASE_PWMC->PWMC_CH[2].PWMC_CDTYR = 2; // AT91C_BASE_PWMC->PWMC_CH[3].PWMC_CDTYR = 2; //KONFIGURACJA WYPROWADZENIA PA11, PA12, PA13, PA14 // AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, 0, AT91C_PA11_PWM0 ); //Uruchomienie wszystkich kana��w PWM PWMC_EnableChannel(0); // PWMC_EnableChannel(1); // PWMC_EnableChannel(2); // PWMC_EnableChannel(3); // AT91C_BASE_PWMC->PWMC_ENA = (AT91C_PWMC_CHID0 | AT91C_PWMC_CHID1 | AT91C_PWMC_CHID2 | AT91C_PWMC_CHID3); }
void imu_blinkenlights(void) { if(!imu_use_leds) { return; } PWMC_SetDutyCycle(PWM, 0, blink_lookup[(BETWEEN(-1000, sensor_data.acc_x, 1000) + 1000)/50]); PWMC_SetDutyCycle(PWM, 1, blink_lookup[(BETWEEN(-1000, sensor_data.acc_y, 1000) + 1000)/50]); PWMC_SetDutyCycle(PWM, 2, blink_lookup[40 - (BETWEEN(-1000, sensor_data.acc_z, 1000) + 1000)/50]); int16_t degree = sensor_data.eul_heading/16; if(degree < 0) { degree += 360; } if(degree < 90) { uint8_t index = degree * 40 / 90; TC0->TC_CHANNEL[0].TC_RA = blink_lookup[40-index];; TC0->TC_CHANNEL[1].TC_RA = 0; TC0->TC_CHANNEL[2].TC_RB = 0; PWMC_SetDutyCycle(PWM, 3, blink_lookup[40-index]); } else if(degree < 180) { uint8_t index = (degree - 90) * 40 / 90; TC0->TC_CHANNEL[0].TC_RA = blink_lookup[index]; TC0->TC_CHANNEL[1].TC_RA = blink_lookup[40-index]; TC0->TC_CHANNEL[2].TC_RB = 0; PWMC_SetDutyCycle(PWM, 3, 0); } else if(degree < 270) { uint8_t index = (degree - 180) * 40 / 90; TC0->TC_CHANNEL[0].TC_RA = 0; TC0->TC_CHANNEL[1].TC_RA = blink_lookup[index]; TC0->TC_CHANNEL[2].TC_RB = blink_lookup[40-index]; PWMC_SetDutyCycle(PWM, 3, 0); } else { uint8_t index = (degree - 270) * 40 / 90; TC0->TC_CHANNEL[0].TC_RA = 0; TC0->TC_CHANNEL[1].TC_RA = 0; TC0->TC_CHANNEL[2].TC_RB = blink_lookup[index]; PWMC_SetDutyCycle(PWM, 3, blink_lookup[index]); } }
/** * \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); }
//////////////////////////////////////////////////////////////////////////////// // Ustawianie wype�nienia dla wybranego kana�u //////////////////////////////////////////////////////////////////////////////// void PWM_Set(int channel, char duty) { //ustawienie wypelnienia // channel = 0 - 3, duty = 2 - 255 // AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CUPDR = duty; PWMC_SetDutyCycle(channel, duty); }
/** * \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; } } }
//Set up the PWM on the pin specified with the alignment and polarity specified customPWM::customPWM(int channel, bool alignment, bool polarity) { period = globPeriod; _lowFreq = period/3; //Calculate the low duty cycle setting, for the motor controller currentDuty = DUTY; motorDuty = DUTY; //Get the appropriate number if a pin is given switch(channel) { case 34: _channel = 0; break; case 36: _channel = 1; break; case 38: _channel = 2; break; case 40: _channel = 3; break; case 9: _channel = 4; break; case 8: _channel = 5; break; case 7: _channel = 6; break; case 6: _channel = 7; break; default: assert(0); //You didn't give it a correct pin } //If its not enabled yet, then enable it with the default settings if(!isEnabled) { customPWMinit(globFrequency, globPeriod); } //Arduino code to set the correct settings on the pins PIO_SetPeripheral(port[_channel], type[_channel], pin[_channel]); //Set the peripheral of the pin and remove control from PIO PIO_DisableInterrupt(port[_channel], pin[_channel]); //Disable the interupt on the pin, not needed since it is disabled in SetPeripheral PIO_PullUp(port[_channel], pin[_channel], (conf[_channel] & PIO_PULLUP)); //Enables the pullup resistor on the pin //Configure the channels //Needed to access the registers because the Arduino code disables the changing of alignment or polarity unsigned int holder = (0xBu & 0xF) | (polarity<<9) | (alignment<<8); point->PWM_CH_NUM[_channel].PWM_CMR = holder; //Set the period (max value) PWMC_SetPeriod(point, _channel, period); //Set the default duty cycle PWMC_SetDutyCycle(point, _channel, DUTY); //Enable the pin and make it go PWMC_EnableChannel(point, _channel); }
//Set the duty cycle of the PWM pin void customPWM::duty(unsigned long dy) { currentDuty = dy; PWMC_SetDutyCycle(point, _channel, dy); }
/*------------------------------------------------------------------------------ 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 */ }
void imu_leds_on(const bool on) { if(on) { PMC->PMC_PCER0 = 1 << ID_PWM; for(uint8_t i = 0; i < 4; i++) { PWMC_ConfigureChannel(PWM, i, PWM_CMR_CPRE_MCK, 0, 0); PWMC_SetPeriod(PWM, i, 0xFFFF); PWMC_SetDutyCycle(PWM, i, 0); PWMC_EnableChannel(PWM, i); } PMC->PMC_PCER0 = 1 << ID_TC0; tc_channel_init(&TC0->TC_CHANNEL[0], TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET | TC_CMR_WAVSEL_UP_RC); TC0->TC_CHANNEL[0].TC_RA = 0; TC0->TC_CHANNEL[0].TC_RC = 0xFFFF; tc_channel_start(&TC0->TC_CHANNEL[0]); PMC->PMC_PCER0 = 1 << ID_TC1; tc_channel_init(&TC0->TC_CHANNEL[1], TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET | TC_CMR_WAVSEL_UP_RC); TC0->TC_CHANNEL[1].TC_RA = 0; TC0->TC_CHANNEL[1].TC_RC = 0xFFFF; tc_channel_start(&TC0->TC_CHANNEL[1]); PMC->PMC_PCER0 = 1 << ID_TC2; tc_channel_init(&TC0->TC_CHANNEL[2], TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_SET | TC_CMR_EEVT_XC0 | TC_CMR_WAVSEL_UP_RC); TC0->TC_CHANNEL[2].TC_RB = 0; TC0->TC_CHANNEL[2].TC_RC = 0xFFFF; tc_channel_start(&TC0->TC_CHANNEL[2]); PIO_Configure(pins_imu_led, PIO_LISTSIZE(pins_imu_led)); } else { PMC->PMC_PCER0 &= ~(1 << ID_PWM); PMC->PMC_PCER0 &= ~(1 << ID_TC0); PMC->PMC_PCER0 &= ~(1 << ID_TC1); PMC->PMC_PCER0 &= ~(1 << ID_TC2); Pin pins[] = {PINS_IMU_LED}; for(uint8_t i = 0; i < PIO_LISTSIZE(pins); i++) { pins[i].type = PIO_OUTPUT_1; } PIO_Configure(pins, PIO_LISTSIZE(pins)); } imu_use_leds = on; }