static void pwm_channel_init(unsigned channel) { unsigned timer = pwm_channels[channel].timer_index; /* configure the GPIO first */ stm32_configgpio(pwm_channels[channel].gpio); /* configure the channel */ switch (pwm_channels[channel].timer_channel) { case 1: rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC1M_SHIFT) | GTIM_CCMR1_OC1PE; rCCR1(timer) = pwm_channels[channel].default_value; rCCER(timer) |= GTIM_CCER_CC1E; break; case 2: rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC2M_SHIFT) | GTIM_CCMR1_OC2PE; rCCR2(timer) = pwm_channels[channel].default_value; rCCER(timer) |= GTIM_CCER_CC2E; break; case 3: rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC3M_SHIFT) | GTIM_CCMR2_OC3PE; rCCR3(timer) = pwm_channels[channel].default_value; rCCER(timer) |= GTIM_CCER_CC3E; break; case 4: rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC4M_SHIFT) | GTIM_CCMR2_OC4PE; rCCR4(timer) = pwm_channels[channel].default_value; rCCER(timer) |= GTIM_CCER_CC4E; break; } }
servo_position_t up_pwm_servo_get(unsigned channel) { if (channel >= PWM_SERVO_MAX_CHANNELS) return 0; unsigned timer = pwm_channels[channel].timer_index; servo_position_t value = 0; /* test timer for validity */ if ((pwm_timers[timer].base == 0) || (pwm_channels[channel].timer_channel == 0)) return 0; /* configure the channel */ switch (pwm_channels[channel].timer_channel) { case 1: value = rCCR1(timer); break; case 2: value = rCCR2(timer); break; case 3: value = rCCR3(timer); break; case 4: value = rCCR4(timer); break; } return value + 1; }
static servo_position_t pwm_channel_get(unsigned channel) { if (channel >= PWM_SERVO_MAX_CHANNELS) { lldbg("pwm_channel_get: bogus channel %u\n", channel); return 0; } unsigned timer = cfg->channels[channel].timer_index; servo_position_t value = 0; /* test timer for validity */ if ((cfg->timers[timer].base == 0) || (cfg->channels[channel].gpio == 0)) return 0; /* configure the channel */ switch (cfg->channels[channel].timer_channel) { case 1: value = rCCR1(timer); break; case 2: value = rCCR2(timer); break; case 3: value = rCCR3(timer); break; case 4: value = rCCR4(timer); break; } return value; }
static void pwm_channel_init(unsigned channel) { unsigned timer = cfg->channels[channel].timer_index; /* configure the GPIO first */ stm32_configgpio(cfg->channels[channel].gpio); /* configure the channel */ switch (cfg->channels[channel].timer_channel) { case 1: rCCMR1(timer) |= (6 << 4); rCCR1(timer) = cfg->channels[channel].default_value; rCCER(timer) |= (1 << 0); break; case 2: rCCMR1(timer) |= (6 << 12); rCCR2(timer) = cfg->channels[channel].default_value; rCCER(timer) |= (1 << 4); break; case 3: rCCMR2(timer) |= (6 << 4); rCCR3(timer) = cfg->channels[channel].default_value; rCCER(timer) |= (1 << 8); break; case 4: rCCMR2(timer) |= (6 << 12); rCCR4(timer) = cfg->channels[channel].default_value; rCCER(timer) |= (1 << 12); break; } }
int led_pwm_servo_set(unsigned channel, uint8_t cvalue) { if (channel >= arraySize(led_pwm_channels)) { return -1; } unsigned timer = led_pwm_channels[channel].timer_index; /* test timer for validity */ if ((led_pwm_timers[timer].base == 0) || (led_pwm_channels[channel].gpio_out == 0)) { return -1; } unsigned period = led_pwm_timer_get_period(timer); #if defined(BOARD_LED_PWM_DRIVE_ACTIVE_LOW) unsigned value = period - (unsigned)cvalue * period / 255; #else unsigned value = (unsigned)cvalue * period / 255; #endif /* configure the channel */ if (value > 0) { value--; } switch (led_pwm_channels[channel].timer_channel) { case 1: rCCR1(timer) = value; break; case 2: rCCR2(timer) = value; break; case 3: rCCR3(timer) = value; break; case 4: rCCR4(timer) = value; break; default: return -1; } return 0; }
static void pwm_channel_init(unsigned channel) { unsigned timer = pwm_channels[channel].timer_index; /* configure the GPIO first */ stm32_configgpio(pwm_channels[channel].gpio); /* configure the channel */ switch (pwm_channels[channel].timer_channel) { case 1: rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC1M_SHIFT) | GTIM_CCMR1_OC1PE; rCCR1(timer) = pwm_channels[channel].default_value; #if defined(CONFIG_ARCH_BOARD_TMRFC_V1) if(channel == 12) rCCER(timer) |= GTIM_CCER_CC1NE; /* complementary output enable */ else #endif rCCER(timer) |= GTIM_CCER_CC1E; break; case 2: rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC2M_SHIFT) | GTIM_CCMR1_OC2PE; rCCR2(timer) = pwm_channels[channel].default_value; #if defined(CONFIG_ARCH_BOARD_TMRFC_V1) if(channel == 6) rCCER(timer) |= GTIM_CCER_CC2NE; /* complementary output enable */ else #endif rCCER(timer) |= GTIM_CCER_CC2E; break; case 3: rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC3M_SHIFT) | GTIM_CCMR2_OC3PE; rCCR3(timer) = pwm_channels[channel].default_value; #if defined(CONFIG_ARCH_BOARD_TMRFC_V1) if(channel == 7) rCCER(timer) |= GTIM_CCER_CC3NE; /* complementary output enable */ else #endif rCCER(timer) |= GTIM_CCER_CC3E; break; case 4: rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC4M_SHIFT) | GTIM_CCMR2_OC4PE; rCCR4(timer) = pwm_channels[channel].default_value; rCCER(timer) |= GTIM_CCER_CC4E; break; } }
static void led_pwm_timer_init_timer(unsigned timer) { irqstate_t flags = px4_enter_critical_section(); /* enable the timer clock before we try to talk to it */ modifyreg32(led_pwm_timers[timer].clock_register, 0, led_pwm_timers[timer].clock_bit); /* disable and configure the timer */ rCR1(timer) = 0; rCR2(timer) = 0; rSMCR(timer) = 0; rDIER(timer) = 0; rCCER(timer) = 0; rCCMR1(timer) = 0; rCCMR2(timer) = 0; rCCR1(timer) = 0; rCCR2(timer) = 0; rCCR3(timer) = 0; rCCR4(timer) = 0; rCCER(timer) = 0; rDCR(timer) = 0; if ((led_pwm_timers[timer].base == STM32_TIM1_BASE) || (led_pwm_timers[timer].base == STM32_TIM8_BASE)) { /* master output enable = on */ rBDTR(timer) = ATIM_BDTR_MOE; } /* If the timer clock source provided as clock_freq is the STM32_APBx_TIMx_CLKIN * then configure the timer to free-run at 1MHz. * Otherwise, other frequencies are attainable by adjusting .clock_freq accordingly. */ rPSC(timer) = (led_pwm_timers[timer].clock_freq / 1000000) - 1; /* configure the timer to update at the desired rate */ rARR(timer) = (1000000 / LED_PWM_RATE) - 1; /* generate an update event; reloads the counter and all registers */ rEGR(timer) = GTIM_EGR_UG; px4_leave_critical_section(flags); }
uint16_t input_pwm_decode(uint32_t status, uint8_t timer, uint8_t timer_channel) { uint16_t count; // for now we don't care about CCxOF, state machine will take care of it switch (timer_channel) { case 1: count = rCCR1(timer); break; /* did we miss an edge? */ if (status & GTIM_SR_CC1OF) goto error; case 2: count = rCCR2(timer); break; /* did we miss an edge? */ if (status & GTIM_SR_CC2OF) goto error; case 3: count = rCCR3(timer); break; /* did we miss an edge? */ if (status & GTIM_SR_CC3OF) goto error; case 4: count = rCCR4(timer); break; /* did we miss an edge? */ if (status & GTIM_SR_CC4OF) goto error; } return count; /* the state machine is corrupted; reset it */ error: /* we don't like the state of the decoder, reset it and try again */ printf("overwrite error\n"); return 0; }
int up_pwm_servo_set(unsigned channel, servo_position_t value) { if (channel >= PWM_SERVO_MAX_CHANNELS) return -1; unsigned timer = pwm_channels[channel].timer_index; /* test timer for validity */ if ((pwm_timers[timer].base == 0) || (pwm_channels[channel].gpio == 0)) return -1; /* configure the channel */ if (value > 0) value--; switch (pwm_channels[channel].timer_channel) { case 1: rCCR1(timer) = value; break; case 2: rCCR2(timer) = value; break; case 3: rCCR3(timer) = value; break; case 4: rCCR4(timer) = value; break; case 5: rCCR2(timer) = value; break; default: return -1; } return 0; }
static void input_pwm_channel_init(unsigned channel) { unsigned timer = input_pwm_channels[channel].timer_index; /* configure the GPIO first */ stm32_configgpio(input_pwm_channels[channel].gpio); /* configure the channel */ switch (input_pwm_channels[channel].timer_channel) { case 1: rDIER(timer) |= GTIM_DIER_CC1IE; rCCMR1(timer) |= (GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR1_CC1S_SHIFT); rCCR1(timer) = 1000; rCCER(timer) |= GTIM_CCER_CC1E | GTIM_CCER_CC1P | GTIM_CCER_CC1NP; break; case 2: rDIER(timer) |= GTIM_DIER_CC2IE; rCCMR1(timer) |= (GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR1_CC2S_SHIFT); rCCR2(timer) = 1000; rCCER(timer) |= GTIM_CCER_CC2E | GTIM_CCER_CC2P | GTIM_CCER_CC2NP; break; case 3: rDIER(timer) |= GTIM_DIER_CC3IE; rCCMR2(timer) |= (GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR2_CC3S_SHIFT); rCCR3(timer) = 1000; rCCER(timer) |= GTIM_CCER_CC3E | GTIM_CCER_CC3P | GTIM_CCER_CC3NP; break; case 4: rDIER(timer) |= GTIM_DIER_CC4IE; rCCMR2(timer) |= (GTIM_CCMR_CCS_CCIN1 << GTIM_CCMR2_CC4S_SHIFT); rCCR4(timer) = 1000; rCCER(timer) |= GTIM_CCER_CC4E | GTIM_CCER_CC4P | GTIM_CCER_CC4NP; break; } }
unsigned led_pwm_servo_get(unsigned channel) { if (channel >= 3) { return 0; } unsigned timer = led_pwm_channels[channel].timer_index; servo_position_t value = 0; /* test timer for validity */ if ((led_pwm_timers[timer].base == 0) || (led_pwm_channels[channel].timer_channel == 0)) { return 0; } /* configure the channel */ switch (led_pwm_channels[channel].timer_channel) { case 1: value = rCCR1(timer); break; case 2: value = rCCR2(timer); break; case 3: value = rCCR3(timer); break; case 4: value = rCCR4(timer); break; } unsigned period = led_pwm_timer_get_period(timer); return ((value + 1) * 255 / period); }
static int pwm_input_timer_isr(void) { uint16_t count = 0; for (unsigned i = 0; i < PWM_INPUT_MAX_TIMERS; i++) { status = rSR(i); //ack the interrupts we just read rSR(i) = ~status; if (status & (GTIM_SR_CC1IF | GTIM_SR_CC1OF)) { count = rCCR1(i); //printf("Captured on T%uC1 %u\n", i, count); for (unsigned j = 0; j < PWM_INPUT_MAX_CHANNELS; j++) { if ((pwm_input_channels[j].timer_channel == 1) && (pwm_input_channels[j].timer_index == i)) { rc[j] = count - rc_last[j]; rc_last[j] = count; if (rc[j] <= MAX_PULSEWIDTH) { ppm_buffer[j]=rc[j]; ppm_last_valid_decode = hrt_absolute_time(); } //printf("RC%u: %u\n", j, rc[j]); } } } if (status & (GTIM_SR_CC2IF | GTIM_SR_CC2OF)) { count = rCCR2(i); //printf("Captured on T%uC2 %u\n", i, count); for (unsigned j = 0; j < PWM_INPUT_MAX_CHANNELS; j++) { if ((pwm_input_channels[j].timer_channel == 2) && (pwm_input_channels[j].timer_index == i)) { rc[j] = count - rc_last[j]; rc_last[j] = count; if (rc[j] <= MAX_PULSEWIDTH) { ppm_buffer[j]=rc[j]; ppm_last_valid_decode = hrt_absolute_time(); } //printf("RC%u: %u\n", j, rc[j]); } } } if (status & (GTIM_SR_CC3IF | GTIM_SR_CC3OF)) { count = rCCR3(i); //printf("Captured on T%uC3 %u\n", i, count); for (unsigned j = 0; j < PWM_INPUT_MAX_CHANNELS; j++) { if ((pwm_input_channels[j].timer_channel == 3) && (pwm_input_channels[j].timer_index == i)) { rc[j] = count - rc_last[j]; rc_last[j] = count; if (rc[j] <= MAX_PULSEWIDTH) { ppm_buffer[j]=rc[j]; ppm_last_valid_decode = hrt_absolute_time(); } //printf("RC%u: %u\n", j, rc[j]); } } } if (status & (GTIM_SR_CC4IF | GTIM_SR_CC4OF)) { count = rCCR4(i); //printf("Captured on T%uC3 %u\n", i, count); for (unsigned j = 0; j < PWM_INPUT_MAX_CHANNELS; j++) { if ((pwm_input_channels[j].timer_channel == 4) && (pwm_input_channels[j].timer_index == i)) { rc[j] = count - rc_last[j]; rc_last[j] = count; if (rc[j] <= MAX_PULSEWIDTH) { ppm_buffer[j]=rc[j]; ppm_last_valid_decode = hrt_absolute_time(); } //printf("RC%u: %u\n", j, rc[j]); } } } } return; }
uint16_t input_pwm_decode(uint32_t status, uint8_t timer, uint8_t timer_channel) { uint16_t count; // for now we don't care about CCxOF, state machine will take care of it switch (timer_channel) { case 1: count = rCCR1(timer); break; /* did we miss an edge? */ if (status & GTIM_SR_CC1OF) goto error; case 2: count = rCCR2(timer); break; /* did we miss an edge? */ if (status & GTIM_SR_CC2OF) goto error; case 3: count = rCCR3(timer); break; /* did we miss an edge? */ if (status & GTIM_SR_CC3OF) goto error; case 4: count = rCCR4(timer); break; /* did we miss an edge? */ if (status & GTIM_SR_CC4OF) goto error; } //printf("count = %d\n", count); return count; /* how long since the last edge? - this handles counter wrapping implicitely. */ /*width = count - pwm.last_edge; switch (pwm.phase) { case ARM: */ /* frame length is everything including the start gap */ /* pwm.phase = ACTIVE; break; case ACTIVE: */ /* if the mark-mark timing is out of bounds, abandon the frame */ /* if ((width < PWM_MIN_CHANNEL_VALUE) || (width > PWM_MAX_CHANNEL_VALUE)) { // goto error; } else { */ /* if we have room to store the value, do so */ /* //if (ppm.next_channel < RC_INPUT_MAX_CHANNELS) _temp_rc_buffer[0] = width; _decoded_channels = 1; pwm.phase = ARM; printf("PWM captured = %d\n", width); } break; } pwm.last_edge = count; return; */ //InputPWM::me->rc_decode(status); /* the state machine is corrupted; reset it */ error: /* we don't like the state of the decoder, reset it and try again */ printf("overwrite error\n"); return 0; //pwm.phase = ARM; //_decoded_channels = 0; }