foxBMS  1.6.0
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 /**
24  * @file nxp_mc33775a-ll.c
25  * @author NXP
26  * @date 2022-07-29 (date of creation)
27  * @updated 2023-09-05 (date of last update)
28  * @version v1.6.0
29  * @ingroup DRIVERS
30  * @prefix N775
31  *
32  * @brief Low level driver for the MC33775A
33  *
34  */
35 
36 /*========== Includes =======================================================*/
37 
38 #include "nxp_mc33775a-ll.h"
39 
40 #include "spi_cfg.h"
41 
42 #include "dma.h"
43 #include "fassert.h"
44 #include "io.h"
45 #include "mcu.h"
46 #include "os.h"
47 #include "spi.h"
48 
49 #include <stdint.h>
50 
51 /*========== Macros and Definitions =========================================*/
52 
53 /** Number of words (16 bits) used for write messages */
54 #define N775_WRITE_SPI_BUFFER_SIZE (4u)
55 /** Number of words (16 bits) in read answers that do not contain data */
56 #define N775_READ_HEADER_SPI_BUFFER_SIZE (3u)
57 /**
58  * Number of words (16 bits) in read answers that contain data.
59  * Based on maximum payload, which is 4 register per answer frame.
60  */
61 #define N775_READ_PAYLOAD_SPI_BUFFER_SIZE (4u)
62 /**
63  * Maximum number of groups of registers that can be read,
64  * to limit buffer size.
65  * Groups can be of size 1 to 4 registers.
66  * One frame = header (e.g., register address) +
67  * payload (data, 1 to 4 registers)
68  */
69 #define N775_MAX_ANSWER_FRAMES (30u)
70 /** Time to wait in microseconds after a write command */
71 #define N775_WAIT_TIME_AFTER_WRITE_US (5u)
72 /** Time to wait in microseconds after a read command */
73 #define N775_WAIT_TIME_AFTER_READ_US (5u)
74 /** Timeout to wait in microseconds for SPI send interrupt. */
75 #define N775_SPI_WRITE_TIMEOUT_US (500u)
76 /**
77  * Timeout to wait in microseconds for reception of a read answer.
78  * After that time the communication is considered to have failed.
79  */
80 #define N775_SPI_READ_TIMEOUT_US (2000u)
81 
82 /*========== Static Constant and Variable Definitions =======================*/
83 static uint16_t referenceMessageCounter[BS_NR_OF_STRINGS][512]; /* fits for all possible nodes */
84 
85 #pragma SET_DATA_SECTION(".sharedRAM")
88 static uint16_t n775FromTplTxBuffer
91 static uint16_t n775FromTplRxBuffer
94 #pragma SET_DATA_SECTION()
95 
96 /*========== Extern Constant and Variable Definitions =======================*/
97 
98 /*========== Static Function Prototypes =====================================*/
99 /**
100  * @brief Copies a message to the buffer to be passed to the SPI transmit
101  * functions
102  * @param pBuffer
103  * @param message
104  */
105 static void N775_ConvertMessageToBuffer(uint16_t *pBuffer, uc_msg_t message);
106 
107 /**
108  * @brief Wait for the SPI transmit communication to complete, using notifications
109  *
110  * return N775_TX_NOTIFIED_VALUE if notification received,
111  * N775_NO_NOTIFIED_VALUE if timeout reached
112  */
113 static uint32_t N775_WaitForTxCompletedNotification(void);
114 
115 /**
116  * @brief Wait for the SPI receive communication to complete, using notifications
117  *
118  * return N775_RX_NOTIFIED_VALUE if notification received,
119  * N775_NO_NOTIFIED_VALUE if timeout reached
120  */
121 static uint32_t N775_WaitForRxCompletedNotification(void);
122 
123 /*========== Static Function Implementations ================================*/
124 
125 static void N775_ConvertMessageToBuffer(uint16_t *pBuffer, uc_msg_t message) {
126  FAS_ASSERT(pBuffer != NULL_PTR);
127  pBuffer[0u] = message.head;
128  pBuffer[1u] = message.data.dhead;
129  pBuffer[2u] = message.data.data[0u];
130  pBuffer[3u] = message.crc;
131 }
132 
133 static uint32_t N775_WaitForTxCompletedNotification(void) {
134  uint32_t notifiedValueTx = N775_NO_NOTIFIED_VALUE;
135  /**
136  * Suspend task and wait for SPI send DMA RX finished notification,
137  * clear notification value on entry and exit
138  */
140  return notifiedValueTx;
141 }
142 
143 static uint32_t N775_WaitForRxCompletedNotification(void) {
144  uint32_t notifiedValueRx = N775_NO_NOTIFIED_VALUE;
145  /**
146  * Suspend task and wait for DMA RX notification,
147  * clear notification value on entry and exit
148  */
150  return notifiedValueRx;
151 }
152 
153 /*========== Extern Function Implementations ================================*/
154 
156  uint16_t deviceAddress,
157  uint16_t registerAddress,
158  uint16_t value,
159  SPI_INTERFACE_CONFIG_s *pSpiInterface) {
160  FAS_ASSERT(pSpiInterface != NULL_PTR);
161  uc_msg_t message = {0}; /* Message for read command */
162 
163  /** The function gets the device address
164  * The N775_CommunicationComposeMessage function adds the chain address.
165  * Chain address = 1 used so (deviceAddress | (1u << 6u)) is used
166  */
168  BMS1_CMD_WRITE, 0, (deviceAddress | (1u << 6u)), registerAddress, 0, &value, &message);
170 
171  /*
172  * Used to clear a pending Tx notification made by the read function
173  * when writing to registers: when reading, commands are sent on SPI1.
174  * In the SPI1 ISR, a notification is made, but it is not used: the system
175  * waits for the SPI Rx notification from SPI4. As a consequence, when the
176  * write function is called after the read function, there is already a
177  * notification pending. The function waiting for the notification in the
178  * ISR of SPI1 exits immediately instead of waiting for the end of the
179  * transmission.
180  */
182 
184 
185  uint32_t notificationTx = N775_WaitForTxCompletedNotification();
186  if (notificationTx != N775_TX_NOTIFIED_VALUE) {
187  /* Tx DMA interrupt has not come, release Tx SPI interface */
188  const uint8_t spiIndex = SPI_GetSpiIndex(spiREG1);
190  spi_busyFlags[spiIndex] = SPI_IDLE;
192  }
193 }
194 
196  uint16_t deviceAddress,
197  uint16_t registerAddress,
198  uint16_t *pValue,
199  N775_STATE_s *pState) {
200  FAS_ASSERT(pValue != NULL_PTR);
201  FAS_ASSERT(pState != NULL_PTR);
202  FAS_ASSERT(pState->pSpiTxSequence != NULL_PTR);
203  FAS_ASSERT(pState->pSpiRxSequence != NULL_PTR);
204  return N775_CommunicationReadMultiple(deviceAddress, 1, 1, registerAddress, pValue, pState);
205 }
206 
208  uint16_t deviceAddress,
209  uint16_t numberOfItems,
210  uint16_t responseLength,
211  uint16_t registerAddress,
212  uint16_t *pValues,
213  N775_STATE_s *pState) {
214  FAS_ASSERT(pValues != NULL_PTR);
215  FAS_ASSERT(pState != NULL_PTR);
216  FAS_ASSERT(pState->pSpiTxSequence != NULL_PTR);
217  FAS_ASSERT(pState->pSpiRxSequence != NULL_PTR);
218 
219  /* Number of registers to read */
220  uint16_t itemsReadRemaining = numberOfItems;
221  uint16_t *pReadValues = pValues;
222 
223  /**
224  * numberOfItems = 0 --> corresponds to one frame
225  * (max_frames - 1): because first frame is for the mirroring of Tx
226  * So (numberOfItems - 1u) is used in the following
227  */
228 
229  /** The function gets the device address
230  * The pack_msg function adds the chain address.
231  * Chain address = 1 used so (deviceAddress | (1u << 6u)) is used in the following
232  * */
233  /* responseLength = 0 means one data word per answer frame so (responseLength - 1u) is used in the following */
234 
235  uc_msg_t txMessage = {0u}; /* Message for read command */
236  uc_msg_t rxMessage = {0u}; /* Message for response */
237 
238  N775_COMMUNICATION_STATUS_e communicationStatus; /* Reception return code */
239  uint16_t read_parameter; /* Read parameter (padding_en, responseLength, num_regs) */
240 
241  uint16_t rsp_cmd; /* Response parts */
242  uint16_t rsp_mst_addr;
243  uint16_t rsp_dev_addr;
244  uint16_t rsp_reg_addr;
245  uint16_t rsp_length;
246  uint16_t rsp_values[4];
247 
248  read_parameter = ((uint16_t)1u << 10u) + /* Use padding */
249  ((responseLength - 1u) << 8u) + /* responseLength */
250  ((numberOfItems - 1u) << 0u); /* (numberOfItems-1u) register to read */
251 
253  BMS1_CMD_READ, 0, (deviceAddress | (1u << 6u)), registerAddress, 0, &read_parameter, &txMessage);
255 
256  /**
257  * After transmission to daisy-chain, daisy-chain will normally answer
258  * Already prepare SPI slave for reception
259  */
260 
261  /**
262  * Compute the number of answer frames needed by the MC33775A.
263  * Padding is used: always same number of registers in each answer frame
264  * (1,2,3 or 4 registers).
265  */
266  uint16_t nrAnswerFrames = (((numberOfItems - 1u) + 1u) / ((responseLength - 1u) + 1u));
267  /**
268  * Additional answer frame if number of registers to read and
269  * number of registers per answer frame are not multiples
270  * Example: 22 registers to read, 4 registers per answer frame.
271  * Answer: (5*4 register) + (2 registers + 2 words padded with 0)
272  */
273  if ((((numberOfItems - 1u) + 1u) % ((responseLength - 1u) + 1u)) != 0u) {
274  nrAnswerFrames++;
275  }
276  /**
277  * N775_WRITE_SPI_BUFFER_SIZE (4u): because of Tx mirroring, the command is received, too
278  * N775_READ_HEADER_SPI_BUFFER_SIZE + (responseLength - 1u) + 1u: size of one answer frame
279  * (responseLength - 1u) 0 --> 1 register --> (responseLength - 1u) +1u = 1
280  * (responseLength - 1u) 1 --> 2 registers --> (responseLength - 1u) +1u = 2
281  * (responseLength - 1u) 2 --> 3 registers --> (responseLength - 1u) +1u = 3
282  * (responseLength - 1u) 3 --> 4 registers --> (responseLength - 1u) +1u = 4
283  * */
284  uint16_t rxBufferLength = N775_WRITE_SPI_BUFFER_SIZE +
285  ((N775_READ_HEADER_SPI_BUFFER_SIZE + (responseLength - 1u) + 1u) * nrAnswerFrames);
286  FAS_ASSERT(
287  rxBufferLength <=
291 
292  /* send message */
294  bool n775_rxCompleted = true;
295 
296  uint32_t notificationRx = N775_WaitForRxCompletedNotification();
297  if (notificationRx != N775_RX_NOTIFIED_VALUE) {
298  n775_rxCompleted = false;
299  /* Rx has not come, release Tx SPI interface */
300  const uint8_t spiIndex = SPI_GetSpiIndex(spiREG1);
302  spi_busyFlags[spiIndex] = SPI_IDLE;
304  }
305 
306  if (n775_rxCompleted == false) {
307  pState->pSpiRxSequence->pNode->INT0 &= ~DMAREQEN_BIT;
308  pState->pSpiRxSequence->pNode->GCR1 &= ~SPIEN_BIT;
309  communicationStatus = N775_COMMUNICATION_ERROR_TIMEOUT;
310  } else {
311  for (uint16_t i = 0; i < nrAnswerFrames; i++) {
312  /* Currently only support for 64 bit communication */
313  rxMessage.message_length = 4u + (responseLength - 1u);
314  /* +4u: because of Tx mirroring, the command is received, too */
315 
316  rxMessage.head = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 0u];
317  rxMessage.data.dhead = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 1u];
318  rxMessage.data.data[0u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 2u];
319  if (rxMessage.message_length <= 4u) {
320  rxMessage.crc = n775FromTplRxBuffer[4u + (i * 4u) + 3u];
321  } else {
322  if (rxMessage.message_length == 5u) {
323  rxMessage.data.data[1u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
324  rxMessage.crc = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 4u];
325  } else {
326  if (rxMessage.message_length == 6u) {
327  rxMessage.data.data[1u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
328  rxMessage.data.data[2u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 4u];
329  rxMessage.crc = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 5u];
330  } else {
331  rxMessage.data.data[1u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
332  rxMessage.data.data[2u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 4u];
333  rxMessage.data.data[3u] = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 5u];
334  rxMessage.crc = n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 6u];
335  }
336  }
337  }
338 
339  communicationStatus = N775_CommunicationDecomposeMessage(
340  &rxMessage,
341  &rsp_cmd,
342  &rsp_mst_addr,
343  &rsp_dev_addr,
344  &rsp_reg_addr,
345  &rsp_length,
346  rsp_values,
347  pState->currentString);
348 
349  if (communicationStatus == N775_COMMUNICATION_OK) {
350  /* SM.e.30 : Communication - Unique ID */
351  if (rsp_dev_addr == (deviceAddress | (1u << 6u))) {
352  if (rsp_reg_addr == (registerAddress + (i * ((responseLength - 1u) + 1u)))) {
353  for (uint16_t j = 0u; j < (rsp_length + 1u); j++) {
354  /* To take padded answer frames into account
355  * Stop before reaching the words padded with 0s
356  */
357  if (itemsReadRemaining > 0u) {
358  *pReadValues = rsp_values[j];
359  pReadValues++;
360  itemsReadRemaining--;
361  } else {
362  break;
363  }
364  }
365  } else {
367  }
368  } else {
370  }
371  }
372  }
373  }
374 
375  return communicationStatus;
376 }
377 
378 /* Reset the message counter for one device */
379 extern void N775_ResetMessageCounter(uint16_t deviceAddress, uint8_t string) {
380  /* Chain address = 1 used so (deviceAddress | (1u << 6u)) is used */
381  referenceMessageCounter[string][deviceAddress | (1u << 6u)] = 0u;
382 }
383 
384 /* Low level communication functions */
385 /* Pack message */
387  uint16_t cmd,
388  uint16_t masterAddress,
389  uint16_t deviceAddress,
390  uint16_t registerAddress,
391  uint16_t length,
392  uint16_t *pValue,
393  uc_msg_t *pMessage) {
394  FAS_ASSERT(pValue != NULL_PTR);
395  FAS_ASSERT(pMessage != NULL_PTR);
396  /* Create message */
397  set_cmd(pMessage, cmd);
398  set_madd(pMessage, masterAddress);
399  set_cadd(pMessage, deviceAddress >> 6u);
400  set_devadd(pMessage, deviceAddress & 0x3Fu);
401  set_msgcnt(pMessage, 0); /* not used by MCU, therefore fixed 0 */
402  set_datalen(pMessage, length);
403  set_regadd(pMessage, registerAddress);
404  for (uint16_t i = 0; i <= length; i++) {
405  set_data(pMessage, pValue[i], i);
406  }
407  set_message_length(pMessage, length + 4u);
408 
409  /* Create CRC */
410  set_crc(pMessage, calc_crc(pMessage));
411 }
412 
413 /* Unpack a message */
415  uc_msg_t *pMessage,
416  uint16_t *pCommand,
417  uint16_t *pMasterAddress,
418  uint16_t *pDeviceAddress,
419  uint16_t *pRegisterAddress,
420  uint16_t *pLength,
421  uint16_t *pValue,
422  uint8_t string) {
423  FAS_ASSERT(pMessage != NULL_PTR);
424  FAS_ASSERT(pCommand != NULL_PTR);
425  FAS_ASSERT(pMasterAddress != NULL_PTR);
426  FAS_ASSERT(pDeviceAddress != NULL_PTR);
427  FAS_ASSERT(pRegisterAddress != NULL_PTR);
428  FAS_ASSERT(pLength != NULL_PTR);
429  FAS_ASSERT(pValue != NULL_PTR);
430  uint16_t messageLength; /* length of received message */
431  uint16_t messageCount; /* message count from message */
432  uint16_t chainAddress; /* chain address */
433  uint16_t deviceAddressInChain; /* device address in the chain */
434 
435  bool errorCodeMatch = false;
437 
438  /* check if we have any content */
439  /* SM.e.28 : Communication - Timeout monitoring */
440  get_message_length(pMessage, &messageLength);
441  if (messageLength == 0u) {
442  errorCodeMatch = true;
443  communicationStatus = N775_COMMUNICATION_ERROR_TIMEOUT;
444  }
445 
446  if ((errorCodeMatch == false) && (messageLength < 4u)) {
447  errorCodeMatch = true;
448  communicationStatus = N775_COMMUNICATION_ERROR_SHORT_MESSAGE;
449  }
450 
451  /* Check CRC */
452  /* SM.e.27 : Communication - Information redundancy */
453  if ((errorCodeMatch == false) && (!check_crc(pMessage, calc_crc(pMessage)))) {
454  errorCodeMatch = true;
455  uint16_t receivedCrc;
456  get_crc(pMessage, &receivedCrc);
457  communicationStatus = N775_COMMUNICATION_ERROR_WRONG_CRC;
458  }
459 
460  /* Extract message parts */
461  get_cmd(pMessage, pCommand);
462  get_madd(pMessage, pMasterAddress);
463  get_cadd(pMessage, &chainAddress);
464  get_devadd(pMessage, &deviceAddressInChain);
465  *pDeviceAddress = (chainAddress << 6u) | deviceAddressInChain;
466  get_msgcnt(pMessage, &messageCount);
467  get_datalen(pMessage, pLength);
468  get_regadd(pMessage, pRegisterAddress);
469 
470  /* Check message counter */
471  /* SM.e.29 : Communication - Message counter */
472  if ((errorCodeMatch == false) && (messageCount != referenceMessageCounter[string][*pDeviceAddress])) {
473  errorCodeMatch = true;
474  referenceMessageCounter[string][*pDeviceAddress] = (messageCount + 1u) & 0xFu;
475  communicationStatus = N775_COMMUNICATION_ERROR_WRONG_MESSAGE_COUNT;
476  }
477  /* Increment message counter */
478  referenceMessageCounter[string][*pDeviceAddress] = (referenceMessageCounter[string][*pDeviceAddress] + 1u) & 0xFu;
479 
480  /* Check error address */
481  if ((errorCodeMatch == false) && (*pRegisterAddress == N775_ERROR_REGISTER_ADDRESS)) {
482  communicationStatus = N775_COMMUNICATION_ERROR_NO_ACCESS;
483  }
484 
485  /* return data */
486  if (errorCodeMatch == false) {
487  for (int i = 0u; i <= *pLength; i++) {
488  get_data(pMessage, &pValue[i], i);
489  }
490  if (*pCommand != BMS1_CMD_RESP) { /* Check for response */
491  communicationStatus = N775_COMMUNICATION_ERROR_NO_RESPONSE;
492  }
493  }
494 
495  /* TODO: check for N775_COMMUNICATION_ERROR_NOT_MATCHING_DEVICE_ADDRESS */
496  /* TODO: check for N775_COMMUNICATION_ERROR_NOT_MATCHING_REGISTER_ADDRESS */
497 
498  return communicationStatus;
499 }
500 
501 /*========== Externalized Static Function Implementations (Unit Test) =======*/
502 #ifdef UNITY_UNIT_TEST
503 #endif
#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:119
#define DMAREQEN_BIT
Definition: dma_cfg.h:117
Assert macro implementation.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
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_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.
static uint32_t N775_WaitForTxCompletedNotification(void)
Wait for the SPI transmit communication to complete, using notifications.
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)]
N775_COMMUNICATION_STATUS_e N775_CommunicationRead(uint16_t deviceAddress, uint16_t registerAddress, uint16_t *pValue, N775_STATE_s *pState)
Read a value from a specific register in a specific device.
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
static uint32_t N775_WaitForRxCompletedNotification(void)
Wait for the SPI receive communication to complete, using notifications.
N775_COMMUNICATION_STATUS_e N775_CommunicationReadMultiple(uint16_t deviceAddress, uint16_t numberOfItems, uint16_t responseLength, uint16_t registerAddress, uint16_t *pValues, N775_STATE_s *pState)
Read multiple values from specific registers in a specific device.
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)]
#define N775_MAX_ANSWER_FRAMES
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.
Header for the low level driver for the MC33775A.
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.
OS_STD_RETURN_e OS_ClearNotificationIndexed(uint32_t indexToClear)
Clear pending notification of a task, with index.
Definition: os_freertos.c:251
OS_STD_RETURN_e OS_WaitForNotificationIndexed(uint32_t indexToWaitOn, uint32_t *pNotifiedValue, uint32_t timeout)
Wait for a notification, with index.
Definition: os_freertos.c:210
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:154
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:150
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:292
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:463
uint8_t SPI_GetSpiIndex(spiBASE_t *pNode)
Returns index of SPI node.
Definition: spi.c:556
Headers for the driver for the SPI module.
SPI_BUSY_STATE_e spi_busyFlags[]
Definition: spi_cfg.c:264
Headers for the configuration for the SPI module.
@ SPI_IDLE
Definition: spi_cfg.h:110
SPI_INTERFACE_CONFIG_s * pSpiTxSequence
SPI_INTERFACE_CONFIG_s * pSpiRxSequence
spiBASE_t * pNode
Definition: spi_cfg.h:127