the PWM callback doe not seem to work ??? PS i can see on scope the wavefrom....
Code: Select all
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "ch.h"
#include "hal.h"
#include "shell.h"
#include "flash.h"
#include "candr.h"
#include "console.h"
#include "filesys.h"
#include "serialcom.h"
/* Total number of channels to be sampled by a single ADC operation.*/
#define ADC_GRP1_NUM_CHANNELS 1
/* Depth of the conversion buffer, channels are sampled four times each.*/
#define ADC_GRP1_BUF_DEPTH 4
static void pwmpcb(PWMDriver *pwmp);
static void adccb(ADCDriver *adcp, adcsample_t *buffer, size_t n);
static THD_WORKING_AREA(waThread1, 128);
/*
* ADC samples buffer.
*/
static adcsample_t samples[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH];
static PWMConfig pwmconf = {
10000,
10000,
pwmpcb,/* call back start ADC*/
{ /* Channel 3 on TIM2 enabled */
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_ACTIVE_HIGH, NULL},
{PWM_OUTPUT_DISABLED, NULL},
},
0,
0,
#if STM32_PWM_USE_ADVANCED
0
#endif
};
/*
* ADC conversion group.
* Mode: Linear buffer, 4 samples of 2 channels, SW triggered.
* Channels: IN10 (41.5 cycles sample time)
* Sensor (239.5 cycles sample time)
*/
static const ADCConversionGroup adcgrpcfg = {
FALSE,
ADC_GRP1_NUM_CHANNELS,
adccb,
NULL,
/* HW dependent part.*/
0,
ADC_CR2_TSVREFE,
ADC_SMPR1_SMP_AN14(ADC_SAMPLE_41P5),
0,
ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS),
0,
ADC_SQR1_SQ14_N(ADC_CHANNEL_IN14)
};
/*
* PWM cyclic callback.
* A new ADC conversion is started.
*/
static void pwmpcb(PWMDriver *pwmp)
{
(void)pwmp;
chSysLockFromISR();
adcStartConversionI(&ADCD1, &adcgrpcfg, samples, ADC_GRP1_BUF_DEPTH);
chSysUnlockFromISR();
}
/*
* ADC end conversion callback.
* The PWM channels are reprogrammed using the latest ADC samples.
* The latest samples are transmitted into a single SPI transaction.
*/
static void adccb(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
(void) buffer; (void) n;
/* Note, only in the ADC_COMPLETE state because the ADC driver fires an
intermediate callback when the buffer is half full.*/
if (adcp->state == ADC_COMPLETE)
{
adcsample_t avg_ch1;;
/* Calculates the average values from the ADC samples.*/
avg_ch1 = (samples[0] + samples[2] + samples[4] + samples[6]) / 4;
chSysLockFromISR();
/* Changes the channels pulse width, the change will be effective
starting from the next cycle.*/
pwmEnableChannelI(&PWMD2, 2, PWM_FRACTION_TO_WIDTH(&PWMD2, 4096, avg_ch1));
chSysUnlockFromISR();
}
}
/*
* LEDs blinker thread, times are in milliseconds.
*/
static THD_FUNCTION(Thread1, arg)
{
(void)arg;
chRegSetThreadName("blinker");
while (TRUE) {
palClearPad(GPIOF, GPIOF_LED4);
palSetPad(GPIOF, GPIOF_LED1);
chThdSleepMilliseconds(250);
palClearPad(GPIOF, GPIOF_LED1);
palSetPad(GPIOF, GPIOF_LED2);
chThdSleepMilliseconds(250);
palClearPad(GPIOF, GPIOF_LED2);
palSetPad(GPIOF, GPIOF_LED3);
chThdSleepMilliseconds(250);
palClearPad(GPIOF, GPIOF_LED3);
palSetPad(GPIOF, GPIOF_LED4);
chThdSleepMilliseconds(250);
}
}
/*
* 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();
/*
* Shell initialization.
*/
shellInit();
/*
* Candr initialization.
*/
candrInit();
/*
* Flash initialization.
*/
flashInit();
/*
* Console initialization.
*/
consoleInit();
/*
* filesys initialization.
*/
filesysInit();
/*
* Serial comms example initialization.
*/
serialcomInit();
/*
* Activates the serial driver 1 and SDC driver 1 using default
* configuration.
*/
sdStart(&SD1, NULL);
sdcStart(&SDCD1, NULL);
/*
* Initializes the ADC driver 1.
* The pin PC0 on the port GPIOC is programmed as analog input.
*/
adcStart(&ADCD1, NULL);
adcStartConversion(&ADCD1,
&adcgrpcfg,
samples,
ADC_GRP1_BUF_DEPTH);
pwmStart(&PWMD2, &pwmconf);
// pwmEnableChannel(&PWMD2, 2, 200); // Port PB10
/*
* Creates the blinker thread.
*/
chThdCreateStatic(waThread1,
sizeof(waThread1),
NORMALPRIO,
Thread1, NULL);
AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP2;
AFIO->MAPR |= AFIO_MAPR_TIM2_REMAP_FULLREMAP;
/*
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and listen for events.
*/
while (TRUE) {
chThdSleepMilliseconds(1000);
}
}