• Nem Talált Eredményt

ADSP-219x/2191 DSP Hardware Reference, Timer

N/A
N/A
Protected

Academic year: 2024

Ossza meg "ADSP-219x/2191 DSP Hardware Reference, Timer"

Copied!
18
0
0

Teljes szövegt

(1)

Table 12-0.

Listing 1-0.

Overview

The ADSP-2191 features three identical 32-bit timers; each timer can be individually configured in any of three modes:

• Pulsewidth Modulation (PWMOUT) mode

• Pulsewidth Count and Capture (WDTH_CAP) mode

• External Event Watchdog (EXT_CLK) mode

Each timer has one dedicated bi-directional chip pin, TMRx. This pin func- tions as an output pin in the PWMOUT mode and as an input pin in the

WDTH_CAP and EXT_CLK modes. To provide these functions, each timer has seven, 16-bit registers. For range and precision, six of these registers can be paired (High/Low) to allow for 32-bit values and appear in Figure 12-1.

The registers for each timer are:

• Timer x Configuration (T_CFGRx) registers

• Timer x High Word Count (T_CNTHx) registers

• Timer x Low Word Count (T_CNTLx) registers

• Timer x High Word Period (T_PRDHx) registers

• Timer x Low Word Period (T_PRDLx) registers

• Timer x High Word Pulsewidth (T_WHRx) registers

• Timer x Low Word Pulsewidth (T_WLRx) registers

(2)

Because the paired “counter” registers operate as a single value, the timer counters are 32-bits wide. When clocked internally, the clock source is the ADSP-2191’s peripheral clock (HCLK). Assuming the peripheral clock is running at 80 MHz, the maximum period for the timer count is

((232-1) * 12.5 ns) = 53.69 seconds.

Timer Global Status and Control (T_GSRx) registers indicate status of all three timers, requiring a single read to check the status of all three timers.

Each T_GSRx register contains timer enable bits that enable the corre- sponding timer (T_GSR0 enables TIMER0, etc. ...). Within T_GSRx, each Figure 12-1. Timer Block Diagram

SUB Perio d (High word/Low word)

Count (High word/Low word)

Pulsewidth (High word/Low word)

Perio d Buffer Pulse width Bu ffer

16 (Read On ly) 1 6 16

E xp i re I/O Memo ry Da ta Bu s

(3)

timer has a pair of “sticky” status bits, that require a “write-one-to-set”

(TIMENx) or “write-one-to-clear” (TIMDISx) —see Table 12-1 on

page 12-4— to either enable or disable the timer. Writing a one to both bits of a pair disables that timer.

After the timer has been enabled, both its TIMENx and TIMDISx bits are set (=1). The timer starts counting three peripheral clock cycles after the

TIMENx bit is set. Setting (writing 1 to) the timer’s TIMDISx bit stops the timer without waiting for any additional event.

Each T_GSRx register also contains an Interrupt Latch bit (TIMILx) and an Overflow/Error Indicator bit (OVF_ERRx) for each timer. These “sticky”

bits are set by the timer hardware and may be watched by software. They need to be cleared in each timer’s corresponding T_GSRx register by soft- ware explicitly. To clear, write a “one” to the corresponding bit.

L

Interrupt and overflow bits may be cleared simultaneously with timer enable or disable.

To enable a timer’s interrupts, set the IRQ_ENA bit in the timer’s Configu- ration (T_CFGRx) register and unmask the timer’s interrupt by setting the corresponding bit of the IMASK register. With the IRQ_ENA bit cleared, the timer does not set its Interrupt Latch (TIMILx) bits. To poll the TIMILx bits without permitting a timer interrupt, programs can set the IRQ_ENA bit while leaving the timer’s interrupt masked.

With interrupts enabled, make sure that the interrupt service routine clears the TIMILx latch before the Rti instruction to assure that the inter- rupt is not re-issued. In external clock (EXT_CLK) mode, the latch should be reset at the very beginning of the interrupt routine to not miss any timer event. To enable timer interrupts, set the IRQ_ENA bit in the proper Timer Configuration (T_CFGRx) register.

To enable an individual timer, set the timer’s TIMEN bit in the correspond- ing T_GSRx register. To disable an individual timer, set the timer’s TIMDIS bit in the corresponding T_GSRx register. To enable all three timers in par- allel, set each TIMEN bit in each timer’s corresponding T_GSRx register.

(4)

Before enabling a timer, always program the corresponding timer’s Con- figuration (T_CFGRx) register. This register defines the timer’s operating mode, the polarity of the TMRx pin, and the timer’s interrupt behavior. Do not alter the operating mode while the timer is running. For more infor- mation on the T_CFGRx register, see Figure B-35 on page B-85.

Table 12-1. Timer Global Status and Control (T_GSRx) Register Bits

Bit(s) Name Definition

0 TIMIL0 Timer 0 Interrupt Latch Write one to clear (also an output) 1 TIMIL1 Timer 1 Interrupt Latch Write one to clear (also an output) 2 TIMIL2 Timer 2 Interrupt Latch Write one to clear (also an output)

3 Reserved

4 OVF_ERR0 Timer 0 Overflow/Error Write one to clear (also an output) 5 OVF_ERR1 Timer 1 Overflow/Error Write one to clear (also an output) 6 OVF_ERR2 Timer 2 Overflow/Error Write one to clear (also an output)

7 Reserved

8 TIMEN0 Timer 0 Enable Write one to enable Timer 0 9 TIMDIS0 Timer 0 Disable Write one to disable Timer 0 10 TIMEN1 Timer 1 Enable Write one to enable Timer 1 11 TIMDIS1 Timer 1 Disable Write one to disable Timer 1 12 TIMEN2 Timer 2 Enable Write one to enable Timer 2 13 TIMDIS2 Timer 2 Disable Write one to disable Timer 2 14 - 15 Reserved

(5)

Timer enable/disable timing appears in Figure 12-2.

Because the timers are 32-bit, hardware support guarantees that high and low-words are always coherent whenever the DSP accesses the period or the pulsewidth registers. There is no similar support for DSP reads of the counter register itself. When a coherent read of the counter register’s high- and low-words is needed, software should stop (disable) the timer before reading the 32-bit counter value.

When the timer is disabled, the counter registers retain their state; when the timer is re-enabled, the counter is re-initialized based on the operating mode. The counter registers are read only. The software cannot overwrite or preset the counter value directly.

Any of the timers can be used to implement a watchdog functionality, which might be controlled by either an internal or an external clock source.

Figure 12-2. Timer Enable and Disable Timing

HCLK

PWMOUT

HCLK

TC OU NT

= M

TC OU NT

= M + 1

TC OUNT

= M + 1 TC OU NT

= M + 1

Timer Enable

Set TI M EN

Timer En a b l e d

TPER I OD = 0x 4 TPWI D T H = 0 x2 TC O UN T = 1 TC OU NT

=xx

TCOU NT

=xx

TC OU NT

=1

TC OUNT

=2

TC OUNT

=4 TCOU NT

=3

Clear TIM EN

Timer Dis ab led

Timer Disable

(6)

For software to service the watchdog, disable the timer and re-enable it again. This resets the timer value. Servicing the watchdog periodically pre- vents the count register from reaching the period value and prevents the timer interrupt from being generated. Assign a very high interrupt priority to this watchdog timer. When the timer reaches the period value and gen- erates the interrupt, reset the DSP within the corresponding watchdog’s interrupt service routine.

Pulsewidth Modulation (PWMOUT) Mode

Setting the TMODE field to 01 in the timer’s configuration (T_CFGRx) regis- ter enables the PWMOUT mode. In PWMOUT mode, the timer’s TMRx pin is an output. It is actively driven as long as the TMODE field remains 01.

The timer is clocked internally by HCLK. Independent of the PERIOD_CNT bit, the PWMOUT mode either generates pulsewidth modulation waveforms or generates a single pulse on the TMRx pin.

When the timer gets enabled, the timer checks the period and width val- ues for plausibility (independent of PERIOD_CNT) and does not start to count when any of the following conditions is true:

• Width equals to zero

• Period value is lower than width value

• Width equals to period

On invalid conditions, the timer sets both the TIMOVFx and the TIMIRQx bit after two HCLK cycles. The count register is not altered, then. Note that after reset, the timer registers are all zero.

If period and width values are valid after enabling, the count register is loaded with the value 0xFFFF FFFF – width. The timer counts upward to 0xFFFF FFFE. Instead incrementing to 0xFFFF FFFF, the timer then reloads the counter with 0xFFFF FFFF – (period – width) and repeats.

(7)

PWM Waveform Generation

If the PERIOD_CNT bit is set, the internally clocked timer generates rectan- gular signals with well defined period and duty cycle. This mode also generates periodic interrupts for real-time DSP processing.

The 32-bit Period (T_PRDHx / T_PRDLx) and Width (T_WHRx / T_WLRx) regis- ters are programmed with the values of the timer count period and pulsewidth modulated output pulsewidth.

Figure 12-3. Timer Flow Diagram - PWMOUT Mode

Data Bus

RESET

TIMER_ENABLE

TPERIODx TPWIDTHx

CLOCK

Yes

Interrupt

High

Low

TMRx Equal?

TCOUNTx

Yes

PWMOUT Logic Equal?

Set PWMOUNT

(8)

When the timer is enabled in this mode, the TMRx pin is pulled to a de-asserted state each time the pulsewidth expires, and the pin is asserted again when the period expires (or when the timer gets started).

To control the assertion sense of the TMRx pin, the PULSE_HI bit in the cor- responding T_CFGRx register is either cleared or set (cleared causes a low assertion level, set causes a high assertion level).

If enabled, a timer interrupt is generated at the end of each period. An interrupt service routine must clear the interrupt latch bit TIMIRQx and might alter period and/or width values. In pulsewidth modulation applica- tions, the software needs to update period and pulsewidth value while the timer is running. To guarantee coherency between not only the high and low-words but also between period and pulsewidth registers, a double buffer mechanism is in place.

DSP core writes to the T_PRDHx, T_PRDLx, and T_WHRx registers do not become active until the DSP core writes to the T_WLRx register. If the soft- ware would like to update only one of these three registers only, it must rewrite the T_WLRx register afterward. When the T_WLRx value is not sub- ject to change, the interrupt service routine might just read back the current value of the T_WLRx register and rewrite it again. On the next counter reload, all the four registers are available to the timer.

To generate the maximum frequency on the TMRx output pin, set the period value to 2 and the pulsewidth to 1. This makes TMRx toggle each HCLK clock producing a duty cycle of 50%.

Single-Pulse Generation

If the PERIOD_CNT bit is cleared, the PWMOUT mode generates a single pulse on the TMRx pin. This mode also can be used to implement well-defined software delay often required by state-machines etc. The pulse width is defined by the width register and the period register is not used.

(9)

At the end of the pulse the interrupt latch bit TIMIRQx gets set and the timer is stopped automatically. If the PULSE_HI bit is set, an active high pulse is generated on the TMRx pin. If PULSE_HI is not set, the pulse is active low.

Pulsewidth Count and Capture (WDTH_CAP) Mode

In WDTH_CAP mode, the TMRx pin is an input pin. The internally clocked timer is used to determine period and pulsewidth of externally applied rectangular waveforms. Setting the TMODE field to 10 in the T_CFGRx enables this mode. The period and width registers are read-only in

WIDTH_CNT mode.

When enabled in this mode, the timer resets words of the count in the

T_CNTHx and T_CNTLx registers value to 0x0000 0001 and does not start counting until it detects the leading edge on the TMRx pin.

When the timer detects a first leading edge, it starts incrementing. When it detects the trailing edge of a waveform, the timer captures the current 32-bit value of the T_CNTHx and T_CNTLx count registers into the T_WHRx and T_WLRx width registers. At the next leading edge, the timer transfers the current 32-bit value of the T_CNTHx and T_CNTLx count registers into the T_PRDHx and T_PRDLx period register. The count registers are reset to 0x0000 0001 again, and the timer continues counting until it is either dis- abled or the count value reaches 0xFFFF FFFF.

In this mode, software can measure both the pulsewidth and the pulse period of a waveform. To control the definition of “leading edge” and

“trailing edge” of the TMRx pin, the PULSE_HI bit in the T_CFGRx register is set or cleared. If the PULSE_HI bit is cleared, the measurement is initiated by a falling edge, the count register is captured to the width register on the rising edge, and the period is captured on the next falling edge.

The PERIOD_CNT bit in the T_CFGRx register controls whether an enabled interrupt is generated when the pulsewidth or pulse period is captured. If the PERIOD_CNT bit is set, the interrupt latch bit (TIMILx) gets set when the

(10)

pulse period value is captured. If the PERIOD_CNT bit is cleared, the TIMILx bit gets set when the pulse width value is captured.

If the PERIOD_CNT bit is cleared, the first period value has not yet been measured when the first interrupt is generated, so the period value is not valid. If the interrupt service routine reads the period value anyway, the timer returns a period zero value in this case.

A timer interrupt (if enabled) is also generated if the count register reaches a value of 0xFFFF FFFF. At that point, the timer gets disabled automati- Figure 12-4. Timer Flow Diagram - WDTH_CAP Mode

Data Bus

RESET Set

COUNT_OVF bit

TPERIODx TPWIDTHx

CLOCK

Interrupt

Set PULSE_CAP

bit PERIOD_CNT

TMRx

TCOUNTx

1

Leading Edge Detect

COUNT_OVF

TMRx Trailing

Edge Detect

Interrupt Logic

PERIOD_CNT 0 1 1

1 2 2

2

2

(11)

cally, and the TIMOVFx status bit is set, indicating a count overflow.

TIMIRQx and TIMOVFx are sticky bits, and software has to explicitly clear them.

The first width value captured in WDTH_CAP mode is erroneous due to syn- chronizer latency. To avert this error, software must issue two NOP

instructions between setting WDTH_CAP mode and setting TIMEN. TIMEN is set subsequently without NOPs.

Auto-Baud Mode

Any one of the three timers may provide auto-baud detection for the UART port. The Timer Input Select (TIN_SEL) bit in the T_CFGRx register causes the timer to sample the UART port receive data (RXD) pin instead of the TMRx pin while enabled for WDTH_CAP mode. A software routine can detect the pulsewidths of serial stream bit-cells. Because the sample base of the timers are synchronous with the UART operation—all derived from the PLL clock, the pulsewidths can be used to calculate the baud rate divider for the UART.

For an auto-baud example, see “Auto-baud Rate Detection Using Timer 0” on page 11-13.

External Event Watchdog (EXT_CLK) Mode

In EXT_CLK mode, the TMRx pin is an input. The timer works as a counter clocked by any external source, which can also be asynchronous to the DSP clock. Setting the TMODE field to 11 in the T_CFGRx register enables this mode. Both the T_PRDHx and T_PRDLx period registers are programmed with the value of the maximum timer external count.

BAUDDIV Timer x pulsewidth register ---16 –1

=

(12)

After the timer has been enabled it waits for the first rising edge on the

TMRx pin. This edge forces the count register to be loaded by the value 0xFFFF FFFF – Period. Every subsequent rising edge increments the count register. After reaching the count value 0xFFFF FFFE the TIMIRQx bit is set and an interrupt is generated. The next rising edge reloads the count register again by 0xFFFF FFFF – Period.

The configuration bits TIN_SEL, PULSE_HI, and PERIOD_CNT have no effect in this mode. Also, TIMOVFx is never set. The width register is unused.

In this mode, an external clock source can use the timer to wake up the DSP from the sleeping mode even if HCLK has been stopped.

Code Examples

This section describes how to setup the timer. In PWMOUT mode, when Timer0 width expires, counter is loaded with (period – width) and contin- ues counting. When period expires, counter is loaded the width value again and the cycle repeats. TMRx pin is alternately driven high/low, deter- mined by PULSE_HI, at each zero. When the width or period expires,

TIMIL0 (if enabled) is set depending on PERIOD_CNT bit in T_CFGR0.

Timer Example Steps

TIMER0 is setup in PWMOUT mode. It is intended to toggle General Purpose I/O’s (GPIO) ON/OFF inside Timer0 Interrupt Service Routine at a 1Hz rate. This is done assuming a 160Mhz core clock (CCLK) and 80Mhz peripheral clock (HCLK).

Prior to initializing or re-configuring the Timer, it is best to reset TIMEN. Because the intended mode of operation in this example is PWMOUT, soft- ware sets the TMODE field to 01 in the T_CFGR0 register to select PWM_OUT

(13)

operation. As a result, this configures TMRx pin as an output pin with its polarity determined by PULSE_HI.

1 – Generates a positive active Width Pulse waveform at TMRx pin.

0 – Generates a negative active Width Pulse waveform at TMRx pin.

This polarity is dependent on the application, but in this example, it is set to be positive active Width Pulse. As well, we initialize to generate a

PWMOUT output, and enable Timer0 interrupt requests.

ax0 = 0x001D;

/* PWM_OUT mode, Positive Active Pulse, Count to end of */

IO(T_CFGR0) = ax0;

/* period ,Int Request Enable, Timer_pin select */

Next, Period and Width register values are initialized. The user updates the high-low Period values first. Once the Period value has been updated, the user must update the high-word Width value followed by the

low-word Width value. Updating the low-word Width value is what actu- ally transfers the Period and Width values to their respective Buffers.

Note: Ensure that Period > Width value.

ax0 = 0x0262;

IO(T_PRDH0) = ax0;

/* Timer 0 Period register (high word) */

ax0 = 0x5A00;

IO(T_PRDL0) = ax0;

/* Timer 0 Period register (low word) */

ax0 = 0x0131;

IO(T_WHR0) = ax0;

/* Timer 0 Width register (high word) */

ax0 = 0x2D00;

IO(T_WLR0) = ax0;

/* Timer 0 Width register (low word) */

Because TIMEN0 is sticky, enabling the Timer0 requires a 1 to be written to bit 8 of the Timer 0 Global Status and Sticky register (T_GSR0). The Timer

(14)

starts 3 cycles after software enables it. In those three seconds, the Timer performs boundary Exception checks on the Period and Width values:

• If (Width = 0 or Period < Width or Period = Width) both OVF_ERR and TIMILx are set.

• If there are no Exceptions, the Width value is loaded in Counter and it starts counting.

Writing bit 9 of T_GSR0 disables Timer0. When disabled, the Counter and other registers retain their state. When the timer is re-enabled, the Buffers and Counter are re-initialized from the Period/Width registers based on the TMODE field in the T_CFGR0 register.

ax0 = 0x0100;

/* Enable Timer0 */

IO(T_GSR0) = ax0;

Lastly, global interrupts are enabled.

ENA INT;

/*Enable Interrupts */

RTS;

The PFx pins are toggled on/off inside the Timer0 Interrupt Service Rou- tine. The interrupt is generated when Period count expires:

AX0 = 0x000F;

AR = 0;

IOPG = General_Purpose_IO;

AX1 = DM(Timer__Flag_Polarity);

AR = TGLBIT 0x0 OF AX1;

/* Toggle Status flag */

if eq jump TURN_OFF;

/* Determine if GPIO was ON or OFF */

TURN_ON:

IO(FLAGS) = AX0;

/* Turn ON GPIOS 0, 1, 2, 3 */

DM(Timer__Flag_Polarity) = AR;

IOPG = ay1;

DIS SR;

(15)

RTI;

TURN_OFF:

IO(FLAGC) = AX0;

* Turn OFF GPIOS 0, 1, 2, 3 */

DM(Timer__Flag_Polarity) = AR;

IOPG = ay1;

DIS SR;

RTI;

In the sections that follow, code illustrates the Timer0 initialization and operation for the ADSP-2191.

Timer0 Initialization Routine

This example shows initialization code for Timer0. This routine is intended for use with the ADSP-2191 EZ-Kit Lite Evaluation Platform.

#include <def2191.h>

/*GLOBAL DECLARATIONS*/

.GLOBAL _main;

.GLOBAL Start;

/*Program memory code*/

.SECTION /pm program;

Start:

_main:

call Program_Timer_Interrupt;

/* Initialize Interrupt Priorities */

call General_Purpose_Intitialization;

/* Initialize General Purpose I/O */

call Timer_register_Initialization;

/* Initialize Timer0 */

wait_forever:

nop;

nop;

nop;

nop;

jump wait_forever;

(16)

/*INTERRUPT PRIORITY CONFIGURATION*/

.SECTION /pm program;

Program_Timer_Interrupt:

IOPG = 0;

ar=io(SYSCR); /* Map Interrupt Vector Table to Page 0*/

ar = setbit 4 of ar;

io(SYSCR)=ar;

DIS int; /* Disable all interrupts */

IRPTL = 0x0; /* Clear all interrupts */

ICNTL = 0x0; /* Interrupt nesting disable */

IMASK = 0; /* Mask all interrupts */

IOPG = Interrupt_Controller_Page;

ar = 0xBB1B; /* Assign Timer0 with priority of 1 */

io(IPR2) = ar;

ar = 0xBBBB; /* Assign remainder with lowest priority */

io(IPR0) = ar;

io(IPR1) = ar;

io(IPR3) = ar;

AY0=IMASK;

AY1=0x0020; /* Unmask Timer0 Interrupt */

AR = AY0 or AY1;

IMASK=AR;

RTS;

/*INITIALIZE GENERAL PURPOSE FLAGS*/

.SECTION /pm program;

General_Purpose_Intitialization:

IOPG = General_Purpose_IO;

AY0 = IO(DIRS);

AY0 = 0x000F; /* Configure FLAGS 0, 1, 2, and 3 as outputs */

AR = AY0 OR AY0;

IO(DIRS) = AR;

AX1 = 0x000F; /* Turn OFF FLAGS 0, 1, 2, and 3 */

IO(FLAGC) = AX1;

AX1 = 0x000F; /* Turn ON FLAGS 0, 1, 2, and 3 */

IO(FLAGS) = AX1;

RTS;

/*TIMER REGISTER INTIALIZATION*/

.SECTION /pm program;

(17)

Timer_register_Initialization:

IOPG = Timer_Page;

ax0 = 0x001D;

/* PWM_OUT mode, Positive Active Pulse, Count to end of */

IO(T_CFGR0) = ax0;

/* period ,Int Request Enable, Timer_pin select */

ax0 = 0x0262;

IO(T_PRDH0) = ax0;

/* Timer 0 Period register (high word) */

ax0 = 0x5A00;

IO(T_PRDL0) = ax0;

/* Timer 0 Period register (low word) */

ax0 = 0x0131;

IO(T_WHR0) = ax0;

/* Timer 0 Width register (high word) */

ax0 = 0x2D00;

IO(T_WLR0) = ax0;

/* Timer 0 Width register (low word) */

ax0 = 0x0100; /* Enable Timer0 */

IO(T_GSR0) = ax0;

ENA INT; /* Globally Enable Interrupts */

RTS;

Timer Interrupt Routine

This example shows a Timer interrupt service routine. This example is intended for use with the ADSP-2191 EZ-Kit Lite Evaluation Platform.

#include <def2191.h>

/* EXTERNAL DECLARATIONS*/

.EXTERN Start;

/* DM data */

.SECTION /dm data1;

.VAR counter_int5 = 0;

.VAR Timer__Flag_Polarity;

/* PM Reset interrupt vector code */

.section/pm IVreset;

jump Start;

(18)

nop; nop; nop;

/* Timer ISR*/

.section/pm IVint5;

ENA SR;

ay1 = IOPG;

IOPG = Timer_Page;

ax0 = 0x0001;

/* Clear Timer0 TIMIL0 */

IO(T_GSR0) = ax0;

ar = dm(counter_int5);

/* Interrupt counter */

ar = ar + 1;

dm(counter_int5) = ar;

Timer0_Interrupt_Handler:

AX0 = 0x000F;

AR = 0;

IOPG = General_Purpose_IO;

AX1 = DM(Timer__Flag_Polarity);

AR = TGLBIT 0x0 OF AX1;

/* Toggle Status flag */

if eq jump TURN_OFF;

/* Determine if GPIO was ON or OFF */

TURN_ON:

IO(FLAGS) = AX0;

/* Turn ON GPIOS 0, 1, 2, 3 */

DM(Timer__Flag_Polarity) = AR;

IOPG = ay1;

DIS SR;

RTI;

TURN_OFF:

IO(FLAGC) = AX0;

/* Turn OFF GPIOS 0, 1, 2, 3 */

DM(Timer__Flag_Polarity) = AR;

IOPG = ay1;

DIS SR;

RTI;

Hivatkozások

KAPCSOLÓDÓ DOKUMENTUMOK