aboutsummaryrefslogtreecommitdiff
path: root/src/drivers/boards/px4cannode-v1/bootloader/common/boot_app_shared.c
blob: b8d649ea6066fd7f77060c73001553ca48101117 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <nuttx/config.h>

#include <stdint.h>
#include <string.h>

#include "chip.h"
#include "stm32.h"

#include <errno.h>
#include "boot_app_shared.h"
#include "crc.h"

#define BOOTLOADER_COMMON_APP_SIGNATURE         0xB0A04150u
#define BOOTLOADER_COMMON_BOOTLOADER_SIGNATURE  0xB0A0424Cu

/*  CAN_FiRx where (i=0..27|13, x=1, 2)
 *                      STM32_CAN1_FIR(i,x)
 * Using i = 2 does not requier there block
 * to be enabled nor FINIT in CAN_FMR to be set.
 * todo:Validate this claim on F2, F3
 */
#define crc_HiLOC       STM32_CAN1_FIR(2,1)
#define crc_LoLOC       STM32_CAN1_FIR(2,2)
#define signature_LOC   STM32_CAN1_FIR(3,1)
#define bus_speed_LOC   STM32_CAN1_FIR(3,2)
#define node_id_LOC     STM32_CAN1_FIR(4,1)
#define CRC_H 1
#define CRC_L 0

inline static void read(bootloader_app_shared_t * pcommon)
{
  pcommon->signature = getreg32(signature_LOC);
  pcommon->bus_speed = getreg32(bus_speed_LOC);
  pcommon->node_id = getreg32(node_id_LOC);
  pcommon->crc.ul[CRC_L] = getreg32(crc_LoLOC);
  pcommon->crc.ul[CRC_H] = getreg32(crc_HiLOC);

}

inline static void write(bootloader_app_shared_t * pcommon)
{
  putreg32(pcommon->signature, signature_LOC);
  putreg32(pcommon->bus_speed, bus_speed_LOC);
  putreg32(pcommon->node_id, node_id_LOC);
  putreg32(pcommon->crc.ul[CRC_L], crc_LoLOC);
  putreg32(pcommon->crc.ul[CRC_H], crc_HiLOC);

}

static uint64_t calulate_signature(bootloader_app_shared_t * pcommon)
{
  size_t size = sizeof(bootloader_app_shared_t) - sizeof(pcommon->crc);
  uint64_t crc = CRC64_INITIAL;
  uint8_t *protected = (uint8_t *) & pcommon->signature;

  while (size--)
    {
      crc = crc64_add(crc, *protected++);
    }
  crc ^= CRC64_OUTPUT_XOR;
  return crc;
}

void bootloader_app_shared_init(bootloader_app_shared_t * pcommon, eRole_t role)
{
  memset(pcommon, 0, sizeof(bootloader_app_shared_t));
  if (role != Invalid)
    {
      pcommon->signature =
        (role ==
         App ? BOOTLOADER_COMMON_APP_SIGNATURE :
         BOOTLOADER_COMMON_BOOTLOADER_SIGNATURE);
    }

}

int bootloader_app_shared_read(bootloader_app_shared_t * pcommon,
                                     eRole_t role)
{
  int rv = -EBADR;
  bootloader_app_shared_t working;

  read(&working);

  if ((role == App ? working.signature == BOOTLOADER_COMMON_APP_SIGNATURE
       : working.signature == BOOTLOADER_COMMON_BOOTLOADER_SIGNATURE)
      && (working.crc.ull == calulate_signature(&working)))
    {
      *pcommon = working;
      rv = OK;
    }
  return rv;
}

void bootloader_app_shared_write(bootloader_app_shared_t * common,
                                       eRole_t role)
{
  bootloader_app_shared_t working = *common;
  working.signature =
    (role ==
     App ? BOOTLOADER_COMMON_APP_SIGNATURE :
     BOOTLOADER_COMMON_BOOTLOADER_SIGNATURE);
  working.crc.ull = calulate_signature(&working);
  write(&working);

}

void bootloader_app_shared_invalidate(void)
{
  bootloader_app_shared_t working;
  bootloader_app_shared_init(&working, Invalid);
  write(&working);
}