please dont rip this site

Scenix Lib IO Dev Modem SIMPLE_FSK_GEN_1_03.SRC

; ******************************************************************************
; Copyright © [12/09/1998] Scenix Semiconductor, Inc. All rights reserved.
;
; Scenix Semiconductor, Inc. assumes no responsibility or liability for
; the use of this [product, application, software, any of these products].
; Scenix Semiconductor conveys no license, implicitly or otherwise, under
; any intellectual property rights.
; Information contained in this publication regarding (e.g.: application,
; implementation) and the like is intended through suggestion only and may
; be superseded by updates. Scenix Semiconductor makes no representation
; or warranties with respect to the accuracy or use of these information,
; or infringement of patents arising from such use or otherwise.
;******************************************************************************
;
;	Designed for use with Scenix Modem Rev 1.2
;
; 	Filename:	simple_fsk_gen_1_03.src
;
; 	Authors:	Chris Fogelklou
;			Applications Engineer	
;			Scenix Semiconductor, Inc.
;	
;	Revision:	1.03
;
; 	Part:		SX28AC datecode 9929AA/ SX52BD datecode AB9919AA
; 	Freq:		50Mhz
;
; 	Compiled using Parallax SX-Key software v1.07 and SASM 1.40
;
;       Date Written: 	December 9, 1998
;	Last Revised: 	November 22, 1999
;
;	Program Description
;	This program demonstrates a simple FSK modulation scheme.  It contains
;	no UART, so the baud rate of the FSK modulation is set by the external
; 	Terminal's UART.  It simply converts high data to a low frequency
;	and low data to a high frequency.  The analog voltage is generated by
;	a 1-pin PDM D/A, and the sine wave values are generated by an artificial
;	sine wave generator.  This program could be improved by adding a UART to
;	the program, and sending the data out after it has been received.  Using
;	this method, the data can be manipulated.
;
;	The FSK modulation constants for other FSK standards besides bell202 are
;	also supported, but most require a baud rate generator and flow control.
;
;	BELL202:	   Supported with other BELL202 Modems.
;	V.23 Answer Mode:  Supported using a 1200bps connection to the modem board,
;			   but won't be autodetected because it doesn't output 2100Hz
;			   answer tone for 3 seconds after picking up.
;	V.23 Originate Mode: Can't be supported because requires a 75bps baud rate
;			   generator.
;	BELL103 Originate Mode: Supported using a 300bps connection to the board.
;			   must use another device to dial out.
;	BELL103 Answer Mode: Supported using a 300bps connection to the modem board,
;			   but can't be auto-detected for the same reasons as the
;			   V.23 Answer mode.
;
;	Uncomment the desired modulation type:
;
BELL202			
;V23_ORIGINATE_MODE
;V23_ANSWER_MODE		
;BELL103_ORIGINATE_MODE
;BELL103_ANSWER_MODE
;
; 	Revision History:
;	1.01 & 1.02:  Documentation Updates.
;	1.03: Updated for new SX template, and Modem Boards, Rev 1.2
;
;	Pins Used:
;		PDM_pin		equ	ra.0	; D/A output pin, connect to filter circuitry
;		rx_pin		equ	ra.1	; RS-232 reception pin
;		tx_pin		equ	ra.2	; RS-232 transmission pin, received characters
;						; are echoed on this pin.
;		led_pin		equ	rb.0	; LED pin... Flashes when characters are received
;		hook		equ	rb.4	; drive hook low to go off-hook
;		cts		equ	rb.7	; indicates to the PC that the SX is ready to 
;						; receive data
;
;******************************************************************************
;*****************************************************************************************
; Target SX
; Uncomment one of the following lines to choose the SX18AC, SX20AC, SX28AC, SX48BD/ES,
; SX48BD, SX52BD/ES or SX52BD. For SX48BD/ES and SX52BD/ES, uncomment both defines,
; SX48_52 and SX48_52_ES.
;*****************************************************************************************
;SX18_20
SX28
;SX48_52
;SX48_52_ES

;*****************************************************************************************
; Assembler Used
; Uncomment the following line if using the Parallax SX-Key assembler. SASM assembler
; enabled by default.
;*****************************************************************************************
;SX_Key

	;*********************************************************************************
	; Assembler directives:
	;	high speed external osc, turbo mode, 8-level stack, and extended option reg.
	;
	;	SX18/20/28 - 4 pages of program memory and 8 banks of RAM enabled by default.
	;	SX48/52 - 8 pages of program memory and 16 banks of RAM enabled by default.
	;                
	;*********************************************************************************

IFDEF SX_Key 				;SX-Key Directives
  IFDEF SX18_20				;SX18AC or SX20AC device directives for SX-Key
		device	SX18L,oschs2,turbo,stackx_optionx
  ENDIF
  IFDEF SX28				;SX28AC device directives for SX-Key		
		device	SX28L,oschs2,turbo,stackx_optionx
  ENDIF
  IFDEF SX48_52_ES			;SX48BD/ES or SX52BD/ES device directives for SX-Key
		device	oschs,turbo,stackx,optionx
  ELSE
    IFDEF SX48_52				;SX48/52/BD device directives for SX-Key
		device	oschs2
    ENDIF
  ENDIF
		freq	50_000_000
ELSE  					;SASM Directives
  IFDEF SX18_20				;SX18AC or SX20AC device directives for SASM
		device	SX18,oschs2,turbo,stackx,optionx
  ENDIF
  IFDEF SX28				;SX28AC device directives for SASM
		device	SX28,oschs2,turbo,stackx,optionx
  ENDIF
  IFDEF SX48_52_ES			;SX48BD/ES or SX52BD/ES device directives for SASM
		device	SX52,oschs,turbo,stackx,optionx
  ELSE
    IFDEF SX48_52			;SX48BD or SX52BD device directives for SASM
		device	SX52,oschs2  
    ENDIF
  ENDIF
ENDIF
		ID	'FSK_TX10'			; Version = 1.01

		reset	reset_entry				; JUMP to start label on reset


;*****************************************************************************************
; Macros
;*****************************************************************************************
	;*********************************************************************************
	; Macro: _bank
	; Sets the bank appropriately for all revisions of SX.
	;
	; This is required since the bank instruction has only a 3-bit operand, it cannot
	; be used to access all 16 banks of the SX48/52. For this reason FSR.4 (for SX48/52BD/ES)
	; or FSR.7 (SX48/52bd production release) needs to be set appropriately, depending
	; on the bank address being accessed. This macro fixes this.
	;
	; So, instead of using the bank instruction to switch between banks, use _bank instead.
	; 
	;*********************************************************************************
_bank	macro	1
	bank	\1

	IFDEF SX48_52
	  IFDEF SX48_52_ES
	    IF \1 & %00010000		;SX48BD/ES and SX52BD/ES (engineering sample) bank instruction
		setb	fsr.4		;modifies FSR bits 5,6 and 7. FSR.4 needs to be set by software.
	    ENDIF
	  ELSE
	    IF \1 & %10000000		;SX48BD and SX52BD (production release) bank instruction 
		setb	fsr.7		;modifies FSR bits 4,5 and 6. FSR.7 needs to be set by software.
	    ELSE
		clrb	fsr.7
	    ENDIF
	  ENDIF
	ENDIF
	endm


	;*********************************************************************************
	; Macro: _mode
	; Sets the MODE register appropriately for all revisions of SX.
	;
	; This is required since the MODE (or MOV M,#) instruction has only a 4-bit operand. 
	; The SX18/20/28AC use only 4 bits of the MODE register, however the SX48/52BD have 
	; the added ability of reading or writing some of the MODE registers, and therefore use
	; 5-bits of the MODE register. The  MOV M,W instruction modifies all 8-bits of the 
	; MODE register, so this instruction must be used on the SX48/52BD to make sure the MODE
	; register is written with the correct value. This macro fixes this.
	;
	; So, instead of using the MODE or MOV M,# instructions to load the M register, use
	;  _mode instead.
	; 
	;*********************************************************************************
_mode	macro	1
	IFDEF SX48_52
		mov	w,#\1		;loads the M register correctly for the SX48BD and SX52BD
		mov	m,w
	ELSE
		mov	m,#\1		;loads the M register correctly for the SX18AC, SX20AC
					;and SX28AC
	ENDIF
	endm

	;*****************************************************************************************
	; Error generating macros
	;*****************************************************************************************

tableStart	macro 0			; Generates an error message if code that MUST be in
					; the first half of a page is moved into the second half.
	if $ & $100
		ERROR  'Must be located in the first half of a page.'
	endif
endm

tableEnd	macro 0			; Generates an error message if code that MUST be in
					; the first half of a page is moved into the second half.
	if $ & $100
		ERROR  'Must be located in the first half of a page.'
	endif
endm

;*****************************************************************************************
; Data Memory address definitions
; These definitions ensure the proper address is used for banks 0 - 7 for 2K SX devices
; (SX18/20/28) and 4K SX devices (SX48/52). 
;*****************************************************************************************
IFDEF SX48_52

global_org	=	$0A
bank0_org	=	$00
bank1_org	=	$10
bank2_org	=	$20
bank3_org	=	$30
bank4_org	=	$40
bank5_org	=	$50
bank6_org	=	$60
bank7_org	=	$70

ELSE

global_org	=	$08
bank0_org	=	$10
bank1_org	=	$30
bank2_org	=	$50
bank3_org	=	$70
bank4_org	=	$90
bank5_org	=	$B0
bank6_org	=	$D0
bank7_org	=	$F0

ENDIF
;*****************************************************************************************
; Global Register definitions
; NOTE: Global data memory starts at $0A on SX48/52 and $08 on SX18/20/28.
;*****************************************************************************************
		org     global_org

	flags0		equ	global_org + 0  ; bit-storage register
	flags1		equ	global_org + 1	; bit-storage register 2
	localTemp0	equ	global_org + 2	; temporary storage register
	localTemp1	equ	global_org + 3	; temporary storage register		
	localTemp2	equ	global_org + 4	; temporary storage register
	isrTemp0	equ	global_org + 5	; Interrupt Service Routine's temp register.  
						; Don't use this register in the mainline.


;*****************************************************************************************
; RAM Bank Register definitions
;*****************************************************************************************

	;*********************************************************************************
	; Bank 0
	;*********************************************************************************
		org     bank0_org

bank0		=	$
	

	;*********************************************************************************
	; Bank 1
	;*********************************************************************************
		org     bank1_org

bank1		=	$

;VP: artificial sine generation

sin_gen_bank	=	$

freq_acc_low	ds	1	; 16-bit accumulator which decides when to increment the sine wave
freq_acc_high	ds	1	; 
freq_count_low	ds	1	; 16-bit counter which decides which frequency for the sine wave
freq_count_high	ds	1	; freq_count = Frequency * 6.83671552
sin		ds	1	; The current value of the imitation sin wave
sinvel		ds	1	; The velocity of the sin wave

;VP: PDM D/A VP

PDM_bank		=	$
	
PDM0_acc		ds	1		; PDM accumulator
PDM0_out		ds	1		; current PDM output (D/A)


	;*********************************************************************************
	; Bank 2
	;*********************************************************************************
		org     bank2_org

bank2		=	$


	;*********************************************************************************
	; Bank 3
	;*********************************************************************************
		org     bank3_org

bank3		=	$


	;*********************************************************************************
	; Bank 4
	;*********************************************************************************
		org     bank4_org

bank4		=	$


	;*********************************************************************************
	; Bank 5
	;*********************************************************************************
		org     bank5_org

bank5		=	$

	;*********************************************************************************
	; Bank 6
	;*********************************************************************************
		org     bank6_org

bank6		=	$


	;*********************************************************************************
	; Bank 7
	;*********************************************************************************
		org     bank7_org

bank7		=	$


IFDEF SX48_52
	;*********************************************************************************
	; Bank 8
	;*********************************************************************************
		org	$80	;bank 8 address on SX52

bank8		=	$


	;*********************************************************************************
	; Bank 9
	;*********************************************************************************
		org	$90	;bank 9 address on SX52

bank9		=	$


	;*********************************************************************************
	; Bank A
	;*********************************************************************************
		org	$A0	;bank A address on SX52

bankA		=	$


	;*********************************************************************************
	; Bank B
	;*********************************************************************************
		org	$B0	;bank B address on SX52

bankB		=	$


	;*********************************************************************************
	; Bank C
	;*********************************************************************************
		org	$C0	;bank C address on SX52

bankC		=	$


	;*********************************************************************************
	; Bank D
	;*********************************************************************************
		org	$D0	;bank D address on SX52

bankD		=	$


	;*********************************************************************************
	; Bank E
	;*********************************************************************************
		org	$E0	;bank E address on SX52

bankE		=	$


	;*********************************************************************************
	; Bank F
	;*********************************************************************************
		org	$F0	;bank F address on SX52

bankF		=	$


ENDIF
		
	;*********************************************************************************
	; Pin Definitions:  These are the pins on the Scenix Modem board.  Not all are
	; 			necessary.  Check the documentation at the top of this 
	;			program.
	;*********************************************************************************
PDM_pin		equ	ra.0	; D/A output pin
rx_pin		equ	ra.1	; RS-232 reception pin
tx_pin		equ	ra.2	; RS-232 transmission pin
nothing		equ	ra.3	; N/C
RA_latch	equ	%11111111		;SX18/20/28/48/52 port A latch init
RA_DDIR		equ	%11111010		;SX18/20/28/48/52 port A DDIR value
RA_LVL		equ	%00000000		;SX18/20/28/48/52 port A LVL value
RA_PLP		equ	%11111111		;SX18/20/28/48/52 port A PLP value

led_pin		equ	rb.0	; LED pin
rxa_pin		equ	rb.1	; FSK receive pin
cntrl_1		equ	rb.2	; drive cntrl_1 low to disable the output of the LPF
ring		equ	rb.3	; ring detection pin
hook		equ	rb.4	; drive hook low to go off-hook
cntrl_3		equ	rb.5	; drive cntrl_3 low to disable the output of the HPF
rts		equ	rb.6	; indicates to the SX that the PC wants to transmit data
cts		equ	rb.7	; indicates to the PC that the SX is ready to receive data
RB_latch	equ	%11011011		;SX18/20/28/48/52 port B latch init
RB_DDIR		equ	%01101110		;SX18/20/28/48/52 port B DDIR value
RB_ST		equ	%11111111		;SX18/20/28/48/52 port B ST value
RB_LVL		equ	%00000000		;SX18/20/28/48/52 port B LVL value
RB_PLP		equ	%11111111		;SX18/20/28/48/52 port B PLP value

dtmf_in_pin	equ	rc.0	; DTMF input pin
dtmf_fdbk_pin	equ	rc.1	; Negative feedback output for DTMF input
AtoD_in_pin	equ	rc.2	; A/D input pin
AtoD_fdbk_pin	equ	rc.3	; Negative feedback for A/D input
imp_450_pin	equ	rc.4	; Set to an output to set hybrid for 450ohm line impedance.  Tristate otherwise.
imp_600_pin	equ	rc.5	; Set to an output to set hybrid for 600ohm line impedance.  Tristate otherwise.
imp_750_pin	equ	rc.6	; Set to an output to set hybrid for 750ohm line impedance.  Tristate otherwise.
imp_900_pin	equ	rc.7	; Set to an output to set hybrid for 900ohm line impedance.  Tristate otherwise.
RC_latch	equ	%00001111		;SX18/20/28/48/52 port C latch init
RC_DDIR		equ	%11010101		;SX18/20/28/48/52 port C DDIR value
RC_ST		equ	%11111111		;SX18/20/28/48/52 port C ST value
RC_LVL		equ	%00000000		;SX18/20/28/48/52 port C LVL value
RC_PLP		equ	%11111111		;SX18/20/28/48/52 port C PLP value

IFDEF SX48_52	;SX48BD/52BD Port initialization values
RD_latch	equ	%00000000		;SX48/52 port D latch init
RD_DDIR		equ	%11111111		;SX48/52 port D DDIR value
RD_ST		equ	%11111111		;SX48/52 port D ST value
RD_LVL		equ	%00000000		;SX48/52 port D LVL value
RD_PLP		equ	%11111111		;SX48/52 port D PLP value

RE_latch	equ	%00000000		;SX48/52 port E latch init
RE_DDIR		equ	%11111111		;SX48/52 port E DDIR value
RE_ST		equ	%11111111		;SX48/52 port E ST value
RE_LVL		equ	%00000000		;SX48/52 port E LVL value
RE_PLP		equ	%11111111		;SX48/52 port E PLP value
ENDIF

;*****************************************************************************************
; Program constants
;*****************************************************************************************
;-------------------------------------------------------------------------------------
; The constant = 2^n * Ts * FREQ, 
; where n is the number of bits in the phase accumulator for each
; signal generator, Ts is the sample rate, and FREQ is the desired
; output frequency.
; We know that the phase accumulator (freq_count) is 16 bits, and each
; time that the phase accumulator rolls over, the sine wave is advanced
; another of 32 states, giving an effective bit count in the phase
; accumulator of 21, so n = 21
; We will choose a phase update rate of 306.7kHz for the FSK Generation
; = 1/([cyclesperinterupt] * [instructiontime] * [ISR passes]) 
; = 1/(163 * 20ns * 1 passes)
; Therefore, the constant = 2^n * (1/Fs) * FREQ
; Convert the result of the calculation to a hexadecimal number and load
; the upper byte into the freq_count_high register and the lower byte
; into the freq_count_low register.
;-------------------------------------------------------------------------------------
;VP: FSK Generation using the artificial sine generator

f390_l		equ	$6a	; V.23 originating mode channel logic '1' (mark)
f390_h		equ	$0a
f450_l		equ	$04	; V.23 originating mode channel logic '0' (space)
f450_h		equ	$0c
f1300_l		equ	$b7	; V.23 answer mode & Bell202 channel logic '1' (mark)
f1300_h		equ	$22
f2100_l		equ	$15	; V.23 answer mode & Bell202 channel logic '0' (space)
f2100_h		equ	$38
f2225_l		equ	$6b	; Bell 103 answer mode channel logic '1' (mark)
f2225_h		equ	$3b
f2025_l		equ	$14	; Bell 103 answer mode channel logic '0' (space)
f2025_h		equ	$36
f1270_l		equ	$ea	; Bell 103 originating mode channel logic '1' (mark)
f1270_h		equ	$21
f1070_l		equ	$93	; Bell 103 originating mode channel logic '0' (space)
f1070_h		equ	$1c

IFDEF	V23_ORIGINATE_MODE
	F0_l	equ	f450_l
	F0_h	equ	f450_h
	F1_l	equ	f390_l
	F1_h	equ	f390_h
	;----------------------------------------------------
	; *** Sample_rate/128 = 9600/128 = 75bps
	;----------------------------------------------------
	fsk_tx_baud_bit	=       7			;
ENDIF
IFDEF	V23_ANSWER_MODE
	F0_l	equ	f2100_l
	F0_h	equ	f2100_h
	F1_l	equ	f1300_l
	F1_h	equ	f1300_h
	;----------------------------------------------------
	; *** Sample_rate/8 = 9600/8 = 75bps
	;----------------------------------------------------
	fsk_tx_baud_bit	=       3			;
ENDIF
IFDEF	BELL202
	F0_l	equ	f2100_l
	F0_h	equ	f2100_h
	F1_l	equ	f1300_l
	F1_h	equ	f1300_h
	;----------------------------------------------------
	; *** Sample_rate/8 = 9600/8 = 75bps
	;----------------------------------------------------
	fsk_tx_baud_bit	=       3			;
ENDIF
IFDEF	BELL103_ORIGINATE_MODE
	F0_l	equ	f1070_l
	F0_h	equ	f1070_h
	F1_l	equ	f1270_l
	F1_h	equ	f1270_h
	;----------------------------------------------------
	; *** Sample_rate/128 = 9600/32 = 300bps
	;----------------------------------------------------
	fsk_tx_baud_bit	=       5			;
ENDIF
IFDEF	BELL103_ANSWER_MODE
	F0_l	equ	f2025_l
	F0_h	equ	f2025_h
	F1_l	equ	f2225_l
	F1_h	equ	f2225_h
	;----------------------------------------------------
	; *** Sample_rate/128 = 9600/32 = 300bps
	;----------------------------------------------------
	fsk_tx_baud_bit	=       5			;
ENDIF
	
;VP:  Interrupt Setup.
;-------------------------------------------------------------------------------------
int_period	equ	163		; Gives an interrupt period at 50MHz of (163 * (1/50000000)s) = 3.26us
					; Which gives an interrupt frequency of (1/3.26u)Hz = 306.75kHz
;-------------------------------------------------------------------------------------
IFDEF SX48_52
	;*********************************************************************************
	; SX48BD/52BD Mode addresses
	; *On SX48BD/52BD, most registers addressed via mode are read and write, with the
	; exception of CMP and WKPND which do an exchange with W.
	;*********************************************************************************
; Timer (read) addresses
TCPL_R		equ	$02		;Read Timer Capture register low byte
TCPH_R		equ	$02		;Read Timer Capture register high byte
TR2CML_R	equ	$02		;Read Timer R2 low byte
TR2CMH_R	equ	$03		;Read Timer R2 high byte
TR1CML_R	equ	$04		;Read Timer R1 low byte
TR1CMH_R	equ	$05 		;Read Timer R1 high byte
TCNTB_R		equ	$06		;Read Timer control register B
TCNTA_R		equ	$07		;Read Timer control register A

; Exchange addresses
CMP		equ	$08		;Exchange Comparator enable/status register with W
WKPND		equ	$09		;Exchange MIWU/RB Interrupts pending with W

; Port setup (read) addresses
WKED_R		equ	$0A		;Read MIWU/RB Interrupt edge setup, 0 = falling, 1 = rising
WKEN_R		equ	$0B		;Read MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_R		equ	$0C		;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_R		equ	$0D		;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_R		equ	$0E		;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_R		equ	$0F		;Read Port Direction

; Timer (write) addresses
TR2CML_W	equ	$12		;Write Timer R2 low byte
TR2CMH_W	equ	$13		;Write Timer R2 high byte
TR1CML_W	equ	$14		;Write Timer R1 low byte
TR1CMH_W	equ	$15 		;Write Timer R1 high byte
TCNTB_W		equ	$16		;Write Timer control register B
TCNTA_W		equ	$17		;Write Timer control register A

; Port setup (write) addresses
WKED_W		equ	$1A		;Write MIWU/RB Interrupt edge setup, 0 = falling, 1 = rising
WKEN_W		equ	$1B		;Write MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_W		equ	$1C		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_W		equ	$1D		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_W		equ	$1E		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_W		equ	$1F		;Write Port Direction

ELSE

	;*********************************************************************************
	; SX18AC/20AC/28AC Mode addresses
	; *On SX18/20/28, all registers addressed via mode are write only, with the exception of
	; CMP and WKPND which do an exchange with W.
	;*********************************************************************************
; Exchange addresses
CMP		equ	$08		;Exchange Comparator enable/status register with W
WKPND		equ	$09		;Exchange MIWU/RB Interrupts pending with W

; Port setup (read) addresses
WKED_W		equ	$0A		;Write MIWU/RB Interrupt edge setup, 0 = falling, 1 = rising
WKEN_W		equ	$0B		;Write MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_W		equ	$0C		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_W		equ	$0D		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_W		equ	$0E		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_W		equ	$0F		;Write Port Direction
ENDIF


;*****************************************************************************************
; Program memory ORG defines
;*****************************************************************************************

INTERRUPT_ORG		equ	$0	; Interrupt must always start at location zero
RESET_ENTRY_ORG		equ	$1FB	; The program will jump here on reset.
MAIN_PROGRAM_ORG	equ	$600	; The main program is in the last page of program memory.




































;****************************** Beginning of program space *******************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
	org	INTERRUPT_ORG			; First location in program memory.
;------------------------------------------------------------------------------
; Interrupt Service Routine
;------------------------------------------------------------------------------
; Note: The interrupt code must always originate at address $0.
;
; Interrupt Frequency = (Cycle Frequency / -(retiw value))  For example:
; With a retiw value of -163 and an oscillator frequency of 50MHz, this
; code runs every 3.26us.
;------------------------------------------------------------------------------
ISR					;3	The interrupt service routine...

;VP: PDM D/A Conversion

PDM_output

	;------------------------------------------------------------------------------
	; Virtual Peripheral: Jitter-Free, Deterministic Pulse Density Modulation
	;
	;	Input variable(s): PDM0_out:  	Value from 0 - 255 corresponding to DC
	;					voltage
	;	Output variable(s): 		Ra.0 pin is PDM output pin
	;	Variable(s) affected: 		PDM0_acc variable
	;	Flag(s) affected: 		None
	;	Program Cycles:			11 cycles (turbo mode)
	;------------------------------------------------------------------------------
	_bank	PDM_bank		;1		; Update the PDM pin
	
	add	PDM0_acc,PDM0_out	;2,3		; set PDM pin if carry
	snc				;1,4	
	jmp	:set_pin		;1,5 or 3,7 (carry)
:clear_pin
	nop				;1,6		; clear PDM pin (no carry)
	nop				;1,7
	clrb	PDM_pin			;1,8
	jmp	:PDM_out		;3,11

:set_pin				;7		; set PDM pin (carry)
	setb	PDM_pin			;1,8
	jmp	:PDM_out		;3,11

:PDM_out				; 11 PDM cycles total.
;------------------------------------------------------------------------------
; TOTAL CYCLE COUNT: 14
;------------------------------------------------------------------------------
	;------------------------------------------------------------------------------
	; Virtual Peripheral: Artificial Sine Wave Generation
	;
	;	Input variable(s): 		freq_count_l, freq_count_h
	;	Output variable(s): 		sin,w returned as current value of sine
	;					wave.
	;	Variable(s) affected: 		freq_acc_high, freq_acc_low, sinvel, sin
	;	Flag(s) affected: 		None
	;	Program Cycles:			20 cycles worst case(turbo mode)
	;	Variable Length?:		Yes
	;------------------------------------------------------------------------------
		_bank	sin_gen_bank	;1

		mov	w,freq_count_low;1
		add	freq_acc_low,w	;1	;advance sine at frequency
		sc			;1
		jmp	:no_carry	;1,3	; if lower byte rolls over
		inc	freq_acc_high	;1	; carry over to upper byte
		sz			;1
		jmp	:no_carry	;1,3	; if carry causes roll-over
		mov	w,freq_count_high;1
		mov	freq_acc_high,w	;1	; then add freq counter to accumulator (which should be zero,
						; so move will work)
						; and update sine wave
		jmp	:change_sin	;3
:no_carry				
		mov	w,freq_count_high;1
		add	freq_acc_high,w	;1	; add the upper bytes of the accumulators
		sc			;1
		jmp	:no_change	;1,14
:change_sin

					; 14 cycles at this point
		mov	w,++sinvel	;1	; if the velocity of sine
		sb	sin.7		;1	; is positive, accelerate
		mov	w,--sinvel	;1	; it.  Otherwise, decelerate it.
		mov	sinvel,w	;1	
		add	sin,w		;1,19	; add the velocity to sin

:no_change
		
sine_generator_out
		mov	w,sin		;1,20 cycles worst case
;------------------------------------------------------------------------------
; TOTAL CYCLE COUNT: 14 + 20wc	=	34 cycles worst case
;------------------------------------------------------------------------------
		_bank	PDM_bank	;1
		mov	PDM0_out,w	;1	; mov the value of SIN into the PDM output
		mov	w,#128		;1
		add	PDM0_out,w	;1 add 128 to put it in the center of the PDM output

;------------------------------------------------------------------------------
ISR_out					; ISR goes here when finished.
;------------------------------------------------------------------------------

isr_end						;3
		mov	w,#-int_period		;1   ; refresh RTCC on return
		retiw				;3,7 ; return from the interrupt
						;    ; = 1/(int_period*RTCC prescaler*1/50MHz)
						;    ; = 1/(163*1*20ns) = 3.26us
;*****************************************************************************************
; End of the Interrupt Service Routine
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************









;*****************************************************************************************
org	RESET_ENTRY_ORG
;*****************************************************************************************
;------------------------------------------------------------------------------
reset_entry					; Program starts here on power-up
	page	_reset_entry
	jmp	_reset_entry
;------------------------------------------------------------------------------




;*****************************************************************************************
org	MAIN_PROGRAM_ORG
;*****************************************************************************************
;*****************************************************************************************
; RESET VECTOR 
;*****************************************************************************************

	;*********************************************************************************
	; Program execution begins here on power-up or after a reset
	;*********************************************************************************
_reset_entry		
	;*********************************************************************************
	; Initialise all port configuration
	;*********************************************************************************

		_mode	ST_W			;point MODE to write ST register
		mov     w,#RB_ST            	;Setup RB Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rb,w		
		mov     w,#RC_ST            	;Setup RC Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rc,w	
IFDEF SX48_52
		mov     w,#RD_ST            	;Setup RD Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rd,w		
		mov     w,#RE_ST            	;Setup RE Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!re,w		
ENDIF
		_mode	LVL_W			;point MODE to write LVL register
		mov     w,#RA_LVL            	;Setup RA CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!ra,w		 
		mov     w,#RB_LVL            	;Setup RB CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!rb,w		
		mov     w,#RC_LVL            	;Setup RC CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!rc,w	
IFDEF SX48_52
		mov     w,#RD_LVL            	;Setup RD CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!rd,w		
		mov     w,#RE_LVL            	;Setup RE CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!re,w		
ENDIF
		_mode	PLP_W			;point MODE to write PLP register
		mov     w,#RA_PLP            	;Setup RA Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!ra,w		 
		mov     w,#RB_PLP            	;Setup RB Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rb,w		
		mov     w,#RC_PLP            	;Setup RC Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rc,w	
IFDEF SX48_52
		mov     w,#RD_PLP            	;Setup RD Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rd,w		
		mov     w,#RE_PLP            	;Setup RE Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!re,w		
ENDIF
		_mode	DDIR_W			;point MODE to write DDIR register
		mov	w,#RA_DDIR		;Setup RA Direction register, 0 = output, 1 = input		
		mov	!ra,w	
		mov	w,#RB_DDIR		;Setup RB Direction register, 0 = output, 1 = input
		mov	!rb,w			
		mov	w,#RC_DDIR		;Setup RC Direction register, 0 = output, 1 = input
		mov	!rc,w			
IFDEF SX48_52
		mov	w,#RD_DDIR		;Setup RD Direction register, 0 = output, 1 = input
		mov	!rd,w			
		mov	w,#RE_DDIR		;Setup RE Direction register, 0 = output, 1 = input
		mov	!re,w			
ENDIF
		mov     w,#RA_latch          	;Initialize RA data latch
		mov     ra,w		
		mov     w,#RB_latch         	;Initialize RB data latch
		mov     rb,w		
		mov     w,#RC_latch          	;Initialize RC data latch
		mov     rc,w		
IFDEF SX48_52
		mov     w,#RD_latch         	;Initialize RD data latch
		mov     rd,w			
		mov     w,#RE_latch         	;Initialize RE data latch
		mov     re,w			
ENDIF


	;*********************************************************************************
	; Clear all Data RAM locations
	;*********************************************************************************
zero_ram
IFDEF SX48_52   				;SX48/52 RAM clear routine
		mov	w,#$0a			;reset all ram starting at $0A
		mov	fsr,w
:zero_ram	clr	ind			;clear using indirect addressing
		incsz	fsr			;repeat until done
		jmp	:zero_ram

		_bank	bank0			;clear bank 0 registers
		clr	$10
		clr	$11
		clr	$12
		clr	$13
		clr	$14
		clr	$15
		clr	$16
		clr	$17
		clr	$18
		clr	$19
		clr	$1a
		clr	$1b
		clr	$1c
		clr	$1d
		clr	$1e
		clr	$1f

ELSE     					;SX18/20/28 RAM clear routine
		clr	fsr			;reset all ram banks
:zero_ram	sb	fsr.4			;are we on low half of bank?
		setb	fsr.3			;If so, don't touch regs 0-7
		clr	ind			;clear using indirect addressing
		incsz	fsr			;repeat until done
		jmp	:zero_ram
ENDIF
	;*********************************************************************************
	; Initialize program/VP registers
	;*********************************************************************************


	;*********************************************************************************
	; Setup and enable RTCC interrupt, WREG register, RTCC/WDT prescaler
	;*********************************************************************************

RTCC_ON		=	%10000000	;Enables RTCC at address $01 (RTW hi)
					;*WREG at address $01 (RTW lo) by default
RTCC_ID		=	%01000000	;Disables RTCC edge interrupt (RTE_IE hi)
					;*RTCC edge interrupt (RTE_IE lo) enabled by default
RTCC_INC_EXT	=	%00100000	;Sets RTCC increment on RTCC pin transition (RTS hi)
					;*RTCC increment on internal instruction (RTS lo) is default
RTCC_FE		=	%00010000	;Sets RTCC to increment on falling edge (RTE_ES hi)
					;*RTCC to increment on rising edge (RTE_ES lo) is default
RTCC_PS_ON	=	%00000000	;Assigns prescaler to RTCC (PSA lo)
RTCC_PS_OFF	=	%00001000	;Assigns prescaler to WDT (PSA lo)
PS_000		=	%00000000	;RTCC = 1:2, WDT = 1:1
PS_001		=	%00000001	;RTCC = 1:4, WDT = 1:2
PS_010		=	%00000010	;RTCC = 1:8, WDT = 1:4
PS_011		=	%00000011	;RTCC = 1:16, WDT = 1:8
PS_100		=	%00000100	;RTCC = 1:32, WDT = 1:16
PS_101		=	%00000101	;RTCC = 1:64, WDT = 1:32
PS_110		=	%00000110	;RTCC = 1:128, WDT = 1:64
PS_111		=	%00000111	;RTCC = 1:256, WDT = 1:128

OPTIONSETUP	equ	RTCC_PS_OFF|PS_111	; the default option setup for this program.
		jmp	@main

;*****************************************************************************************
; MAIN PROGRAM CODE 
;*****************************************************************************************

	;*********************************************************************************
	; Main
	;*********************************************************************************
main		
		_bank	sin_gen_bank			
;		mov	sin,#32			; init variables.  A sine starts at 1, a cos wave starts at 0. 
;		mov	sinvel,#0		
		mov	sin,#-4			; use these values for a wave which is 90 degrees out of phase.
		mov	sinvel,#-8

		clrb	CTS			; enable transmission from the PC if hardware flow
						; control is enabled.
		mov	w,#OPTIONSETUP		; setup option register for RTCC interrupts enabled 
		mov	!option,w		; and no prescaler.
	
		_bank	sin_gen_bank
		mov	freq_count_high,#f2100_h; output a frequency of 2100Hz
		mov	freq_count_low,#f2100_l	; (bell202)

		clrb	hook			; go off-hook
		jb	rx_pin,$		; wait until data is received (Start bit is a low)

		mov	w,#OPTIONSETUP		; setup option register for RTCC interrupts enabled 
		mov	!option,w		; and no prescaler.
		
		clrb	hook			; go off-hook
main_loop
		jb	rx_pin,:rx_is_high	; If the rs_232 receive pin is currently a low

:rx_is_low	clrb	led_pin			; Turn the LED on
		clrb	tx_pin			; Echo the character
		mov	freq_count_high,#f0_h	; output a frequency of 2100Hz
		mov	freq_count_low,#f0_l	; (bell202)
		jmp	main_loop			
:rx_is_high	setb	led_pin			; Else turn the LED off
		setb	tx_pin			; turn Echo the character
		mov	freq_count_high,#f1_h	; output a frequency of 1300Hz
		mov	freq_count_low,#f1_l	; (bell202)
		jmp	main_loop			



;*****************************************************************************************
END		;End of program code
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************


file: /Techref/scenix/lib/io/dev/modem/simple_fsk_gen_1_03.SRC, 38KB, , updated: 2002/4/11 12:05, local time: 2024/11/14 08:32,
TOP NEW HELP FIND: 
18.225.55.210:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://linistepper.com/Techref/scenix/lib/io/dev/modem/simple_fsk_gen_1_03.SRC"> scenix lib io dev modem simple_fsk_gen_1_03</A>

Did you find what you needed?