Barcode reader with a TCD1304AP TOSHIBA CCD linear image sensor and NUCLEO-F103RB board.

Dependencies:   mbed zbar

Barcode Reader

Barcodes represent data by varying the widths of spaces and bars. These barcodes, now commonly referred to as linear or one-dimensional (1D), can be scanned by barcode readers. In this project a TCD1304AP TOSHIBA CCD linear image sensor is used to scan barcodes. The obtained light intensity stream is passed to the ZBar library streamlined for embedded use.

Flow charthttps://os.mbed.com/media/uploads/hudakz/barcodereader_diagram.png
TCD1304AP Driver

The TCD1304AP requires three clock signals (see below the Timing chart). It can operate with or without a built-in electronic shutter. In this project the electronic shutter is used to control the integration (exposure) time:

https://os.mbed.com/media/uploads/hudakz/barcodereader_timing.png




I used STM32CubeIDE to build the driver for the TCD1304AP sensor and then merged it with the Mbed OS 2 project.

STM32F103RB clock configuration
https://os.mbed.com/media/uploads/hudakz/barcodereader_clockconf.png


STM32F103RB pinout
https://os.mbed.com/media/uploads/hudakz/barcodereader_pinout.png


  • The signal for TCD1304AP's master clock (fiM) is generated by STM32F103's TIM1 timer and it is output at pin PA_8.
  • The Shift Gate clock signal (SH) is produced by timer TIM2 and it's available at pin PA_15.
  • The Integration Clear Gate pulses (ICG) are generated by timer TIM3 at pin PA_6.

The TCD1304AP's master clock runs at 1.714MHz. Pixel data is available at its output (OS) after each four pulses. To keep up with such speed DMA (Direct Memmory Access) is used to move the voltage data produced by the ADC (Analog to Digital Convertor) into the STM32F103's SRAM. The ADC is clocked with a 12MHz signal and runs in continuous mode.

https://os.mbed.com/media/uploads/hudakz/barcodereader_clocking.png

Committer:
hudakz
Date:
Fri Jan 10 22:10:07 2020 +0000
Revision:
3:f2e67488f5ab
Parent:
2:415e979c52cf
Barcode reader with a TCD1304AP TOSHIBA CCD linear image sensor and NUCLEO-F103RB board.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:cd0771c3346e 1 /*
hudakz 0:cd0771c3346e 2 * Barcode reader
hudakz 0:cd0771c3346e 3 *
hudakz 0:cd0771c3346e 4 * Target: NUCLEO-F103RB
hudakz 3:f2e67488f5ab 5 * Sensor: TCD1304AP(DG) - TOSHIBA CCD linear image sensor
hudakz 0:cd0771c3346e 6 *
hudakz 0:cd0771c3346e 7 * Author: Zoltan Hudak
hudakz 0:cd0771c3346e 8 * Date: 2020-01
hudakz 0:cd0771c3346e 9 *
hudakz 3:f2e67488f5ab 10 * Depends on the ZBar library <http://zbar.sourceforge.net>
hudakz 0:cd0771c3346e 11 *
hudakz 0:cd0771c3346e 12 */
hudakz 0:cd0771c3346e 13 #include "main.h"
hudakz 0:cd0771c3346e 14 #include "mbed.h"
hudakz 0:cd0771c3346e 15 #include <inttypes.h>
hudakz 0:cd0771c3346e 16 #include <stdlib.h>
hudakz 0:cd0771c3346e 17 #include <stdio.h>
hudakz 0:cd0771c3346e 18 #include <string.h>
hudakz 0:cd0771c3346e 19 #include <assert.h>
hudakz 0:cd0771c3346e 20 #include <zbar.h>
hudakz 0:cd0771c3346e 21
hudakz 0:cd0771c3346e 22 using namespace zbar;
hudakz 0:cd0771c3346e 23
hudakz 1:9231777638b6 24 //#define TEST_DECODER // Uncomment to carry out a decoder test
hudakz 0:cd0771c3346e 25 #define DATA_LEN 3694
hudakz 0:cd0771c3346e 26 #define MARGIN_LEFT 32
hudakz 0:cd0771c3346e 27 #define MARGIN_RIGHT 14
hudakz 0:cd0771c3346e 28 #define FWD 1
hudakz 0:cd0771c3346e 29 #define REV 0
hudakz 0:cd0771c3346e 30
hudakz 0:cd0771c3346e 31 class Handler : public Decoder::Handler
hudakz 0:cd0771c3346e 32 {
hudakz 0:cd0771c3346e 33 public:
hudakz 0:cd0771c3346e 34 Handler() { }
hudakz 0:cd0771c3346e 35 virtual ~Handler() { }
hudakz 0:cd0771c3346e 36 virtual void decode_callback(Decoder& decoder)
hudakz 0:cd0771c3346e 37 {
hudakz 0:cd0771c3346e 38 if (decoder.get_type() <= ZBAR_PARTIAL) {
hudakz 0:cd0771c3346e 39 return;
hudakz 0:cd0771c3346e 40 }
hudakz 0:cd0771c3346e 41
hudakz 0:cd0771c3346e 42 printf("%s%s:%s\n", decoder.get_symbol_name(), decoder.get_addon_name(), decoder.get_data_chars());
hudakz 0:cd0771c3346e 43 }
hudakz 0:cd0771c3346e 44 };
hudakz 0:cd0771c3346e 45
hudakz 0:cd0771c3346e 46 ADC_HandleTypeDef hadc1;
hudakz 0:cd0771c3346e 47 DMA_HandleTypeDef hdma_adc1;
hudakz 0:cd0771c3346e 48 TIM_HandleTypeDef htim1;
hudakz 0:cd0771c3346e 49 TIM_HandleTypeDef htim2;
hudakz 0:cd0771c3346e 50 TIM_HandleTypeDef htim3;
hudakz 0:cd0771c3346e 51 DigitalOut led(LED1);
hudakz 0:cd0771c3346e 52 DigitalIn btn(USER_BUTTON);
hudakz 0:cd0771c3346e 53 uint16_t adcData[DATA_LEN];
hudakz 0:cd0771c3346e 54 volatile bool adcDmaStarted = false;
hudakz 0:cd0771c3346e 55 volatile bool adcDataAvailable = false;
hudakz 2:415e979c52cf 56 volatile bool ledIsOn = false; // Use this rather than the 'led' variable to make ISR as fast as possible
hudakz 0:cd0771c3346e 57 Decoder* decoder;
hudakz 0:cd0771c3346e 58 Handler* handler;
hudakz 0:cd0771c3346e 59 Scanner* scanner;
hudakz 0:cd0771c3346e 60
hudakz 0:cd0771c3346e 61 static void MX_GPIO_Init();
hudakz 0:cd0771c3346e 62 static void MX_ADC1_Init();
hudakz 0:cd0771c3346e 63 static void MX_TIM2_Init();
hudakz 0:cd0771c3346e 64 static void MX_DMA_Init();
hudakz 0:cd0771c3346e 65 static void MX_TIM3_Init();
hudakz 0:cd0771c3346e 66 static void MX_TIM1_Init();
hudakz 0:cd0771c3346e 67
hudakz 0:cd0771c3346e 68 /**
hudakz 0:cd0771c3346e 69 * @brief
hudakz 0:cd0771c3346e 70 * @note
hudakz 0:cd0771c3346e 71 * @param
hudakz 0:cd0771c3346e 72 * @retval
hudakz 0:cd0771c3346e 73 */
hudakz 0:cd0771c3346e 74 void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef* htim)
hudakz 0:cd0771c3346e 75 {
hudakz 0:cd0771c3346e 76 if (htim->Instance == TIM3) {
hudakz 0:cd0771c3346e 77 if (ledIsOn && !adcDmaStarted) {
hudakz 0:cd0771c3346e 78 HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcData, DATA_LEN);
hudakz 0:cd0771c3346e 79 adcDmaStarted = true;
hudakz 0:cd0771c3346e 80 }
hudakz 0:cd0771c3346e 81 }
hudakz 0:cd0771c3346e 82 }
hudakz 0:cd0771c3346e 83
hudakz 0:cd0771c3346e 84 /**
hudakz 0:cd0771c3346e 85 * @brief
hudakz 0:cd0771c3346e 86 * @note
hudakz 0:cd0771c3346e 87 * @param
hudakz 0:cd0771c3346e 88 * @retval
hudakz 0:cd0771c3346e 89 */
hudakz 0:cd0771c3346e 90 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
hudakz 0:cd0771c3346e 91 {
hudakz 0:cd0771c3346e 92 adcDataAvailable = true;
hudakz 0:cd0771c3346e 93 }
hudakz 0:cd0771c3346e 94
hudakz 0:cd0771c3346e 95 #ifdef TEST_DECODER
hudakz 0:cd0771c3346e 96
hudakz 0:cd0771c3346e 97 /**
hudakz 0:cd0771c3346e 98 * @brief
hudakz 0:cd0771c3346e 99 * @note
hudakz 0:cd0771c3346e 100 * @param
hudakz 0:cd0771c3346e 101 * @retval
hudakz 0:cd0771c3346e 102 */
hudakz 0:cd0771c3346e 103 static void test_decoder()
hudakz 0:cd0771c3346e 104 {
hudakz 0:cd0771c3346e 105 printf("Decoding space/bar widths ...\n");
hudakz 0:cd0771c3346e 106
hudakz 0:cd0771c3346e 107 /*$off*/
hudakz 0:cd0771c3346e 108 // Space/bar widths of the string 'WIKIPEDIA' encoded in Code-39 barcode
hudakz 0:cd0771c3346e 109 unsigned space_bar_widths[] =
hudakz 0:cd0771c3346e 110 {
hudakz 0:cd0771c3346e 111 9, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
hudakz 0:cd0771c3346e 112 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 2,
hudakz 0:cd0771c3346e 113 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1,
hudakz 0:cd0771c3346e 114 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1,
hudakz 0:cd0771c3346e 115 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 9
hudakz 0:cd0771c3346e 116 };
hudakz 0:cd0771c3346e 117 /*$on*/
hudakz 0:cd0771c3346e 118 size_t size = sizeof(space_bar_widths) / sizeof(*space_bar_widths);
hudakz 0:cd0771c3346e 119
hudakz 0:cd0771c3346e 120 decoder->new_scan();
hudakz 0:cd0771c3346e 121
hudakz 0:cd0771c3346e 122 for (size_t i = 0; i < size; i++) {
hudakz 0:cd0771c3346e 123 decoder->decode_width(space_bar_widths[i]);
hudakz 0:cd0771c3346e 124 }
hudakz 0:cd0771c3346e 125 }
hudakz 0:cd0771c3346e 126 #endif
hudakz 0:cd0771c3346e 127
hudakz 0:cd0771c3346e 128 /**
hudakz 0:cd0771c3346e 129 * @brief
hudakz 0:cd0771c3346e 130 * @note
hudakz 0:cd0771c3346e 131 * @param
hudakz 0:cd0771c3346e 132 * @retval
hudakz 0:cd0771c3346e 133 */
hudakz 0:cd0771c3346e 134 int main()
hudakz 0:cd0771c3346e 135 {
hudakz 0:cd0771c3346e 136 printf("Starting ...\r\n");
hudakz 0:cd0771c3346e 137
hudakz 0:cd0771c3346e 138 MX_GPIO_Init();
hudakz 0:cd0771c3346e 139 MX_DMA_Init();
hudakz 0:cd0771c3346e 140 MX_TIM1_Init();
hudakz 0:cd0771c3346e 141 MX_TIM2_Init();
hudakz 0:cd0771c3346e 142 MX_TIM3_Init();
hudakz 0:cd0771c3346e 143 MX_ADC1_Init();
hudakz 0:cd0771c3346e 144 HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
hudakz 0:cd0771c3346e 145 HAL_TIM_OC_Start(&htim2, TIM_CHANNEL_1);
hudakz 0:cd0771c3346e 146 HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_1);
hudakz 0:cd0771c3346e 147 decoder = new Decoder;
hudakz 0:cd0771c3346e 148 handler = new Handler;
hudakz 0:cd0771c3346e 149 scanner = new Scanner(decoder);
hudakz 0:cd0771c3346e 150 decoder->set_handler(*handler);
hudakz 0:cd0771c3346e 151 decoder->set_config(ZBAR_NONE, ZBAR_CFG_MIN_LEN, 0);
hudakz 0:cd0771c3346e 152
hudakz 0:cd0771c3346e 153 while (1) {
hudakz 0:cd0771c3346e 154 if ((btn == 0) && !ledIsOn) {
hudakz 0:cd0771c3346e 155 led = 1;
hudakz 0:cd0771c3346e 156 ledIsOn = true;
hudakz 0:cd0771c3346e 157 }
hudakz 0:cd0771c3346e 158
hudakz 0:cd0771c3346e 159 if (adcDataAvailable) {
hudakz 0:cd0771c3346e 160 adcDataAvailable = false;
hudakz 0:cd0771c3346e 161 led = 0;
hudakz 0:cd0771c3346e 162
hudakz 0:cd0771c3346e 163 printf("---------------------------\n");
hudakz 0:cd0771c3346e 164
hudakz 0:cd0771c3346e 165 #ifdef TEST_DECODER
hudakz 0:cd0771c3346e 166 test_decoder();
hudakz 0:cd0771c3346e 167 #else
hudakz 0:cd0771c3346e 168 scanner->flush();
hudakz 0:cd0771c3346e 169 scanner->flush();
hudakz 0:cd0771c3346e 170 scanner->new_scan();
hudakz 0:cd0771c3346e 171
hudakz 3:f2e67488f5ab 172 uint16_t black = 0;
hudakz 3:f2e67488f5ab 173 int i;
hudakz 0:cd0771c3346e 174
hudakz 0:cd0771c3346e 175 for (i = MARGIN_LEFT; i < DATA_LEN - MARGIN_RIGHT; i++) {
hudakz 0:cd0771c3346e 176 if (adcData[i] > black)
hudakz 0:cd0771c3346e 177 black = adcData[i];
hudakz 0:cd0771c3346e 178 }
hudakz 0:cd0771c3346e 179
hudakz 0:cd0771c3346e 180 for (i = MARGIN_LEFT; i < DATA_LEN - MARGIN_RIGHT; i++) {
hudakz 3:f2e67488f5ab 181 scanner->scan_y(black - adcData[i]);
hudakz 0:cd0771c3346e 182 }
hudakz 0:cd0771c3346e 183 #endif
hudakz 0:cd0771c3346e 184 printf("Scan done.\r\n");
hudakz 0:cd0771c3346e 185 wait_ms(300); // Debauncing the button
hudakz 0:cd0771c3346e 186 ledIsOn = false;
hudakz 0:cd0771c3346e 187 adcDmaStarted = false;
hudakz 0:cd0771c3346e 188 }
hudakz 0:cd0771c3346e 189 }
hudakz 0:cd0771c3346e 190 }
hudakz 0:cd0771c3346e 191
hudakz 0:cd0771c3346e 192 /**
hudakz 0:cd0771c3346e 193 * @brief ADC1 Initialization Function
hudakz 0:cd0771c3346e 194 * @note
hudakz 0:cd0771c3346e 195 * @param
hudakz 0:cd0771c3346e 196 * @retval
hudakz 0:cd0771c3346e 197 */
hudakz 0:cd0771c3346e 198 static void MX_ADC1_Init()
hudakz 0:cd0771c3346e 199 {
hudakz 0:cd0771c3346e 200 ADC_ChannelConfTypeDef sConfig = { 0 };
hudakz 0:cd0771c3346e 201 /** Common config
hudakz 0:cd0771c3346e 202 */
hudakz 0:cd0771c3346e 203 hadc1.Instance = ADC1;
hudakz 0:cd0771c3346e 204 hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hudakz 0:cd0771c3346e 205 hadc1.Init.ContinuousConvMode = ENABLE;
hudakz 0:cd0771c3346e 206 hadc1.Init.DiscontinuousConvMode = DISABLE;
hudakz 0:cd0771c3346e 207 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hudakz 0:cd0771c3346e 208 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hudakz 0:cd0771c3346e 209 hadc1.Init.NbrOfConversion = 1;
hudakz 0:cd0771c3346e 210 if (HAL_ADC_Init(&hadc1) != HAL_OK) {
hudakz 0:cd0771c3346e 211 Error_Handler();
hudakz 0:cd0771c3346e 212 }
hudakz 0:cd0771c3346e 213
hudakz 0:cd0771c3346e 214 /** Configure Regular Channel
hudakz 0:cd0771c3346e 215 */
hudakz 0:cd0771c3346e 216 sConfig.Channel = ADC_CHANNEL_0;
hudakz 0:cd0771c3346e 217 sConfig.Rank = ADC_REGULAR_RANK_1;
hudakz 0:cd0771c3346e 218 sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
hudakz 0:cd0771c3346e 219 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
hudakz 0:cd0771c3346e 220 Error_Handler();
hudakz 0:cd0771c3346e 221 }
hudakz 0:cd0771c3346e 222
hudakz 0:cd0771c3346e 223 while (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK);
hudakz 0:cd0771c3346e 224 }
hudakz 0:cd0771c3346e 225
hudakz 0:cd0771c3346e 226 /**
hudakz 0:cd0771c3346e 227 * @brief TIM1 Initialization Function
hudakz 0:cd0771c3346e 228 * @note
hudakz 0:cd0771c3346e 229 * @param
hudakz 0:cd0771c3346e 230 * @retval
hudakz 0:cd0771c3346e 231 */
hudakz 0:cd0771c3346e 232 static void MX_TIM1_Init()
hudakz 0:cd0771c3346e 233 {
hudakz 0:cd0771c3346e 234 TIM_ClockConfigTypeDef sClockSourceConfig = { 0 };
hudakz 0:cd0771c3346e 235 TIM_MasterConfigTypeDef sMasterConfig = { 0 };
hudakz 0:cd0771c3346e 236 TIM_OC_InitTypeDef sConfigOC = { 0 };
hudakz 0:cd0771c3346e 237 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = { 0 };
hudakz 0:cd0771c3346e 238
hudakz 0:cd0771c3346e 239 htim1.Instance = TIM1;
hudakz 0:cd0771c3346e 240 htim1.Init.Prescaler = 0;
hudakz 0:cd0771c3346e 241 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
hudakz 0:cd0771c3346e 242 htim1.Init.Period = 21 - 1;
hudakz 0:cd0771c3346e 243 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
hudakz 0:cd0771c3346e 244 htim1.Init.RepetitionCounter = 0;
hudakz 0:cd0771c3346e 245 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
hudakz 0:cd0771c3346e 246 if (HAL_TIM_Base_Init(&htim1) != HAL_OK) {
hudakz 0:cd0771c3346e 247 Error_Handler();
hudakz 0:cd0771c3346e 248 }
hudakz 0:cd0771c3346e 249
hudakz 0:cd0771c3346e 250 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
hudakz 0:cd0771c3346e 251 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) {
hudakz 0:cd0771c3346e 252 Error_Handler();
hudakz 0:cd0771c3346e 253 }
hudakz 0:cd0771c3346e 254
hudakz 0:cd0771c3346e 255 if (HAL_TIM_OC_Init(&htim1) != HAL_OK) {
hudakz 0:cd0771c3346e 256 Error_Handler();
hudakz 0:cd0771c3346e 257 }
hudakz 0:cd0771c3346e 258
hudakz 0:cd0771c3346e 259 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
hudakz 0:cd0771c3346e 260 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
hudakz 0:cd0771c3346e 261 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) {
hudakz 0:cd0771c3346e 262 Error_Handler();
hudakz 0:cd0771c3346e 263 }
hudakz 0:cd0771c3346e 264
hudakz 0:cd0771c3346e 265 sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
hudakz 0:cd0771c3346e 266 sConfigOC.Pulse = 0;
hudakz 0:cd0771c3346e 267 sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
hudakz 0:cd0771c3346e 268 sConfigOC.OCNPolarity = TIM_OCNPOLARITY_LOW;
hudakz 0:cd0771c3346e 269 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
hudakz 0:cd0771c3346e 270 sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
hudakz 0:cd0771c3346e 271 sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
hudakz 0:cd0771c3346e 272 if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
hudakz 0:cd0771c3346e 273 Error_Handler();
hudakz 0:cd0771c3346e 274 }
hudakz 0:cd0771c3346e 275
hudakz 0:cd0771c3346e 276 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
hudakz 0:cd0771c3346e 277 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
hudakz 0:cd0771c3346e 278 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
hudakz 0:cd0771c3346e 279 sBreakDeadTimeConfig.DeadTime = 0;
hudakz 0:cd0771c3346e 280 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
hudakz 0:cd0771c3346e 281 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
hudakz 0:cd0771c3346e 282 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
hudakz 0:cd0771c3346e 283 if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) {
hudakz 0:cd0771c3346e 284 Error_Handler();
hudakz 0:cd0771c3346e 285 }
hudakz 0:cd0771c3346e 286
hudakz 0:cd0771c3346e 287 HAL_TIM_MspPostInit(&htim1);
hudakz 0:cd0771c3346e 288 }
hudakz 0:cd0771c3346e 289
hudakz 0:cd0771c3346e 290 /**
hudakz 0:cd0771c3346e 291 * @brief TIM2 Initialization Function
hudakz 0:cd0771c3346e 292 * @note
hudakz 0:cd0771c3346e 293 * @param
hudakz 0:cd0771c3346e 294 * @retval
hudakz 0:cd0771c3346e 295 */
hudakz 0:cd0771c3346e 296 static void MX_TIM2_Init()
hudakz 0:cd0771c3346e 297 {
hudakz 0:cd0771c3346e 298 TIM_SlaveConfigTypeDef sSlaveConfig = { 0 };
hudakz 0:cd0771c3346e 299 TIM_MasterConfigTypeDef sMasterConfig = { 0 };
hudakz 0:cd0771c3346e 300 TIM_OC_InitTypeDef sConfigOC = { 0 };
hudakz 0:cd0771c3346e 301
hudakz 0:cd0771c3346e 302 htim2.Instance = TIM2;
hudakz 0:cd0771c3346e 303 htim2.Init.Prescaler = 0;
hudakz 0:cd0771c3346e 304 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
hudakz 0:cd0771c3346e 305 htim2.Init.Period = 60 - 1;
hudakz 0:cd0771c3346e 306 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
hudakz 0:cd0771c3346e 307 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
hudakz 0:cd0771c3346e 308 if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
hudakz 0:cd0771c3346e 309 Error_Handler();
hudakz 0:cd0771c3346e 310 }
hudakz 0:cd0771c3346e 311
hudakz 0:cd0771c3346e 312 if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) {
hudakz 0:cd0771c3346e 313 Error_Handler();
hudakz 0:cd0771c3346e 314 }
hudakz 0:cd0771c3346e 315
hudakz 0:cd0771c3346e 316 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
hudakz 0:cd0771c3346e 317 sSlaveConfig.InputTrigger = TIM_TS_ITR0;
hudakz 0:cd0771c3346e 318 if (HAL_TIM_SlaveConfigSynchronization(&htim2, &sSlaveConfig) != HAL_OK) {
hudakz 0:cd0771c3346e 319 Error_Handler();
hudakz 0:cd0771c3346e 320 }
hudakz 0:cd0771c3346e 321
hudakz 0:cd0771c3346e 322 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
hudakz 0:cd0771c3346e 323 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
hudakz 0:cd0771c3346e 324 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) {
hudakz 0:cd0771c3346e 325 Error_Handler();
hudakz 0:cd0771c3346e 326 }
hudakz 0:cd0771c3346e 327
hudakz 0:cd0771c3346e 328 sConfigOC.OCMode = TIM_OCMODE_PWM1;
hudakz 0:cd0771c3346e 329 sConfigOC.Pulse = 30;
hudakz 0:cd0771c3346e 330 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
hudakz 0:cd0771c3346e 331 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
hudakz 0:cd0771c3346e 332 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
hudakz 0:cd0771c3346e 333 Error_Handler();
hudakz 0:cd0771c3346e 334 }
hudakz 0:cd0771c3346e 335
hudakz 0:cd0771c3346e 336 __HAL_TIM_DISABLE_OCxPRELOAD(&htim2, TIM_CHANNEL_1);
hudakz 0:cd0771c3346e 337
hudakz 0:cd0771c3346e 338 HAL_TIM_MspPostInit(&htim2);
hudakz 0:cd0771c3346e 339 }
hudakz 0:cd0771c3346e 340
hudakz 0:cd0771c3346e 341 /**
hudakz 0:cd0771c3346e 342 * @brief TIM3 Initialization Function
hudakz 0:cd0771c3346e 343 * @note
hudakz 0:cd0771c3346e 344 * @param
hudakz 0:cd0771c3346e 345 * @retval
hudakz 0:cd0771c3346e 346 */
hudakz 0:cd0771c3346e 347 static void MX_TIM3_Init()
hudakz 0:cd0771c3346e 348 {
hudakz 0:cd0771c3346e 349 TIM_SlaveConfigTypeDef sSlaveConfig = { 0 };
hudakz 0:cd0771c3346e 350 TIM_MasterConfigTypeDef sMasterConfig = { 0 };
hudakz 0:cd0771c3346e 351 TIM_OC_InitTypeDef sConfigOC = { 0 };
hudakz 0:cd0771c3346e 352 htim3.Instance = TIM3;
hudakz 0:cd0771c3346e 353 htim3.Init.Prescaler = 0;
hudakz 0:cd0771c3346e 354 htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
hudakz 0:cd0771c3346e 355 htim3.Init.Period = 20 * 100 - 1;
hudakz 0:cd0771c3346e 356 htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
hudakz 0:cd0771c3346e 357 htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
hudakz 0:cd0771c3346e 358 if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {
hudakz 0:cd0771c3346e 359 Error_Handler();
hudakz 0:cd0771c3346e 360 }
hudakz 0:cd0771c3346e 361
hudakz 0:cd0771c3346e 362 if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) {
hudakz 0:cd0771c3346e 363 Error_Handler();
hudakz 0:cd0771c3346e 364 }
hudakz 0:cd0771c3346e 365
hudakz 0:cd0771c3346e 366 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
hudakz 0:cd0771c3346e 367 sSlaveConfig.InputTrigger = TIM_TS_ITR1;
hudakz 0:cd0771c3346e 368 if (HAL_TIM_SlaveConfigSynchronization(&htim3, &sSlaveConfig) != HAL_OK) {
hudakz 0:cd0771c3346e 369 Error_Handler();
hudakz 0:cd0771c3346e 370 }
hudakz 0:cd0771c3346e 371
hudakz 0:cd0771c3346e 372 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
hudakz 0:cd0771c3346e 373 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
hudakz 0:cd0771c3346e 374 if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) {
hudakz 0:cd0771c3346e 375 Error_Handler();
hudakz 0:cd0771c3346e 376 }
hudakz 0:cd0771c3346e 377
hudakz 0:cd0771c3346e 378 sConfigOC.OCMode = TIM_OCMODE_PWM2;
hudakz 0:cd0771c3346e 379 sConfigOC.Pulse = 1;
hudakz 0:cd0771c3346e 380 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
hudakz 0:cd0771c3346e 381 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
hudakz 0:cd0771c3346e 382 if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
hudakz 0:cd0771c3346e 383 Error_Handler();
hudakz 0:cd0771c3346e 384 }
hudakz 0:cd0771c3346e 385
hudakz 0:cd0771c3346e 386 __HAL_TIM_DISABLE_OCxPRELOAD(&htim3, TIM_CHANNEL_1);
hudakz 0:cd0771c3346e 387
hudakz 0:cd0771c3346e 388 HAL_TIM_MspPostInit(&htim3);
hudakz 0:cd0771c3346e 389 }
hudakz 0:cd0771c3346e 390
hudakz 0:cd0771c3346e 391 /**
hudakz 0:cd0771c3346e 392 * Enable DMA controller clock
hudakz 0:cd0771c3346e 393 */
hudakz 0:cd0771c3346e 394 static void MX_DMA_Init()
hudakz 0:cd0771c3346e 395 {
hudakz 0:cd0771c3346e 396 /* DMA controller clock enable */
hudakz 0:cd0771c3346e 397 __HAL_RCC_DMA1_CLK_ENABLE();
hudakz 0:cd0771c3346e 398
hudakz 0:cd0771c3346e 399 /* DMA interrupt init */
hudakz 0:cd0771c3346e 400 /* DMA1_Channel1_IRQn interrupt configuration */
hudakz 0:cd0771c3346e 401 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
hudakz 0:cd0771c3346e 402 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
hudakz 0:cd0771c3346e 403 }
hudakz 0:cd0771c3346e 404
hudakz 0:cd0771c3346e 405 /**
hudakz 0:cd0771c3346e 406 * @brief GPIO Initialization Function
hudakz 0:cd0771c3346e 407 * @note
hudakz 0:cd0771c3346e 408 * @param
hudakz 0:cd0771c3346e 409 * @retval
hudakz 0:cd0771c3346e 410 */
hudakz 0:cd0771c3346e 411 static void MX_GPIO_Init()
hudakz 0:cd0771c3346e 412 {
hudakz 0:cd0771c3346e 413 GPIO_InitTypeDef GPIO_InitStruct = { 0 };
hudakz 0:cd0771c3346e 414
hudakz 0:cd0771c3346e 415 /* GPIO Ports Clock Enable */
hudakz 0:cd0771c3346e 416 __HAL_RCC_GPIOC_CLK_ENABLE();
hudakz 0:cd0771c3346e 417 __HAL_RCC_GPIOD_CLK_ENABLE();
hudakz 0:cd0771c3346e 418 __HAL_RCC_GPIOA_CLK_ENABLE();
hudakz 0:cd0771c3346e 419 __HAL_RCC_GPIOB_CLK_ENABLE();
hudakz 0:cd0771c3346e 420
hudakz 0:cd0771c3346e 421 /*Configure GPIO pin : PA2 */
hudakz 0:cd0771c3346e 422 GPIO_InitStruct.Pin = GPIO_PIN_2;
hudakz 0:cd0771c3346e 423 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
hudakz 0:cd0771c3346e 424 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
hudakz 0:cd0771c3346e 425 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hudakz 0:cd0771c3346e 426
hudakz 0:cd0771c3346e 427 /*Configure GPIO pin : PA3 */
hudakz 0:cd0771c3346e 428 GPIO_InitStruct.Pin = GPIO_PIN_3;
hudakz 0:cd0771c3346e 429 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
hudakz 0:cd0771c3346e 430 GPIO_InitStruct.Pull = GPIO_NOPULL;
hudakz 0:cd0771c3346e 431 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hudakz 0:cd0771c3346e 432 }
hudakz 0:cd0771c3346e 433
hudakz 0:cd0771c3346e 434 /**
hudakz 0:cd0771c3346e 435 * @brief
hudakz 0:cd0771c3346e 436 * @note
hudakz 0:cd0771c3346e 437 * @param
hudakz 0:cd0771c3346e 438 * @retval
hudakz 0:cd0771c3346e 439 */
hudakz 0:cd0771c3346e 440 void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef* htim)
hudakz 0:cd0771c3346e 441 { }
hudakz 0:cd0771c3346e 442
hudakz 0:cd0771c3346e 443 /**
hudakz 0:cd0771c3346e 444 * @brief
hudakz 0:cd0771c3346e 445 * @note
hudakz 0:cd0771c3346e 446 * @param
hudakz 0:cd0771c3346e 447 * @retval
hudakz 0:cd0771c3346e 448 */
hudakz 0:cd0771c3346e 449 void Error_Handler()
hudakz 0:cd0771c3346e 450 {
hudakz 0:cd0771c3346e 451 printf("Error handler called!\r\n");
hudakz 0:cd0771c3346e 452 }