void demo_led_set(int led, int brightness) { switch (led) { case 3: pwmEnableChannel(&PWMD4, 1, (pwmcnt_t) brightness); break; case 4: pwmEnableChannel(&PWMD4, 0, (pwmcnt_t) brightness); break; case 5: pwmEnableChannel(&PWMD4, 2, (pwmcnt_t) brightness); break; case 6: pwmEnableChannel(&PWMD4, 3, (pwmcnt_t) brightness); break; } }
static msg_t Thread3(void *arg) { chThdSleepMilliseconds(5000); (void)arg; chRegSetThreadName("motorthread"); while (TRUE) { pwmEnableChannel(&PWMD3, 2, speedMotor); } return (msg_t)0; }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Turn off the RGB LED. */ palSetPad(GPIO_LED_RED, PIN_LED_RED); /* red */ palSetPad(GPIO_LED_GREEN, PIN_LED_GREEN); /* green */ palSetPad(GPIO_LED_BLUE, PIN_LED_BLUE); /* blue */ /* * Start the PWM driver, route TPM2 output to PTB18, PTB19. * Enable channels now to avoid a blink later. */ pwmStart(&PWM_DRIVER, &pwmcfg); palSetPadMode(GPIO_LED_RED, PIN_LED_RED, PAL_MODE_ALTERNATIVE_3); palSetPadMode(GPIO_LED_GREEN, PIN_LED_GREEN, PAL_MODE_ALTERNATIVE_3); pwmEnableChannel(&PWM_DRIVER, 0, 0); pwmEnableChannel(&PWM_DRIVER, 1, 0); /* * Create the breathe thread. */ chThdCreateStatic(waBreatheThread, sizeof(waBreatheThread), NORMALPRIO, BreatheThread, NULL); /* * Normal main() thread activity, in this demo it does nothing except * sleeping in a loop. */ while(true) { chThdSleepMilliseconds(500); } }
static __attribute__((noreturn)) msg_t PWMThread2(void *arg){ (void)arg; chRegSetThreadName("PWM Thread 2"); uint16_t pwmVal2 = 1; palSetPadMode(GPIOA, GPIOA_PA1, PAL_MODE_OUTPUT_PUSHPULL); pwmStart(&PWMD2,&pwmcfg2); while(TRUE){ if(pwmVal2 >= 1024){ pwmVal2 = 1; } else { pwmVal2 <<= 1; } pwmEnableChannel(&PWMD2,1,pwmVal2); chThdSleepMilliseconds(100); } }
THD_TABLE_END #endif int main(void) { halInit(); /* * NOTE: when compiling for NIL, after the chSysInit() call, nothing * more can be done in this thread so we first initialize PWM subsystem. */ static PWMConfig pwm3cfg = { 1023, /* Not real clock */ 1023, /* Maximum PWM count */ NULL, { {PWM_OUTPUT_ACTIVE_HIGH, NULL}, {PWM_OUTPUT_ACTIVE_HIGH, NULL}, {PWM_OUTPUT_ACTIVE_HIGH, NULL}, }, }; /* PE3-5 are timer 3 pwm channel outputs */ palSetPadMode(IOPORT5, 3, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(IOPORT5, 4, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(IOPORT5, 5, PAL_MODE_OUTPUT_PUSHPULL); pwmStart(&PWMD3, &pwm3cfg); /* channel 0 with 50% duty cycle, 1 with 25% and 2 with 75% */ pwmEnableChannel(&PWMD3, 0, 511); pwmEnableChannel(&PWMD3, 1, 255); pwmEnableChannel(&PWMD3, 2, 767); chSysInit(); while (1) {} }
static THD_FUNCTION(BreatheThread, arg) { (void)arg; chRegSetThreadName("breatheThread"); while(true) { pwmEnableChannel(&PWM_DRIVER, active_led, PWM_PERCENTAGE_TO_WIDTH(&PWM_DRIVER,breathing_table[table_pos])); table_pos++; if(table_pos == TABLE_SIZE) { table_pos = 0; active_led = (active_led+1) % 2; } chThdSleepMilliseconds(BREATHE_STEP); } }
/** * set the light level from external thread * @param level */ void CLightHandler::SetLightLevel(uint8_t level){ /* deactivate light alarm */ bLightAlarm = false; /* wait for access */ semLightLevelSet.wait(); u16LightLevel = PWM_PERCENTAGE_TO_WIDTH(&PWMD5, level); pwmEnableChannel(&PWMD5,0,u16LightLevel); /* release access */ semLightLevelSet.signal(); }
static THD_FUNCTION(BreatheThread, arg) { (void)arg; chRegSetThreadName("breatheThread"); while(true) { switch(active_led) { case 0: /* red LED */ pwmEnableChannel(&PWM_DRIVER, 2, PWM_PERCENTAGE_TO_WIDTH(&PWM_DRIVER,breathing_table[table_pos])); break; case 1: /* green LED */ pwmEnableChannel(&PWM_DRIVER, 4, PWM_PERCENTAGE_TO_WIDTH(&PWM_DRIVER,breathing_table[table_pos])); break; case 2: /* blue LED */ pwmEnableChannel(&PWM_DRIVER, 5, PWM_PERCENTAGE_TO_WIDTH(&PWM_DRIVER,breathing_table[table_pos])); break; } table_pos++; if(table_pos == TABLE_SIZE) { table_pos = 0; active_led = (active_led+1) % 3; } chThdSleepMilliseconds(BREATHE_STEP); } }
//initialize motors int motorInit(ioportid_t gpio, int p11, int p12, int p21, int p22, PWMDriver *pwm, int lpa, int lpb, int rpa, int rpb){ //vars lp1 = lpa; lp2 = lpb; rp1 = rpa; rp2 = rpb; motor_pwm = pwm; //configure palSetPadMode(gpio, p11, PAL_MODE_ALTERNATE(2)); palSetPadMode(gpio, p12, PAL_MODE_ALTERNATE(2)); palSetPadMode(gpio, p21, PAL_MODE_ALTERNATE(2)); palSetPadMode(gpio, p22, PAL_MODE_ALTERNATE(2)); chBSemInit(&motor_left_sem, FALSE); chBSemInit(&motor_right_sem, FALSE); //disable motors pwmStart(motor_pwm, &motor_pwmcfg); pwmEnableChannel(motor_pwm, lp1, PWM_PERCENTAGE_TO_WIDTH(motor_pwm,0)); pwmEnableChannel(motor_pwm, lp2, PWM_PERCENTAGE_TO_WIDTH(motor_pwm,0)); pwmEnableChannel(motor_pwm, rp1, PWM_PERCENTAGE_TO_WIDTH(motor_pwm,0)); pwmEnableChannel(motor_pwm, rp2, PWM_PERCENTAGE_TO_WIDTH(motor_pwm,0)); return TRUE; }
void blik(arg_t) { static int16_t ja = 0; static int16_t inc = 10; //palTogglePad(TEST_LED_PORT, TEST_LED_PIN); if (ja > 800) inc = -10; if (ja < 30) inc = 10; ja = ja + inc; pwmEnableChannel(&PWMD2, 2, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, ja)); }
static msg_t Thread4(void *arg) { // chThdSleepMilliseconds(2000); //steering motor (void)arg; chRegSetThreadName("steeringthread"); enum {UP, DOWN}; int dir = UP, step = 2, width = 1100 , center =1500; while (TRUE) { pwmEnableChannel(&PWMD3, 3, steeringMotor); width += 100; chThdSleepMilliseconds(5000); } return (msg_t)0; }
/* * GPIO_TRIGGER interrupt callback. Start transmit burst, disable additional * transmit interrupts for TRANSMIT_LOCKOUT. */ static void extTransmit(EXTDriver *extp, expchannel_t channel) { (void)extp; (void)channel; //Start transmitting pwmEnableChannel(&PWMD2, 3, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, 5000)); palClearPad(GPIOA, GPIO_RX); //Disable Transmit interrupt and start timer to reenable extChannelDisableI(&EXTD1, 0); //Disable transmit interrupt gptStartOneShotI(&GPTD1, TRANSMIT_TIME); //Start timer for transmit gptStartOneShotI(&GPTD3, TRANSMIT_LOCKOUT); //Start timer for transmit unlock chSysUnlockFromIsr(); }
void motorInit(void) { //Pin selection PC8 PC9 palSetPadMode(GPIOC, 8, PAL_MODE_ALTERNATE(2)); palSetPadMode(GPIOC, 9, PAL_MODE_ALTERNATE(2));//650 // hardware confg pwmStart(&PWMD3, &pwmcfg); //drive motor enable pwmEnableChannel(&PWMD3, 2, drive_pulse); //wait until it enables drive motor chThdSleepMilliseconds(500); //start threed chThdCreateStatic(waThread3, sizeof(waThread3),NORMALPRIO + 10, Thread3, NULL); chThdCreateStatic(waThread4, sizeof(waThread4),NORMALPRIO + 10, Thread4, NULL); }
static msg_t Thread1(void *arg) { (void)arg; // Next deadline. systime_t time; chRegSetThreadName("accelreader"); // Reader thread loop. time = chTimeNow(); while (TRUE) { readAccel(); chMtxLock(&accelMtx); // Reprogramming the four PWM channels using the accelerometer data. if (accel_y[4] < 0) { pwmEnableChannel(&PWMD4, 0, (pwmcnt_t)-accel_y[4]); pwmEnableChannel(&PWMD4, 2, (pwmcnt_t)0); } else { pwmEnableChannel(&PWMD4, 2, (pwmcnt_t)accel_y[4]); pwmEnableChannel(&PWMD4, 0, (pwmcnt_t)0); } if (accel_x[4] < 0) { pwmEnableChannel(&PWMD4, 1, (pwmcnt_t)-accel_x[4]); pwmEnableChannel(&PWMD4, 3, (pwmcnt_t)0); } else { pwmEnableChannel(&PWMD4, 3, (pwmcnt_t)accel_x[4]); pwmEnableChannel(&PWMD4, 1, (pwmcnt_t)0); } chMtxUnlock(); // Waiting until the next 250 milliseconds time interval. chThdSleepUntil(time += MS2ST(100)); } return (msg_t)0; }
int main(void) { static int step = 100, width = 500; /* starts at .7ms, ends at 2.5ms */ halInit(); chSysInit(); // sets alternate mode 2 which is TIM4 palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(2)); pwmStart(&PWMD4, &pwmcfg); while (TRUE) { pwmEnableChannel(&PWMD4, 2, width); // if all the way to the left or right, go back the way you came if (width <= 700) step = 100; else if (width >= 2500) step = -100; // now increment the width by step width += step; // brief delay chThdSleepMilliseconds(100); } }
/** * thread function * @return nothing useful */ msg_t CLightHandler::main(void){ const uint16_t STEPS = 100; static systime_t interval = 0; static uint16_t pwmStep = 0; /* config listener to alarm notification */ CLightAlarmNotification *alarm; Listener<CLightAlarmNotification,5> listenerAlarm(¬ifyLightAlarm); /* pwm configuration */ static PWMConfig pwmcfg = { u16LightPWMFreq, /* 10kHz PWM clock frequency. */ u16LightPWMMax, /* Initial PWM period 1S. */ NULL, { {PWM_OUTPUT_ACTIVE_HIGH, NULL}, {PWM_OUTPUT_ACTIVE_HIGH, NULL}, {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_DISABLED, NULL} }, 0, 0 }; /* * start pwm with 0 level */ pwmStart(&PWMD5, &pwmcfg); pwmEnableChannel(&PWMD5,0,u16LightLevel); /* Task loop */ while(true){ /* check for the light alarm */ alarm = listenerAlarm.get(); /* build intervall in ms, be carefull with numbers its uint16 */ interval = ((uint16_t)alarm->u8LightMinutes)*(60000/STEPS); /* the pwm step needs to be greater than 0 to do just anything */ pwmStep = ((u16LightPWMMax - u16LightLevel) / STEPS) +1; /* set flag that light alarm is avtive */ bLightAlarm = true; /* * step though the sunrise :) */ for( ; u16LightLevel < u16LightPWMMax; u16LightLevel += pwmStep){ /* some one set the light to a fixed level */ if(bLightAlarm == false){ break; } /* wait for access */ semLightLevelSet.wait(); if(u16LightLevel > u16LightPWMMax){ u16LightLevel = u16LightPWMMax; } pwmEnableChannel(&PWMD5,0,u16LightLevel); /* release access */ semLightLevelSet.signal(); sleep(interval); } /* reset flag that light alarm is avtive */ bLightAlarm = false; } return 0; }
static THD_FUNCTION(ThreadRecord, arg) { (void)arg; chRegSetThreadName("Recording"); uint16_t duty = 0; uint8_t result = 0; uint8_t count = 0; bool debounce = false; bool indicator = false; /* Load settings from EE first */ if (readSettingsFromEE() != 0) { pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 10000)); writeSettingsToEE(); chThdSleepMilliseconds(3000); } if (readTablesFromEE() != 0) { pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 0)); chThdSleepMilliseconds(1000); pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 10000)); chThdSleepMilliseconds(3000); } while (true) { if (palReadPad(PORT_BUTTON1, PAD_BUTTON1) == PAL_LOW) { if (!debounce) { pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 10000)); count++; indicator = true; } else { count = 0; indicator = false; } } else { count = 0; debounce = false; indicator = false; } if (count >= 2 && !debounce) { /* Toggle Record mode */ settings.functions ^= FUNC_RECORD; writeSettingsToEE(); readSettingsFromEE(); debounce = true; pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 0)); chThdSleepMilliseconds(150); pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 10000)); chThdSleepMilliseconds(150); pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 0)); chThdSleepMilliseconds(150); pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 10000)); chThdSleepMilliseconds(150); pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, 0)); } if (settings.functions & FUNC_RECORD) { /* Record tables */ result = writeTablesToEE(); if (result == 0) { duty = duty == 0 ? 10000 : 0; } else { duty = duty == 0 ? 1000 : 0; } } else { duty = 0; } if (!indicator) pwmEnableChannel(&PWMD_LED1, CHN_LED1, PWM_PERCENTAGE_TO_WIDTH(&PWMD_LED1, duty)); chThdSleepMilliseconds(500); } return; }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * LED initially off. */ palSetPad(IOPORT3, GPIOC_LED); /* * Initializes the PWM driver 1 and ICU driver 4. */ pwmStart(&PWMD1, &pwmcfg); palSetPadMode(IOPORT1, 8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); icuStart(&ICUD4, &icucfg); icuEnable(&ICUD4); chThdSleepMilliseconds(2000); /* * Starts the PWM channel 0 using 75% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 7500)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 50% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 25% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 2500)); chThdSleepMilliseconds(5000); /* * Changes PWM period to half second the duty cycle becomes 50% * implicitly. */ pwmChangePeriod(&PWMD1, 5000); chThdSleepMilliseconds(5000); /* * Disables channel 0 and stops the drivers. */ pwmDisableChannel(&PWMD1, 0); pwmStop(&PWMD1); icuDisable(&ICUD4); icuStop(&ICUD4); palSetPad(IOPORT3, GPIOC_LED); /* * Normal main() thread activity, in this demo it does nothing. */ while (TRUE) { chThdSleepMilliseconds(500); } return 0; }
static THD_FUNCTION(Thread1, arg) { static int8_t xbuf[4], ybuf[4]; /* Last accelerometer data.*/ systime_t time; /* Next deadline.*/ (void)arg; chRegSetThreadName("reader"); /* LIS302DL initialization.*/ lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG1, 0x43); lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG2, 0x00); lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG3, 0x00); /* Reader thread loop.*/ time = chVTGetSystemTime(); while (TRUE) { int32_t x, y; unsigned i; /* Keeping an history of the latest four accelerometer readings.*/ for (i = 3; i > 0; i--) { xbuf[i] = xbuf[i - 1]; ybuf[i] = ybuf[i - 1]; } /* Reading MEMS accelerometer X and Y registers.*/ xbuf[0] = (int8_t)lis302dlReadRegister(&SPID1, LIS302DL_OUTX); ybuf[0] = (int8_t)lis302dlReadRegister(&SPID1, LIS302DL_OUTY); /* Transmitting accelerometer the data over SPI2.*/ spiSelect(&SPID2); spiSend(&SPID2, 4, xbuf); spiSend(&SPID2, 4, ybuf); spiUnselect(&SPID2); /* Calculating average of the latest four accelerometer readings.*/ x = ((int32_t)xbuf[0] + (int32_t)xbuf[1] + (int32_t)xbuf[2] + (int32_t)xbuf[3]) / 4; y = ((int32_t)ybuf[0] + (int32_t)ybuf[1] + (int32_t)ybuf[2] + (int32_t)ybuf[3]) / 4; /* Reprogramming the four PWM channels using the accelerometer data.*/ if (y < 0) { pwmEnableChannel(&PWMD4, 0, (pwmcnt_t)-y); pwmEnableChannel(&PWMD4, 2, (pwmcnt_t)0); } else { pwmEnableChannel(&PWMD4, 2, (pwmcnt_t)y); pwmEnableChannel(&PWMD4, 0, (pwmcnt_t)0); } if (x < 0) { pwmEnableChannel(&PWMD4, 1, (pwmcnt_t)-x); pwmEnableChannel(&PWMD4, 3, (pwmcnt_t)0); } else { pwmEnableChannel(&PWMD4, 3, (pwmcnt_t)x); pwmEnableChannel(&PWMD4, 1, (pwmcnt_t)0); } /* Waiting until the next 250 milliseconds time interval.*/ chThdSleepUntil(time += MS2ST(100)); } }
extern void bldcStart(void) { // The PWM output generator channel. pwmEnableChannel (&PWMD1, PWM_PULSE0_CH, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, bldc.dutyCycle)); }
void actuators_pwm_commit(void) { #ifdef PWM_SERVO_0 pwmEnableChannel(&PWM_SERVO_0_DRIVER, PWM_SERVO_0_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_0])); #endif #ifdef PWM_SERVO_1 pwmEnableChannel(&PWM_SERVO_1_DRIVER, PWM_SERVO_1_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_1])); #endif #ifdef PWM_SERVO_2 pwmEnableChannel(&PWM_SERVO_2_DRIVER, PWM_SERVO_2_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_2])); #endif #ifdef PWM_SERVO_3 pwmEnableChannel(&PWM_SERVO_3_DRIVER, PWM_SERVO_3_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_3])); #endif #ifdef PWM_SERVO_4 pwmEnableChannel(&PWM_SERVO_4_DRIVER, PWM_SERVO_4_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_4])); #endif #ifdef PWM_SERVO_5 pwmEnableChannel(&PWM_SERVO_5_DRIVER, PWM_SERVO_5_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_5])); #endif #ifdef PWM_SERVO_6 pwmEnableChannel(&PWM_SERVO_6_DRIVER, PWM_SERVO_6_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_6])); #endif #ifdef PWM_SERVO_7 pwmEnableChannel(&PWM_SERVO_7_DRIVER, PWM_SERVO_7_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_7])); #endif #ifdef PWM_SERVO_8 pwmEnableChannel(&PWM_SERVO_8_DRIVER, PWM_SERVO_8_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_8])); #endif #ifdef PWM_SERVO_9 pwmEnableChannel(&PWM_SERVO_9_DRIVER, PWM_SERVO_9_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_9])); #endif #ifdef PWM_SERVO_10 pwmEnableChannel(&PWM_SERVO_10_DRIVER, PWM_SERVO_10_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_10])); #endif #ifdef PWM_SERVO_11 pwmEnableChannel(&PWM_SERVO_11_DRIVER, PWM_SERVO_11_CHANNEL, PWM_CMD_TO_US(actuators_pwm_values[PWM_SERVO_11])); #endif }
void InitHardware() { // Pin configuration for motors/ESCs palSetPadMode(GPIOA, 4, PAL_MODE_ALTERNATE(2)); // motor 1 -> PA4 : TIM3 CH2 palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(2)); // motor 2 -> PA6 : TIM3 CH1 palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATE(2)); // motor 3 -> PB0 : TIM3 CH3 palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATE(2)); // motor 4 -> PB1 : TIM3 CH4 // Timer 3 used for all motors pwmStart(&PWMD3, &pwmcfg); PWMD3.tim->CR1=0; // Disable counter PWMD3.tim->CNT=0; // Reset timer counter // Enable timer 1 Channel 0 pwmEnableChannel(&PWMD3, 1, THROTTLE_MIN); pwmEnableChannel(&PWMD3, 0, THROTTLE_MIN); pwmEnableChannel(&PWMD3, 2, THROTTLE_MIN); pwmEnableChannel(&PWMD3, 3, THROTTLE_MIN); PWMD3.tim->CCMR2|=(7<<4)|(7<<12); // PWM mode 2 PWMD3.tim->CCMR2&=~((1<<3)|(1<<11)); // Clear OC1PE PWMD3.tim->CCMR1|=(7<<4)|(7<<12); // PWM mode 2 PWMD3.tim->CCMR1&=~((1<<3)|(1<<11)); // Clear OC1PE /* * I2C I/O pins setup. */ palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(4)); palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(4)); i2cStart(&I2CD2, &i2cconfig); #if LOG /* * SPI2 I/O pins setup. */ palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) |PAL_STM32_OSPEED_HIGHEST); /* New SCK. */ palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(5) |PAL_STM32_OSPEED_HIGHEST); /* New MISO. */ palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST); /* New MOSI. */ palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); /* New CS. */ palSetPad(GPIOB, 12); #endif /* * LEDs settings */ palSetPadMode(GPIOB, 5, PAL_MODE_OUTPUT_PUSHPULL); /* SCK. */ TURN_LED_OFF(); #if BUZZER /* * UART Inverter settings */ palSetPadMode(GPIOA, 0, PAL_MODE_OUTPUT_PUSHPULL); /* SCK. */ palClearPad(GPIOA, 0); #endif /* * UART Receiver pin */ palSetPadMode(GPIOB, 4, PAL_MODE_ALTERNATE(7)); /* UART 6 RX. */ /* * Activates the USB driver and then the USB bus pull-up on D+. * Note, a delay is inserted in order to not have to disconnect the cable * after a reset. */ #if (DEBUG_MODE || LOG) sduObjectInit(&SDU1); sduStart(&SDU1, &serusbcfg); usbDisconnectBus(serusbcfg.usbp); chThdSleepMilliseconds(1500); usbStart(serusbcfg.usbp, &usbcfg); usbConnectBus(serusbcfg.usbp); #endif }
/* * Application entry point. */ int main(void) { /* Initialization of all the imported components in the order specified in the application wizard. The function is generated automatically.*/ componentsInit(); palClearPad(PORT11, P11_LED4); /* * Initializes the PWM driver 8 and ICU driver 1. * PIN80 is the PWM output. * PIN63 is the ICU input. * The two pins have to be externally connected together. */ /* Sets PIN63 alternative function.*/ SIU.PCR[179].R = 0b0000011000001100; /* Sets PIN65 alternative function.*/ SIU.PCR[181].R = 0b0000010100001100; icuStart(&ICUD2, &icucfg); icuEnable(&ICUD2); pwmStart(&PWMD1, &pwmcfg); chThdSleepMilliseconds(2000); /* * Starts the PWM channel 0 using 75% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 7500)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 50% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 25% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 2500)); chThdSleepMilliseconds(5000); /* * Changes PWM period and the PWM channel 0 to 50% duty cycle. */ pwmChangePeriod(&PWMD1, 25000); pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); chThdSleepMilliseconds(5000); /* * Disables PWM channel 0 and stops the drivers. */ pwmDisableChannel(&PWMD1, 0); pwmStop(&PWMD1); /* * Disables and stops the ICU drivers. */ icuDisable(&ICUD2); icuStop(&ICUD2); palClearPad(PORT11, P11_LED3); palClearPad(PORT11, P11_LED4); /* * Normal main() thread activity, in this demo it does nothing. */ while (TRUE) { chThdSleepMilliseconds(500); } return 0; }
static THD_FUNCTION(ThreadButton, arg) { (void)arg; bool bfs; bool bns; chRegSetThreadName("ON_ext"); while(true){ /** lock "pause" interupt task **/ chSysLock(); tp_button = chThdGetSelfX(); chSchGoSleepS(CH_STATE_SUSPENDED); chSysUnlock(); extStop(&EXTD1); /**disable EXT driver **/ pwmEnableChannel(&PWMD4, 1, 255); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 0); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 255); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 0); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 255); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 0); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 255); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 0); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 255); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 0); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 255); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 0); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 255); chThdSleep(5000); pwmEnableChannel(&PWMD4, 1, 0); chThdSleep(5000); /** READ button pin**/ bns = palReadPad(GPIOC,button_ID); if ( !bns){ switch(button_ID){ case 0: CanWriteDATA( DEVICE_ID_IN_BCC , BCC_ID ,inttofloat(TPMCCV)); //CanWriteDATA( 101 ,1202 ,inttofloat(8)); break; case 1: CanWriteDATA( DEVICE_ID_IN_BCC ,BCC_ID ,inttofloat(FCMCCV)); //CanWriteDATA( 101 ,1202 ,inttofloat(4)); break; case 2: CanWriteDATA( DEVICE_ID_IN_BCC ,BCC_ID ,inttofloat(OPMCCV)); //CanWriteDATA( 101 ,1202 ,inttofloat(2)); break; case 3: CanWriteDATA( DEVICE_ID_IN_BCC ,BCC_ID ,inttofloat(SBMCCV)); //CanWriteDATA( 101 ,1202 ,inttofloat(1)); break; } } StartEXT(); /** EXT driver On agen **/ } }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Starting PWM driver 1 and enabling the notifications. * GPIOA8 is programmed as PWM output (channel 1 of TIM1). */ pwmStart(&PWMD1, &pwmcfg); pwmEnablePeriodicNotification(&PWMD1); palSetPadMode(GPIOA, GPIOA_ARD_D5, PAL_MODE_ALTERNATE(1)); /* * Starting ICU driver 2. * GPIOA15 is programmed as ICU input (channel 1 of TIM2). */ icuStart(&ICUD2, &icucfg); palSetPadMode(GPIOA, GPIOA_ARD_D9, PAL_MODE_ALTERNATE(1)); /* * GPIOI1 is programmed as output (board LED). */ palClearPad(GPIOI, GPIOI_ARD_D13); palSetPadMode(GPIOI, GPIOI_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL); chThdSleepMilliseconds(1000); /* * Starting ICU capture and enabling the notifications. */ icuStartCapture(&ICUD2); icuEnableNotifications(&ICUD2); /* * Normal main() thread activity, various PWM patterns are generated * cyclically, if the ICU input is connected to the PWM output the * board LED mirrors the PWM output. */ while (true) { /* * Starts the PWM channel 0 using 75% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 7500)); pwmEnableChannelNotification(&PWMD1, 0); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 50% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 25% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 2500)); chThdSleepMilliseconds(5000); /* * Changes PWM period to half second the duty cycle becomes 50% * implicitly. */ pwmChangePeriod(&PWMD1, 5000); chThdSleepMilliseconds(5000); /* * Disables channel 0. */ pwmDisableChannel(&PWMD1, 0); } }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Initializes the PWM driver 2 and ICU driver 3. * GPIOA15 is the PWM output. * GPIOC6 is the ICU input. * The two pins have to be externally connected together. */ pwmStart(&PWMD2, &pwmcfg); palSetPadMode(GPIOA, 15, PAL_MODE_ALTERNATE(1)); icuStart(&ICUD3, &icucfg); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); icuEnable(&ICUD3); chThdSleepMilliseconds(2000); /* * Starts the PWM channel 0 using 75% duty cycle. */ pwmEnableChannel(&PWMD2, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, 7500)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 50% duty cycle. */ pwmEnableChannel(&PWMD2, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, 5000)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 25% duty cycle. */ pwmEnableChannel(&PWMD2, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, 2500)); chThdSleepMilliseconds(5000); /* * Changes PWM period to half second the duty cycle becomes 50% * implicitly. */ pwmChangePeriod(&PWMD2, 5000); chThdSleepMilliseconds(5000); /* * Disables channel 0 and stops the drivers. */ pwmDisableChannel(&PWMD2, 0); pwmStop(&PWMD2); icuDisable(&ICUD3); icuStop(&ICUD3); palClearPad(GPIOE, GPIOE_LED4_BLUE); palClearPad(GPIOE, GPIOE_LED9_BLUE); /* * Normal main() thread activity, in this demo it does nothing. */ while (TRUE) { chThdSleepMilliseconds(500); } return 0; }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); palSetPadMode(GPIOF, GPIOF_LED_RED, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(GPIOF, GPIOF_LED_GREEN, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(GPIOF, GPIOF_LED_BLUE, PAL_MODE_OUTPUT_PUSHPULL); /* * Start PWM driver */ pwmStart(&PWMD1, &pwmcfg); pwmEnableChannel(&PWMD1, 0, 0); pwmEnableChannel(&PWMD1, 1, 0); pwmEnableChannel(&PWMD1, 2, 0); pwmEnableChannelNotification(&PWMD1, 0); pwmEnableChannelNotification(&PWMD1, 1); pwmEnableChannelNotification(&PWMD1, 2); pwmEnablePeriodicNotification(&PWMD1); /* * Normal main() thread activity */ while (TRUE) { uint16_t rgbColour[3]; uint8_t decColour; uint16_t i; // Start off with red. rgbColour[0] = pwmcfg.frequency - 2; rgbColour[1] = 0; rgbColour[2] = 0; // Choose the colours to increment and decrement. for (decColour = 0; decColour < 3; decColour++) { int incColour = decColour == 2 ? 0 : decColour + 1; // cross-fade the two colours. for(i = 0; i < pwmcfg.frequency - 2; i++) { rgbColour[decColour] -= 1; rgbColour[incColour] += 1; pwmEnableChannel(&PWMD1, 0, rgbColour[0]); pwmEnableChannel(&PWMD1, 1, rgbColour[1]); pwmEnableChannel(&PWMD1, 2, rgbColour[2]); chThdSleepMilliseconds(1); } } } return 0; }
/** * @brief This is the pressure control thread * @param void* to a PID Loops configuration * @retval msg_t status */ msg_t Pressure_Thread(void *This_Config) { /* This thread is passed a pointer to a PID loop configuration */ PID_State Pressure_PID_Controllers[((Pressure_Config_Type*)This_Config)->Number_Setpoints]; memset(Pressure_PID_Controllers,0,((Pressure_Config_Type*)This_Config)->Number_Setpoints*sizeof(PID_State));/* Initialise as zeros */ float* Last_PID_Out=(float*)chHeapAlloc(NULL,sizeof(float)*((Pressure_Config_Type*)This_Config)->Number_Setpoints);/* PID output for interpol */ adcsample_t Pressure_Samples[PRESSURE_SAMPLES],Pressure_Sample;/* Use multiple pressure samples to drive down the noise */ float PID_Out,Pressure;//,step=0.01,sawtooth=0.7; uint32_t Setpoint=0; uint8_t Old_Setpoint=0, Previous_Setpoint; chRegSetThreadName("PID_Pressure"); //palSetGroupMode(GPIOC, PAL_PORT_BIT(5) | PAL_PORT_BIT(4), 0, PAL_MODE_INPUT_ANALOG); palSetPadMode(GPIOE, 9, PAL_MODE_ALTERNATE(1)); /* Only set the pin as AF output here, so as to avoid solenoid getting driven earlier*/ palSetPadMode(GPIOE, 11, PAL_MODE_ALTERNATE(1)); /* Experimental servo output here */ #ifndef USE_SERVO /* * Activates the PWM driver */ pwmStart(&PWM_Driver_Solenoid, &PWM_Config_Solenoid); /* Have to define the timer to use for PWM_Driver in hardware config */ /* * Set the solenoid PWM to off */ pwmEnableChannel(&PWM_Driver_Solenoid, (pwmchannel_t)PWM_CHANNEL_SOLENOID, (pwmcnt_t)0); #else /* * Activates the experimental servo driver */ pwmStart(&PWM_Driver_Servo, &PWM_Config_Servo); /* Have to define the timer to use for PWM_Driver in hardware config */ #endif /* * Activates the ADC2 driver *and the thermal sensor*. */ adcStart(&ADCD2, NULL); //adcSTM32EnableTSVREFE(); /* / Now we run the sensor offset calibration loop */ do { adcConvert(&ADCD2, &adcgrpcfg1, &Pressure_Sample, 1);/* This function blocks until it has one sample*/ } while(Calibrate_Sensor((uint16_t)Pressure_Sample)); systime_t time = chTimeNow(); /* T0 */ systime_t Interpolation_Timeout = time; /* Set to T0 to show there is no current interpolation */ /* Loop for the pressure control thread */ while(TRUE) { /* * Linear conversion. */ adcConvert(&ADCD2, &adcgrpcfg1, Pressure_Samples, PRESSURE_SAMPLES);/* This function blocks until it has the samples via DMA*/ /* / Now we process the data and apply the PID controller - we use a median filter to take out the non guassian noise */ Pressure_Sample = quick_select(Pressure_Samples, PRESSURE_SAMPLES); Pressure = Convert_Pressure((uint16_t)Pressure_Sample);/* Converts to PSI as a float */ /* Retrieve a new setpoint from the setpoint mailbox, only continue if we get it*/ if(chMBFetch(&Pressures_Setpoint, (msg_t*)&Setpoint, TIME_IMMEDIATE) == RDY_OK) { //Pressure=Run_Pressure_Filter(Pressure);/* Square root raised cosine filter for low pass with minimal lag */ Pressure = Pressure<0?0.0:Pressure; /* A negative pressure is impossible with current hardware setup - disregard*/ Setpoint &= 0x000000FF; /* The controller is built around an interpolated array of independant PID controllers with seperate setpoints */ if(Setpoint != Old_Setpoint) { /* The setpoint has changed */ Previous_Setpoint = Old_Setpoint;/* This is for use by the interpolator */ Old_Setpoint = Setpoint; /* Store the setpoint */ /* Store the time at which the interpolation to new setpoint completes*/ Interpolation_Timeout = time + (systime_t)( 4.0 / ((Pressure_Config_Type*)This_Config)->Interpolation_Base ); } if(Interpolation_Timeout > time) { /* If we have an ongoing interpolation - note, operates in tick units */ /* Value goes from 1 to -1 */ float interpol = erff( (float)(Interpolation_Timeout - time) *\ ((Pressure_Config_Type*)This_Config)->Interpolation_Base - 2.0 );/* erf function interpolator */ interpol = ( (-interpol + 1.0) / 2.0);/* Interpolation value goes from 0 to 1 */ PID_Out = ( Last_PID_Out[Previous_Setpoint] * (1.0 - interpol) ) + ( Last_PID_Out[Setpoint] * interpol ); Pressure_PID_Controllers[Setpoint].Last_Input = Pressure;/* Make sure the input to next PID controller is continuous */ } else { PID_Out = Run_PID_Loop( ((Pressure_Config_Type*)This_Config)->PID_Loop_Config, &Pressure_PID_Controllers[Setpoint],\ (((Pressure_Config_Type*)This_Config)->Setpoints)[Setpoint], \ Pressure, (float)PRESSURE_TIME_INTERVAL/1000.0);/* Run PID */ Last_PID_Out[Setpoint] = PID_Out;/* Store for use by the interpolator */ } } else PID_Out=0; /* So we can turn off the solenoid simply by failing to send Setpoints */ PID_Out=PID_Out>1.0?1.0:PID_Out; PID_Out=PID_Out<0.0?0.0:PID_Out; /* Enforce range limits on the PID output */ //sawtooth+=step; /* Test code for debugging mechanics with a sawtooth */ //if(sawtooth>=1 || sawtooth<=0.65) // step=-step; //PID_Out=sawtooth; #ifndef USE_SERVO /* / Now we apply the PID output to the PWM based solenoid controller, and feed data into the mailbox output - Note fractional input */ pwmEnableChannel(&PWM_Driver_Solenoid, (pwmchannel_t)PWM_CHANNEL_SOLENOID, (pwmcnt_t)PWM_FRACTION_TO_WIDTH(&PWM_Driver_Solenoid, 1000\ , (uint32_t)(1000.0*PID_Out))); #else pwmEnableChannel(&PWM_Driver_Servo, (pwmchannel_t)PWM_CHANNEL_SERVO, (pwmcnt_t)PWM_FRACTION_TO_WIDTH(&PWM_Driver_Servo, 10000\ , (uint32_t)(1000.0*(PID_Out+1.0)))); #endif chMBPost(&Pressures_Reported, *((msg_t*)&Pressure), TIME_IMMEDIATE);/* Non blocking write attempt to the Reported Pressure mailbox FIFO */ /* / The Thread is syncronised to system time */ time += MS2ST(PRESSURE_TIME_INTERVAL); /* Next deadline */ chThdSleepUntil(time); /* Gives us a thread with regular timing */ } }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Initializes the PWM driver 1 and ICU driver 1. * GPIOD10 is the PWM output. * GPIOA0 is the ICU input. * The two pins have to be externally connected together. */ icuStart(&ICUD1, &icucfg); icuEnable(&ICUD1); /* Sets A0 alternative function.*/ SIU.PCR[0].R = 0b0100010100000100; pwmStart(&PWMD1, &pwmcfg); /* Sets D10 alternative function.*/ SIU.PCR[58].R = 0b0100010100000100; chThdSleepMilliseconds(2000); /* * Starts the PWM channel 0 using 75% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 7500)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 50% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 25% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 2500)); chThdSleepMilliseconds(5000); /* * Changes PWM period and the PWM channel 0 to 50% duty cycle. */ pwmChangePeriod(&PWMD1, 25000); pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); chThdSleepMilliseconds(5000); /* * Disables channel 0 and stops the drivers. */ pwmDisableChannel(&PWMD1, 0); pwmStop(&PWMD1); icuDisable(&ICUD1); icuStop(&ICUD1); palClearPad(PORT_D, PD_LED3); palClearPad(PORT_D, PD_LED4); /* * Normal main() thread activity, in this demo it does nothing. */ while (TRUE) { chThdSleepMilliseconds(500); } return 0; }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Initializes the PWM driver 1 and ICU driver 2. * GPIOE9 is the PWM output. * GPIOA0 is the ICU input. * The two pins have to be externally connected together. */ pwmStart(&PWMD1, &pwmcfg); pwmEnablePeriodicNotification(&PWMD1); icuStart(&ICUD2, &icucfg); icuStartCapture(&ICUD2); icuEnableNotifications(&ICUD2); chThdSleepMilliseconds(2000); /* * Starts the PWM channel 0 using 75% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 7500)); pwmEnableChannelNotification(&PWMD1, 0); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 50% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 25% duty cycle. */ pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 2500)); chThdSleepMilliseconds(5000); /* * Changes PWM period to half second the duty cycle becomes 50% * implicitly. */ pwmChangePeriod(&PWMD1, 5000); chThdSleepMilliseconds(5000); /* * Disables channel 0 and stops the drivers. */ pwmDisableChannel(&PWMD1, 0); pwmStop(&PWMD1); icuStopCapture(&ICUD2); icuStop(&ICUD2); palClearPad(GPIOB, GPIOB_LED1); palClearPad(GPIOB, GPIOB_LED2); /* * Normal main() thread activity, in this demo it does nothing. */ while (true) { chThdSleepMilliseconds(500); } return 0; }