From f02cdbe2e8ad426e86b2da576f2f9f43cf186503 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 24 Sep 2011 14:18:32 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3398 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-STM32L152-DISCOVERY/halconf.h | 6 +- demos/ARMCM3-STM32L152-DISCOVERY/iar/ch.ewp | 18 +++ demos/ARMCM3-STM32L152-DISCOVERY/main.c | 178 ++++++++++++++++++++++++---- demos/ARMCM3-STM32L152-DISCOVERY/mcuconf.h | 6 +- 4 files changed, 180 insertions(+), 28 deletions(-) diff --git a/demos/ARMCM3-STM32L152-DISCOVERY/halconf.h b/demos/ARMCM3-STM32L152-DISCOVERY/halconf.h index b9bee3656..e8acd1f13 100644 --- a/demos/ARMCM3-STM32L152-DISCOVERY/halconf.h +++ b/demos/ARMCM3-STM32L152-DISCOVERY/halconf.h @@ -45,7 +45,7 @@ * @brief Enables the ADC subsystem. */ #if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) -#define HAL_USE_ADC FALSE +#define HAL_USE_ADC TRUE #endif /** @@ -101,7 +101,7 @@ * @brief Enables the PWM subsystem. */ #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) -#define HAL_USE_PWM FALSE +#define HAL_USE_PWM TRUE #endif /** @@ -129,7 +129,7 @@ * @brief Enables the SPI subsystem. */ #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) -#define HAL_USE_SPI FALSE +#define HAL_USE_SPI TRUE #endif /** diff --git a/demos/ARMCM3-STM32L152-DISCOVERY/iar/ch.ewp b/demos/ARMCM3-STM32L152-DISCOVERY/iar/ch.ewp index d6c066984..c70831761 100644 --- a/demos/ARMCM3-STM32L152-DISCOVERY/iar/ch.ewp +++ b/demos/ARMCM3-STM32L152-DISCOVERY/iar/ch.ewp @@ -2083,6 +2083,12 @@ platform + + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32L1xx\adc_lld.c + + + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32L1xx\adc_lld.h + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32L1xx\hal_lld.c @@ -2095,12 +2101,24 @@ $PROJ_DIR$\..\..\..\os\hal\platforms\STM32\GPIOv2\pal_lld.h + + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32\pwm_lld.c + + + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32\pwm_lld.h + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32\serial_lld.c $PROJ_DIR$\..\..\..\os\hal\platforms\STM32\serial_lld.h + + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32\spi_lld.c + + + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32\spi_lld.h + $PROJ_DIR$\..\..\..\os\hal\platforms\STM32\DMAv1\stm32_dma.c diff --git a/demos/ARMCM3-STM32L152-DISCOVERY/main.c b/demos/ARMCM3-STM32L152-DISCOVERY/main.c index c5b0dd974..61532bcbd 100644 --- a/demos/ARMCM3-STM32L152-DISCOVERY/main.c +++ b/demos/ARMCM3-STM32L152-DISCOVERY/main.c @@ -22,24 +22,149 @@ #include "hal.h" #include "test.h" +static void pwmpcb(PWMDriver *pwmp); +static void adccb(ADCDriver *adcp, adcsample_t *buffer, size_t n); +static void spicb(SPIDriver *spip); + +/* Total number of channels to be sampled by a single ADC operation.*/ +#define ADC_GRP1_NUM_CHANNELS 2 + +/* Depth of the conversion buffer, channels are sampled four times each.*/ +#define ADC_GRP1_BUF_DEPTH 4 + +/* + * ADC samples buffer. + */ +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 (48 cycles sample time) + * Sensor (192 cycles sample time) + */ +static const ADCConversionGroup adcgrpcfg = { + FALSE, + ADC_GRP1_NUM_CHANNELS, + adccb, + NULL, + /* HW dependent part.*/ + 0, + 0, + 0, + ADC_SMPR2_SMP_AN10(ADC_SAMPLE_48) | ADC_SMPR2_SMP_SENSOR(ADC_SAMPLE_192), + 0, + ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS), + 0, + 0, + 0, + ADC_SQR5_SQ2_N(ADC_CHANNEL_IN10) | ADC_SQR5_SQ1_N(ADC_CHANNEL_SENSOR) +}; + +/* + * PWM configuration structure. + * Cyclic callback enabled, channels 3 and 4 enabled without callbacks, + * the active state is a logic one. + */ +static PWMConfig pwmcfg = { + 10000, /* 10KHz PWM clock frequency. */ + 10000, /* PWM period 1S (in ticks). */ + pwmpcb, + { + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL} + }, + /* HW dependent part.*/ + 0 +}; + +/* + * SPI configuration structure. + * Maximum speed (12MHz), CPHA=0, CPOL=0, 16bits frames, MSb transmitted first. + * The slave select line is the pin GPIOA_SPI1NSS on the port GPIOA. + */ +static const SPIConfig spicfg = { + spicb, + /* HW dependent part.*/ + GPIOB, + 12, + SPI_CR1_DFF +}; + +/* + * PWM cyclic callback. + * A new ADC conversion is started. + */ +static void pwmpcb(PWMDriver *pwmp) { + + (void)pwmp; + + /* Starts an asynchronous ADC conversion operation, the conversion + will be executed in parallel to the current PWM cycle and will + terminate before the next PWM cycle.*/ + 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. + */ +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, avg_ch2; + + /* Calculates the average values from the ADC samples.*/ + avg_ch1 = (samples[0] + samples[2] + samples[4] + samples[6]) / 4; + avg_ch2 = (samples[1] + samples[3] + samples[5] + samples[7]) / 4; + + chSysLockFromIsr(); + + /* Changes the channels pulse width, the change will be effective + starting from the next cycle.*/ + pwmEnableChannelI(&PWMD4, 0, PWM_FRACTION_TO_WIDTH(&PWMD4, 4096, avg_ch1)); + pwmEnableChannelI(&PWMD4, 1, PWM_FRACTION_TO_WIDTH(&PWMD4, 4096, avg_ch2)); + + /* SPI slave selection and transmission start.*/ + spiSelectI(&SPID2); + spiStartSendI(&SPID2, ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH, samples); + + chSysUnlockFromIsr(); + } +} + +/* + * SPI end transfer callback. + */ +static void spicb(SPIDriver *spip) { + + /* On transfer end just releases the slave select line.*/ + chSysLockFromIsr(); + spiUnselectI(spip); + chSysUnlockFromIsr(); +} + /* * This is a periodic thread that does absolutely nothing except increasing * a seconds counter. */ static WORKING_AREA(waThread1, 128); static msg_t Thread1(void *arg) { + static uint32_t seconds_counter; (void)arg; - chRegSetThreadName("blinker"); + chRegSetThreadName("counter"); while (TRUE) { - palSetPad(GPIOB, GPIOB_LED3); - chThdSleepMilliseconds(250); - palClearPad(GPIOB, GPIOB_LED3); - chThdSleepMilliseconds(250); - palSetPad(GPIOB, GPIOB_LED4); - chThdSleepMilliseconds(250); - palClearPad(GPIOB, GPIOB_LED4); - chThdSleepMilliseconds(250); + chThdSleepMilliseconds(1000); + seconds_counter++; } } @@ -75,27 +200,36 @@ int main(void) { TestThread(&SD1); /* - * Initializes the SPI driver 1. + * Initializes the SPI driver 2. The SPI2 signals are routed as follow: + * PB12 - NSS. + * PB13 - SCK. + * PB14 - MISO. + * PB15 - MOSI. */ -// spiStart(&SPID1, &spicfg); + spiStart(&SPID2, &spicfg); + palSetPad(GPIOB, 12); + palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL | + PAL_STM32_OSPEED_HIGHEST); /* NSS. */ + palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) | + PAL_STM32_OSPEED_HIGHEST); /* SCK. */ + palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(5)); /* MISO. */ + palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(5) | + PAL_STM32_OSPEED_HIGHEST); /* MOSI. */ /* - * Initializes the ADC driver 1. + * Initializes the ADC driver 1 and enable the thermal sensor. * The pin PC0 on the port GPIOC is programmed as analog input. */ -// adcStart(&ADCD1, NULL); -// palSetGroupMode(GPIOC, PAL_PORT_BIT(0), PAL_MODE_INPUT_ANALOG); + adcStart(&ADCD1, NULL); + adcSTM32EnableTSVREFE(); + palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG); /* - * Initializes the PWM driver 1, re-routes the TIM3 outputs, programs the - * pins as alternate functions. - * Note, the AFIO access routes the TIM3 output pins on the PC6...PC9 - * where the LEDs are connected. + * Initializes the PWM driver 4, routes the TIM4 outputs to the board LEDs. */ -// pwmStart(&PWMD3, &pwmcfg); -// AFIO->MAPR |= AFIO_MAPR_TIM3_REMAP_0 | AFIO_MAPR_TIM3_REMAP_1; -// palSetGroupMode(GPIOC, PAL_PORT_BIT(GPIOC_LED3) | PAL_PORT_BIT(GPIOC_LED4), -// PAL_MODE_STM32_ALTERNATE_PUSHPULL); + pwmStart(&PWMD4, &pwmcfg); + palSetPadMode(GPIOB, GPIOB_LED4, PAL_MODE_ALTERNATE(2)); + palSetPadMode(GPIOB, GPIOB_LED3, PAL_MODE_ALTERNATE(2)); /* * Creates the example thread. diff --git a/demos/ARMCM3-STM32L152-DISCOVERY/mcuconf.h b/demos/ARMCM3-STM32L152-DISCOVERY/mcuconf.h index 4071c4507..3aa958d8f 100644 --- a/demos/ARMCM3-STM32L152-DISCOVERY/mcuconf.h +++ b/demos/ARMCM3-STM32L152-DISCOVERY/mcuconf.h @@ -122,8 +122,8 @@ #define STM32_PWM_USE_ADVANCED FALSE #define STM32_PWM_USE_TIM1 FALSE #define STM32_PWM_USE_TIM2 FALSE -#define STM32_PWM_USE_TIM3 TRUE -#define STM32_PWM_USE_TIM4 FALSE +#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM4 TRUE #define STM32_PWM_USE_TIM5 FALSE #define STM32_PWM_USE_TIM8 FALSE #define STM32_PWM_TIM1_IRQ_PRIORITY 7 @@ -150,7 +150,7 @@ /* * SPI driver system settings. */ -#define STM32_SPI_USE_SPI1 TRUE +#define STM32_SPI_USE_SPI1 FALSE #define STM32_SPI_USE_SPI2 TRUE #define STM32_SPI_USE_SPI3 FALSE #define STM32_SPI_SPI1_DMA_PRIORITY 1 -- cgit v1.2.3