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