diff options
-rw-r--r-- | demos/ARMCM3-STM32F100-DISCOVERY-GCC/main.c | 8 | ||||
-rw-r--r-- | demos/ARMCM3-STM32F100-DISCOVERY-GCC/readme.txt | 2 | ||||
-rw-r--r-- | os/hal/platforms/STM32/adc_lld.h | 113 | ||||
-rw-r--r-- | os/hal/platforms/STM32/pwm_lld.c | 16 | ||||
-rw-r--r-- | readme.txt | 3 | ||||
-rw-r--r-- | todo.txt | 2 |
6 files changed, 101 insertions, 43 deletions
diff --git a/demos/ARMCM3-STM32F100-DISCOVERY-GCC/main.c b/demos/ARMCM3-STM32F100-DISCOVERY-GCC/main.c index c86d00e4c..b1bc37c29 100644 --- a/demos/ARMCM3-STM32F100-DISCOVERY-GCC/main.c +++ b/demos/ARMCM3-STM32F100-DISCOVERY-GCC/main.c @@ -39,15 +39,17 @@ static adcsample_t samples[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH]; /*
* ADC conversion group.
* Mode: Linear buffer, 4 samples of 2 channels, SW triggered.
- * Channels: IN10, Sensor.
+ * Channels: IN10 (41.5 cycles sample time)
+ * Sensor (239.5 cycles sample time)
*/
static const ADCConversionGroup adcgrpcfg = {
FALSE,
ADC_GRP1_NUM_CHANNELS,
adccb,
+ /* HW dependent part.*/
0,
ADC_CR2_EXTSEL_SWSTART | ADC_CR2_TSVREFE | ADC_CR2_CONT,
- 0,
+ ADC_SMPR1_SMP_AN10(ADC_SAMPLE_41P5) | ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_239P5),
0,
ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS),
0,
@@ -73,6 +75,7 @@ static PWMConfig pwmcfg = { {PWM_OUTPUT_ACTIVE_HIGH, NULL},
{PWM_OUTPUT_ACTIVE_HIGH, NULL}
},
+ /* HW dependent part.*/
PWM_COMPUTE_PSC(STM32_TIMCLK1, 10000), /* 10KHz PWM clock frequency. */
PWM_COMPUTE_ARR(10000, 1000000000), /* PWM period 1S (in nS). */
0
@@ -85,6 +88,7 @@ static PWMConfig pwmcfg = { */
static const SPIConfig spicfg = {
spicb,
+ /* HW dependent part.*/
GPIOA,
GPIOA_SPI1NSS,
SPI_CR1_DFF
diff --git a/demos/ARMCM3-STM32F100-DISCOVERY-GCC/readme.txt b/demos/ARMCM3-STM32F100-DISCOVERY-GCC/readme.txt index 4d80483e8..7f19c0889 100644 --- a/demos/ARMCM3-STM32F100-DISCOVERY-GCC/readme.txt +++ b/demos/ARMCM3-STM32F100-DISCOVERY-GCC/readme.txt @@ -10,7 +10,7 @@ The demo runs on an ST STM32VL-Discovery board. The demo shows how to use the ADC, PWM and SPI drivers using asynchronous
APIs. The ADC samples two channels (temperature sensor and PC0) and modulates
-the PWM using the sampled values. The sample data is also transmitted on
+the PWM using the sampled values. The sample data is also transmitted using
the SPI port 1.
By pressing the button located on the board the test procedure is activated
with output on the serial port COM1 (USART1).
diff --git a/os/hal/platforms/STM32/adc_lld.h b/os/hal/platforms/STM32/adc_lld.h index aa62ca514..c6ba26c05 100644 --- a/os/hal/platforms/STM32/adc_lld.h +++ b/os/hal/platforms/STM32/adc_lld.h @@ -56,6 +56,15 @@ #define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
+#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */
+#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */
+#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */
+#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */
+#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */
+#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */
+#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */
+#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -143,52 +152,59 @@ typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n); */
typedef struct {
/**
- * @brief Enables the circular buffer mode for the group.
+ * @brief Enables the circular buffer mode for the group.
*/
bool_t acg_circular;
/**
- * @brief Number of the analog channels belonging to the conversion group.
+ * @brief Number of the analog channels belonging to the conversion group.
*/
adc_channels_num_t acg_num_channels;
/**
- * @brief Callback function associated to the group or @p NULL.
- * @note In order to use synchronous functions this field must be set to
- * @p NULL, callbacks and synchronous operations are mutually
- * exclusive.
+ * @brief Callback function associated to the group or @p NULL.
+ * @note In order to use synchronous functions this field must be set to
+ * @p NULL, callbacks and synchronous operations are mutually
+ * exclusive.
*/
adccallback_t acg_endcb;
/* End of the mandatory fields.*/
/**
- * @brief ADC CR1 register initialization data.
- * @note All the required bits must be defined into this field except
- * @p ADC_CR1_SCAN that is enforced inside the driver.
+ * @brief ADC CR1 register initialization data.
+ * @note All the required bits must be defined into this field except
+ * @p ADC_CR1_SCAN that is enforced inside the driver.
*/
uint32_t acg_cr1;
/**
- * @brief ADC CR2 register initialization data.
- * @note All the required bits must be defined into this field except
- * @p ADC_CR2_DMA and @p ADC_CR2_ADON that are enforced inside the
- * driver.
+ * @brief ADC CR2 register initialization data.
+ * @note All the required bits must be defined into this field except
+ * @p ADC_CR2_DMA and @p ADC_CR2_ADON that are enforced inside the
+ * driver.
*/
uint32_t acg_cr2;
/**
- * @brief ADC SMPR1 register initialization data.
+ * @brief ADC SMPR1 register initialization data.
+ * @details In this field must be specified the sample times for channels
+ * 10...17.
*/
uint32_t acg_smpr1;
/**
- * @brief ADC SMPR2 register initialization data.
+ * @brief ADC SMPR2 register initialization data.
+ * @details In this field must be specified the sample times for channels
+ * 0...9.
*/
uint32_t acg_smpr2;
/**
- * @brief ADC SQR1 register initialization data.
+ * @brief ADC SQR1 register initialization data.
+ * @details Conversion group sequence 13...16 + sequence length.
*/
uint32_t acg_sqr1;
/**
- * @brief ADC SQR2 register initialization data.
+ * @brief ADC SQR2 register initialization data.
+ * @details Conversion group sequence 7...12.
*/
uint32_t acg_sqr2;
/**
- * @brief ADC SQR3 register initialization data.
+ * @brief ADC SQR3 register initialization data.
+ * @details Conversion group sequence 0...6.
*/
uint32_t acg_sqr3;
} ADCConversionGroup;
@@ -262,26 +278,51 @@ struct ADCDriver { /* Driver macros. */
/*===========================================================================*/
+/**
+ * @brief Number of channels in a conversion sequence.
+ */
#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
-#define ADC_SQR3_SQ0_N(n) ((n) << 0)
-#define ADC_SQR3_SQ1_N(n) ((n) << 5)
-#define ADC_SQR3_SQ2_N(n) ((n) << 10)
-#define ADC_SQR3_SQ3_N(n) ((n) << 15)
-#define ADC_SQR3_SQ4_N(n) ((n) << 20)
-#define ADC_SQR3_SQ5_N(n) ((n) << 25)
-
-#define ADC_SQR2_SQ6_N(n) ((n) << 0)
-#define ADC_SQR2_SQ7_N(n) ((n) << 5)
-#define ADC_SQR2_SQ8_N(n) ((n) << 10)
-#define ADC_SQR2_SQ9_N(n) ((n) << 15)
-#define ADC_SQR2_SQ10_N(n) ((n) << 20)
-#define ADC_SQR2_SQ11_N(n) ((n) << 25)
-
-#define ADC_SQR1_SQ13_N(n) ((n) << 0)
-#define ADC_SQR1_SQ14_N(n) ((n) << 5)
-#define ADC_SQR1_SQ15_N(n) ((n) << 10)
-#define ADC_SQR1_SQ16_N(n) ((n) << 15)
+#define ADC_SQR3_SQ0_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
+#define ADC_SQR3_SQ1_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
+#define ADC_SQR3_SQ2_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
+#define ADC_SQR3_SQ3_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
+#define ADC_SQR3_SQ4_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
+#define ADC_SQR3_SQ5_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
+
+#define ADC_SQR2_SQ6_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
+#define ADC_SQR2_SQ7_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
+#define ADC_SQR2_SQ8_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
+#define ADC_SQR2_SQ9_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
+#define ADC_SQR2_SQ10_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
+#define ADC_SQR2_SQ11_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
+
+#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
+#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
+#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
+#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
+
+#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
+#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
+#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
+#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
+#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
+#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
+#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
+#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
+#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
+#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
+
+#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
+#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
+#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
+#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
+#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
+#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
+#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
+ sampling time. */
+#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
+ sampling time. */
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index 9b9140eba..5e39d8cb6 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -30,6 +30,18 @@ #if HAL_USE_PWM || defined(__DOXYGEN__)
+/* There are differences in vector names in the ST header for devices
+ including TIM15, TIM16, TIM17.*/
+#if STM32_HAS_TIM15
+#define TIM1_BRK_IRQn TIM1_BRK_TIM15_IRQn
+#endif
+#if STM32_HAS_TIM16
+#define TIM1_UP_IRQn TIM1_UP_TIM16_IRQn
+#endif
+#if STM32_HAS_TIM17
+#define TIM1_TRG_COM_IRQn TIM1_TRG_COM_TIM17_IRQn
+#endif
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -285,7 +297,7 @@ void pwm_lld_start(PWMDriver *pwmp) { #if STM32_PWM_USE_TIM2
if (&PWMD2 == pwmp) {
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
- RCC->APB1RSTR = RCC_APB1RSTR_TIM1RST;
+ RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
RCC->APB1RSTR = 0;
NVICEnableVector(TIM2_IRQn,
CORTEX_PRIORITY_MASK(STM32_PWM_PWM2_IRQ_PRIORITY));
@@ -330,12 +342,12 @@ void pwm_lld_start(PWMDriver *pwmp) { pwmp->pd_tim->CCR2 = 0; /* Comparator 2 disabled. */
pwmp->pd_tim->CCR3 = 0; /* Comparator 3 disabled. */
pwmp->pd_tim->CCR4 = 0; /* Comparator 4 disabled. */
+ pwmp->pd_tim->CNT = 0;
}
/* Timer configuration.*/
pwmp->pd_tim->CR2 = pwmp->pd_config->pc_cr2;
pwmp->pd_tim->PSC = pwmp->pd_config->pc_psc;
- pwmp->pd_tim->CNT = 0;
pwmp->pd_tim->ARR = pwmp->pd_config->pc_arr;
/* Output enables and polarities setup.*/
ccer = 0;
diff --git a/readme.txt b/readme.txt index 6b3aafc53..bf9901e1e 100644 --- a/readme.txt +++ b/readme.txt @@ -76,6 +76,9 @@ - FIX: Fixed typo in board name (bug 3113574)(backported to 2.0.7).
- FIX: Fixed defective event wait functions with timeout (bug 3113443)
(backported to 2.0.7).
+- NEW: Added to the STM32 ADC driver the macros for easy handling of the
+ sampling time for each channel.
+- NEW: Greatly simplified the STM32 PWM driver implementation.
- NEW: Added new macro PWM_FRACTION_TO_WIDTH() to the PWM driver model.
- NEW: ARM7 port reorganization following the same pattern of the ARMCMx
one, on now the port is also supports the ARM9 architecture (but not
@@ -53,8 +53,6 @@ N Evaluate if to add a synchronous API to the UART driver, eventually do so. * STM8L-Discovery demo.
* Add the STM32F100 (Value Line) sub-family to the official STM32 HAL support.
* STM32VL-Discovery demo.
- - Problem, some IRQ vectors have a different vector name in the STM32F100
- sub-family. Use vector numbers instead?
* Remove the PAL default configuration from the various hal_lld.c and move
them into board.c files, this will remove an ugly dependency.
* Realign the STM8 port to the new STM8L one as options, naming conventions
|