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