41 #define N775_WRITE_SPI_BUFFER_SIZE (4u)
43 #define N775_READ_HEADER_SPI_BUFFER_SIZE (3u)
48 #define N775_READ_PAYLOAD_SPI_BUFFER_SIZE (4u)
56 #define N775_MAX_ANSWER_FRAMES (30u)
58 #define N775_WAIT_TIME_AFTER_WRITE_US (5u)
60 #define N775_WAIT_TIME_AFTER_READ_US (5u)
62 #define N775_SPI_WRITE_TIMEOUT_US (500u)
67 #define N775_SPI_READ_TIMEOUT_US (2000u)
72 #pragma SET_DATA_SECTION(".sharedRAM")
81 #pragma SET_DATA_SECTION()
114 pBuffer[0u] = message.head;
115 pBuffer[1u] = message.data.dhead;
116 pBuffer[2u] = message.data.data[0u];
117 pBuffer[3u] = message.crc;
127 return notifiedValueTx;
137 return notifiedValueRx;
143 uint16_t deviceAddress,
144 uint16_t registerAddress,
148 uc_msg_t message = {0};
155 BMS1_CMD_WRITE, 0, (deviceAddress | (1u << 6u)), registerAddress, 0, &value, &message);
183 uint16_t deviceAddress,
184 uint16_t registerAddress,
195 uint16_t deviceAddress,
196 uint16_t numberOfItems,
197 uint16_t responseLength,
198 uint16_t registerAddress,
207 uint16_t itemsReadRemaining = numberOfItems;
208 uint16_t *pReadValues = pValues;
222 uc_msg_t txMessage = {0u};
223 uc_msg_t rxMessage = {0u};
226 uint16_t read_parameter;
229 uint16_t rsp_mst_addr;
230 uint16_t rsp_dev_addr;
231 uint16_t rsp_reg_addr;
233 uint16_t rsp_values[4];
235 read_parameter = ((uint16_t)1u << 10u) +
236 ((responseLength - 1u) << 8u) +
237 ((numberOfItems - 1u) << 0u);
240 BMS1_CMD_READ, 0, (deviceAddress | (1u << 6u)), registerAddress, 0, &read_parameter, &txMessage);
253 uint16_t nrAnswerFrames = (((numberOfItems - 1u) + 1u) / ((responseLength - 1u) + 1u));
260 if ((((numberOfItems - 1u) + 1u) % ((responseLength - 1u) + 1u)) != 0u) {
281 bool n775_rxCompleted =
true;
285 n775_rxCompleted =
false;
293 if (n775_rxCompleted ==
false) {
298 for (uint16_t i = 0; i < nrAnswerFrames; i++) {
300 rxMessage.message_length = 4u + (responseLength - 1u);
305 rxMessage.data.data[0u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 2u];
306 if (rxMessage.message_length <= 4u) {
309 if (rxMessage.message_length == 5u) {
310 rxMessage.data.data[1u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
313 if (rxMessage.message_length == 6u) {
314 rxMessage.data.data[1u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
315 rxMessage.data.data[2u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 4u];
318 rxMessage.data.data[1u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 3u];
319 rxMessage.data.data[2u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 4u];
320 rxMessage.data.data[3u] =
n775FromTplRxBuffer[4u + (i * (4u + (responseLength - 1u))) + 5u];
338 if (rsp_dev_addr == (deviceAddress | (1u << 6u))) {
339 if (rsp_reg_addr == (registerAddress + (i * ((responseLength - 1u) + 1u)))) {
340 for (uint16_t j = 0u; j < (rsp_length + 1u); j++) {
344 if (itemsReadRemaining > 0u) {
345 *pReadValues = rsp_values[j];
347 itemsReadRemaining--;
362 return communicationStatus;
375 uint16_t masterAddress,
376 uint16_t deviceAddress,
377 uint16_t registerAddress,
380 uc_msg_t *pMessage) {
384 set_cmd(pMessage, cmd);
385 set_madd(pMessage, masterAddress);
386 set_cadd(pMessage, deviceAddress >> 6u);
387 set_devadd(pMessage, deviceAddress & 0x3Fu);
388 set_msgcnt(pMessage, 0);
389 set_datalen(pMessage, length);
390 set_regadd(pMessage, registerAddress);
391 for (uint16_t i = 0; i <= length; i++) {
392 set_data(pMessage, pValue[i], i);
394 set_message_length(pMessage, length + 4u);
397 set_crc(pMessage, calc_crc(pMessage));
404 uint16_t *pMasterAddress,
405 uint16_t *pDeviceAddress,
406 uint16_t *pRegisterAddress,
417 uint16_t messageLength;
418 uint16_t messageCount;
419 uint16_t chainAddress;
420 uint16_t deviceAddressInChain;
422 bool errorCodeMatch =
false;
427 get_message_length(pMessage, &messageLength);
428 if (messageLength == 0u) {
429 errorCodeMatch =
true;
433 if ((errorCodeMatch ==
false) && (messageLength < 4u)) {
434 errorCodeMatch =
true;
440 if ((errorCodeMatch ==
false) && (!check_crc(pMessage, calc_crc(pMessage)))) {
441 errorCodeMatch =
true;
442 uint16_t receivedCrc;
443 get_crc(pMessage, &receivedCrc);
448 get_cmd(pMessage, pCommand);
449 get_madd(pMessage, pMasterAddress);
450 get_cadd(pMessage, &chainAddress);
451 get_devadd(pMessage, &deviceAddressInChain);
452 *pDeviceAddress = (chainAddress << 6u) | deviceAddressInChain;
453 get_msgcnt(pMessage, &messageCount);
454 get_datalen(pMessage, pLength);
455 get_regadd(pMessage, pRegisterAddress);
460 errorCodeMatch =
true;
473 if (errorCodeMatch ==
false) {
474 for (
int i = 0u; i <= *pLength; i++) {
475 get_data(pMessage, &pValue[i], i);
477 if (*pCommand != BMS1_CMD_RESP) {
485 return communicationStatus;
489 #ifdef UNITY_UNIT_TEST
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
Headers for the driver for the DMA module.
Assert macro implementation.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
#define NULL_PTR
Null pointer.
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.
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)]
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.
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
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.
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.
OS_STD_RETURN_e OS_ClearNotificationIndexed(uint32_t indexToClear)
Clear pending notification of a task, with index.
OS_STD_RETURN_e OS_WaitForNotificationIndexed(uint32_t indexToWaitOn, uint32_t *pNotifiedValue, uint32_t timeout)
Wait for a notification, with index.
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[]
Headers for the configuration for the SPI module.
SPI_INTERFACE_CONFIG_s * pSpiTxSequence
SPI_INTERFACE_CONFIG_s * pSpiRxSequence