Submitted by:
Glenn Clark
VersaTech Electronics
To download the schematic and source code of this application note follow the link AN011.
This application note gives simple examples of setting the Xtender general purpose pins high, setting them low, and reading their input levels. In the TICkit, standard routines exist which set the pins high or set them low. These routines, pin_high() and pin_low() take a number ranging from 0 to 15 to determine which pin to act upon. The specified pin is turned into an output and the level is set according to the function name. Likewise, in the TICkit, a standard routine called pin_in() acts upon the specified pin by making it an input and then returning either 0 or 0xff depending on the level at the pin.
No such functions, or more properly commands, are implemented in the Xtender. Instead, there are commands which can be issued to the Xtender which are more similar to the TICkit's dport_get() or dport_set(), and dtris_get() or dtris_set(). The commands for the Xtender are defined in the "xtn73e.lib" file as follows:
xtn_pins_in
xtn_pins_out
xtn_pins_high
xtn_pins_low
xtn_pins
These commands use the 8 bit data pattern to set the direction or level of the Xtender's general purpose pins. The "xtn_pins" command, when issued in an i2c_read() function, will return the levels on the general purpose pins at the time of sampling. For all of the commands which deal with the general purpose pins, the data byte is NOT the number of the pin (0-7) but rather a mask of the eight pins so that each bit of the data byte corresponds to the eight general purpose pins.
The following program and circuit is just a simple example of how to use the general purpose (GP) pins of an Xtender. The program implements three push buttons to control one LED. Obviously, the program does not have a lot of real world application, but it is a simple example to draw from. The program will blink the LED very quickly, then button A will turn on the LED, button B will turn off the LED and button C will end the program and re-establish the debug link to the console.
The program to implement this hardware is as follows:
; Program to demonstrate testing and setting Xtender General Purpose Pins DEF tic57_e LIB fbasic.lib LIB xtn73e.lib GLOBAL byte trash ; throw away values from xtender FUNC none main BEGIN =( trash, i2c_read( xtn_dev0 | xtn_reset )) ; resets the xtender device. i2c_write( xtn_dev0 | xtn_pins_in, xtn_gp7 | xtn_gp6 | xtn_gp5 ) ; make the button pins inputs. i2c_write( xtn_dev0 | xtn_pins_out, xtn_gp0 ) ; make the LED pin an output. i2c_write( xtn_dev0 | xtn_pins_low, xtn_gp0 ) ; This section will turn LED1 on. Any GP pin can be controlled in this ; simply by using the appropriate pin designation as defined in the ; xtn73e.lib file. LED1 is turned on by making GP0 low. i2c_write( xtn_dev0 | xtn_pins_high, xtn_gp0 ) ; This line turns LED1 off by making the pin high. ; to test the level of a GP pin simply get the level of all the pins ; and mask out the one or ones that you want. REP IF and( i2c_read( xtn_dev0 | xtn_pins ), xtn_gp7 ) ELSE ; this statement will execute only if button A is pressed ; which causes GP 7 to be low i2c_write( xtn_dev0 | xtn_pins_low, xtn_gp0 ) ; pressing button A will turn the LED on ENDIF IF and( i2c_read( xtn_dev0 | xtn_pins ), xtn_gp6 ) ELSE ; this statement will execute only if button B is pressed ; which causes GP 6 to be low i2c_write( xtn_dev0 | xtn_pins_high, xtn_gp0 ) ; pressing button B will turn the LED off ENDIF UNTIL ==( and( i2c_read( xtn_dev0 | xtn_pins ), xtn_gp5 ), 0b ) ; this point in the program can only be reached by pressing button C REP debug_on() LOOP ENDFUN
For the sake of simplicity, the "xtn73e.lib" file is shown below. This file has been revised many times, so check the dates of your current copy. You may wish to download the ZIP file of this application and replace your current xtn73e.lib with the file in the ZIP.
; Library for Versatech Xtender - XTN73E ; standard device address DEF xtn_dev0 0x8000w DEF xtn_dev1 0x8200w DEF xtn_dev2 0x8400w DEF xtn_dev3 0x8600w DEF xtn_dev4 0x8800w DEF xtn_dev5 0x8A00w DEF xtn_dev6 0x8C00w DEF xtn_dev7 0x8E00w ; All RAM locations vary from address 00 to 7F ; Control of Interrupt pins and time bases DEF xtn_flag_enable1 0x0095w ; r/w Enables flags to effect IRQ output DEF xtn_flag_status1 0x0097w ; read Reads flag's status DEF xtn_flag_ack1 0x0097w ; write high bits reset corresponding flags DEF xtn_int_tb001 0y00000001b ; 1/100 second time base DEF xtn_int_tb01 0y00000010b ; 1/10 second time base DEF xtn_int_tb1 0y00000100b ; 1 second time base DEF xtn_int_tb10 0y00001000b ; 10 second time base DEF xtn_int_rec 0y00010000b ; RS232 byte received flag DEF xtn_int_xmit 0y00100000b ; RS232 xmit buffer full DEF xtn_int_avail 0y01000000b ; Network message received & available DEF xtn_int_sent 0y10000000b ; Network message sent & acknowledged DEF xtn_flag_enable2 0x0096w ; r/w Enables flags to effect IRQ output DEF xtn_flag_status2 0x0098w ; read Reads flag's status DEF xtn_flag_ack2 0x0098w ; write high bits reset corresponding flags DEF xtn_int_ccp1 0y00000001b ; CCP1 has generated an interrupt DEF xtn_int_ccp2 0y00000010b ; CCP2 has generated an interrupt DEF xtn_int_step 0y00000100b ; Current stepper sequence finished DEF xtn_int_tmr1 0y00001000b ; Timer1 has overflowed DEF xtn_int_neterr 0y00010000b ; A Network Error (timeout) occurred ; Control of 8 General Purpose I/O pins ; General Purpose PWM (100hz fixed frequency on GP 0,1,2,3) ; General Purpose Stepper (Unipolar phases on GP 4,5,6,7) (limits on GP 2,3) DEF xtn_pins 0x0080w ; r/w Directly controls output levels DEF xtn_tris 0x0081w ; r/w Directly controls direction (1=input) DEF xtn_pins_low 0x009Bw ; write high bits make GP pins low, others unchanges DEF xtn_pins_high 0x009Cw ; write high bits make GP pins high, others unchanges DEF xtn_pins_out 0x009Dw ; write high bits make GP pins output, others unchanges DEF xtn_pins_in 0x009Ew ; write high bits make GP pins input, others unchanges DEF xtn_buf_levels 0x009Bw ; reads output buffer levels (not pin levels) DEF xtn_gp0 0y00000001b ; mask for GP0 DEF xtn_gp1 0y00000010b ; mask for GP1 DEF xtn_gp2 0y00000100b ; mask for GP2 DEF xtn_gp3 0y00001000b ; mask for GP3 DEF xtn_gp4 0y00010000b ; mask for GP4 DEF xtn_gp5 0y00100000b ; mask for GP5 DEF xtn_gp6 0y01000000b ; mask for GP6 DEF xtn_gp7 0y10000000b ; mask for GP7 DEF xtn_gp_cont 0x009Fw ; r/w bits 0,1,2,3 enable pwm on GP 0,1,2,3 DEF xtn_pwme_0 0y00000001b ; enables pwm output on GP 0 DEF xtn_pwme_1 0y00000010b ; enables pwm output on GP 1 DEF xtn_pwme_2 0y00000100b ; enables pwm output on GP 2 DEF xtn_pwme_3 0y00001000b ; enables pwm output on GP 3 DEF xtn_stepen 0y00010000b ; enables step phase outputs on GP 4567 DEF xtn_stepgo 0y00100000b ; execute step sequence, unconditional DEF xtn_steplo 0y01000000b ; execute step until GP4 goes low DEF xtn_stephi 0y10000000b ; execute step until GP5 goes high DEF xtn_pwm_0 0x00A0w ; r/w Sets PWM high time in 1/25600 second DEF xtn_pwm_1 0x00A1w ; r/w Sets PWM high time in 1/25600 second DEF xtn_pwm_2 0x00A2w ; r/w Sets PWM high time in 1/25600 second DEF xtn_pwm_3 0x00A3w ; r/w Sets PWM high time in 1/25600 second DEF xtn_step_curlow 0x00A4w ; r/w Current Stepper Sequence Count low DEF xtn_step_curhigh 0x00A5w ; r/w Current Stepper Sequence Count high DEF xtn_step_curper 0x00A6w ; r/w Current Step Seq period in 1/6400 sec. DEF xtn_step_nextlow 0x00A7w ; r/w Next Stepper Sequence Count low DEF xtn_step_nexthigh 0x00A8w ; r/w Next Stepper Sequence Count high DEF xtn_step_nextper 0x00A9w ; r/w Next Step Seq period in 1/6400 sec. ; 5 channel A/D converter DEF xtn_ad_con 0x0082w ; write A/D control register DEF xtn_ad_pwr 0y00000001b ; powers resistive ladder (always 1) DEF xtn_ad_vref 0y00000010b ; voltage ref select (0=internal) DEF xtn_ad_chan0 0y00000100b ; channel select 0 DEF xtn_ad_chan1 0y00001100b ; channel select 1 DEF xtn_ad_chan2 0y00010100b ; channel select 2 DEF xtn_ad_chan3 0y00011100b ; channel select 3 DEF xtn_ad_chan4 0y00100100b ; channel select 4 DEF xtn_ad_reg 0x0082w ; read A/D result register ; Timer 1 (16bit counter) can use with CCP capture or compare functions DEF xtn_tmr1_con 0x0083w ; r/w control register DEF xtn_tmr1_en 0y00000001b ; enable counting on timer1 DEF xtn_tmr1_srce 0y00000010b ; 1=external clock, 0=osc/4 DEF xtn_tmr1_pre 0y00001100b ; prescale value ( 1,2,4,8 ) DEF xtn_tmr1_low 0x0087w ; r/w count low (read captures register) DEF xtn_tmr1_high 0x0088w ; r/w count high (write sets register) ; Timer 2 (8bit counter with 8bit period register) can use with CCP PWM functions DEF xtn_tmr2_con 0x0084w ; r/w control register DEF xtn_tmr2_pre 0y00000011b ; prescale value ( 1, 4, 16, 16 ) DEF xtn_tmr2_en 0y00000100b ; enable counting on timer2 DEF xtn_tmr2_post 0y01111000b ; postscale division value ( 1 to 16 ) DEF xtn_tmr2_reg 0x0085w ; r/w count (8bit) DEF xtn_tmr2_per 0x0086w ; r/w period (8bit) ; Capture/Compare/PWM section #1 ( use with timer1 or timer2 ) DEF xtn_ccp1_con 0x0089w ; r/w control register DEF xtn_ccp1_off 0y00000000b ; ccp1 off DEF xtn_ccp1_cfall 0y00000100b ; capture on every falling edge DEF xtn_ccp1_crise 0y00000101b ; capture on every rising edge DEF xtn_ccp1_cri4 0y00000110b ; capture on every 4th rising edge DEF xtn_ccp1_cri16 0y00000111b ; capture on every 16th rising edge DEF xtn_ccp1_comp1 0y00001000b ; compare output 1 on match DEF xtn_ccp1_comp0 0y00001001b ; compare output 0 on match DEF xtn_ccp1_compi 0y00001010b ; compare generate interrupt match DEF xtn_ccp1_compc 0y00001011b ; compare clear timer1 on match DEF xtn_ccp1_pwm 0y00001100b ; pwm on output use res. for 10bit DEF xtn_ccp1_10bit 0y00110000b ; mask for 10 lsbs of 10bit pwm DEF xtn_ccp1_low 0x008Bw ; r/w register low (read captures register) DEF xtn_ccp1_high 0x008Cw ; r/w register high (write sets register) ; Capture/Compare/PWM section #2 ( use with timer1 or timer2 ) DEF xtn_ccp2_con 0x008Aw ; r/w control register DEF xtn_ccp2_off 0y00000000b ; ccp2 off DEF xtn_ccp2_cfall 0y00000100b ; capture on every falling edge DEF xtn_ccp2_crise 0y00000101b ; capture on every rising edge DEF xtn_ccp2_cri4 0y00000110b ; capture on every 4th rising edge DEF xtn_ccp2_cri16 0y00000111b ; capture on every 16th rising edge DEF xtn_ccp2_comp1 0y00001000b ; compare output 1 on match DEF xtn_ccp2_comp0 0y00001001b ; compare output 0 on match DEF xtn_ccp2_compi 0y00001010b ; compare generate interrupt match DEF xtn_ccp2_compa 0y00001011b ; compare A/D conv on match (not implemented) DEF xtn_ccp2_pwm 0y00001100b ; pwm on output use res. for 10bit DEF xtn_ccp2_10bit 0y00110000b ; mask for 10 lsbs of 10bit pwm DEF xtn_ccp2_low 0x008Dw ; r/w register low (read captures register) DEF xtn_ccp2_high 0x008Ew ; r/w register high (write sets register) ; Clock counter (1/100 second and 32bit elapsed seconds count) DEF xtn_clk_tic 0x008Fw ; r/w 1/100 seconds (read captures count) DEF xtn_clk_cnt0 0x0090w ; r/w count byte 0, least significant byte DEF xtn_clk_cnt1 0x0091w ; r/w count byte 1 DEF xtn_clk_cnt2 0x0092w ; r/w count byte 2 DEF xtn_clk_cnt3 0x0093w ; r/w count byte 3 (write sets count) ; RS232 and Network section DEF xtn_xmit_buf 0x0094w ; writes data to xmit buffer of rs232 and Net DEF xtn_rec_buf 0x0094w ; reads data from rec buffer of rs232 and Net DEF xtn_xmit_stat 0x0099w ; write sets buffer format/ reads xmit status DEF xtn_xstat_bcnt 0y00001111b ; xmit buffer count DEF xtn_xstat_over 0y00010000b ; buffer overflow flag (used internal) DEF xtn_xstat_empt 0y00100000b ; xmit buffer is empty DEF xtn_xstat_pckt 0y01000000b ; network packet is being sent DEF xtn_xstat_mode 0y10000000b ; buffer mode 1=16 or 8 byte xmit buff ; buffer mode 0=net, or 16 rec buffer ; xtn_rstat_mode determines entire mode DEF xtn_rec_stat 0x009Aw ; write sets buffer format/ read rec status DEF xtn_rstat_bcnt 0y00001111b ; receive buffer count DEF xtn_rstat_over 0y00010000b ; buffer overrun flag DEF xtn_rstat_empt 0y00100000b ; framing error has occurred DEF xtn_rstat_pckt 0y01000000b ; network packet has been received DEF xtn_rstat_mode 0y10000000b ; buffer mode 1=16 or 8 byte rec buff ; buffer mode 0=net, or 16 xmit buffer ; xtn_rstat_mode determines entire mode DEF xtn_baud_64 0x00AAw ; write sets baud divisor with /64 prescaler DEF xtn_b64_1200 255b DEF xtn_b64_2400 127b DEF xtn_b64_4800 63b DEF xtn_b64_9600 31b DEF xtn_b64_19k 15b DEF xtn_b64_38k 7b DEF xtn_b64_76k 3b DEF xtn_b64_153k 2b DEF xtn_b64_307k 1b DEF xtn_b64_614k 0b DEF xtn_b64_31k 39b ; Midi 1% error DEF xtn_b64_115k 10b ; IBM max rate 3% error DEF xtn_baud_div 0x00AAw ; read current divisor DEF xtn_baud_16 0x00ABw ; write sets baud divisor with /16 prescaler DEF xtn_baud_pre 0x00ABw ; read prescaler (0=div64, 255=div16) DEF xtn_net_dest 0x00AEw ; writes Destination for the net packet, ; read initiates packet send DEF xtn_net_source 0x00AFw ; writes to this register reset byte pointer ; of current received net packet and enables ; reception of next packet. ; reads of this register inform of the source ; of the network packet just received. DEF xtn_net_address 0x00B0w ; r/w sets the network node address of this ; I2C net adapter. Only values of 1 to 127 ; should be used. DEF xtn_net_status 0x00B1w ; r/w shows current status of network adapter DEF xtn_nstat_wait 0y00000001b ; waiting for data reception DEF xtn_nstat_ack 0y00001000b ; acknowledge byte DEF xtn_nstat_src 0y00010000b ; source/dest or checksum/data DEF xtn_nstat_dat 0y00100000b ; data/header DEF xtn_nstat_tran 0y01000000b ; Transmit packet DEF xtn_nstat_ign 0y10000000b ; ignore net activity until marker ; Miscellaneous Xtender functions DEF xtn_revision 0x009Dw ; reads current revision of Xtender DEF xtn_reset 0x009Ew ; reads current revision and resets Xtender DEF xtn_sin_angle 0x009Cw ; write sin angle, 0-255 ~~ 0-89.95 degrees DEF xtn_sin_radius 0x009Cw ; reads sin radius, 0-255 ~~ 0 to almost 1 DEF xtn_atn_ratio 0x009Dw ; write atn ratio, 0-255 ~~ 0 to almost 1 DEF xtn_atn_angle 0x009Dw ; read atn angle, 0-255 ~~ 0-45 degrees
Protean Logic Inc. Copyright 05/06/04 Top of Page