foxBMS  1.4.1
The foxBMS Battery Management System API Documentation
nxp_mc33775a-ll.c
Go to the documentation of this file.
1 /* Copyright 2019 NXP
2 *
3 * Redistribution and use in source and binary forms, with or without modification, are permitted
4 * provided that the following terms are met:
5 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions
6 * and the following disclaimer.
7 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions,
8 * and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
10 * or promote products derived from this software without specific prior written permission.
11 *
12 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ?AS IS? AND ANY
13 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
15 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
17 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA; OR PROFITS; OR BUSINESS INTERRUPTION)
18 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
19 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 */
22 
23 /*========== Includes =======================================================*/
24 #include "general.h"
25 
26 #include "nxp_mc33775a-ll.h"
27 
28 #include "dma.h"
29 #include "io.h"
30 #include "mcu.h"
31 #include "os.h"
32 #include "spi.h"
33 
34 /*========== Macros and Definitions =========================================*/
35 
36 /** Number of words (16 bits) used for write messages */
37 #define N775_WRITE_SPI_BUFFER_SIZE (4u)
38 /** Number of words (16 bits) in read answers that do not contain data */
39 #define N775_READ_HEADER_SPI_BUFFER_SIZE (3u)
40 /**
41  * Number of words (16 bits) in read answers that contain data.
42  * Based on maximum payload, which is 4 register per answer frame.
43  */
44 #define N775_READ_PAYLOAD_SPI_BUFFER_SIZE (4u)
45 /**
46  * Maximum number of groups of registers that can be read,
47  * to limit buffer size.
48  * Groups can be of size 1 to 4 registers.
49  * One frame = header (e.g., register address) +
50  * payload (data, 1 to 4 registers)
51  */
52 #define N775_MAX_ANSWER_FRAMES (30u)
53 /** Time to wait in microseconds after a write command */
54 #define N775_WAIT_TIME_AFTER_WRITE_US (5u)
55 /** Time to wait in microseconds after a read command */
56 #define N775_WAIT_TIME_AFTER_READ_US (5u)
57 /** Timeout to wait in microseconds for SPI send interrupt. */
58 #define N775_SPI_WRITE_TIMEOUT_US (500u)
59 /**
60  * Timeout to wait in microseconds for reception of a read answer.
61  * After that time the communication is considered to have failed.
62  */
63 #define N775_SPI_READ_TIMEOUT_US (2000u)
64 
65 /*========== Static Constant and Variable Definitions =======================*/
66 static uint16_t referenceMessageCounter[BS_NR_OF_STRINGS][512]; /* fits for all possible nodes */
67 
68 #pragma SET_DATA_SECTION(".sharedRAM")
71 static uint16_t n775FromTplTxBuffer
74 static uint16_t n775FromTplRxBuffer
77 #pragma SET_DATA_SECTION()
78 
79 /*========== Extern Constant and Variable Definitions =======================*/
80 
81 /*========== Static Function Prototypes =====================================*/
82 /**
83  * @brief Copies a message to the buffer to be passed to the SPI transmit
84  * functions
85  * @param pBuffer
86  * @param message
87  */
88 static void N775_ConvertMessageToBuffer(uint16_t *pBuffer, uc_msg_t message);
89 
90 #if (N775_USE_NOTIFICATIONS == false)
91 /**
92  * @brief Wait for the SPI transmit communication to complete, blocking
93  *
94  * return 0 if transaction completed interrupt did not come,
95  * non zero value otherwise
96  */
97 static uint16_t N775_WaitForTxCompleted(void);
98 
99 /**
100  * @brief Wait for the SPI receive communication to complete, blocking
101  *
102  * return 0 if transaction completed interrupt did not come,
103  * non zero value otherwise
104  */
105 static uint16_t N775_WaitForRxCompleted(void);
106 #else
107 /**
108  * @brief Clear pending notifications
109  *
110  * Used to clear pending Tx notifications made by the read function
111  * when writing to registers: when reading, commands are sent on SPI1.
112  * In the SPI1 ISR, a notification is made, but it is not used: the system
113  * waits for the SPI Rx notification from SPI4. As a consequence, when the
114  * write function is called after the read function, there is already a
115  * notification pending. The function waiting for the notification in the
116  * ISR of SPI1 exits immediately instead of waiting for the end of the
117  * transmission.
118  */
119 void N775_ClearNotifications(void);
120 
121 /**
122  * @brief Wait for the SPI transmit communication to complete, using notifications
123  *
124  * return N775_TX_NOTIFIED_VALUE if notification received,
125  * N775_NO_NOTIFIED_VALUE if timeout reached
126  */
127 static uint32_t N775_WaitForTxCompletedNotification(void);
128 
129 /**
130  * @brief Wait for the SPI receive communication to complete, using notifications
131  *
132  * return N775_RX_NOTIFIED_VALUE if notification received,
133  * N775_NO_NOTIFIED_VALUE if timeout reached
134  */
135 static uint32_t N775_WaitForRxCompletedNotification(void);
136 #endif
137 
138 /*========== Static Function Implementations ================================*/
139 
140 static void N775_ConvertMessageToBuffer(uint16_t *pBuffer, uc_msg_t message) {
141  FAS_ASSERT(pBuffer != NULL_PTR);
142  pBuffer[0u] = message.head;
143  pBuffer[1u] = message.data.dhead;
144  pBuffer[2u] = message.data.data[0u];
145  pBuffer[3u] = message.crc;
146 }
147 
148 #if (N775_USE_NOTIFICATIONS == false)
149 static uint16_t N775_WaitForTxCompleted(void) {
150  uint16_t timeoutTx = N775_SPI_WRITE_TIMEOUT_US;
151  while (false == spi_txFinished) {
152  MCU_delay_us(1);
153  timeoutTx--;
154  if (timeoutTx == 0u) {
155  break;
156  }
157  }
158  MCU_delay_us(N775_WAIT_TIME_AFTER_WRITE_US);
159  return timeoutTx;
160 }
161 
162 static uint16_t N775_WaitForRxCompleted(void) {
163  uint16_t timeoutRx = N775_SPI_READ_TIMEOUT_US;
164  while (spi_rxFinished == false) {
165  MCU_delay_us(1u);
166  timeoutRx--;
167  if (timeoutRx == 0u) {
168  break;
169  }
170  }
171  MCU_delay_us(N775_WAIT_TIME_AFTER_READ_US);
172  return timeoutRx;
173 }
174 #else
175 void N775_ClearNotifications(void) {
176  xTaskNotifyStateClearIndexed(NULL, N775_NOTIFICATION_TX_INDEX);
177 }
178 
179 static uint32_t N775_WaitForTxCompletedNotification(void) {
180  uint32_t notifiedValueTx = N775_NO_NOTIFIED_VALUE;
181  /**
182  * Suspend task and wait for SPI send DMA RX finished notification,
183  * clear notification value on entry and exit
184  */
185  xTaskNotifyWaitIndexed(
186  N775_NOTIFICATION_TX_INDEX, UINT32_MAX, UINT32_MAX, &notifiedValueTx, N775_NOTIFICATION_TX_TIMEOUT_ms);
187  return notifiedValueTx;
188 }
189 
190 static uint32_t N775_WaitForRxCompletedNotification(void) {
191  uint32_t notifiedValueRx = N775_NO_NOTIFIED_VALUE;
192  /**
193  * Suspend task and wait for DMA RX notification,
194  * clear notification value on entry and exit
195  */
196  xTaskNotifyWaitIndexed(
197  N775_NOTIFICATION_RX_INDEX, UINT32_MAX, UINT32_MAX, &notifiedValueRx, N775_NOTIFICATION_RX_TIMEOUT_ms);
198  return notifiedValueRx;
199 }
200 #endif
201 
202 /*========== Extern Function Implementations ================================*/
203 
205  uint16_t deviceAddress,
206  uint16_t registerAddress,
207  uint16_t value,
208  SPI_INTERFACE_CONFIG_s *pSpiInterface) {
209  FAS_ASSERT(pSpiInterface != NULL_PTR);
210  uc_msg_t message = {0}; /* Message for read command */
211 
212  /** The function gets the device address
213  * The N775_CommunicationComposeMessage function adds the chain address.
214  * Chain address = 1 used so (deviceAddress | (1u << 6u)) is used
215  */
217  BMS1_CMD_WRITE, 0, (deviceAddress | (1u << 6u)), registerAddress, 0, &value, &message);
219 
220  spi_txFinished = false;
221 #if (N775_USE_NOTIFICATIONS == true)
222  N775_ClearNotifications();
223 #endif
225 #if (N775_USE_NOTIFICATIONS == false)
226  (void)N775_WaitForTxCompleted();
227 #else
228  uint32_t notificationTx = N775_WaitForTxCompletedNotification();
229  if (notificationTx != N775_TX_NOTIFIED_VALUE) {
230  /* Tx DMA interrupt has not come, release Tx SPI interface */
231  const uint8_t spiIndex = SPI_GetSpiIndex(spiREG1);
233  spi_busyFlags[spiIndex] = SPI_IDLE;
235  }
236 #endif
237 }
238 
240  uint16_t deviceAddress,
241  uint16_t registerAddress,
242  uint16_t *pValue,
243  N775_STATE_s *n775_state) {
244  FAS_ASSERT(pValue != NULL_PTR);
245  FAS_ASSERT(n775_state != NULL_PTR);
246  FAS_ASSERT(n775_state->pSpiTxSequence != NULL_PTR);
247  FAS_ASSERT(n775_state->pSpiRxSequence != NULL_PTR);
248  return N775_CommunicationReadMultiple(deviceAddress, 1, 1, registerAddress, pValue, n775_state);
249 }
250 
252  uint16_t deviceAddress,
253  uint16_t numberOfItems,
254  uint16_t responseLength,
255  uint16_t registerAddress,
256  uint16_t *pValues,
257  N775_STATE_s *n775_state) {
258  FAS_ASSERT(pValues != NULL_PTR);
259  FAS_ASSERT(n775_state != NULL_PTR);
260  FAS_ASSERT(n775_state->pSpiTxSequence != NULL_PTR);
261  FAS_ASSERT(n775_state->pSpiRxSequence != NULL_PTR);
262 
263  /* Number of registers to read */
264  uint16_t itemsReadRemaining = numberOfItems;
265  uint16_t *pReadValues = pValues;
266 
267  /**
268  * numberOfItems = 0 --> corresponds to one frame
269  * (max_frames - 1): because first frame is for the mirroring of Tx
270  * So (numberOfItems - 1u) is used in the following
271  */
272 
273  /** The function gets the device address
274  * The pack_msg function adds the chain address.
275  * Chain address = 1 used so (deviceAddress | (1u << 6u)) is used in the following
276  * */
277  /* responseLength = 0 means one data word per answer frame so (responseLength - 1u) is used in the following */
278 
279  uc_msg_t txMessage = {0u}; /* Message for read command */
280  uc_msg_t rxMessage = {0u}; /* Message for response */
281 
282  N775_COMMUNICATION_STATUS_e communicationStatus; /* Reception return code */
283  uint16_t read_parameter; /* Read parameter (padding_en, responseLength, num_regs) */
284 
285  uint16_t rsp_cmd; /* Response parts */
286  uint16_t rsp_mst_addr;
287  uint16_t rsp_dev_addr;
288  uint16_t rsp_reg_addr;
289  uint16_t rsp_length;
290  uint16_t rsp_values[4];
291 
292  read_parameter = ((uint16_t)1u << 10u) + /* Use padding */
293  ((responseLength - 1u) << 8u) + /* responseLength */
294  ((numberOfItems - 1u) << 0u); /* (numberOfItems-1u) register to read */
295 
297  BMS1_CMD_READ, 0, (deviceAddress | (1u << 6u)), registerAddress, 0, &read_parameter, &txMessage);
299 
300  /**
301  * After transmission to daisy-chain, daisy-chain will normally answer
302  * Already prepare SPI slave for reception
303  */
304 
305  /**
306  * Compute the number of answer frames needed by the MC33775A.
307  * Padding is used: always same number of registers in each answer frame
308  * (1,2,3 or 4 registers).
309  */
310  uint16_t nrAnswerFrames = (((numberOfItems - 1u) + 1u) / ((responseLength - 1u) + 1u));
311  /**
312  * Additional answer frame if number of registers to read and
313  * number of registers per answer frame are not multiples
314  * Example: 22 registers to read, 4 registers per answer frame.
315  * Answer: (5*4 register) + (2 registers + 2 words padded with 0)
316  */
317  if ((((numberOfItems - 1u) + 1u) % ((responseLength - 1u) + 1u)) != 0u) {
318  nrAnswerFrames++;
319  }
320  /**
321  * N775_WRITE_SPI_BUFFER_SIZE (4u): because of Tx mirroring, the command is received, too
322  * N775_READ_HEADER_SPI_BUFFER_SIZE + (responseLength - 1u) + 1u: size of one answer frame
323  * (responseLength - 1u) 0 --> 1 register --> (responseLength - 1u) +1u = 1
324  * (responseLength - 1u) 1 --> 2 registers --> (responseLength - 1u) +1u = 2
325  * (responseLength - 1u) 2 --> 3 registers --> (responseLength - 1u) +1u = 3
326  * (responseLength - 1u) 3 --> 4 registers --> (responseLength - 1u) +1u = 4
327  * */
328  uint16_t rxBufferLength = N775_WRITE_SPI_BUFFER_SIZE +
329  ((N775_READ_HEADER_SPI_BUFFER_SIZE + (responseLength - 1u) + 1u) * nrAnswerFrames);
330  FAS_ASSERT(
331  rxBufferLength <=
335 
336  /* send message */
337  spi_rxFinished = false;
339  bool n775_rxCompleted = true;
340 #if (N775_USE_NOTIFICATIONS == false)
341  if (0u == N775_WaitForRxCompleted()) {
342  n775_rxCompleted = false;
343  }
344 #else
345  uint32_t notificationRx = N775_WaitForRxCompletedNotification();
346  if (notificationRx != N775_RX_NOTIFIED_VALUE) {
347  n775_rxCompleted = false;
348  /* Rx has not come, release Tx SPI interface */
349  const uint8_t spiIndex = SPI_GetSpiIndex(spiREG1);
351  spi_busyFlags[spiIndex] = SPI_IDLE;
353  }
354 #endif
355 
356  if (n775_rxCompleted == false) {
357  n775_state->pSpiRxSequence->pNode->INT0 &= ~DMAREQEN_BIT;
358  n775_state->pSpiRxSequence->pNode->GCR1 &= ~SPIEN_BIT;
359  communicationStatus = N775_COMMUNICATION_ERROR_TIMEOUT;
360  } else {
361  for (uint16_t i = 0; i < nrAnswerFrames; i++) {
362  /* Currently only support for 64 bit communication */
363  rxMessage.message_length = 4u + (responseLength - 1u);
364  /* +4u: because of Tx mirroring, the command is received, too */
365 
366  rxMessage.head = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 0u];
367  rxMessage.data.dhead = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 1u];
368  rxMessage.data.data[0u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 2u];
369  if (rxMessage.message_length <= 4u) {
370  rxMessage.crc = n775FromTplRxBuffer[4u + (i * 4u) + 3u];
371  } else {
372  if (rxMessage.message_length == 5u) {
373  rxMessage.data.data[1u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
374  rxMessage.crc = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 4u];
375  } else {
376  if (rxMessage.message_length == 6u) {
377  rxMessage.data.data[1u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
378  rxMessage.data.data[2u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 4u];
379  rxMessage.crc = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 5u];
380  } else {
381  rxMessage.data.data[1u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
382  rxMessage.data.data[2u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 4u];
383  rxMessage.data.data[3u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 5u];
384  rxMessage.crc = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 6u];
385  }
386  }
387  }
388 
389  communicationStatus = N775_CommunicationDecomposeMessage(
390  &rxMessage,
391  &rsp_cmd,
392  &rsp_mst_addr,
393  &rsp_dev_addr,
394  &rsp_reg_addr,
395  &rsp_length,
396  rsp_values,
397  n775_state->currentString);
398 
399  if (communicationStatus == N775_COMMUNICATION_OK) {
400  /* SM.e.30 : Communication - Unique ID */
401  if (rsp_dev_addr == (deviceAddress | (1u << 6u))) {
402  if (rsp_reg_addr == (registerAddress + (i * ((responseLength - 1u) + 1u)))) {
403  for (uint16_t j = 0u; j < (rsp_length + 1u); j++) {
404  /* To take padded answer frames into account
405  * Stop before reaching the words padded with 0s
406  */
407  if (itemsReadRemaining > 0u) {
408  *pReadValues = rsp_values[j];
409  pReadValues++;
410  itemsReadRemaining--;
411  } else {
412  break;
413  }
414  }
415  } else {
417  }
418  } else {
420  }
421  }
422  }
423  }
424 
425  return communicationStatus;
426 }
427 
428 /* Reset the message counter for one device */
429 extern void N775_ResetMessageCounter(uint16_t deviceAddress, uint8_t string) {
430  /* Chain address = 1 used so (deviceAddress | (1u << 6u)) is used */
431  referenceMessageCounter[string][deviceAddress | (1u << 6u)] = 0u;
432 }
433 
434 /* Low level communication functions */
435 /* Pack message */
437  uint16_t cmd,
438  uint16_t masterAddress,
439  uint16_t deviceAddress,
440  uint16_t registerAddress,
441  uint16_t length,
442  uint16_t *pValue,
443  uc_msg_t *pMessage) {
444  FAS_ASSERT(pValue != NULL_PTR);
445  FAS_ASSERT(pMessage != NULL_PTR);
446  /* Create message */
447  set_cmd(pMessage, cmd);
448  set_madd(pMessage, masterAddress);
449  set_cadd(pMessage, deviceAddress >> 6u);
450  set_devadd(pMessage, deviceAddress & 0x3Fu);
451  set_msgcnt(pMessage, 0); /* not used by MCU, therefore fixed 0 */
452  set_datalen(pMessage, length);
453  set_regadd(pMessage, registerAddress);
454  for (uint16_t i = 0; i <= length; i++) {
455  set_data(pMessage, pValue[i], i);
456  }
457  set_message_length(pMessage, length + 4u);
458 
459  /* Create CRC */
460  set_crc(pMessage, calc_crc(pMessage));
461 }
462 
463 /* Unpack a message */
465  uc_msg_t *pMessage,
466  uint16_t *pCommand,
467  uint16_t *pMasterAddress,
468  uint16_t *pDeviceAddress,
469  uint16_t *pRegisterAddress,
470  uint16_t *pLength,
471  uint16_t *pValue,
472  uint8_t string) {
473  FAS_ASSERT(pMessage != NULL_PTR);
474  FAS_ASSERT(pCommand != NULL_PTR);
475  FAS_ASSERT(pMasterAddress != NULL_PTR);
476  FAS_ASSERT(pDeviceAddress != NULL_PTR);
477  FAS_ASSERT(pRegisterAddress != NULL_PTR);
478  FAS_ASSERT(pLength != NULL_PTR);
479  FAS_ASSERT(pValue != NULL_PTR);
480  uint16_t messageLength; /* length of received message */
481  uint16_t messageCount; /* message count from message */
482  uint16_t chainAddress; /* chain address */
483  uint16_t deviceAddressInChain; /* device address in the chain */
484 
485  bool errorCodeMatch = false;
487 
488  /* check if we have any content */
489  /* SM.e.28 : Communication - Timeout monitoring */
490  get_message_length(pMessage, &messageLength);
491  if (messageLength == 0u) {
492  errorCodeMatch = true;
493  communicationStatus = N775_COMMUNICATION_ERROR_TIMEOUT;
494  }
495 
496  if ((errorCodeMatch == false) && (messageLength < 4u)) {
497  errorCodeMatch = true;
498  communicationStatus = N775_COMMUNICATION_ERROR_SHORT_MESSAGE;
499  }
500 
501  /* Check CRC */
502  /* SM.e.27 : Communication - Information redundancy */
503  if ((errorCodeMatch == false) && (!check_crc(pMessage, calc_crc(pMessage)))) {
504  errorCodeMatch = true;
505  uint16_t receivedCrc;
506  get_crc(pMessage, &receivedCrc);
507  communicationStatus = N775_COMMUNICATION_ERROR_WRONG_CRC;
508  }
509 
510  /* Extract message parts */
511  get_cmd(pMessage, pCommand);
512  get_madd(pMessage, pMasterAddress);
513  get_cadd(pMessage, &chainAddress);
514  get_devadd(pMessage, &deviceAddressInChain);
515  *pDeviceAddress = (chainAddress << 6u) | deviceAddressInChain;
516  get_msgcnt(pMessage, &messageCount);
517  get_datalen(pMessage, pLength);
518  get_regadd(pMessage, pRegisterAddress);
519 
520  /* Check message counter */
521  /* SM.e.29 : Communication - Message counter */
522  if ((errorCodeMatch == false) && (messageCount != referenceMessageCounter[string][*pDeviceAddress])) {
523  errorCodeMatch = true;
524  referenceMessageCounter[string][*pDeviceAddress] = (messageCount + 1u) & 0xFu;
525  communicationStatus = N775_COMMUNICATION_ERROR_WRONG_MESSAGE_COUNT;
526  }
527  /* Increment message counter */
528  referenceMessageCounter[string][*pDeviceAddress] = (referenceMessageCounter[string][*pDeviceAddress] + 1u) & 0xFu;
529 
530  /* Check error address */
531  if ((errorCodeMatch == false) && (*pRegisterAddress == N775_ERROR_REGISTER_ADDRESS)) {
532  communicationStatus = N775_COMMUNICATION_ERROR_NO_ACCESS;
533  }
534 
535  /* return data */
536  if (errorCodeMatch == false) {
537  for (int i = 0u; i <= *pLength; i++) {
538  get_data(pMessage, &pValue[i], i);
539  }
540  if (*pCommand != BMS1_CMD_RESP) { /* Check for response */
541  communicationStatus = N775_COMMUNICATION_ERROR_NO_RESPONSE;
542  }
543  }
544 
545  /* TODO: check for N775_COMMUNICATION_ERROR_NOT_MATCHING_DEVICE_ADDRESS */
546  /* TODO: check for N775_COMMUNICATION_ERROR_NOT_MATCHING_REGISTER_ADDRESS */
547 
548  return communicationStatus;
549 }
550 
551 /*========== Externalized Static Function Implementations (Unit Test) =======*/
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
Headers for the driver for the DMA module.
#define SPIEN_BIT
Definition: dma_cfg.h:111
#define DMAREQEN_BIT
Definition: dma_cfg.h:109
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:252
#define NULL
NULL definition.
Definition: fstd_types.h:66
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
General macros and definitions for the whole platform.
Header for the driver for the IO module.
Headers for the driver for the MCU module.
#define N775_READ_HEADER_SPI_BUFFER_SIZE
N775_COMMUNICATION_STATUS_e N775_CommunicationReadMultiple(uint16_t deviceAddress, uint16_t numberOfItems, uint16_t responseLength, uint16_t registerAddress, uint16_t *pValues, N775_STATE_s *n775_state)
Read multiple values from specific registers in a specific device.
N775_COMMUNICATION_STATUS_e N775_CommunicationDecomposeMessage(uc_msg_t *pMessage, uint16_t *pCommand, uint16_t *pMasterAddress, uint16_t *pDeviceAddress, uint16_t *pRegisterAddress, uint16_t *pLength, uint16_t *pValue, uint8_t string)
Decomposes and analysis a message.
#define N775_WAIT_TIME_AFTER_READ_US
static uint16_t n775FromTplRxBuffer[N775_WRITE_SPI_BUFFER_SIZE+((N775_READ_HEADER_SPI_BUFFER_SIZE+N775_READ_PAYLOAD_SPI_BUFFER_SIZE) *N775_MAX_ANSWER_FRAMES)]
static uint16_t referenceMessageCounter[BS_NR_OF_STRINGS][512]
static uint16_t n775ToTplTxBuffer[N775_WRITE_SPI_BUFFER_SIZE]
static uint16_t n775ToTplRxBuffer[N775_WRITE_SPI_BUFFER_SIZE]
#define N775_READ_PAYLOAD_SPI_BUFFER_SIZE
void N775_ResetMessageCounter(uint16_t deviceAddress, uint8_t string)
Reset the message counter for one or all devices.
static void N775_ConvertMessageToBuffer(uint16_t *pBuffer, uc_msg_t message)
Copies a message to the buffer to be passed to the SPI transmit functions.
void N775_CommunicationWrite(uint16_t deviceAddress, uint16_t registerAddress, uint16_t value, SPI_INTERFACE_CONFIG_s *pSpiInterface)
Write a value into a specific register in a specific device.
#define N775_WRITE_SPI_BUFFER_SIZE
static uint16_t n775FromTplTxBuffer[N775_WRITE_SPI_BUFFER_SIZE+((N775_READ_HEADER_SPI_BUFFER_SIZE+N775_READ_PAYLOAD_SPI_BUFFER_SIZE) *N775_MAX_ANSWER_FRAMES)]
static uint16_t N775_WaitForRxCompleted(void)
Wait for the SPI receive communication to complete, blocking.
#define N775_WAIT_TIME_AFTER_WRITE_US
static uint16_t N775_WaitForTxCompleted(void)
Wait for the SPI transmit communication to complete, blocking.
#define N775_SPI_READ_TIMEOUT_US
#define N775_MAX_ANSWER_FRAMES
N775_COMMUNICATION_STATUS_e N775_CommunicationRead(uint16_t deviceAddress, uint16_t registerAddress, uint16_t *pValue, N775_STATE_s *n775_state)
Read a value from a specific register in a specific device.
#define N775_SPI_WRITE_TIMEOUT_US
void N775_CommunicationComposeMessage(uint16_t cmd, uint16_t masterAddress, uint16_t deviceAddress, uint16_t registerAddress, uint16_t length, uint16_t *pValue, uc_msg_t *pMessage)
Composes a message.
enum N775_COMMUNICATION_STATUS N775_COMMUNICATION_STATUS_e
@ N775_COMMUNICATION_ERROR_NOT_MATCHING_REGISTER_ADDRESS
@ N775_COMMUNICATION_ERROR_NO_ACCESS
@ N775_COMMUNICATION_ERROR_WRONG_MESSAGE_COUNT
@ N775_COMMUNICATION_OK
@ N775_COMMUNICATION_ERROR_WRONG_CRC
@ N775_COMMUNICATION_ERROR_TIMEOUT
@ N775_COMMUNICATION_ERROR_SHORT_MESSAGE
@ N775_COMMUNICATION_ERROR_NO_RESPONSE
@ N775_COMMUNICATION_ERROR_NOT_MATCHING_DEVICE_ADDRESS
#define N775_ERROR_REGISTER_ADDRESS
#define N775_NOTIFICATION_RX_TIMEOUT_ms
#define N775_NOTIFICATION_TX_TIMEOUT_ms
#define N775_NO_NOTIFIED_VALUE
#define N775_RX_NOTIFIED_VALUE
#define N775_NOTIFICATION_RX_INDEX
#define N775_NOTIFICATION_TX_INDEX
#define N775_TX_NOTIFIED_VALUE
Declaration of the OS wrapper interface.
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:135
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:131
STD_RETURN_TYPE_e SPI_TransmitReceiveDataDma(SPI_INTERFACE_CONFIG_s *pSpiInterface, uint16_t *pTxBuff, uint16_t *pRxBuff, uint32_t frameLength)
Transmits and receives data on SPI with DMA.
Definition: spi.c:219
bool spi_rxFinished
Definition: spi.c:78
STD_RETURN_TYPE_e SPI_SlaveSetReceiveDataDma(SPI_INTERFACE_CONFIG_s *pSpiInterface, uint16_t *pTxBuff, uint16_t *pRxBuff, uint32_t frameLength)
Transmits and receives data on SPI with DMA.
Definition: spi.c:390
uint8_t SPI_GetSpiIndex(spiBASE_t *pNode)
Returns index of SPI node.
Definition: spi.c:483
bool spi_txFinished
Definition: spi.c:77
Headers for the driver for the SPI module.
SPI_BUSY_STATE_e spi_busyFlags[]
Definition: spi_cfg.c:260
@ SPI_IDLE
Definition: spi_cfg.h:109
SPI_INTERFACE_CONFIG_s * pSpiTxSequence
SPI_INTERFACE_CONFIG_s * pSpiRxSequence
spiBASE_t * pNode
Definition: spi_cfg.h:125