8XC196KR: Using the A/D Scan Mode
ABSTRACT:
This techbit describes one implementation of the A/D scan mode using the PTS on the 8XC196KR. The PTS cycles are initiated by the A/D Done interrupt. The example shown, uses the A/D Done interrupt to trigger consecutive PTS cycles.
1.0 Introduction
The A/D scan mode is one of several modes available when using the Peripheral Transaction Server (PTS). The other modes are Single Transfer, Block transfer, PWM Toggle, and PWM Remap.
As the name suggests, this mode supports A/D conversions. As such, the PTS cycles are usually triggered by the AD_DONE interrupt pending bit. However, any interrupt can be used to start PTS cycles. The PTS starts new A/D conversions and stores the result using minimal CPU overhead.
The primary benefit from using A/D scan mode is the time saved compared to using a normal interrupt. Other advantages are:
- More uniform latency time from setting AD_DONE to start of conversion.
- Less code when performing multiple conversions.
- Higher priority than an interrupt.
The PTS responds to interrupts faster than using interrupt service routines but many factors still influence PTS latency. An enabled PTS will interrupt a normal interrupt service routine but not another PTS cycle in progress. The users manual gives a complete description of various components that affect the PTS latency. The A/D Scan mode does not decrease the amount of time required for each A/D conversion.
2.0 A/D Scan Mode Description
The A/D Scan mode uses the PTS to store the result of a completed A/D conversion and load AD_COMMAND. These two tasks constitute a PTS cycle. The user programs the number of PTS cycles to execute in the PTS Control Block (PTSCB). The maximum count is 256 cycles. The count decrements after each PTS cycle. The PTS clears the PTSSEL bit and sets the PTSSRV bit when the count reaches 0. PTSSEL selects whether the PTS or an interrupt service routine handles the interrupt.
The PTS sets PTSSRV to indicate the end of the PTS cycles and the PTS needs servicing. Setting PTSSRV causes the following process to occur:
- The controller fetches the interrupt vector for the interrupt serviced by the PTS.
- The program branches to the interrupt service routine.
- The interrupt service routine should service the PTS. This may include leaving the PTS disabled.
The A/D Scan mode uses two command/data structures, the PTSCB and the Command/Data table. The PTSCB identifies which mode the PTS operates in, the number of PTS cycles, and where to retrieve and store data. The A/D Command/Data table stores results from completed conversions and contains A/D commands. Sections 2.1 and 2.2 describe the PTSCB and A/D Command/Data table.
Interrupts initiate PTS transfers and allow data manipulation without software intervention. Software is used only for initialization and when the count equals 0. During the initialization the user must set up the interrupts, PTSCB, Command/Data Table, and enable the PTS. When the PTS count equals 0 an interrupt service routine takes over. In the service routine the user can re-enable the PTS, reinitialize the pointer, and/or load the counter. This allows the PTS to start over, continue from where it left off, or be disabled.
2.1 PTSCB
This description of the PTSCB assumes the A/D Scan mode will be used for A/D conversions. Figure 1 shows the A/D Scan mode PTSCB format. Some PTSCBs contain 8 bytes but this mode only uses 6. The PTSCB must be quad word aligned (divisible by 8) and located in Register RAM. The least significant byte of the PTSCB, in this case PTSCOUNT, determines alignment. The two unused bytes above PTS_PTR2 (high) are treated as normal register RAM.
PTS_PTR2 points to the A/D_RESULT SFR (1FAAH).
PTS_PTR1 is a pointer that identifies where to retrieve the A/D command or store the A/D result (A/D Command/Data table).
PTSCOUNT determines how many cycles will occur before setting the PTSSRV bit and disabling the PTS. The maximum number of cycles is 256.
To set up the PTSCB, PTS_PTR1 must point to an A/D command in the command/data table and PTS_PTR2 points to AD_RESULT. Load PTSCOUNT with the number of A/D results to be stored. Two temporary registers (TEMP1 and TEMP2) are used. These are not SFRs or part of the PTSCB and are inaccessible to the user.
2.2 A/D Command/Data Table
The Command/Data table consists of A/D commands and interleaved blank entries. The PTS fills in the blanks later. Figure 2 shows an example of a Command/Data table. The last A/D command is all 0s to prevent any further conversions from starting. Allocate the space for the A/D Command/Data table somewhere in RAM as the PTS must store the results. Normally, ROM is the source for the commands loaded into a table in RAM during initialization.
There is no limit to the size of the table. It can range from 1 command up to the maximum amount of data memory available. The table can reside in internal or external RAM. Since the A/D scan mode uses the PTS, a maximum of 256 conversions can be completed before generating an interrupt. When the interrupt occurs, user software must service the PTS Control Block (PTSCB) but this does not limit the table length.
The PTS loads the AD_COMMAND SFR with the lower 8 bits retrieved from the table. The upper 8 bits are not used. The A/D Command table entries determine:
- the A/D channel to be converted -
0-7
- when the conversion begins -
now or by an EPA channel
- type of conversion -
8 or 10 bit
- Normal conversion -
mandatory
Figure 3 shows the format of the A/D command.
3.0 A/D Scan Mode Operation
The steps the PTS goes through during a PTS cycle are:
- Store PTS_PTR1 in TEMP1 (TEMP1=n)
- Fetch the word pointed to by TEMP1 (an A/D command) and store in TEMP2
- Increment TEMP1 by two (TEMP1=n+2)
- Fetch the word pointed to by PTS_PTR2 (AD_RESULT) and store at the address in TEMP1 (n+2)
- Increment TEMP1 by two (TEMP1=n+4)
- Load TEMP2 (holding the A/D command) into the SFR, AD_COMMAND
- If the update bit in PTS_CONTROL equals 1, load PTS_PTR1 with TEMP1 (PTS_PTR1=n+4) (will fetch next command)
- If the update bit equals 0, leave PTS_PTR1 unchanged (PTS_PTR1=n) (will fetch same command)
- decrement PTSCOUNT
If PTSCOUNT does not equal 0, the PTS waits for the next AD_DONE interrupt. If PTSCOUNT=0, the PTS clears PTSSEL and sets PTSSRV. The interrupt service routine must then:
- Reinitialize PTSCOUNT
- Load PTS_PTR1
- Set PTSSEL
The user can implement any combination of these three tasks or do nothing. Not doing #3 leaves the PTS disabled.
3.1 Flow Chart
(See last page for flow chart.)
4.0 Implementation
Breaking down the A/D Scan mode into individual steps makes it easier to implement. The steps described are:
- Setting up the PTS Control Block
- Setting up the Command/Data table
- Starting the first A/D conversion
- Responding to the PTS interrupt
- Ending the A/D Scan mode
Steps 1 and 2 can be done in any order. Steps 3, 4, and 5 must be done in the sequence shown.
4.1 Setting up the PTSCB
As shown in figure 1, the PTSCB consists of: the PTSCOUNT, PTS_CONTROL, PTS_PTR1, and PTS_PTR2. The only restrictions are that the PTSCB be quad word aligned (divisible by 8) and reside in register RAM.
PTSCOUNT - determines how many PTS cycles will execute before setting an interrupt pending bit. A 0 in PTSCOUNT means that 256 PTS cycles will occur. If performing less than 256 A/D conversions, then load that number. If executing 256 or more conversions, then load 0. If completing greater than 256 conversions, the interrupt service routine must set PTSSEL and implement a loop counter. The loop counter tracks the number of times the count underflows. When the last loop occurs, the user loads PTSCOUNT with the remaining number of conversions. Also load every 256th command with 0.
PTS_CONTROL - determines the PTS mode. In A/D scan mode the only option is whether to update the source address at the end of each PTS cycle. Figure 4 shows the format of the PTS_CONTROL byte.
Initially, the PTS reads the pointers into temporary registers (TEMP1 or TEMP2). With increment set and B#/W = 1, the value in the temporary register increases by two for every access. When update is set, any changes made to the temporary register are saved in the pointer after completing the PTS cycle. If update is cleared, the pointer is unchanged.
A note of caution when using RL-96: Make the base address for the PTSCB absolute as there is no directive to insure quad word alignment.
4.2 Setting up the Command/Data Table
The Command/Data table is usually loaded from ROM. For instance, a group of A/D commands are stored in ROM. When initializing the device, transfer the string of commands from ROM into RAM. The pointer used to store the data into RAM is incremented twice for each incrementation of the pointer to ROM. An example of code that would do this is:
Initialize:
Ld ROM_POINTER, #ROM_TABLE_ADDRESS
Ld RAM_POINTER, #COMMAND_DATA_TABLE
Ld COUNTER, #COMMAND_COUNT
Command_Data_Table_Load:
Ld TEMP_WORD,[ROM_POINTER]+
St TEMP_WORD,[RAM_POINTER]+
Inc RAM_POINTER
Djnzw COUNTER,Command_Data_Table_Load
The PTS only loads the lower 8 bits of data into the SFR, A/D_COMMAND. The format of the data is:
A/D CHANNEL - Channel number (0 through 7) to be converted
GO - 0 = Start by EPA, 1 = Start now
MODE - 0 = 10-bit conversion, 1 = 8-bit conversion
TD - Must be 1 when using A/D scan mode for normal conversions.
Bit 6,7 - 0
To convert each A/D input with 10-bit results the data stored in ROM is:
ROM_TABLE_ADDRESS:
00101001B | ;Convert channel 1 |
00101010B | ;Convert channel 2 |
00101011B | ;Convert channel 3 |
00101100B | ;Convert channel 4 |
00101101B | ;Convert channel 5 |
00101110B | ;Convert channel 6 |
00101111B | ;Convert channel 7 |
00000000B | ;Stop further conversions |
Note that the sequence starts with channel 1 and ends with all 0s. Start the first conversion under software control using channel 0. On completion of the first conversion, the PTS takes over starting with channel 1. After all eight channels convert, no further conversions will start.
4.3 Starting the first A/D Conversion
Start the first A/D conversion under program control. Loading AD_COMMAND initiates a conversion. The user has the choice of starting conversions immediately (GO = 1) or later (GO = 0). If GO equals 0, an EPA channel starts the conversion. The user must start the first conversion because the AD_DONE interrupt initiates the PTS cycles.
4.4 Responding to the PTS Interrupt
When the PTSCOUNT reaches 0, PTSSRV.5 is set and PTSSEL.5 is cleared. PTSSRV.5 = 1 generates a conventional interrupt to the AD_DONE interrupt service routine. In the AD_DONE service routine, the user initializes the PTS to execute more A/D conversions or leaves the PTS disabled. The steps required to reinitialize the PTS for more conversions are:
- initialize PTSCOUNT
- Set PTSSEL.5
- Load PTSPTR1
- Starting the next (first) A/D conversion
Steps 1,2, and 3 are optional, step 4 is necessary.
4.5 Ending the A/D Scan mode
The final A/D conversion occurs when PTSCOUNT reaches 0. Completion of the last conversion clears the PTSSEL bit and disables the PTS. The user does not need to do anything else to end the A/D Scan mode but it is good practice to disable the A/D interrupt. Clearing the PTSSEL bit and A/D interrupt enable with software also ends the A/D Scan mode.
5.0 Example
$debug errorprint xref
;***************************************************
;** This program is the first example program **
;** for the A/D Scan mode tech bit. **
;** REV 1.0 6/4/91 **
;***************************************************
$NOLIST
$INCLUDE (KR.INC)
$LIST
PUBLIC START
AD_PTSCOUNT equ 10H ;do 16 a/d conversions
AD_PTSCONTROL equ 11001011B
AD_PTSPTR1 equ AD_RESULT
AD_PTSPTR2 equ 6000H ;must equal address of
command_start
AD_COMMAND0 equ 00011000B ;norm conv, 8-bit, start now,ch0
AD_COMMAND1 equ 00000000B ;no conv
AD_TIME_LOAD equ 0A6H ;value to load into AD_TIME register
rseg at 50H
ad_pts: dsb 6 ;must be quad word aligned
rseg
temp0: dsw 1
temp1: dsw 1
pntr0: dsw 1
pntr1: dsw 1
cseg at 200AH
dcw ad_done_isr
cseg at 204AH
dcw ad_pts
cseg
START: ;Initialize for A/D Scan Mode
AD_TABLE_LOAD:
Ld temp0,#ad_ptscount ;number of commands to load
Ld pntr0,#ad_command_data
Ld pntr1,#command_start
AD_TABLE_LOOP:
Ld temp1,[pntr0]+ ;loop until command/data table
St temp1,[pntr1]+ ;filled
Inc pntr1
Inc pntr1 ;increment twice to skip blank
Djnz temp0,ad_table_loop
PTSCB_LOAD:
Ld pntr0,#ad_pts_table
Ld pntr1,#ad_pts
Ld temp0,#6 ;number of bytes in PTSCB
PTSCB_LOOP:
Ldb temp1,[pntr0]+ ;loop until PTSCB filled
Stb temp1,[pntr1]+
Djnz temp0,ptscb_loop
Ldb temp0,#ad_time_load
Stb temp0,ad_time ;load AD_TIME register
Stb zero_reg,ad_test ;clear AD_TEST register
Ldb temp0,int_mask
orb temp0,#00100000B
Stb temp0,int_mask ;enable AD_DONE interrupt
Ld temp0,ptssel
Or temp0,#0000000000100000B
Stb temp0,ptssel ;enable A/D PTS servicing
Ei ;enable interrupts
Epts ;enable PTS
Br main_start
AD_DONE_ISR:
Br $ ;loop forever when pts count=0
nop
nop
MAIN_START:
Ldb temp0,#ad_command0
Stb temp0,ad_command ;start first A/D conversion on Ch0
MAIN_LOOP:
Br $ ;loop until interrupt or
;pts cycle occurs
nop
nop
AD_COMMAND_DATA:
cseg
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command0
dcw AD_Command1
AD_PTS_TABLE:
dcb 10H
dcb 11001011B
dcw command_start
dcw ad_result
dseg at 6000H
COMMAND_START:
dsw 32 ;save storage space for 16 commands/results
end
* Legal Information © 1999 Intel Corporation