37 #define N775_WRITE_SPI_BUFFER_SIZE (4u)
39 #define N775_READ_HEADER_SPI_BUFFER_SIZE (3u)
44 #define N775_READ_PAYLOAD_SPI_BUFFER_SIZE (4u)
52 #define N775_MAX_ANSWER_FRAMES (30u)
54 #define N775_WAIT_TIME_AFTER_WRITE_US (5u)
56 #define N775_WAIT_TIME_AFTER_READ_US (5u)
58 #define N775_SPI_WRITE_TIMEOUT_US (500u)
63 #define N775_SPI_READ_TIMEOUT_US (2000u)
68 #pragma SET_DATA_SECTION(".sharedRAM")
77 #pragma SET_DATA_SECTION()
90 #if (N775_USE_NOTIFICATIONS == false)
119 void N775_ClearNotifications(
void);
127 static uint32_t N775_WaitForTxCompletedNotification(
void);
135 static uint32_t N775_WaitForRxCompletedNotification(
void);
142 pBuffer[0u] = message.head;
143 pBuffer[1u] = message.data.dhead;
144 pBuffer[2u] = message.data.data[0u];
145 pBuffer[3u] = message.crc;
148 #if (N775_USE_NOTIFICATIONS == false)
154 if (timeoutTx == 0u) {
167 if (timeoutRx == 0u) {
175 void N775_ClearNotifications(
void) {
179 static uint32_t N775_WaitForTxCompletedNotification(
void) {
185 xTaskNotifyWaitIndexed(
187 return notifiedValueTx;
190 static uint32_t N775_WaitForRxCompletedNotification(
void) {
196 xTaskNotifyWaitIndexed(
198 return notifiedValueRx;
205 uint16_t deviceAddress,
206 uint16_t registerAddress,
210 uc_msg_t message = {0};
217 BMS1_CMD_WRITE, 0, (deviceAddress | (1u << 6u)), registerAddress, 0, &value, &message);
221 #if (N775_USE_NOTIFICATIONS == true)
222 N775_ClearNotifications();
225 #if (N775_USE_NOTIFICATIONS == false)
228 uint32_t notificationTx = N775_WaitForTxCompletedNotification();
240 uint16_t deviceAddress,
241 uint16_t registerAddress,
252 uint16_t deviceAddress,
253 uint16_t numberOfItems,
254 uint16_t responseLength,
255 uint16_t registerAddress,
264 uint16_t itemsReadRemaining = numberOfItems;
265 uint16_t *pReadValues = pValues;
279 uc_msg_t txMessage = {0u};
280 uc_msg_t rxMessage = {0u};
283 uint16_t read_parameter;
286 uint16_t rsp_mst_addr;
287 uint16_t rsp_dev_addr;
288 uint16_t rsp_reg_addr;
290 uint16_t rsp_values[4];
292 read_parameter = ((uint16_t)1u << 10u) +
293 ((responseLength - 1u) << 8u) +
294 ((numberOfItems - 1u) << 0u);
297 BMS1_CMD_READ, 0, (deviceAddress | (1u << 6u)), registerAddress, 0, &read_parameter, &txMessage);
310 uint16_t nrAnswerFrames = (((numberOfItems - 1u) + 1u) / ((responseLength - 1u) + 1u));
317 if ((((numberOfItems - 1u) + 1u) % ((responseLength - 1u) + 1u)) != 0u) {
339 bool n775_rxCompleted =
true;
340 #if (N775_USE_NOTIFICATIONS == false)
342 n775_rxCompleted =
false;
345 uint32_t notificationRx = N775_WaitForRxCompletedNotification();
347 n775_rxCompleted =
false;
356 if (n775_rxCompleted ==
false) {
361 for (uint16_t i = 0; i < nrAnswerFrames; i++) {
363 rxMessage.message_length = 4u + (responseLength - 1u);
368 rxMessage.data.data[0u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 2u];
369 if (rxMessage.message_length <= 4u) {
372 if (rxMessage.message_length == 5u) {
373 rxMessage.data.data[1u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
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];
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];
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++) {
407 if (itemsReadRemaining > 0u) {
408 *pReadValues = rsp_values[j];
410 itemsReadRemaining--;
425 return communicationStatus;
438 uint16_t masterAddress,
439 uint16_t deviceAddress,
440 uint16_t registerAddress,
443 uc_msg_t *pMessage) {
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);
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);
457 set_message_length(pMessage, length + 4u);
460 set_crc(pMessage, calc_crc(pMessage));
467 uint16_t *pMasterAddress,
468 uint16_t *pDeviceAddress,
469 uint16_t *pRegisterAddress,
480 uint16_t messageLength;
481 uint16_t messageCount;
482 uint16_t chainAddress;
483 uint16_t deviceAddressInChain;
485 bool errorCodeMatch =
false;
490 get_message_length(pMessage, &messageLength);
491 if (messageLength == 0u) {
492 errorCodeMatch =
true;
496 if ((errorCodeMatch ==
false) && (messageLength < 4u)) {
497 errorCodeMatch =
true;
503 if ((errorCodeMatch ==
false) && (!check_crc(pMessage, calc_crc(pMessage)))) {
504 errorCodeMatch =
true;
505 uint16_t receivedCrc;
506 get_crc(pMessage, &receivedCrc);
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);
523 errorCodeMatch =
true;
536 if (errorCodeMatch ==
false) {
537 for (
int i = 0u; i <= *pLength; i++) {
538 get_data(pMessage, &pValue[i], i);
540 if (*pCommand != BMS1_CMD_RESP) {
548 return communicationStatus;
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
Headers for the driver for the DMA module.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
#define NULL
NULL definition.
#define NULL_PTR
Null pointer.
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_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.
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
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.
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.
uint8_t SPI_GetSpiIndex(spiBASE_t *pNode)
Returns index of SPI node.
Headers for the driver for the SPI module.
SPI_BUSY_STATE_e spi_busyFlags[]
SPI_INTERFACE_CONFIG_s * pSpiTxSequence
SPI_INTERFACE_CONFIG_s * pSpiRxSequence