diff --git a/Target/Source/ARM7_LPC2000/can.c b/Target/Source/ARM7_LPC2000/can.c index 4dcd12d4..28987edc 100644 --- a/Target/Source/ARM7_LPC2000/can.c +++ b/Target/Source/ARM7_LPC2000/can.c @@ -37,6 +37,8 @@ /**************************************************************************************** * Macro definitions ****************************************************************************************/ +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) /** \brief Transmit buffer 1 idle bit. */ #define CAN_TBS1 (0x00000004) /** \brief Transmit buffer 1 complete bit. */ @@ -214,6 +216,8 @@ void CanInit(void) ****************************************************************************************/ void CanTransmitPacket(blt_int8u *data, blt_int8u len) { + blt_int32u timeout; + /* check that transmit buffer 1 is ready to accept a new message */ ASSERT_RT((CAN1SR & CAN_TBS1) != 0); /* write dlc and configure message as a standard message with 11-bit identifier */ @@ -234,11 +238,20 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) CAN1TDB1 = (data[7] << 24) + (data[6] << 16) + (data[5] << 8) + data[4]; /* write transmission request for transmit buffer 1 */ CAN1CMR = CAN_TR | CAN_STB1; + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* wait for transmit completion */ while ((CAN1SR & CAN_TCS1) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/ARM7_LPC2000/uart.c b/Target/Source/ARM7_LPC2000/uart.c index 24791875..c19c1ed1 100644 --- a/Target/Source/ARM7_LPC2000/uart.c +++ b/Target/Source/ARM7_LPC2000/uart.c @@ -41,7 +41,8 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) - +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /** \brief Divisor latch access bit. */ #define UART_DLAB (0x80) @@ -261,6 +262,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx holding register can accept new data */ if ((U0LSR & UART_THRE) == 0) { @@ -269,14 +273,22 @@ static blt_bool UartTransmitByte(blt_int8u data) } /* write byte to transmit holding register */ U0THR = data; + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while ((U0LSR & UART_THRE) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM0_STM32F0/can.c b/Target/Source/ARMCM0_STM32F0/can.c index bb5f281f..fad6a38b 100644 --- a/Target/Source/ARMCM0_STM32F0/can.c +++ b/Target/Source/ARMCM0_STM32F0/can.c @@ -35,6 +35,13 @@ #if (BOOT_COM_CAN_ENABLE > 0) +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) + + /**************************************************************************************** * Type definitions ****************************************************************************************/ @@ -186,8 +193,9 @@ void CanInit(void) void CanTransmitPacket(blt_int8u *data, blt_int8u len) { CanTxMsg txMsg; - uint8_t byteIdx; - uint8_t txMailbox; + blt_int8u byteIdx; + blt_int8u txMailbox; + blt_int32u timeout; /* prepare message */ if ((BOOT_COM_CAN_TX_MSG_ID & 0x80000000) == 0) @@ -210,11 +218,20 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) txMsg.Data[byteIdx] = data[byteIdx]; } txMailbox = CAN_Transmit(CAN, &txMsg); + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* wait for transmit completion */ while (CAN_TransmitStatus(CAN, txMailbox) == CAN_TxStatus_Pending) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/ARMCM0_STM32F0/uart.c b/Target/Source/ARMCM0_STM32F0/uart.c index 34572106..dd6959dc 100644 --- a/Target/Source/ARMCM0_STM32F0/uart.c +++ b/Target/Source/ARMCM0_STM32F0/uart.c @@ -41,6 +41,9 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) + /* map the configured UART channel index to the STM32's USART peripheral */ #if (BOOT_COM_UART_CHANNEL_INDEX == 0) /** \brief Set UART base address to USART1. */ @@ -241,6 +244,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx holding register can accept new data */ if (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_TXE) == RESET) { @@ -249,13 +255,22 @@ static blt_bool UartTransmitByte(blt_int8u data) } /* write byte to transmit holding register */ USART_SendData(USART_CHANNEL, data); + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_TXE) == RESET) { - ; + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM0_XMC1/can.c b/Target/Source/ARMCM0_XMC1/can.c index 20762202..76c7ceb5 100644 --- a/Target/Source/ARMCM0_XMC1/can.c +++ b/Target/Source/ARMCM0_XMC1/can.c @@ -39,6 +39,9 @@ /**************************************************************************************** * Macro definitions ****************************************************************************************/ +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) + /** \brief Macro for accessing the CAN channel handle in the format that is expected * by the XMClib CAN driver. */ @@ -108,11 +111,15 @@ void CanInit(void) while (canModuleFreqHz < 12000000) { canModuleFreqHz *= 2; + /* keep the watchdog happy */ + CopService(); } /* decrease if too high */ while (canModuleFreqHz > 120000000) { canModuleFreqHz /= 2; + /* keep the watchdog happy */ + CopService(); } /* configure CAN module*/ @@ -216,6 +223,7 @@ void CanInit(void) void CanTransmitPacket(blt_int8u *data, blt_int8u len) { blt_int8u byteIdx; + blt_int32u timeout; /* copy message data */ transmitMsgObj.can_data_length = len; @@ -229,11 +237,20 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) XMC_CAN_MO_ResetStatus(&transmitMsgObj, XMC_CAN_MO_RESET_STATUS_TX_PENDING); /* submit message for transmission */ XMC_CAN_MO_Transmit(&transmitMsgObj); + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* wait for transmit completion */ while ((XMC_CAN_MO_GetStatus(&transmitMsgObj) & XMC_CAN_MO_STATUS_TX_PENDING) != 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/ARMCM0_XMC1/uart.c b/Target/Source/ARMCM0_XMC1/uart.c index b4961726..1b6e5c0c 100644 --- a/Target/Source/ARMCM0_XMC1/uart.c +++ b/Target/Source/ARMCM0_XMC1/uart.c @@ -42,6 +42,9 @@ */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) + /** \brief Macro for accessing the UART channel handle in the format that is expected * by the XMClib UART driver. */ @@ -230,6 +233,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx fifo can accept new data */ if (XMC_USIC_CH_TXFIFO_IsFull(UART_CHANNEL) != 0) { @@ -238,15 +244,24 @@ static blt_bool UartTransmitByte(blt_int8u data) } /* submit data for transmission */ XMC_UART_CH_Transmit(UART_CHANNEL, data); + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for transmission to be done */ while( (XMC_USIC_CH_TXFIFO_GetEvent(UART_CHANNEL) & XMC_USIC_CH_TXFIFO_EVENT_STANDARD) == 0) { - ; + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } /* reset event */ XMC_USIC_CH_TXFIFO_ClearEvent(UART_CHANNEL, XMC_USIC_CH_TXFIFO_EVENT_STANDARD); - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM3_EFM32/uart.c b/Target/Source/ARMCM3_EFM32/uart.c index 7fc5827e..1c18e1f2 100644 --- a/Target/Source/ARMCM3_EFM32/uart.c +++ b/Target/Source/ARMCM3_EFM32/uart.c @@ -44,6 +44,8 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /**************************************************************************************** @@ -223,6 +225,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx holding register can accept new data */ if ((LEUART1->STATUS & LEUART_STATUS_TXBL) == 0) { @@ -236,9 +241,15 @@ static blt_bool UartTransmitByte(blt_int8u data) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM3_LM3S/can.c b/Target/Source/ARMCM3_LM3S/can.c index 187fb5a8..3ccfa260 100644 --- a/Target/Source/ARMCM3_LM3S/can.c +++ b/Target/Source/ARMCM3_LM3S/can.c @@ -43,6 +43,8 @@ /**************************************************************************************** * Macro definitions ****************************************************************************************/ +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) /** \brief Index of the used reception message object. */ #define CAN_RX_MSGOBJECT_IDX (0) /** \brief Index of the used transmission message object. */ @@ -167,6 +169,7 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) { blt_int32u status; tCANMsgObject msgObject; + blt_int32u timeout; /* get bitmask of message objects that are busy transmitting messages */ status = CANStatusGet(CAN0_BASE, CAN_STS_TXREQUEST); @@ -184,12 +187,21 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) msgObject.ulMsgLen = len; msgObject.pucMsgData = data; CANMessageSet(CAN0_BASE, CAN_TX_MSGOBJECT_IDX+1, &msgObject, MSG_OBJ_TYPE_TX); + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* now wait for the transmission to complete */ do { status = CANStatusGet(CAN0_BASE, CAN_STS_TXREQUEST); /* service the watchdog */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } while ((status & canBitNum2Mask[CAN_TX_MSGOBJECT_IDX]) != 0); } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/ARMCM3_LM3S/uart.c b/Target/Source/ARMCM3_LM3S/uart.c index f95536bf..ee0cddcc 100644 --- a/Target/Source/ARMCM3_LM3S/uart.c +++ b/Target/Source/ARMCM3_LM3S/uart.c @@ -46,6 +46,8 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /**************************************************************************************** @@ -209,20 +211,31 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* write byte to transmit holding register */ if (UARTCharPutNonBlocking(UART0_BASE, data) == false) { /* tx holding register can accept new data */ return BLT_FALSE; } + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while (UARTSpaceAvail(UART0_BASE) == false) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM3_STM32F1/can.c b/Target/Source/ARMCM3_STM32F1/can.c index 28ce83fb..0122dcc5 100644 --- a/Target/Source/ARMCM3_STM32F1/can.c +++ b/Target/Source/ARMCM3_STM32F1/can.c @@ -34,6 +34,16 @@ #if (BOOT_COM_CAN_ENABLE > 0) +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/** \brief Timeout for entering/leaving CAN initialization mode in milliseconds. */ +#define CAN_INIT_TIMEOUT_MS (250u) + +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) + + /**************************************************************************************** * Type definitions ****************************************************************************************/ @@ -218,6 +228,7 @@ void CanInit(void) blt_int16u prescaler; blt_int8u tseg1, tseg2; blt_bool result; + blt_int32u timeout; /* the current implementation supports CAN1. throw an assertion error in case a * different CAN channel is configured. @@ -230,21 +241,35 @@ void CanInit(void) CANx->IER = (blt_int32u)0; /* set request to reset the can controller */ CANx->MCR |= CAN_BIT_RESET ; + /* set timeout time to wait for can controller reset */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that the can controller was reset */ while ((CANx->MCR & CAN_BIT_RESET) != 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* exit from sleep mode, which is the default mode after reset */ CANx->MCR &= ~CAN_BIT_SLEEP; /* set request to enter initialisation mode */ CANx->MCR |= CAN_BIT_INRQ ; + /* set timeout time to wait for entering initialization mode */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that initialization mode was entered */ while ((CANx->MSR & CAN_BIT_INAK) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* configure the bittming */ CANx->BTR = (blt_int32u)((blt_int32u)(tseg1 - 1) << 16) | \ @@ -252,11 +277,18 @@ void CanInit(void) (blt_int32u)(prescaler - 1); /* set request to leave initialisation mode */ CANx->MCR &= ~CAN_BIT_INRQ; + /* set timeout time to wait for exiting initialization mode */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that initialization mode was exited */ while ((CANx->MSR & CAN_BIT_INAK) != 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* enter initialisation mode for the acceptance filter */ CANx->FMR |= CAN_BIT_FINIT; @@ -288,6 +320,7 @@ void CanInit(void) void CanTransmitPacket(blt_int8u *data, blt_int8u len) { blt_int32u txMsgId = BOOT_COM_CAN_TX_MSG_ID; + blt_int32u timeout; /* make sure that transmit mailbox 0 is available */ ASSERT_RT((CANx->TSR&CAN_BIT_TME0) == CAN_BIT_TME0); @@ -322,11 +355,20 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) ((blt_int32u)data[4])); /* request the start of message transmission */ CANx->sTxMailBox[0].TIR |= CAN_BIT_TXRQ; + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* wait for transmit completion */ while ((CANx->TSR&CAN_BIT_TME0) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/ARMCM3_STM32F1/flash.c b/Target/Source/ARMCM3_STM32F1/flash.c index 3acaee03..44a33fa9 100644 --- a/Target/Source/ARMCM3_STM32F1/flash.c +++ b/Target/Source/ARMCM3_STM32F1/flash.c @@ -66,6 +66,17 @@ #define BOOT_FLASH_VECTOR_TABLE_CS_OFFSET (0x150) #endif +/** \brief Maximum time for a sector erase operation as specified by the STM32F1 data- + * sheet with an added margin of at least 20%. + */ +#define FLASH_ERASE_TIME_MAX_MS (100) + +/** \brief Maximum time for a page program operation as specified by the STM32F1 data- + * sheet with an added margin of at least 20%. + */ +#define FLASH_PROGRAM_TIME_MAX_MS (5) + + #define FLASH_KEY1 ((blt_int32u)0x45670123) #define FLASH_KEY2 ((blt_int32u)0xCDEF89AB) #define FLASH_LOCK_BIT ((blt_int32u)0x00000080) @@ -669,6 +680,7 @@ static blt_bool FlashWriteBlock(tFlashBlockInfo *block) blt_addr prog_addr; blt_int32u prog_data; blt_int32u word_cnt; + blt_int32u timeout; /* check that address is actually within flash */ sector_num = FlashGetSector(block->base_addr); @@ -712,19 +724,35 @@ static blt_bool FlashWriteBlock(tFlashBlockInfo *block) prog_data = *(volatile blt_int32u *)(&block->data[word_cnt * sizeof(blt_int32u)]); /* program the first half word */ *(volatile blt_int16u *)prog_addr = (blt_int16u)prog_data; + /* set the timeout time for the program operation */ + timeout = TimerGet() + FLASH_PROGRAM_TIME_MAX_MS; /* wait for the program operation to complete */ while ((FLASH->SR & FLASH_BSY_BIT) == FLASH_BSY_BIT) { /* keep the watchdog happy */ CopService(); + /* check for timeout */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } /* program the second half word */ *(volatile blt_int16u *)(prog_addr+2) = (blt_int16u)(prog_data >> 16); + /* set the timeout time for the program operation */ + timeout = TimerGet() + FLASH_PROGRAM_TIME_MAX_MS; /* wait for the program operation to complete */ while ((FLASH->SR & FLASH_BSY_BIT) == FLASH_BSY_BIT) { /* keep the watchdog happy */ CopService(); + /* check for timeout */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } /* verify that the written data is actually there */ if (*(volatile blt_int32u *)prog_addr != prog_data) @@ -737,7 +765,7 @@ static blt_bool FlashWriteBlock(tFlashBlockInfo *block) FLASH->CR &= ~FLASH_PG_BIT; /* lock the flash array */ FlashLock(); - /* still here so all is okay */ + /* give the result back to the caller */ return result; } /*** end of FlashWriteBlock ***/ @@ -755,6 +783,8 @@ static blt_bool FlashEraseSectors(blt_int8u first_sector, blt_int8u last_sector) blt_int16u block_cnt; blt_addr start_addr; blt_addr end_addr; + blt_int32u timeout; + blt_bool result = BLT_TRUE; /* validate the sector numbers */ if (first_sector > last_sector) @@ -791,19 +821,27 @@ static blt_bool FlashEraseSectors(blt_int8u first_sector, blt_int8u last_sector) FLASH->AR = start_addr + (block_cnt * FLASH_ERASE_BLOCK_SIZE); /* start the block erase operation */ FLASH->CR |= FLASH_STRT_BIT; + /* set the timeout time for the erase operation */ + timeout = TimerGet() + FLASH_ERASE_TIME_MAX_MS; /* wait for the erase operation to complete */ while ((FLASH->SR & FLASH_BSY_BIT) == FLASH_BSY_BIT) { /* keep the watchdog happy */ CopService(); + /* check for timeout */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } } /* reset the page erase bit because we're all done erasing */ FLASH->CR &= ~FLASH_PER_BIT; /* lock the flash array */ FlashLock(); - /* still here so all went okay */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of FlashEraseSectors ***/ diff --git a/Target/Source/ARMCM3_STM32F1/uart.c b/Target/Source/ARMCM3_STM32F1/uart.c index 22f2ec60..7cc00322 100644 --- a/Target/Source/ARMCM3_STM32F1/uart.c +++ b/Target/Source/ARMCM3_STM32F1/uart.c @@ -63,6 +63,8 @@ typedef struct * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /** \brief USART enable bit. */ #define UART_BIT_UE ((blt_int16u)0x2000) /** \brief Transmitter enable bit. */ @@ -255,6 +257,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx holding register can accept new data */ if ((UARTx->SR & UART_BIT_TXE) == 0) { @@ -263,14 +268,22 @@ static blt_bool UartTransmitByte(blt_int8u data) } /* write byte to transmit holding register */ UARTx->DR = data; + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while ((UARTx->SR & UART_BIT_TXE) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM3_STM32F2/can.c b/Target/Source/ARMCM3_STM32F2/can.c index c4ea9e1e..a32685d9 100644 --- a/Target/Source/ARMCM3_STM32F2/can.c +++ b/Target/Source/ARMCM3_STM32F2/can.c @@ -34,6 +34,16 @@ #if (BOOT_COM_CAN_ENABLE > 0) +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/** \brief Timeout for entering/leaving CAN initialization mode in milliseconds. */ +#define CAN_INIT_TIMEOUT_MS (250u) + +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) + + /**************************************************************************************** * Type definitions ****************************************************************************************/ @@ -227,6 +237,7 @@ void CanInit(void) blt_int16u prescaler=0; blt_int8u tseg1=0, tseg2=0; blt_bool result; + blt_int32u timeout; /* the current implementation supports CAN1 and 2. throw an assertion error in case a * different CAN channel is configured. @@ -240,21 +251,35 @@ void CanInit(void) CANx->IER = (blt_int32u)0; /* set request to reset the can controller */ CANx->MCR |= CAN_BIT_RESET ; + /* set timeout time to wait for can controller reset */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that the can controller was reset */ while ((CANx->MCR & CAN_BIT_RESET) != 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* exit from sleep mode, which is the default mode after reset */ CANx->MCR &= ~CAN_BIT_SLEEP; /* set request to enter initialisation mode */ CANx->MCR |= CAN_BIT_INRQ ; + /* set timeout time to wait for entering initialization mode */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that initialization mode was entered */ while ((CANx->MSR & CAN_BIT_INAK) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* configure the bittming */ CANx->BTR = (blt_int32u)((blt_int32u)(tseg1 - 1) << 16) | \ @@ -262,11 +287,18 @@ void CanInit(void) (blt_int32u)(prescaler - 1); /* set request to leave initialisation mode */ CANx->MCR &= ~CAN_BIT_INRQ; + /* set timeout time to wait for exiting initialization mode */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that initialization mode was exited */ while ((CANx->MSR & CAN_BIT_INAK) != 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } #if (BOOT_COM_CAN_CHANNEL_INDEX == 0) @@ -319,6 +351,7 @@ void CanInit(void) void CanTransmitPacket(blt_int8u *data, blt_int8u len) { blt_int32u txMsgId = BOOT_COM_CAN_TX_MSG_ID; + blt_int32u timeout; /* make sure that transmit mailbox 0 is available */ ASSERT_RT((CANx->TSR&CAN_BIT_TME0) == CAN_BIT_TME0); @@ -353,11 +386,20 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) ((blt_int32u)data[4])); /* request the start of message transmission */ CANx->sTxMailBox[0].TIR |= CAN_BIT_TXRQ; + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* wait for transmit completion */ while ((CANx->TSR&CAN_BIT_TME0) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/ARMCM3_STM32F2/uart.c b/Target/Source/ARMCM3_STM32F2/uart.c index b6d5fbaa..b1d9452f 100644 --- a/Target/Source/ARMCM3_STM32F2/uart.c +++ b/Target/Source/ARMCM3_STM32F2/uart.c @@ -41,6 +41,8 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /* map the configured UART channel index to the STM32's USART peripheral */ #if (BOOT_COM_UART_CHANNEL_INDEX == 0) /** \brief Set UART base address to USART1. */ @@ -231,6 +233,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx holding register can accept new data */ if (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_TXE) == RESET) { @@ -239,13 +244,22 @@ static blt_bool UartTransmitByte(blt_int8u data) } /* write byte to transmit holding register */ USART_SendData(USART_CHANNEL, data); + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_TXE) == RESET) { - ; + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM4_STM32F3/uart.c b/Target/Source/ARMCM4_STM32F3/uart.c index 1d8c5063..e945d450 100644 --- a/Target/Source/ARMCM4_STM32F3/uart.c +++ b/Target/Source/ARMCM4_STM32F3/uart.c @@ -42,8 +42,8 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) -/** \brief Timeout for transmitting a byte. */ -#define UART_TX_TIMEOUT_MS (5u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /* map the configured UART channel index to the STM32's USART peripheral */ #if (BOOT_COM_UART_CHANNEL_INDEX == 0) /** \brief Set UART base address to USART1. */ @@ -220,19 +220,20 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static void UartTransmitByte(blt_int8u data) { - blt_int32u txTimeoutTime; + blt_int32u timeout; - /* Determine timeout time for the transmit operation. */ - txTimeoutTime = TimerGet() + UART_TX_TIMEOUT_MS; /* write byte to transmit holding register */ LL_USART_TransmitData8(USART_CHANNEL, data); + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while (LL_USART_IsActiveFlag_TXE(USART_CHANNEL) == 0) { - /* Check if a timeout occurred to prevent lockup. */ - if (TimerGet() > txTimeoutTime) + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) { - /* Cannot transmit so stop waiting for its completion. */ break; } } diff --git a/Target/Source/ARMCM4_STM32F4/can.c b/Target/Source/ARMCM4_STM32F4/can.c index fcc81121..207bb846 100644 --- a/Target/Source/ARMCM4_STM32F4/can.c +++ b/Target/Source/ARMCM4_STM32F4/can.c @@ -34,6 +34,16 @@ #if (BOOT_COM_CAN_ENABLE > 0) +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/** \brief Timeout for entering/leaving CAN initialization mode in milliseconds. */ +#define CAN_INIT_TIMEOUT_MS (250u) + +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) + + /**************************************************************************************** * Type definitions ****************************************************************************************/ @@ -227,6 +237,7 @@ void CanInit(void) blt_int16u prescaler; blt_int8u tseg1, tseg2; blt_bool result; + blt_int32u timeout; /* the current implementation supports CAN1 and 2. throw an assertion error in case a * different CAN channel is configured. @@ -240,21 +251,35 @@ void CanInit(void) CANx->IER = (blt_int32u)0; /* set request to reset the can controller */ CANx->MCR |= CAN_BIT_RESET ; + /* set timeout time to wait for can controller reset */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that the can controller was reset */ while ((CANx->MCR & CAN_BIT_RESET) != 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* exit from sleep mode, which is the default mode after reset */ CANx->MCR &= ~CAN_BIT_SLEEP; /* set request to enter initialisation mode */ CANx->MCR |= CAN_BIT_INRQ ; + /* set timeout time to wait for entering initialization mode */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that initialization mode was entered */ while ((CANx->MSR & CAN_BIT_INAK) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* configure the bittming */ CANx->BTR = (blt_int32u)((blt_int32u)(tseg1 - 1) << 16) | \ @@ -262,11 +287,18 @@ void CanInit(void) (blt_int32u)(prescaler - 1); /* set request to leave initialisation mode */ CANx->MCR &= ~CAN_BIT_INRQ; + /* set timeout time to wait for exiting initialization mode */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for acknowledge that initialization mode was exited */ while ((CANx->MSR & CAN_BIT_INAK) != 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } #if (BOOT_COM_CAN_CHANNEL_INDEX == 0) @@ -319,6 +351,7 @@ void CanInit(void) void CanTransmitPacket(blt_int8u *data, blt_int8u len) { blt_int32u txMsgId = BOOT_COM_CAN_TX_MSG_ID; + blt_int32u timeout; /* make sure that transmit mailbox 0 is available */ ASSERT_RT((CANx->TSR&CAN_BIT_TME0) == CAN_BIT_TME0); @@ -353,11 +386,20 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) ((blt_int32u)data[4])); /* request the start of message transmission */ CANx->sTxMailBox[0].TIR |= CAN_BIT_TXRQ; + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* wait for transmit completion */ while ((CANx->TSR&CAN_BIT_TME0) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/ARMCM4_STM32F4/uart.c b/Target/Source/ARMCM4_STM32F4/uart.c index 8c01ff3b..7c73d10f 100644 --- a/Target/Source/ARMCM4_STM32F4/uart.c +++ b/Target/Source/ARMCM4_STM32F4/uart.c @@ -42,6 +42,9 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) + /* map the configured UART channel index to the STM32's USART peripheral */ #if (BOOT_COM_UART_CHANNEL_INDEX == 0) /** \brief Set UART base address to USART1. */ @@ -232,6 +235,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx holding register can accept new data */ if (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_TXE) == RESET) { @@ -240,13 +246,22 @@ static blt_bool UartTransmitByte(blt_int8u data) } /* write byte to transmit holding register */ USART_SendData(USART_CHANNEL, data); + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_TXE) == RESET) { - ; + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM4_STM32L4/can.c b/Target/Source/ARMCM4_STM32L4/can.c index 9874d4ec..4a85e2b2 100644 --- a/Target/Source/ARMCM4_STM32L4/can.c +++ b/Target/Source/ARMCM4_STM32L4/can.c @@ -229,7 +229,7 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) blt_int32u txMsgId = BOOT_COM_CAN_TX_MSG_ID; CAN_TxHeaderTypeDef txMsgHeader; blt_int32u txMsgMailbox; - blt_int32u txMsgTimeout; + blt_int32u timeout; HAL_StatusTypeDef txStatus; /* configure the message that should be transmitted. */ @@ -256,18 +256,17 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) if (txStatus == HAL_OK) { /* determine timeout time for the transmit completion. */ - txMsgTimeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* poll for completion of the transmit operation. */ while (HAL_CAN_IsTxMessagePending(&canHandle, txMsgMailbox) != 0) { /* service the watchdog. */ CopService(); - /* did a timeout occur? */ - if (TimerGet() > txMsgTimeout) + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) { - /* stop waiting. no need for further action. if the response cannot be - * transmitted, then the receiving node will detect a timeout. - */ break; } } diff --git a/Target/Source/ARMCM4_STM32L4/uart.c b/Target/Source/ARMCM4_STM32L4/uart.c index d3d1d17b..f3ca65b4 100644 --- a/Target/Source/ARMCM4_STM32L4/uart.c +++ b/Target/Source/ARMCM4_STM32L4/uart.c @@ -42,8 +42,8 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) -/** \brief Timeout for transmitting a byte. */ -#define UART_TX_TIMEOUT_MS (5u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /* map the configured UART channel index to the STM32's USART peripheral */ #if (BOOT_COM_UART_CHANNEL_INDEX == 0) /** \brief Set UART base address to USART1. */ @@ -228,19 +228,20 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static void UartTransmitByte(blt_int8u data) { - blt_int32u txTimeoutTime; + blt_int32u timeout; - /* Determine timeout time for the transmit operation. */ - txTimeoutTime = TimerGet() + UART_TX_TIMEOUT_MS; /* write byte to transmit holding register */ LL_USART_TransmitData8(USART_CHANNEL, data); + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while (LL_USART_IsActiveFlag_TXE(USART_CHANNEL) == 0) { - /* Check if a timeout occurred to prevent lockup. */ - if (TimerGet() > txTimeoutTime) + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) { - /* Cannot transmit so stop waiting for its completion. */ break; } } diff --git a/Target/Source/ARMCM4_TM4C/uart.c b/Target/Source/ARMCM4_TM4C/uart.c index 32818113..23822775 100644 --- a/Target/Source/ARMCM4_TM4C/uart.c +++ b/Target/Source/ARMCM4_TM4C/uart.c @@ -48,6 +48,8 @@ * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /**************************************************************************************** @@ -211,20 +213,31 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* write byte to transmit holding register */ if (UARTCharPutNonBlocking(UART0_BASE, data) == false) { /* tx holding register can accept new data */ return BLT_FALSE; } + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while (UARTSpaceAvail(UART0_BASE) == false) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/ARMCM4_XMC4/can.c b/Target/Source/ARMCM4_XMC4/can.c index bd633930..0bd40897 100644 --- a/Target/Source/ARMCM4_XMC4/can.c +++ b/Target/Source/ARMCM4_XMC4/can.c @@ -39,6 +39,9 @@ /**************************************************************************************** * Macro definitions ****************************************************************************************/ +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) + /** \brief Macro for accessing the CAN channel handle in the format that is expected * by the XMClib CAN driver. */ @@ -112,11 +115,15 @@ void CanInit(void) while (canModuleFreqHz < 12000000) { canModuleFreqHz *= 2; + /* keep the watchdog happy */ + CopService(); } /* decrease if too high */ while (canModuleFreqHz > 120000000) { canModuleFreqHz /= 2; + /* keep the watchdog happy */ + CopService(); } /* configure CAN module*/ @@ -220,6 +227,7 @@ void CanInit(void) void CanTransmitPacket(blt_int8u *data, blt_int8u len) { blt_int8u byteIdx; + blt_int32u timeout; /* copy message data */ transmitMsgObj.can_data_length = len; @@ -233,11 +241,20 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) XMC_CAN_MO_ResetStatus(&transmitMsgObj, XMC_CAN_MO_RESET_STATUS_TX_PENDING); /* submit message for transmission */ XMC_CAN_MO_Transmit(&transmitMsgObj); + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; /* wait for transmit completion */ while ((XMC_CAN_MO_GetStatus(&transmitMsgObj) & XMC_CAN_MO_STATUS_TX_PENDING) != 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/ARMCM4_XMC4/uart.c b/Target/Source/ARMCM4_XMC4/uart.c index a9403444..88bdd7b2 100644 --- a/Target/Source/ARMCM4_XMC4/uart.c +++ b/Target/Source/ARMCM4_XMC4/uart.c @@ -42,6 +42,9 @@ */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) + /** \brief Macro for accessing the UART channel handle in the format that is expected * by the XMClib UART driver. */ @@ -232,6 +235,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx fifo can accept new data */ if (XMC_USIC_CH_TXFIFO_IsFull(UART_CHANNEL) != 0) { @@ -240,15 +246,24 @@ static blt_bool UartTransmitByte(blt_int8u data) } /* submit data for transmission */ XMC_UART_CH_Transmit(UART_CHANNEL, data); + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for transmission to be done */ while( (XMC_USIC_CH_TXFIFO_GetEvent(UART_CHANNEL) & XMC_USIC_CH_TXFIFO_EVENT_STANDARD) == 0) { - ; + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } /* reset event */ XMC_USIC_CH_TXFIFO_ClearEvent(UART_CHANNEL, XMC_USIC_CH_TXFIFO_EVENT_STANDARD); - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/HCS12/can.c b/Target/Source/HCS12/can.c index bed9c50a..1fc35745 100644 --- a/Target/Source/HCS12/can.c +++ b/Target/Source/HCS12/can.c @@ -107,6 +107,11 @@ typedef struct /**************************************************************************************** * Macro definitions ****************************************************************************************/ +/** \brief Timeout for entering/leaving CAN initialization mode in milliseconds. */ +#define CAN_INIT_TIMEOUT_MS (250u) +/** \brief Timeout for transmitting a CAN message in milliseconds. */ +#define CAN_MSG_TX_TIMEOUT_MS (50u) + #if (BOOT_COM_CAN_CHANNEL_INDEX == 0) /** \brief Set CAN base address to CAN0. */ #define CAN_REGS_BASE_ADDRESS (0x0140) @@ -217,6 +222,7 @@ void CanInit(void) blt_bool result; blt_int32u accept_code; blt_int32u accept_mask; + blt_int32u timeout; /* the current implementation supports CAN0..4. throw an assertion error in case a * different CAN channel is configured. @@ -225,10 +231,18 @@ void CanInit(void) /* enter initialization mode. note that this automatically disables CAN interrupts */ CAN->cctl0 = INITRQ_BIT; + /* set timeout time for entering init mode */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for initialization mode entry handshake from the hardware */ while ((CAN->cctl1 & INITAK_BIT) == 0) { - ; + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* enable the CAN controller, disable wake up and listen modes and set the @@ -278,10 +292,18 @@ void CanInit(void) /* leave initialization mode and synchronize to the CAN bus */ CAN->cctl0 &= ~INITRQ_BIT; + /* set timeout time for leaving init mode */ + timeout = TimerGet() + CAN_INIT_TIMEOUT_MS; /* wait for CAN bus synchronization handshake from the hardware */ while ((CAN->cctl1 & INITAK_BIT) != 0) { - ; + /* keep the watchdog happy */ + CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + break; + } } /* bring transmit buffer 0 in the foreground as this is the only one used by this @@ -302,6 +324,7 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) { blt_int8u byte_idx; blt_int32u txMsgId; + blt_int32u timeout; /* double check that the transmit slot is really available */ ASSERT_RT((CAN->ctflg & TXE0_BIT) != 0); @@ -342,11 +365,21 @@ void CanTransmitPacket(blt_int8u *data, blt_int8u len) */ CAN->ctflg = TXE0_BIT; + /* set timeout time to wait for transmission completion */ + timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS; + /* wait for transmit completion */ while ((CAN->ctflg & TXE0_BIT) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure or no other + * nodes connected to the bus. + */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CanTransmitPacket ***/ diff --git a/Target/Source/HCS12/uart.c b/Target/Source/HCS12/uart.c index 500014c3..30fb52aa 100644 --- a/Target/Source/HCS12/uart.c +++ b/Target/Source/HCS12/uart.c @@ -57,6 +57,9 @@ typedef volatile struct * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) + #if (BOOT_COM_UART_CHANNEL_INDEX == 0) /** \brief Set UART base address to SCI0. */ #define UART_REGS_BASE_ADDRESS (0x00c8) @@ -250,6 +253,9 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* check if tx holding register can accept new data */ if ((UART->scisr1 & TDRE_BIT) == 0) { @@ -258,14 +264,22 @@ static blt_bool UartTransmitByte(blt_int8u data) } /* write byte to transmit holding register */ UART->scidrl = data; + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for tx holding register to be empty */ while ((UART->scisr1 & TDRE_BIT) == 0) { /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */ diff --git a/Target/Source/TRICORE_TC1798/GCC/cpu_comp.c b/Target/Source/TRICORE_TC1798/GCC/cpu_comp.c index 15dcfd2f..2592730f 100644 --- a/Target/Source/TRICORE_TC1798/GCC/cpu_comp.c +++ b/Target/Source/TRICORE_TC1798/GCC/cpu_comp.c @@ -33,6 +33,12 @@ #include +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +#define CPU_INIT_MODE_TIMEOUT_MS (250u) + + /**************************************************************************************** * Local function prototypes ****************************************************************************************/ @@ -73,13 +79,22 @@ void CpuIrqEnable(void) ****************************************************************************************/ void CpuEnterInitMode(void) { + blt_int32u timeout; + /* request clearing of the EndInit bit */ CpuWriteWDTCON0(WDT_CON0.reg & ~0x00000001); + /* set timeout to wait for hardware handshake */ + timeout = TimerGet() + CPU_INIT_MODE_TIMEOUT_MS; /* wait for hardware handshake */ while (WDT_CON0.bits.ENDINIT != 0) { /* keep the watchdog happy */ CopService(); + /* break loop if timeout occurred */ + if (TimerGet() > timeout) + { + break; + } } } /*** end of CpuEnterInitMode ***/ diff --git a/Target/Source/TRICORE_TC1798/flash.c b/Target/Source/TRICORE_TC1798/flash.c index 78033e22..e01bf47d 100644 --- a/Target/Source/TRICORE_TC1798/flash.c +++ b/Target/Source/TRICORE_TC1798/flash.c @@ -103,6 +103,16 @@ #define FLASH_CS_RANGE_TOTAL_WORDS ((FLASH_WRITE_BLOCK_SIZE/4u) - \ (FLASH_CS_RANGE_START_OFFSET/4u)) +/** \brief Maximum time for a sector erase operation as specified by the Tricore data- + * sheet with an added margin of at least 20%. + */ +#define FLASH_ERASE_TIME_MAX_MS (5100) + +/** \brief Maximum time for a page program operation as specified by the Tricore data- + * sheet with an added margin of at least 20%. + */ +#define FLASH_PROGRAM_TIME_MAX_MS (40) + /**************************************************************************************** * Plausibility checks @@ -818,6 +828,7 @@ static blt_bool FlashTricoreProgramPage(blt_addr start_addr, blt_int8u *data) blt_int8u *readPtr; blt_int32u idx; FLASHn_FSR_t *pflashFSR; + blt_int32u timeout; /* check address alignment to a page in PFLASH */ if ((start_addr % FLASH_WRITE_BLOCK_SIZE) != 0) @@ -834,6 +845,8 @@ static blt_bool FlashTricoreProgramPage(blt_addr start_addr, blt_int8u *data) FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x5554u, 0x00000050u); /* perform DSYNC */ CpuSetDSYNC(); + /* set timeout time for hardware handshake */ + timeout = TimerGet() + FLASH_PROGRAM_TIME_MAX_MS; /* wait until FSR.xFPAGE = '1' */ while (pflashFSR->bits.PFPAGE != 1) { @@ -849,6 +862,11 @@ static blt_bool FlashTricoreProgramPage(blt_addr start_addr, blt_int8u *data) } /* keep the watchdog happy */ CopService(); + /* fail in case of timeout */ + if (TimerGet() > timeout) + { + return BLT_FALSE; + } } /* load FLASH_WRITE_BLOCK_SIZE bytes of program data into the assembly buffer */ dataPtr = (blt_int32u *)data; @@ -868,6 +886,8 @@ static blt_bool FlashTricoreProgramPage(blt_addr start_addr, blt_int8u *data) FLASH_WRITE_TO_U32_PTR_BY_ADDR(start_addr, 0x000000AAu); /* perform DSYNC */ CpuSetDSYNC(); + /* set timeout time for hardware handshake */ + timeout = TimerGet() + FLASH_PROGRAM_TIME_MAX_MS; /* wait until FSR.PROG = '1' */ while (pflashFSR->bits.PROG != 1) { @@ -883,7 +903,14 @@ static blt_bool FlashTricoreProgramPage(blt_addr start_addr, blt_int8u *data) } /* keep the watchdog happy */ CopService(); + /* fail in case of timeout */ + if (TimerGet() > timeout) + { + return BLT_FALSE; + } } + /* set timeout time for hardware handshake */ + timeout = TimerGet() + FLASH_PROGRAM_TIME_MAX_MS; /* wait until FSR.xBUSY = '0' */ while (pflashFSR->bits.PBUSY == 1) { @@ -896,6 +923,11 @@ static blt_bool FlashTricoreProgramPage(blt_addr start_addr, blt_int8u *data) } /* keep the watchdog happy */ CopService(); + /* fail in case of timeout */ + if (TimerGet() > timeout) + { + return BLT_FALSE; + } } /* check FSR.VER flag */ if (pflashFSR->bits.VER != 0) @@ -948,6 +980,7 @@ static blt_bool FlashTricoreEraseSector(blt_addr start_addr) blt_int8u sectorNum; blt_int32u *readPtr; blt_int32u idx; + blt_int32u timeout; /* determine base address of the PFLASH module */ baseAddr = FLASH_GET_PFLASH_BASE(start_addr); @@ -964,6 +997,8 @@ static blt_bool FlashTricoreEraseSector(blt_addr start_addr) FLASH_WRITE_TO_U32_PTR_BY_ADDR(start_addr, 0x00000030u); /* perform DSYNC */ CpuSetDSYNC(); + /* set timeout time for hardware handshake */ + timeout = TimerGet() + FLASH_ERASE_TIME_MAX_MS; /* wait until FSR.ERASE = '1' */ while (pflashFSR->bits.ERASE != 1) { @@ -979,7 +1014,14 @@ static blt_bool FlashTricoreEraseSector(blt_addr start_addr) } /* keep the watchdog happy */ CopService(); + /* fail in case of timeout */ + if (TimerGet() > timeout) + { + return BLT_FALSE; + } } + /* set timeout time for hardware handshake */ + timeout = TimerGet() + FLASH_ERASE_TIME_MAX_MS; /* wait until FSR.xBUSY = '0' */ while (pflashFSR->bits.PBUSY == 1) { @@ -992,6 +1034,11 @@ static blt_bool FlashTricoreEraseSector(blt_addr start_addr) } /* keep the watchdog happy */ CopService(); + /* fail in case of timeout */ + if (TimerGet() > timeout) + { + return BLT_FALSE; + } } /* check FSR.VER flag */ if (pflashFSR->bits.VER != 0) diff --git a/Target/Source/TRICORE_TC1798/uart.c b/Target/Source/TRICORE_TC1798/uart.c index d379bcb0..6f87cde1 100644 --- a/Target/Source/TRICORE_TC1798/uart.c +++ b/Target/Source/TRICORE_TC1798/uart.c @@ -66,6 +66,8 @@ typedef struct * reception of the first packet byte. */ #define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) +/** \brief Timeout for transmitting a byte in milliseconds. */ +#define UART_BYTE_TX_TIMEOUT_MS (10u) /**************************************************************************************** @@ -264,17 +266,29 @@ static blt_bool UartReceiveByte(blt_int8u *data) ****************************************************************************************/ static blt_bool UartTransmitByte(blt_int8u data) { + blt_int32u timeout; + blt_bool result = BLT_TRUE; + /* reset transmit buffer interrupt request */ UARTx->TBSRC.bits.CLRR = 1; /* write byte to transmit buffer register */ UARTx->TBUF.reg = data; + /* set timeout time to wait for transmit completion. */ + timeout = TimerGet() + UART_BYTE_TX_TIMEOUT_MS; /* wait for transmit buffer register to be empty */ while (UARTx->TBSRC.bits.SRR == 0) { + /* keep the watchdog happy */ CopService(); + /* break loop upon timeout. this would indicate a hardware failure. */ + if (TimerGet() > timeout) + { + result = BLT_FALSE; + break; + } } - /* byte transmitted */ - return BLT_TRUE; + /* give the result back to the caller */ + return result; } /*** end of UartTransmitByte ***/ #endif /* BOOT_COM_UART_ENABLE > 0 */