Thursday, August 27, 2015

IAR, Vybrid, Low Power Timer, and Getting Started Example

This is a short blog on a tiny issue I found working with the FreeScale Vybrid Tower evaluation board with the IAR IDE 'Getting Started' example.

The Getting Started example has two interrupts, one for a periodic timer using the Lower Power Timer (0) and a hardware interrupt for a button, SW1.

There are two IRQs, one for the timer, and one for the button.

The button IRQ outputs the number of times the button has been pushed each time the button is pushed. The timer IRQ blinks a blue LED, off for 1/2 second and on for 1/2 second.

I decided to tweak the example. I want to report the value of the timer counter when the button is pushed. I should see a value from 0 to 500, as the periodic timer is set to 1kHz.

I used the existing IAR symbols, LPTMR0->CNR, to read the timer counter.

Each time I pushed the button the value for CNR was 0.

The Low Power Timer documentation in the FreeScale Vybrid reference manual, pg. 1910-1913.

On page 1913, 41.4.5 LPTMR Counter, it states

The CNR cannot be initialized, but can be read at any time. On each read of the CNR, software must first write to the CNR with any value. This will synchronize and register the current value of the CNR into a temporary register. The contents of the temporary register are returned on each read of the CNR.

Thus one must first write to CNR, then read. The write does not change CNR, it just enables the timer counter to be latched into the CNR register when read.

LPTMR0->CNR = 1;
printf("Timer: %d\n:, LPTMR0->CNR);

Unfortunately, the first line of code gives a compiler error. The error states that CNR cannot be modified.

The structure defined in the Getting Started example for the Vybrid tower that defines the LPTMR registers (MVF50GS10MK50.h), CSR, PSR, CMR and CNR. The registers CSR, PSR, and CMR are defined _IO uint32_t. _IO means read/write.

CNR is defined _I uint32_t as read only. Wrong.

The CNR definition must be changed to _IO uint32_t in order to read CNR.

/** LPTMR - Register Layout Typedef */
typedef struct {
  __IO uint32_t CSR;                               /**< Low Power
Timer Control Status Register, offset: 0x0 */
  __IO uint32_t PSR;                               /**< Low Power
Timer Prescale Register, offset: 0x4 */
  __IO uint32_t CMR;                               /**< Low Power
Timer Compare Register, offset: 0x8 */
  __IO  uint32_t CNR;        /* 
__I  uint32_t */   /**< Low Power
Timer Counter Register, offset: 0xC */
} LPTMR_Type;



Oops.

As I said, a tiny issue.

No comments:

Post a Comment