Subversion Repositories canSerial

Rev

Rev 4 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/* USER CODE BEGIN Header */
5 mjames 2
 
2 mjames 3
/**
4
 ******************************************************************************
5
 * @file           : main.c
6
 * @brief          : Main program body
7
 ******************************************************************************
8
 * @attention
9
 *
10
 * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
11
 * All rights reserved.</center></h2>
12
 *
13
 * This software component is licensed by ST under BSD 3-Clause license,
14
 * the "License"; You may not use this file except in compliance with the
15
 * License. You may obtain a copy of the License at:
16
 *                        opensource.org/licenses/BSD-3-Clause
17
 *
18
 ******************************************************************************
19
 */
5 mjames 20
/** @note
21
 * Reference : implementation created from reversing code in:
22
 * https://github.com/canboat/canboat/tree/master/ikonvert-serial
23
 */
24
 
2 mjames 25
/* USER CODE END Header */
26
/* Includes ------------------------------------------------------------------*/
27
#include "main.h"
28
 
29
/* Private includes ----------------------------------------------------------*/
30
/* USER CODE BEGIN Includes */
5 mjames 31
#include <stdio.h>
32
#include <stdlib.h>
33
 
3 mjames 34
#include "display.h"
35
 
2 mjames 36
#include "string.h"
37
#include "base64.h"
38
#include "libSerial/serial.H"
3 mjames 39
#include "libSerial/serialUtils.H"
2 mjames 40
#include "libSmallPrintf/small_printf.h"
41
 
42
/* USER CODE END Includes */
43
 
44
/* Private typedef -----------------------------------------------------------*/
45
/* USER CODE BEGIN PTD */
46
 
47
typedef enum
48
{
49
  FAIL,
50
  REJECT,
51
  ACCEPT,
52
  COMPLETE
53
} appendStatus;
54
 
55
typedef struct
56
{
57
  uint8_t payloadBuffer[233];
58
  uint32_t payloadId;
59
  uint8_t payloadRemaining;  // number of bytes remaining
60
  uint8_t payloadTotal;      // number total number of bytes
61
  uint8_t payloadOffset;     // byte offset
62
  uint8_t payloadNextSeq;    // next sequence frame expected
63
  uint32_t payloadTimestamp; // timestamp of reception
64
  appendStatus status;
65
} contextType;
66
 
67
/* USER CODE END PTD */
68
 
69
/* Private define ------------------------------------------------------------*/
70
/* USER CODE BEGIN PD */
71
/* USER CODE END PD */
72
 
73
/* Private macro -------------------------------------------------------------*/
74
/* USER CODE BEGIN PM */
75
#define False (0)
76
#define True (1)
77
/* USER CODE END PM */
78
 
79
/* Private variables ---------------------------------------------------------*/
80
CAN_HandleTypeDef hcan;
81
 
3 mjames 82
SPI_HandleTypeDef hspi1;
83
 
2 mjames 84
UART_HandleTypeDef huart1;
85
 
86
/* USER CODE BEGIN PV */
87
 
88
/* USER CODE END PV */
89
 
90
/* Private function prototypes -----------------------------------------------*/
91
void SystemClock_Config(void);
92
static void MX_GPIO_Init(void);
93
static void MX_CAN_Init(void);
94
static void MX_USART1_UART_Init(void);
3 mjames 95
static void MX_SPI1_Init(void);
2 mjames 96
/* USER CODE BEGIN PFP */
97
 
98
/* USER CODE END PFP */
99
 
100
/* Private user code ---------------------------------------------------------*/
101
/* USER CODE BEGIN 0 */
102
 
103
#define CONTEXTS 6
104
contextType contexts[CONTEXTS];
105
 
106
CAN_TxHeaderTypeDef TxHeader;
107
CAN_RxHeaderTypeDef RxHeader;
108
 
109
uint8_t TxData[8];
110
uint8_t RxData[8];
111
 
112
// Storage for the data
113
 
114
uint32_t TxMailbox;
115
 
116
char const version[] = "$PDGY,Mike_James_Converter_#00001_Mode:15\r\n";
117
char const keepawake[] = "$PDGY,000000,1,,4,%ld.%03ld,,,\r\n";
5 mjames 118
char const commandHdr[] = "$PDGY,";
2 mjames 119
 
4 mjames 120
// Allocation of serial buffer sizes and storage
121
#define TX_BUFFER_SIZE 512
122
#define RX_BUFFER_SIZE 16
123
uint8_t tx_buffer[TX_BUFFER_SIZE];
124
uint8_t rx_buffer[RX_BUFFER_SIZE];
125
 
2 mjames 126
// reset a search context
127
void resetContext(contextType *c)
128
{
129
  c->payloadRemaining = 0; // number of bytes remaining
130
  c->payloadTotal = 0;     // number total number of bytes
131
  c->payloadOffset = 0;
132
  c->payloadNextSeq = 0;
133
  c->payloadTimestamp = 0;
134
  c->status = FAIL;
135
  c->payloadId = 0;
136
}
137
 
138
uint8_t singleFrame(uint32_t pgn)
139
{
140
 
141
  switch (pgn)
142
  {
143
  case 129029:
144
  case 129038:
145
  case 126996:
146
  case 127489:
147
    return False;
148
  default:
149
    break;
150
  }
151
 
152
  if (pgn >= 130816 && pgn <= 131071)
153
    return False;
154
  if (pgn >= 65536 && pgn <= 126975)
155
    return False;
156
  return True;
157
}
158
 
159
// called from CAN frame callback
160
appendStatus append(contextType *c, CAN_RxHeaderTypeDef *packet)
161
{
162
  uint32_t extId = RxHeader.ExtId;
163
 
164
  if (c->payloadId != 0 && c->payloadId != extId)
165
    return REJECT;
166
  uint8_t newId = c->payloadId == 0; // set a flag if this is a newly discovered frame
167
  c->payloadId = extId;
168
 
169
  uint32_t pgn = (c->payloadId >> 8) & ((1 << 18) - 1);
170
  uint8_t pf = (pgn >> 8) & 0xFF;
171
 
172
  if (pf < 240)
173
  {
174
    // process PS if in PDU1 , address is low byte
175
    pgn = pgn & 0x3FF00;
176
  }
177
 
178
  uint8_t packetLen = RxHeader.DLC;
179
 
180
  if (singleFrame(pgn))
181
  {
182
    c->payloadTimestamp = HAL_GetTick();
183
    memcpy(c->payloadBuffer, RxData, packetLen);
184
    c->payloadRemaining = 0;
185
    c->payloadTotal = packetLen;
186
    c->status = COMPLETE;
187
    return c->status; // successfully filled frame
188
  }
189
  else
190
  {
191
    // sort out fastpacket new ID
192
    if (newId)
193
    {
194
      if ((RxData[0] & 0x1f) != 0)
195
      {
196
        resetContext(c);
197
        return FAIL;
198
      }
199
      c->payloadTimestamp = HAL_GetTick();
200
      c->payloadNextSeq = RxData[0] + 1;
201
      c->payloadId = extId;
202
      c->payloadRemaining = RxData[1];
203
      c->payloadTotal = RxData[1];
204
      // no data , return
205
      if (c->payloadTotal == 0)
206
      {
207
        resetContext(c);
208
        return FAIL;
209
      }
210
      uint8_t numBytes = packetLen - 2;
211
      memcpy(c->payloadBuffer, RxData + 2, numBytes);
212
 
213
      // CAN frame can be longer than remaining bytes, do not make payloadRemaining wrap around !
214
      if (numBytes < c->payloadRemaining)
215
        c->payloadRemaining -= numBytes;
216
      else
217
        c->payloadRemaining = 0;
218
      c->payloadOffset = numBytes;
219
    }
220
    else
221
    {
222
      if (RxData[0] != c->payloadNextSeq)
223
      {
224
        resetContext(c);
225
        return FAIL;
226
      }
227
      // predict next payload sequence
228
      c->payloadNextSeq++;
229
      uint8_t numBytes = packetLen - 1;
230
      memcpy(c->payloadBuffer + c->payloadOffset, RxData + 1, numBytes);
231
      c->payloadRemaining -= numBytes;
232
      c->payloadOffset += numBytes;
233
    }
234
  }
235
 
236
  appendStatus stat = (c->payloadRemaining != 0) ? ACCEPT : COMPLETE;
237
  c->status = stat;
238
  return stat;
239
}
240
 
241
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
242
{
243
  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
244
  HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData);
245
 
246
  int i;
247
  for (i = 0; i < CONTEXTS; ++i)
248
  {
249
    contextType *ctx = &contexts[i];
250
    appendStatus stat = append(ctx, &RxHeader);
251
    if (stat == ACCEPT || stat == COMPLETE)
252
      break; // accepted data, stop loop
253
  }
254
}
255
 
256
void heartBeat()
257
{
258
  char lineBuff[80];
259
  uint32_t timestamp = HAL_GetTick();
260
  size_t pos = small_sprintf(lineBuff, keepawake,
261
                             timestamp / 1000, // seconds
262
                             timestamp % 1000  // milliseconds
263
  );
264
  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
265
  if (pos < SerialTransmitSpace(&uc1))
266
  {
267
    __disable_irq();
268
    sendString(&uc1, (char *)lineBuff, pos);
269
    __enable_irq();
270
  }
271
}
272
 
273
// utility function to set up the filter mask
274
void CAN_FilterMaskEXT(CAN_FilterTypeDef *filter_, uint32_t id_, uint32_t mask_)
275
{
276
  filter_->FilterIdHigh = id_ >> 13;
277
  filter_->FilterIdLow = ((id_ & 0x1FFF) << 3) | CAN_ID_EXT;
278
  filter_->FilterMaskIdHigh = mask_ >> 13;
279
  filter_->FilterMaskIdLow = ((mask_ & 0x1FFF) << 3) | CAN_ID_EXT;
280
}
281
 
282
void processCmd(char *buff, int len)
283
{
284
  buff[len] = 0; // terminate in case of error
5 mjames 285
                 /// expect $PDGY,pgn,dst,payloadBase64
286
  const char tokens[] = ",";
287
 
288
  char *s = strtok(buff, tokens);
289
  if (strcmp(s, "$PDGY") != 0)
290
    return;
291
 
292
  char *pgnStr = strtok(NULL, tokens);
293
  if (!pgnStr)
294
    return;
295
  char *dstStr = strtok(NULL, tokens);
296
  if (!dstStr)
297
    return;
298
  char *payloadStr = strtok(NULL, tokens);
299
  if (!payloadStr)
300
    return;
301
 
302
  // decode string into lineBuff from base64
303
  uint8_t  frameData[8];
304
  size_t bytes = 0;
305
  base64_decode(payloadStr, strlen(payloadStr), (char *) frameData, &bytes);
306
 
307
  int pgn = atoi(pgnStr);
308
 
309
 // int dst = atoi(dstStr);
310
 
311
  CAN_TxHeaderTypeDef Header;
312
  Header.ExtId = pgn;
313
  Header.DLC = bytes < 8 ? bytes : 8;
314
  Header.IDE = 0;
315
  Header.RTR = 0;
316
 
317
  uint32_t usedMailbox;
318
  HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(&hcan, &Header,
319
                                                  (uint8_t *)frameData, &usedMailbox);
320
 
321
  if (status == HAL_OK)
2 mjames 322
  {
5 mjames 323
     char lineBuff[100];
324
 int pos = small_sprintf(lineBuff, "$PDGY,ACK,%s\r\n", buff);
325
    if (pos < SerialTransmitSpace(&uc1))
326
    {
327
      __disable_irq();
328
      sendString(&uc1, (char *)lineBuff, pos);
329
      __enable_irq();
330
    }
2 mjames 331
  }
332
}
333
 
334
/* USER CODE END 0 */
335
 
336
/**
337
 * @brief  The application entry point.
338
 * @retval int
339
 */
340
int main(void)
341
{
342
  /* USER CODE BEGIN 1 */
343
 
344
  /* USER CODE END 1 */
345
 
346
  /* MCU Configuration--------------------------------------------------------*/
347
 
348
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
349
  HAL_Init();
350
 
351
  /* USER CODE BEGIN Init */
352
 
353
  /* USER CODE END Init */
354
 
355
  /* Configure the system clock */
356
  SystemClock_Config();
357
 
358
  /* USER CODE BEGIN SysInit */
3 mjames 359
  cc_init();
2 mjames 360
 
361
  /* USER CODE END SysInit */
362
 
363
  /* Initialize all configured peripherals */
364
  MX_GPIO_Init();
365
  MX_CAN_Init();
366
  MX_USART1_UART_Init();
3 mjames 367
  MX_SPI1_Init();
2 mjames 368
  /* USER CODE BEGIN 2 */
369
 
370
  HAL_CAN_Start(&hcan);
371
 
4 mjames 372
  init_usart_ctl(&uc1, &huart1,
373
                 tx_buffer,
374
                 rx_buffer,
375
                 TX_BUFFER_SIZE,
376
                 RX_BUFFER_SIZE);
2 mjames 377
 
378
  EnableSerialRxInterrupt(&uc1);
379
 
380
  // Activate the notification
381
  HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
382
 
383
  // send out a version string on the serial port
384
  sendString(&uc1, (char *)version, sizeof(version));
385
 
386
  uint32_t sendTime = HAL_GetTick() + 1000;
387
  char cmdBuff[100];
388
 
4 mjames 389
  // serial utils library command editor
3 mjames 390
  editBuffer cmdEdit;
391
 
4 mjames 392
  initReadLine(&cmdEdit, cmdBuff, 100, READLINES_CR);
393
 
2 mjames 394
  for (int i = 0; i < CONTEXTS; ++i)
395
    resetContext(&contexts[i]);
396
 
397
  /* USER CODE END 2 */
398
 
399
  /* Infinite loop */
400
  /* USER CODE BEGIN WHILE */
401
  while (1)
402
  {
403
    /* USER CODE END WHILE */
404
 
405
    /* USER CODE BEGIN 3 */
406
 
4 mjames 407
    editBufferReturn ret = readLine(&uc1, &cmdEdit);
3 mjames 408
 
4 mjames 409
    if (ret == EDIT_CR)
410
    {
411
      processCmd(cmdBuff, charCount(&cmdEdit));
412
      resetInput(&cmdEdit);
413
    }
3 mjames 414
 
2 mjames 415
    if (HAL_GetTick() > sendTime)
416
    {
417
      sendTime += 1000;
418
      heartBeat();
3 mjames 419
      cc_display(2);
2 mjames 420
    }
421
 
422
    for (int i = 0; i < CONTEXTS; ++i)
423
    {
424
      contextType *ctx = &contexts[i];
425
      /// check for too old
426
      //   if (ctx->status == ACCEPT && ctx->payloadTimestamp < old)
427
      //   {
428
      //     resetContext(ctx);
429
      //     continue;
430
      //   }
431
 
432
      if (ctx->status == COMPLETE)
433
      {
434
        __disable_irq();
435
 
436
        uint8_t prio = (ctx->payloadId >> 26) & 0x7;
437
        uint8_t src = ctx->payloadId & 0xFF;
438
        uint8_t dst = 255;
439
        // mask out the PGN field as 18 bits.
440
        uint32_t pgn = (ctx->payloadId >> 8) & ((1 << 18) - 1);
441
        uint8_t pf = (pgn >> 8) & 0xFF;
442
 
443
        if (pf < 240)
444
        {
445
          // process PS if in PDU1 , address is low byte
446
          dst = pgn & 0xFF;
447
          pgn = pgn & 0x3FF00;
448
        }
449
 
450
        char lineBuff[300];
451
        size_t pos = small_sprintf(lineBuff, "!PDGY,%ld,%d,%d,%d,%ld.%03ld,",
452
                                   pgn,  // PGN
453
                                   prio, // priority
454
                                   src,  // source address
455
                                   dst,  // destination address
456
 
457
                                   ctx->payloadTimestamp / 1000, // milliseconds
458
                                   ctx->payloadTimestamp % 1000);
459
 
460
        size_t base64_len;
461
        base64_encode(ctx->payloadBuffer,
462
                      ctx->payloadTotal,
463
                      lineBuff + pos,
464
                      &base64_len);
465
 
466
        pos += base64_len;
467
        lineBuff[pos++] = '\r';
468
        lineBuff[pos++] = '\n';
469
        __enable_irq();
470
 
471
        // skip sending if this would overrun the buffer
472
        if (pos < SerialTransmitSpace(&uc1))
473
          sendString(&uc1, lineBuff, pos);
474
        __disable_irq();
475
 
476
        resetContext(ctx);
477
        __enable_irq();
478
      }
479
    }
480
  }
481
  /* USER CODE END 3 */
482
}
483
 
484
/**
485
 * @brief System Clock Configuration
486
 * @retval None
487
 */
488
void SystemClock_Config(void)
489
{
490
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
491
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
492
 
493
  /** Initializes the RCC Oscillators according to the specified parameters
494
   * in the RCC_OscInitTypeDef structure.
495
   */
496
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
497
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
498
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
499
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
500
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
501
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
502
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
503
  {
504
    Error_Handler();
505
  }
506
 
507
  /** Initializes the CPU, AHB and APB buses clocks
508
   */
509
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
510
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
511
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
512
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
513
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
514
 
515
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
516
  {
517
    Error_Handler();
518
  }
519
}
520
 
521
/**
522
 * @brief CAN Initialization Function
523
 * @param None
524
 * @retval None
525
 */
526
static void MX_CAN_Init(void)
527
{
528
 
529
  /* USER CODE BEGIN CAN_Init 0 */
530
 
531
  /* USER CODE END CAN_Init 0 */
532
 
533
  /* USER CODE BEGIN CAN_Init 1 */
534
 
535
  /* USER CODE END CAN_Init 1 */
536
  hcan.Instance = CAN1;
537
  hcan.Init.Prescaler = 16;
538
  hcan.Init.Mode = CAN_MODE_NORMAL;
539
  hcan.Init.SyncJumpWidth = CAN_SJW_2TQ;
540
  hcan.Init.TimeSeg1 = CAN_BS1_3TQ;
541
  hcan.Init.TimeSeg2 = CAN_BS2_4TQ;
542
  hcan.Init.TimeTriggeredMode = DISABLE;
543
  hcan.Init.AutoBusOff = DISABLE;
544
  hcan.Init.AutoWakeUp = DISABLE;
545
  hcan.Init.AutoRetransmission = ENABLE;
546
  hcan.Init.ReceiveFifoLocked = DISABLE;
547
  hcan.Init.TransmitFifoPriority = DISABLE;
548
  if (HAL_CAN_Init(&hcan) != HAL_OK)
549
  {
550
    Error_Handler();
551
  }
552
  /* USER CODE BEGIN CAN_Init 2 */
553
  /* USER CODE BEGIN CAN_Init 2 */
554
 
555
  // allow absolutely everything into filter
556
  CAN_FilterTypeDef filterConfig;
557
  filterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
558
  filterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
559
  filterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
560
  filterConfig.FilterActivation = CAN_FILTER_ENABLE;
561
  filterConfig.FilterBank = 0;
562
 
563
  CAN_FilterMaskEXT(&filterConfig, 0, 0);
564
 
565
  HAL_CAN_ConfigFilter(&hcan, &filterConfig);
566
 
567
  /* USER CODE END CAN_Init 2 */
568
}
569
 
570
/**
3 mjames 571
 * @brief SPI1 Initialization Function
572
 * @param None
573
 * @retval None
574
 */
575
static void MX_SPI1_Init(void)
576
{
577
 
578
  /* USER CODE BEGIN SPI1_Init 0 */
579
 
580
  /* USER CODE END SPI1_Init 0 */
581
 
582
  /* USER CODE BEGIN SPI1_Init 1 */
583
 
584
  /* USER CODE END SPI1_Init 1 */
585
  /* SPI1 parameter configuration*/
586
  hspi1.Instance = SPI1;
587
  hspi1.Init.Mode = SPI_MODE_MASTER;
588
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
589
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
590
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
591
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
592
  hspi1.Init.NSS = SPI_NSS_SOFT;
593
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
594
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
595
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
596
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
597
  hspi1.Init.CRCPolynomial = 10;
598
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
599
  {
600
    Error_Handler();
601
  }
602
  /* USER CODE BEGIN SPI1_Init 2 */
603
 
604
  /* USER CODE END SPI1_Init 2 */
605
}
606
 
607
/**
2 mjames 608
 * @brief USART1 Initialization Function
609
 * @param None
610
 * @retval None
611
 */
612
static void MX_USART1_UART_Init(void)
613
{
614
 
615
  /* USER CODE BEGIN USART1_Init 0 */
616
 
617
  /* USER CODE END USART1_Init 0 */
618
 
619
  /* USER CODE BEGIN USART1_Init 1 */
620
 
621
  /* USER CODE END USART1_Init 1 */
622
  huart1.Instance = USART1;
623
  huart1.Init.BaudRate = 460800;
624
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
625
  huart1.Init.StopBits = UART_STOPBITS_1;
626
  huart1.Init.Parity = UART_PARITY_NONE;
627
  huart1.Init.Mode = UART_MODE_TX_RX;
628
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
629
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
630
  if (HAL_UART_Init(&huart1) != HAL_OK)
631
  {
632
    Error_Handler();
633
  }
634
  /* USER CODE BEGIN USART1_Init 2 */
635
 
636
  /* USER CODE END USART1_Init 2 */
637
}
638
 
639
/**
640
 * @brief GPIO Initialization Function
641
 * @param None
642
 * @retval None
643
 */
644
static void MX_GPIO_Init(void)
645
{
646
  GPIO_InitTypeDef GPIO_InitStruct = {0};
3 mjames 647
  /* USER CODE BEGIN MX_GPIO_Init_1 */
648
  /* USER CODE END MX_GPIO_Init_1 */
2 mjames 649
 
650
  /* GPIO Ports Clock Enable */
651
  __HAL_RCC_GPIOC_CLK_ENABLE();
652
  __HAL_RCC_GPIOD_CLK_ENABLE();
653
  __HAL_RCC_GPIOA_CLK_ENABLE();
654
 
655
  /*Configure GPIO pin Output Level */
656
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
657
 
3 mjames 658
  /*Configure GPIO pin Output Level */
659
  HAL_GPIO_WritePin(GPIOA, SPI1_CS_Pin | SPI1_CD_Pin | SPI1_RESET_Pin, GPIO_PIN_RESET);
660
 
2 mjames 661
  /*Configure GPIO pin : LED_Pin */
662
  GPIO_InitStruct.Pin = LED_Pin;
663
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
664
  GPIO_InitStruct.Pull = GPIO_NOPULL;
665
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
666
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
3 mjames 667
 
668
  /*Configure GPIO pins : SPI1_CS_Pin SPI1_CD_Pin SPI1_RESET_Pin */
669
  GPIO_InitStruct.Pin = SPI1_CS_Pin | SPI1_CD_Pin | SPI1_RESET_Pin;
670
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
671
  GPIO_InitStruct.Pull = GPIO_NOPULL;
672
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
673
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
674
 
675
  /* USER CODE BEGIN MX_GPIO_Init_2 */
676
  /* USER CODE END MX_GPIO_Init_2 */
2 mjames 677
}
678
 
679
/* USER CODE BEGIN 4 */
680
 
681
/* USER CODE END 4 */
682
 
683
/**
684
 * @brief  This function is executed in case of error occurrence.
685
 * @retval None
686
 */
687
void Error_Handler(void)
688
{
689
  /* USER CODE BEGIN Error_Handler_Debug */
690
  /* User can add his own implementation to report the HAL error return state */
691
 
692
  /* USER CODE END Error_Handler_Debug */
693
}
694
 
695
#ifdef USE_FULL_ASSERT
696
/**
697
 * @brief  Reports the name of the source file and the source line number
698
 *         where the assert_param error has occurred.
699
 * @param  file: pointer to the source file name
700
 * @param  line: assert_param error line source number
701
 * @retval None
702
 */
703
void assert_failed(uint8_t *file, uint32_t line)
704
{
705
  /* USER CODE BEGIN 6 */
706
  /* User can add his own implementation to report the file name and line number,
707
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
708
  /* USER CODE END 6 */
709
}
710
#endif /* USE_FULL_ASSERT */