libyggdrasil  v1.0.0
can.hpp
Go to the documentation of this file.
1  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * _____.___. .___ .__.__ *
3  * \__ | | ____ ____ __| _/___________ _____|__| | *
4  * / | |/ ___\ / ___\ / __ |\_ __ \__ \ / ___/ | | *
5  * \____ / /_/ > /_/ > /_/ | | | \// __ \_\___ \| | |__ *
6  * / ______\___ /\___ /\____ | |__| (____ /____ >__|____/ *
7  * \/ /_____//_____/ \/ \/ \/ *
8  * - Midgard - *
9  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
10  * This software can be used by students and other personal of the *
11  * Bern University of Applied Sciences under the terms of the MIT *
12  * license. *
13  * For other persons this software is under the terms of the GNU *
14  * General Public License version 2. *
15  * *
16  * Copyright © 2021, Bern University of Applied Sciences. *
17  * All rights reserved. *
18  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #pragma once
27 
29 
30 #include <string>
31 #include <string_view>
32 #include <array>
33 
34 namespace bsp::mid::drv {
35 
42  template<auto Context>
43  struct CAN {
44 
51  static bool init() {
52  setStdFilter(0, 0, 0); // bank 0 will accept all IDs
53  return HAL_CAN_Start(Context) == HAL_OK;
54  }
55 
61  static bool deinit() {
62  return true;
63  }
64 
68  static bool enable() {
69  return HAL_CAN_Start(Context) == HAL_OK;
70  }
71 
75  static bool disable() {
76  return HAL_CAN_Stop(Context) == HAL_OK;
77  }
78 
79 
88  static void read(u32 &id, u32 &extendedId, u32 &timestamp, std::array<u8, 8> &data) {
89  CAN_RxHeaderTypeDef rxHeader = {0};
90  while (HAL_CAN_GetRxFifoFillLevel(Context, CAN_RX_FIFO0) == 0);
91  HAL_CAN_GetRxMessage(Context, CAN_RX_FIFO0, &rxHeader, data.data());
92  id = rxHeader.StdId;
93  extendedId = rxHeader.ExtId;
94  timestamp = rxHeader.Timestamp;
95  }
96 
103  template<typename T>
105  u32 pTxMailbox;
106  CAN_TxHeaderTypeDef txHeader = {0};
107  constexpr size_t Size = sizeof(T);
108 
109  std::array<u8, Size> data;
110  std::memcpy(data.data(), &packet.data, Size);
111  txHeader.StdId = packet.id;
112  txHeader.ExtId = packet.extendedId;
113  txHeader.TransmitGlobalTime = static_cast<FunctionalState>(packet.transmitGlobalTime);
114  txHeader.DLC = Size;
115 
116  if(packet.extendedId > 0) txHeader.IDE = CAN_ID_EXT;
117  else txHeader.IDE = CAN_ID_STD;
118 
119 
120  HAL_CAN_AddTxMessage(Context, &txHeader, const_cast<u8*>(data.data()), &pTxMailbox);
121  while (HAL_CAN_GetTxMailboxesFreeLevel(Context) != 3);
122  return pTxMailbox;
123  }
124 
133  static bool setStdFilter(u8 bank, u16 id, u16 mask) {
134  if (bank > 28) return false;
135  if (id > 0x7FF) return false;
136  if (mask > 0x7FF) return false;
137 
138  CAN_FilterTypeDef sFilterConfig;
139  sFilterConfig.FilterBank = bank;
140  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
141  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
142  sFilterConfig.FilterIdHigh = (id << 5);
143  sFilterConfig.FilterIdLow = 0;
144  sFilterConfig.FilterMaskIdHigh = (mask << 5);
145  sFilterConfig.FilterMaskIdLow = 0;
146  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
147  sFilterConfig.FilterActivation = ENABLE;
148  sFilterConfig.SlaveStartFilterBank = 0;
149 
150  if (HAL_CAN_ConfigFilter(Context, &sFilterConfig) != HAL_OK) return false;
151  return true;
152  }
153 
154 
165  static bool setExtFilter(u8 bank, u32 id, u32 mask) {
166  if (bank > 28) return false;
167  if (id > 0x1FFFFFFF) return false;
168  if (mask > 0x1FFFFFFF) return false;
169 
170  CAN_FilterTypeDef sFilterConfig;
171  sFilterConfig.FilterBank = bank;
172  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
173  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
174  sFilterConfig.FilterIdHigh = ((id & 0x7FF) << 5) | ((id >> 27) & 0xFFFF);
175  sFilterConfig.FilterIdLow = ((id >> 11) << 3) & 0xFFFF;
176  sFilterConfig.FilterMaskIdHigh = ((mask & 0x7FF) << 5) | ((mask >> 27) & 0xFFFF);
177  sFilterConfig.FilterMaskIdLow = ((mask >> 11) << 3) & 0xFFFF;
178  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
179  sFilterConfig.FilterActivation = ENABLE;
180  sFilterConfig.SlaveStartFilterBank = 0;
181 
182  if (HAL_CAN_ConfigFilter(Context, &sFilterConfig) != HAL_OK)
183  return false;
184 
185  return true;
186  }
187 
194  static bool disableFilter(u8 bank) {
195  if (bank > 28) return false;
196 
197  CAN_FilterTypeDef sFilterConfig;
198  sFilterConfig.FilterBank = bank;
199  sFilterConfig.FilterActivation = DISABLE;
200 
201  if (HAL_CAN_ConfigFilter(Context, &sFilterConfig) != HAL_OK) return false;
202  return true;
203  }
204 
205 
206  };
207 
208 }
bsp::mid::drv::CAN::write
static u32 write(bsp::drv::CANPacket< T > packet)
CAN write.
Definition: can.hpp:104
u16
uint16_t u16
Definition: types.h:37
u8
uint8_t u8
Unsigned integer definitions.
Definition: types.h:36
bsp::mid::drv::CAN::setExtFilter
static bool setExtFilter(u8 bank, u32 id, u32 mask)
Extended ID filter configuration function.
Definition: can.hpp:165
bsp::mid::drv::CAN::disableFilter
static bool disableFilter(u8 bank)
Filter bank disable.
Definition: can.hpp:194
bsp::drv::CANPacket::id
u32 id
Definition: can.hpp:39
bsp::mid::drv::CAN::deinit
static bool deinit()
Deinit function.
Definition: can.hpp:61
bsp::drv::CANPacket::extendedId
u32 extendedId
Definition: can.hpp:39
bsp::mid::drv::CAN::setStdFilter
static bool setStdFilter(u8 bank, u16 id, u16 mask)
Standard ID filter configuration function.
Definition: can.hpp:133
bsp::mid::drv::CAN::read
static void read(u32 &id, u32 &extendedId, u32 &timestamp, std::array< u8, 8 > &data)
CAN receive.
Definition: can.hpp:88
u32
uint32_t u32
Definition: types.h:38
bsp::drv::CANPacket
Definition: can.hpp:38
bsp::drv::CANPacket::data
T data
Definition: can.hpp:43
bsp::drv::CANPacket::transmitGlobalTime
u32 transmitGlobalTime
Definition: can.hpp:41
bsp::mid::drv::CAN::enable
static bool enable()
Can enable.
Definition: can.hpp:68
bsp::mid::drv::CAN
CAN implementation for Midgard.
Definition: can.hpp:43
can.hpp
Frontend for the CAN abstraction.
bsp::mid::drv::CAN::disable
static bool disable()
Can disable.
Definition: can.hpp:75
bsp::mid::drv::CAN::init
static bool init()
Init function.
Definition: can.hpp:51
bsp::mid::drv
Definition: adc.hpp:32