PXA255 Loosing Clock Int when

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

PXA255 Loosing Clock Int when

Joe Porthouse
I have only been programming using eCos for a few months so please excuse me
if I missed something obvious here.

On the PXA255 when I service interrupts for a serial port ISR, I
occasionally stop receiving my system clock interrupts, while the serial
interrupts continue.  I can always recreate this problem but it takes
between 5,000 and 300,000 received chars before it occurs.

The code below will recreate the problem I am experiencing.  It simply:
1.  Configures and sets up the ISR for the BTUART in the PXA255.
2.  The ISR simply pulls out received chars from the UART FIFO.
3.  The main loop displays the current system ticks and the number of
received characters.

I am sending a 700 character packet once a second at 38,400 baud for my
test.

This is the output I see:

Test Starting...
Time: 0, Rx: 0
...
Time: 10164, Rx: 215555
Time: 10164, Rx: 215555
Time: 10164, Rx: 215555
Time: 10164, Rx: 215555
Time: 10164, Rx: 215555
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215565
Time: 10164, Rx: 215565
Time: 10164, Rx: 215565
Time: 10164, Rx: 215565
Time: 10164, Rx: 215568
Time: 10164, Rx: 215568
Time: 10164, Rx: 215568
Time: 10165, Rx: 215568
Time: 10165, Rx: 215571
Time: 10165, Rx: 215571
Time: 10165, Rx: 215571
Time: 10165, Rx: 215571
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215580
Time: 10165, Rx: 215580
Time: 10165, Rx: 215580
Time: 10165, Rx: 215580
Time: 10165, Rx: 215580
Time: 10165, Rx: 215608 // note large jump in RX chars
Time: 10165, Rx: 215611 // main loop starved, ISRs messed up???
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215614
Time: 10165, Rx: 215614
Time: 10165, Rx: 215614
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215622
Time: 10165, Rx: 215622
Time: 10165, Rx: 215622
Time: 10165, Rx: 215622
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215628
Time: 10165, Rx: 215628
Time: 10165, Rx: 215628
Time: 10165, Rx: 215628
Time: 10165, Rx: 215632
Time: 10165, Rx: 215632
Time: 10165, Rx: 215632
Time: 10165, Rx: 215632
Time: 10165, Rx: 215635
Time: 10165, Rx: 215635
Time: 10165, Rx: 215639
...
Time: 10165, Rx: 226991
Time: 10165, Rx: 226991
Time: 10165, Rx: 226991

System Ticks stop incrementing, but the RX ISR continues to receive
characters.



#include <stdio.h>
#include <stdlib.h>
#include "cyg/kernel/kapi.h"

// removed many register #defs from here, will supply on req.

#define CYGNUM_HAL_INTERRUPT_22   22
#define CYGNUM_HAL_INTERRUPT_21   21
#define CYGNUM_HAL_INTERRUPT_20   20
#define CYG_HAL_PRI_HIGH           0

static cyg_interrupt  btuart_interrupt_new_object;
static cyg_handle_t   btuart_interrupt_handle;
static cyg_vector_t   btuart_interrupt_vector   = CYGNUM_HAL_INTERRUPT_21;
static cyg_priority_t btuart_interrupt_priority = CYG_HAL_PRI_HIGH;



unsigned int isr_rx_count = 0;

cyg_uint32 btuart_interrupt_isr(
  cyg_vector_t vector,
  cyg_addrword_t data)
{
  unsigned int iir, lsr, rbr;

  iir = PXA255_BTIIR;

  // check if RX FIFO interrupt
  if((iir & PXA255_IIR_IID_INT_ID_MASK) ==
PXA255_IIR_IID_RX_FIFO_INT_PENDING)
  {
    lsr = PXA255_BTLSR;
    while(lsr & PXA255_LSR_DR_DATA_READY)
    {
      rbr = PXA255_BTRBR;
      isr_rx_count++;
      lsr = PXA255_BTLSR;
    }
  }

  cyg_interrupt_acknowledge(vector);

  return(CYG_ISR_HANDLED);
}



void serial_port_start(void)
{
  // BTUART GPIO
  // GPIO_42 BTRXD IN  ALT_FN_1_IN
  // GPIO_43 BTTXD OUT ALT_FN_2_OUT
  // GPIO_44 BTCTS IN  ALT_FN_1_IN
  // GPIO_45 BTRTS OUT ALT_FN_2_OUT
  // Set all low
  PXA255_GPCR1 = 0x00003C00;
  // Set BTUART GPIO signals for OUTPUT
  PXA255_GPDR1 =
    (PXA255_GPDR1 & ~0x00003C00) | 0x00002800;
  // Enable GPIO pins for BTUART functionality
  PXA255_GAFR1_L =
    (PXA255_GAFR1_L & 0xF00FFFFF) | 0x09900000;

  PXA255_BTIER = PXA255_IER_UUE_UART_UNIT_DISABLED;
  PXA255_BTLCR = PXA255_LCR_DLAB_DIVISOR_LATCH_ACCESS_ENABLED;
  PXA255_BTDLL = BAUD_38400_DIVISOR_LOW;
  PXA255_BTDLH = BAUD_38400_DIVISOR_HIGH;
  PXA255_BTLCR =
    PXA255_LCR_PEN_PARITY_DISABLED|
    PXA255_LCR_WLS_8_BIT_WORD_SELECTED|
    PXA255_LCR_STB_1_STOP_BIT_SELECTED;
  PXA255_BTFCR =
    PXA255_FCR_TRFIFOE_FIFO_ENABLED|
    PXA255_FCR_RESETRF_RESET_RX_FIFO|
    PXA255_FCR_RESETTF_RESET_TX_FIFO|
    PXA255_FCR_ITL_INT_TRIGGER_LEVEL_32;
  PXA255_BTMCR =
    PXA255_MCR_LOOP_LOOPBACK_DISABLED |
    PXA255_MCR_OUT2_UART_INTERRUPT_ENABLED;
  PXA255_BTISR =
    PXA255_ISR_RCVEIR_REVEIVER_IR_MODE_DISABLED |
    PXA255_ISR_XMITIR_TRANSMITTER_IR_MODE_DISABLED;

  cyg_interrupt_create(
    btuart_interrupt_vector,
    btuart_interrupt_priority,
    0,
    &btuart_interrupt_isr,
    0,
    &btuart_interrupt_handle,
    &btuart_interrupt_new_object);

  cyg_interrupt_attach(btuart_interrupt_handle);

  cyg_interrupt_unmask(btuart_interrupt_vector);

  PXA255_BTIER =
    PXA255_IER_UUE_UART_UNIT_ENABLED |
    PXA255_IER_RTOIE_RX_TIMEOUT_INT_ENABLED |
    PXA255_IER_RAVIE_RX_INT_ENABLED;
}



#define CYG_REAL_TIME_CLOCK_FREQUENCY 100
#define TICKS_PER_SECOND 20

unsigned int get_ticks(void)
{
  unsigned int current_ticks =
    cyg_current_time() / (CYG_REAL_TIME_CLOCK_FREQUENCY/TICKS_PER_SECOND);
  return current_ticks;
}



int main(void)
{
  printf("Test Starting...\n");

  serial_port_start();

  for(;;)
  {
    printf("Time: %u, Rx: %u \n", get_ticks(), isr_rx_count);
  }

  printf("Test Never Ends...\n");
  return 0;
}



Joe Porthouse
Toptech Systems, Inc.
280 Hunt Park Cove
Longwood, FL 32750
407-332-1774 x-265



--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

Reply | Threaded
Open this post in threaded view
|

RE: PXA255 Loosing Clock Int when

Joe Porthouse
Just a quick follow up note.

I noticed that the problem occurs when I set interrupt_priority to 0 or 1,
but setting it to 4 seems to have eliminated the problem, or at least
lessened its occurrence rate greatly.

I am at a loss why the interrupt priority should have this behavior unless
the clock interrupt is getting preempted by the serial interrupt and the
context is not being restored correctly.  Has this been an issue?

I also do not understand what the normal range and assignment of interrupt
priorities should be on the PXA255.

Joe Porthouse
Toptech Systems, Inc.
280 Hunt Park Cove
Longwood, FL 32750
-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Joe Porthouse
Sent: Sunday, November 13, 2005 10:02 AM
To: [hidden email]
Subject: [ECOS] PXA255 Loosing Clock Int when

I have only been programming using eCos for a few months so please excuse me
if I missed something obvious here.

On the PXA255 when I service interrupts for a serial port ISR, I
occasionally stop receiving my system clock interrupts, while the serial
interrupts continue.  I can always recreate this problem but it takes
between 5,000 and 300,000 received chars before it occurs.

The code below will recreate the problem I am experiencing.  It simply:
1.  Configures and sets up the ISR for the BTUART in the PXA255.
2.  The ISR simply pulls out received chars from the UART FIFO.
3.  The main loop displays the current system ticks and the number of
received characters.

I am sending a 700 character packet once a second at 38,400 baud for my
test.

This is the output I see:

Test Starting...
Time: 0, Rx: 0
...
Time: 10164, Rx: 215555
Time: 10164, Rx: 215555
Time: 10164, Rx: 215555
Time: 10164, Rx: 215555
Time: 10164, Rx: 215555
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215562
Time: 10164, Rx: 215565
Time: 10164, Rx: 215565
Time: 10164, Rx: 215565
Time: 10164, Rx: 215565
Time: 10164, Rx: 215568
Time: 10164, Rx: 215568
Time: 10164, Rx: 215568
Time: 10165, Rx: 215568
Time: 10165, Rx: 215571
Time: 10165, Rx: 215571
Time: 10165, Rx: 215571
Time: 10165, Rx: 215571
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215574
Time: 10165, Rx: 215580
Time: 10165, Rx: 215580
Time: 10165, Rx: 215580
Time: 10165, Rx: 215580
Time: 10165, Rx: 215580
Time: 10165, Rx: 215608 // note large jump in RX chars
Time: 10165, Rx: 215611 // main loop starved, ISRs messed up???
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215611
Time: 10165, Rx: 215614
Time: 10165, Rx: 215614
Time: 10165, Rx: 215614
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215618
Time: 10165, Rx: 215622
Time: 10165, Rx: 215622
Time: 10165, Rx: 215622
Time: 10165, Rx: 215622
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215625
Time: 10165, Rx: 215628
Time: 10165, Rx: 215628
Time: 10165, Rx: 215628
Time: 10165, Rx: 215628
Time: 10165, Rx: 215632
Time: 10165, Rx: 215632
Time: 10165, Rx: 215632
Time: 10165, Rx: 215632
Time: 10165, Rx: 215635
Time: 10165, Rx: 215635
Time: 10165, Rx: 215639
...
Time: 10165, Rx: 226991
Time: 10165, Rx: 226991
Time: 10165, Rx: 226991

System Ticks stop incrementing, but the RX ISR continues to receive
characters.



#include <stdio.h>
#include <stdlib.h>
#include "cyg/kernel/kapi.h"

// removed many register #defs from here, will supply on req.

#define CYGNUM_HAL_INTERRUPT_22   22
#define CYGNUM_HAL_INTERRUPT_21   21
#define CYGNUM_HAL_INTERRUPT_20   20
#define CYG_HAL_PRI_HIGH           0

static cyg_interrupt  btuart_interrupt_new_object;
static cyg_handle_t   btuart_interrupt_handle;
static cyg_vector_t   btuart_interrupt_vector   = CYGNUM_HAL_INTERRUPT_21;
static cyg_priority_t btuart_interrupt_priority = CYG_HAL_PRI_HIGH;



unsigned int isr_rx_count = 0;

cyg_uint32 btuart_interrupt_isr(
  cyg_vector_t vector,
  cyg_addrword_t data)
{
  unsigned int iir, lsr, rbr;

  iir = PXA255_BTIIR;

  // check if RX FIFO interrupt
  if((iir & PXA255_IIR_IID_INT_ID_MASK) ==
PXA255_IIR_IID_RX_FIFO_INT_PENDING)
  {
    lsr = PXA255_BTLSR;
    while(lsr & PXA255_LSR_DR_DATA_READY)
    {
      rbr = PXA255_BTRBR;
      isr_rx_count++;
      lsr = PXA255_BTLSR;
    }
  }

  cyg_interrupt_acknowledge(vector);

  return(CYG_ISR_HANDLED);
}



void serial_port_start(void)
{
  // BTUART GPIO
  // GPIO_42 BTRXD IN  ALT_FN_1_IN
  // GPIO_43 BTTXD OUT ALT_FN_2_OUT
  // GPIO_44 BTCTS IN  ALT_FN_1_IN
  // GPIO_45 BTRTS OUT ALT_FN_2_OUT
  // Set all low
  PXA255_GPCR1 = 0x00003C00;
  // Set BTUART GPIO signals for OUTPUT
  PXA255_GPDR1 =
    (PXA255_GPDR1 & ~0x00003C00) | 0x00002800;
  // Enable GPIO pins for BTUART functionality
  PXA255_GAFR1_L =
    (PXA255_GAFR1_L & 0xF00FFFFF) | 0x09900000;

  PXA255_BTIER = PXA255_IER_UUE_UART_UNIT_DISABLED;
  PXA255_BTLCR = PXA255_LCR_DLAB_DIVISOR_LATCH_ACCESS_ENABLED;
  PXA255_BTDLL = BAUD_38400_DIVISOR_LOW;
  PXA255_BTDLH = BAUD_38400_DIVISOR_HIGH;
  PXA255_BTLCR =
    PXA255_LCR_PEN_PARITY_DISABLED|
    PXA255_LCR_WLS_8_BIT_WORD_SELECTED|
    PXA255_LCR_STB_1_STOP_BIT_SELECTED;
  PXA255_BTFCR =
    PXA255_FCR_TRFIFOE_FIFO_ENABLED|
    PXA255_FCR_RESETRF_RESET_RX_FIFO|
    PXA255_FCR_RESETTF_RESET_TX_FIFO|
    PXA255_FCR_ITL_INT_TRIGGER_LEVEL_32;
  PXA255_BTMCR =
    PXA255_MCR_LOOP_LOOPBACK_DISABLED |
    PXA255_MCR_OUT2_UART_INTERRUPT_ENABLED;
  PXA255_BTISR =
    PXA255_ISR_RCVEIR_REVEIVER_IR_MODE_DISABLED |
    PXA255_ISR_XMITIR_TRANSMITTER_IR_MODE_DISABLED;

  cyg_interrupt_create(
    btuart_interrupt_vector,
    btuart_interrupt_priority,
    0,
    &btuart_interrupt_isr,
    0,
    &btuart_interrupt_handle,
    &btuart_interrupt_new_object);

  cyg_interrupt_attach(btuart_interrupt_handle);

  cyg_interrupt_unmask(btuart_interrupt_vector);

  PXA255_BTIER =
    PXA255_IER_UUE_UART_UNIT_ENABLED |
    PXA255_IER_RTOIE_RX_TIMEOUT_INT_ENABLED |
    PXA255_IER_RAVIE_RX_INT_ENABLED;
}



#define CYG_REAL_TIME_CLOCK_FREQUENCY 100
#define TICKS_PER_SECOND 20

unsigned int get_ticks(void)
{
  unsigned int current_ticks =
    cyg_current_time() / (CYG_REAL_TIME_CLOCK_FREQUENCY/TICKS_PER_SECOND);
  return current_ticks;
}



int main(void)
{
  printf("Test Starting...\n");

  serial_port_start();

  for(;;)
  {
    printf("Time: %u, Rx: %u \n", get_ticks(), isr_rx_count);
  }

  printf("Test Never Ends...\n");
  return 0;
}



Joe Porthouse
Toptech Systems, Inc.
280 Hunt Park Cove
Longwood, FL 32750
407-332-1774 x-265



--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss




--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss