Difference between revisions of "83Plus:Ports:30"

From WikiTI
Jump to: navigation, search
(Last I checked, the 83+SE had crystal timers too...)
(Wikified)
Line 1: Line 1:
[[Category:83Plus:Ports:By_Address|30 - Timer1 Speed]] [[Category:83Plus:Ports:By_Name|Timer1 Speed]]
+
[[Category:83Plus:Ports:By_Address|30-38 - Timers]] [[Category:83Plus:Ports:By_Name|Timers]]
 
{{SE-Only Port|10}}
 
{{SE-Only Port|10}}
{{wikify}}
 
  
 
== Synopsis ==
 
== Synopsis ==
'''Port Number:''' 30
+
'''Port Number:''' 30 - 38
  
'''Function:''' Timer1 Speed
+
'''Function:''' Timers
 +
On the 83+SE and 84+(SE) there are 3 timers that are independent of each other and each timer is controled by 3 ports, On/off, Loop control, and the counter itself. They can be used for accurate delay waiting, interrupts that execute at almost any desired frequency, or for...well...keeping time.
  
                                                                                                                                                                                                                                                             
+
{| width="40%" cellspacing="1"
Frequencies for timers on SE.
+
| width="20%" |
 +
| width="20%" bgcolor="808080" | On/Off
 +
| width="20%" bgcolor="808080" | Loop Control
 +
| width="20%" bgcolor="808080" | Counter
 +
|-
 +
| width="20%" bgcolor="808080" | Timer1
 +
| width="20%" bgcolor="C0C0C0" | 30
 +
| width="20%" bgcolor="C0C0C0" | 31
 +
| width="20%" bgcolor="C0C0C0" | 32
 +
|-
 +
| width="20%" bgcolor="808080" | Timer2
 +
| width="20%" bgcolor="C0C0C0" | 33
 +
| width="20%" bgcolor="C0C0C0" | 34
 +
| width="20%" bgcolor="C0C0C0" | 35
 +
|-
 +
| width="20%" bgcolor="808080" | Timer3
 +
| width="20%" bgcolor="C0C0C0" | 36
 +
| width="20%" bgcolor="C0C0C0" | 37
 +
| width="20%" bgcolor="C0C0C0" | 38
 +
|}
  
There seem to be some programmable timers on the 83P SE.  In fact,
 
there seem to be three of them.  The timers themselves are eight bit,
 
and with their setup ports, they run 3 ports each: from 30h to 38h.
 
The first port in each set of three is the speed/timer select port.
 
It determines which clock to use for the timer, and the frequency of
 
the timer.
 
The second port has only two bits for input.  If bit 0 is reset, the
 
timer will stop timing when it reaches zero (the timers are
 
count-down).  If bit 0 is set, it will just go on forever.  If bit 1 is
 
set, the calculator will crash when the counter expires (what this is
 
actually doing, I have no clue) ((This is probably generating an interrupt and was crashing because it was an old OS version that wasn't set up to handle it)).  If you've got it running on forever,
 
bit 2 will be set when the timer underflows.  You can check this flag
 
to see when the timer has gone through 256 cycles, and reset it by
 
outputting a value of 1 to the port again.
 
The third port is the actual timer.  On input, it just returns the
 
current value of the timer.  On output, it sets the value for the.
 
If you're just going on forever, the value doesn't matter much, but if
 
you want it to count down to zero and then stop (bit 0 of the second
 
port reset), you'll want to output the value to start from.  The
 
counter will not start automatically once you set the first two ports.
 
You must output a number to the third port for the timer to start.
 
  
 +
===On/Off ports:===
  
On the speed port, 30h, 33h, or 36h, the top two bits determine what
+
The On/Off ports are 30, 33, and 36. These ports control what clock is used for this timer and a divisor(needed since the counter is only 8bit). The upper two bits(6 & 7) tell what clock is being used. 00 if none and the timer is off, 01 for the crystal timer, and 02 for the CPU clock. 03 would suggest a combination of the cpu clock and the crystal timers, but I highly doubt it. Bits 0-5 of the On/Off ports control the divisor. For simplicity, here is a table with the output values next to the the frequencies that would be generated.
clock to use for the timer. 00 = none, 01 = xtal, 10 = CPU clock
+
11 = ???? A combination of both xtal and CPU clock?
+
When using CPU clock, it'll be either 6 MHZ or 15 MHZ, depending on
+
what speed the CPU is currently running at.
+
  
(Note: The particular program I used to test this was not very accurate
+
{| width="30%" cellspacing="1"
at very low frequencies, so the 10 HZ and 8 HZ are very rough.
+
|- bgcolor="808080"
Actually, everything is very rough, but those, more so.)
+
| width="20%" | Value
 +
| width="80%" | Frequency
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 00h
 +
| width="80%" | OFF
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | ~
 +
| width="80%" | ~
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 40h
 +
| width="80%" | 10922.67 Hz
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 41h
 +
| width="80%" | 933 Hz
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 42h
 +
| width="80%" | 100 Hz
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 43h
 +
| width="80%" | 10 Hz
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 44h
 +
| width="80%" | 32768 Hz
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 45h
 +
| width="80%" | 2048 Hz
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 46h
 +
| width="80%" | 128 Hz
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 47h
 +
| width="80%" | 8 Hz
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | ~
 +
| width="80%" | ~
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 80h
 +
| width="80%" | CPU clock speed
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 81h
 +
| width="80%" | CPU clock / 2
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 82h
 +
| width="80%" | CPU clock / 4
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 84h
 +
| width="80%" | CPU clock / 8
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 88h
 +
| width="80%" | CPU clock / 16
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | 90h
 +
| width="80%" | CPU clock / 32
 +
|- bgcolor="C0C0C0"
 +
| width="20%" | A0h
 +
| width="80%" | CPU clock / 64
 +
|}
  
xtal freqs - There are three significant bits, bits 3/4/5 don't seem
+
Since Silver Edition calculators cpu speed can be adjusted the timers will run at whatever the current CPU speed is(if selected ofcourse).
to do anything.
+
40h - 10882.56 HZ
+
41h - 990.72 HZ
+
42h - 97.28 HZ
+
43h - 10 HZ
+
44h - 32706.56 HZ (natural xtal frequency, close to 32.768 khz)
+
45h - 2042.88 HZ (close to 2048 HZ)
+
46h - 125.44 HZ (close to 128 HZ)
+
47h - 8 HZ
+
  
So....It seems to go 10000 -> 1000 -> 100 -> 10.  Then 2^15 -> 2^11 ->
 
2^7 -> 2^3.  In practice it seems that everything seems to be a small
 
bit slower than it should be "ideally", and I'm going to take the fact
 
that my 40h frequency is actually above 10K as a fluke, probably caused
 
by human error.
 
  
 +
===Loop Control ports:===
  
CPU clock freqs - These are a factor (of a power of two) of the main
+
The Loop Control ports are 31, 34, and 37.
CPU clock.
+
 
80h      - CPU
+
When bit 0 is set on this port it causes the timer to loop when the counter hits 0.  Once it does, the counter will sart back at the value you intially placed in it. To keep it looping from that value, you must output to the loop control port at every loop. If you miss one bit 2 of this port will be set, and the counter will carry to FF continue to count down.
81h      - CPU/2
+
 
82h/83h  - CPU/4
+
When bit 1 is set this timer will generate an interrupt when the counter hits 0. The interrupt must acknowledge or it will recurse upon EI. Acknowledge it by writing to the Loop contorl port. Depending on whether you have looping enabled or not, you can start the timer again by write to the counter port.
84h-87h - CPU/8
+
 
88h-8Fh  - CPU/16
+
At this point I want to stress that you must acknowledge the timers whenever the counter reaches zero. Everytime the counter hits zero the appropreiate bit is set in [[83Plus:Ports:04|port 04h]]. To reset those bits you MUST write to the loop control port, whether you have interrupts enabled or not.
90h-9Fh  - CPU/32
+
 
A0h-BFh  - CPU/64
+
 
 +
===Counter ports:===
 +
 
 +
The Counter ports are 32, 35, and 38.
 +
 
 +
Once the prior 2 ports have been setup all that is need to activate the timer is to send the desired value you wish to count down from to the counter port. However if you send 0 it will loop no matter what and it will not affect port 4, so keep it above 0.
 +
 
 +
Also note that you should turn off the timer when you are done, do this by writing 0 to the on/off port and loop control.
 +
 
 +
 
 +
== Comments ==
 +
For some reasons the timers do not seem to generate interrupts if the CPU is halt. I can only imagine that this is either a bug in the hardware or that there is more information missing. In any case, if you intend to use the crystal timers to genterate an interrupt leave the normal timers on so that you can escape any halt.
 +
 
 +
 
 +
== Example Code ==
 +
 
 +
  <nowiki> ;Setup up a timer that waits 2 seconds
 +
  di
 +
  ld a,$47      ;8 hz
 +
  out ($30),a
 +
  ld a,0        ; no loop, no interrupt
 +
  out ($31),a
 +
  ld a,16      ;16 ticks / 8 hz equals 2 seconds
 +
  out ($32),a
 +
wait:
 +
  in a,(4)
 +
  bit 5,a      ;bit 5 tells if timer 1
 +
  jr z,wait    ;is done
 +
  xor a
 +
  out ($30),a  ;Turn off the timer.
 +
  out ($31),a</nowiki>
 +
 
 +
== Credits and Contributions ==
 +
* '''Michael Vincent''': Documentation found [http://www.michaelv.org/programs/calcs/rtc.txt here].
 +
* '''James Montelongo''': Documentation found [http://www.geocities.com/jimm09876/calc/timers.html here].

Revision as of 04:24, 9 August 2005

This port only exists as a distinct port on the TI-83 Plus Silver Edition, the TI-84 Plus, and the TI-84 Plus Silver Edition. On the standard TI-83 Plus, it acts as a shadow of port 10.

Synopsis

Port Number: 30 - 38

Function: Timers On the 83+SE and 84+(SE) there are 3 timers that are independent of each other and each timer is controled by 3 ports, On/off, Loop control, and the counter itself. They can be used for accurate delay waiting, interrupts that execute at almost any desired frequency, or for...well...keeping time.

On/Off Loop Control Counter
Timer1 30 31 32
Timer2 33 34 35
Timer3 36 37 38


On/Off ports:

The On/Off ports are 30, 33, and 36. These ports control what clock is used for this timer and a divisor(needed since the counter is only 8bit). The upper two bits(6 & 7) tell what clock is being used. 00 if none and the timer is off, 01 for the crystal timer, and 02 for the CPU clock. 03 would suggest a combination of the cpu clock and the crystal timers, but I highly doubt it. Bits 0-5 of the On/Off ports control the divisor. For simplicity, here is a table with the output values next to the the frequencies that would be generated.

Value Frequency
00h OFF
~ ~
40h 10922.67 Hz
41h 933 Hz
42h 100 Hz
43h 10 Hz
44h 32768 Hz
45h 2048 Hz
46h 128 Hz
47h 8 Hz
~ ~
80h CPU clock speed
81h CPU clock / 2
82h CPU clock / 4
84h CPU clock / 8
88h CPU clock / 16
90h CPU clock / 32
A0h CPU clock / 64

Since Silver Edition calculators cpu speed can be adjusted the timers will run at whatever the current CPU speed is(if selected ofcourse).


Loop Control ports:

The Loop Control ports are 31, 34, and 37.

When bit 0 is set on this port it causes the timer to loop when the counter hits 0. Once it does, the counter will sart back at the value you intially placed in it. To keep it looping from that value, you must output to the loop control port at every loop. If you miss one bit 2 of this port will be set, and the counter will carry to FF continue to count down.

When bit 1 is set this timer will generate an interrupt when the counter hits 0. The interrupt must acknowledge or it will recurse upon EI. Acknowledge it by writing to the Loop contorl port. Depending on whether you have looping enabled or not, you can start the timer again by write to the counter port.

At this point I want to stress that you must acknowledge the timers whenever the counter reaches zero. Everytime the counter hits zero the appropreiate bit is set in port 04h. To reset those bits you MUST write to the loop control port, whether you have interrupts enabled or not.


Counter ports:

The Counter ports are 32, 35, and 38.

Once the prior 2 ports have been setup all that is need to activate the timer is to send the desired value you wish to count down from to the counter port. However if you send 0 it will loop no matter what and it will not affect port 4, so keep it above 0.

Also note that you should turn off the timer when you are done, do this by writing 0 to the on/off port and loop control.


Comments

For some reasons the timers do not seem to generate interrupts if the CPU is halt. I can only imagine that this is either a bug in the hardware or that there is more information missing. In any case, if you intend to use the crystal timers to genterate an interrupt leave the normal timers on so that you can escape any halt.


Example Code

 ;Setup up a timer that waits 2 seconds
   di
   ld a,$47      ;8 hz
   out ($30),a
   ld a,0        ; no loop, no interrupt
   out ($31),a
   ld a,16       ;16 ticks / 8 hz equals 2 seconds
   out ($32),a
wait:
   in a,(4)
   bit 5,a       ;bit 5 tells if timer 1
   jr z,wait     ;is done
   xor a
   out ($30),a   ;Turn off the timer.
   out ($31),a

Credits and Contributions

  • Michael Vincent: Documentation found here.
  • James Montelongo: Documentation found here.