I my code in my logger SW shord make a Timestamp every Time a Serial Frame Error is recognised - because i need this information - for this i use this code:
I use Arduino 1.05 r2 because i modify old project from 2014 an library parameters have changed since them.
ISR in Serial1.c
void uart0_error_isr (void)
{
uint8_t status, temp;
uint32_t count, current, istatus,microseconds;
__disable_irq();
current = SYST_CVR;
count = systick_millis_count;
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
__enable_irq();
//systick_current = current;
//systick_count = count;
//systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
current = ((F_CPU / 1000) - 1) - current;
microseconds = count * 1000 + current / (F_CPU / 1000000);
if (microseconds>microseconds_last) elapsed_microseconds = microseconds-microseconds_last;
else elapsed_microseconds = (0xFFFFFFFF + microseconds_last - microseconds);
elapsed_milliseconds = elapsed_microseconds/1000;
microseconds_last = microseconds;
/* Since the flag clearing mechanism will clear any flags in S1
* that are set, we have to save off the value of the status register
* and then check against the saved value to be able to detect all of
* the flags that were set (if you read the status register over and
* over again, then you'll only capture the first one that was set.
*/
/* Read and save the S1 value */
status = UART0_S1;
/* Check to see if a receiver overrun has been detected */
if (status & UART_S1_OR)
{
//printf("\nUART receiver overrun detected.\n");
num_or_errors++;
/* Read data register to clear the flag */
temp = UART0_D;
}
/* Check to see if the noise flag is set */
if (status & UART_S1_NF)
{
// printf("\nUART noise error detected.\n");
num_nf_errors++;
/* Read data register to clear the flag */
temp = UART0_D;
}
/* Check to see if a framing error was detected */
if (status & UART_S1_FE)
{
if (sum_rx_data > 0)
{
num_frame_posistion[num_frame_posistion_counter] = sum_rx_data;
sum_elapsed_milliseconds = elapsed_milliseconds + sum_elapsed_milliseconds;
num_frame_posistion_time[num_frame_posistion_counter] = sum_elapsed_milliseconds;
sum_rx_data = 0;
if (num_frame_posistion_counter >= num_frame_posistion_size)
{
num_frame_posistion_counter=0;
num_framing_errors=0;
}
else
{
num_frame_posistion_counter++;
num_framing_errors++;
}
}
/* Read data register to clear the flag */
temp = UART0_D;
UART0_BDH = (baudrate >> 13) & 0x1F;
UART0_BDL = (baudrate >> 5) & 0xFF;
// __enable_irq();
}
/* Check to see if a parity error was detected */
if (status & UART_S1_PF)
{
// printf("\nUART parity error detected.\n");
num_parity_errors++;
/* Read data register to clear the flag */
temp = UART0_D;
}
/* Check to see if a transmit buffer overflow was detected */
if (UART0_SFIFO & UART_SFIFO_TXOF)
{
// printf("\nUART transmit buffer overflow detected.\n");
num_txof_errors++;
/* Write 1 to flag to clear the flag */
UART0_SFIFO = UART_SFIFO_TXOF;
}
/* Check to see if a receiver underflow was detected */
if (UART0_SFIFO & UART_SFIFO_RXUF)
{
// printf("\nUART receiver buffer underflow detected.\n");
num_rxuf_errors++;
/* Write 1 to flag to clear the flag */
UART0_SFIFO = UART_SFIFO_RXUF ;
}
}
in the attacement the value of behavor of sum_elapsed_milliseconds is seen.
sometimes it seems to have a jump and later a glitch - can someone explain me why this happend and how i can write the code better?
In my old project the ISR is modified direct inside the Hardware file (serial1.c)
Can this also be done outside - because this is a one way solution - if i want to upgrade arduino or if i want to use a new teensyduino version - i must migrate it to the serial1.c of the new version.
every advice would be helpful for me....
Many thanks,
Frank Muenzner
I use Arduino 1.05 r2 because i modify old project from 2014 an library parameters have changed since them.
ISR in Serial1.c
void uart0_error_isr (void)
{
uint8_t status, temp;
uint32_t count, current, istatus,microseconds;
__disable_irq();
current = SYST_CVR;
count = systick_millis_count;
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
__enable_irq();
//systick_current = current;
//systick_count = count;
//systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
current = ((F_CPU / 1000) - 1) - current;
microseconds = count * 1000 + current / (F_CPU / 1000000);
if (microseconds>microseconds_last) elapsed_microseconds = microseconds-microseconds_last;
else elapsed_microseconds = (0xFFFFFFFF + microseconds_last - microseconds);
elapsed_milliseconds = elapsed_microseconds/1000;
microseconds_last = microseconds;
/* Since the flag clearing mechanism will clear any flags in S1
* that are set, we have to save off the value of the status register
* and then check against the saved value to be able to detect all of
* the flags that were set (if you read the status register over and
* over again, then you'll only capture the first one that was set.
*/
/* Read and save the S1 value */
status = UART0_S1;
/* Check to see if a receiver overrun has been detected */
if (status & UART_S1_OR)
{
//printf("\nUART receiver overrun detected.\n");
num_or_errors++;
/* Read data register to clear the flag */
temp = UART0_D;
}
/* Check to see if the noise flag is set */
if (status & UART_S1_NF)
{
// printf("\nUART noise error detected.\n");
num_nf_errors++;
/* Read data register to clear the flag */
temp = UART0_D;
}
/* Check to see if a framing error was detected */
if (status & UART_S1_FE)
{
if (sum_rx_data > 0)
{
num_frame_posistion[num_frame_posistion_counter] = sum_rx_data;
sum_elapsed_milliseconds = elapsed_milliseconds + sum_elapsed_milliseconds;
num_frame_posistion_time[num_frame_posistion_counter] = sum_elapsed_milliseconds;
sum_rx_data = 0;
if (num_frame_posistion_counter >= num_frame_posistion_size)
{
num_frame_posistion_counter=0;
num_framing_errors=0;
}
else
{
num_frame_posistion_counter++;
num_framing_errors++;
}
}
/* Read data register to clear the flag */
temp = UART0_D;
UART0_BDH = (baudrate >> 13) & 0x1F;
UART0_BDL = (baudrate >> 5) & 0xFF;
// __enable_irq();
}
/* Check to see if a parity error was detected */
if (status & UART_S1_PF)
{
// printf("\nUART parity error detected.\n");
num_parity_errors++;
/* Read data register to clear the flag */
temp = UART0_D;
}
/* Check to see if a transmit buffer overflow was detected */
if (UART0_SFIFO & UART_SFIFO_TXOF)
{
// printf("\nUART transmit buffer overflow detected.\n");
num_txof_errors++;
/* Write 1 to flag to clear the flag */
UART0_SFIFO = UART_SFIFO_TXOF;
}
/* Check to see if a receiver underflow was detected */
if (UART0_SFIFO & UART_SFIFO_RXUF)
{
// printf("\nUART receiver buffer underflow detected.\n");
num_rxuf_errors++;
/* Write 1 to flag to clear the flag */
UART0_SFIFO = UART_SFIFO_RXUF ;
}
}
in the attacement the value of behavor of sum_elapsed_milliseconds is seen.
sometimes it seems to have a jump and later a glitch - can someone explain me why this happend and how i can write the code better?
In my old project the ISR is modified direct inside the Hardware file (serial1.c)
Can this also be done outside - because this is a one way solution - if i want to upgrade arduino or if i want to use a new teensyduino version - i must migrate it to the serial1.c of the new version.
every advice would be helpful for me....
Many thanks,
Frank Muenzner