*********************************************************
* 	SPI Example Code				*
* 							*
* This code is derived from the SPI setup example on 	*
* page 7-335 of the 68360 UM. 				*
*********************************************************
* 1) This code sets up the SPI				*
* 2) It sets up one transmit and one receive buffer	*
* 3) It sends the data out the SPI port.		*
*					JS 7/14/94	*
***********************************************************************
* Board Specific Equates
INIT	EQU	$0403000	; QUADS Board DRAM User Space

************************** DUAL PORT RAM ******************************
MBAR	EQU	$03FF00 ; Module Base Address, (MBAR)=REGB
*
***********************************************************************
* The following equates assume that they will be used in register
* indirect addressing.  The address register  should hold the base
* address of the QUICC internal memory.  All system equates are
* offsets into this memory
REGB	EQU	$1000	; Base address of Internal Registers
SPIPB   EQU     $0D80   ; SPI Protocol Base

************************ SIM Module registers **************************
MCR	EQU	REGB+$0000	; Module Configuration
AVR	EQU	REGB+$0008	; Auto Vector
RSR	EQU	REGB+$0009	; Reset Status
CLKOCR	EQU	REGB+$000C	; CLKO Control
PLLCR	EQU	REGB+$0010	; PLL Control
CDVCR	EQU	REGB+$0014	; Clock Divider Control
*
PEPAR	EQU	REGB+$0016	; Port E Pin Assignment
*
GMR	EQU	REGB+$0040	; Global Memory
MSTAT	EQU	REGB+$0044	; MEMC Status
*
************************ CPM Module registers *******************
*
*** SDMA
SDSR	EQU	REGB+$051C	; SDMA Status
SDCR	EQU	REGB+$051E	; SDMA Configuration Register
SDAR	EQU	REGB+$0520	; SDMA Address Register
*** CP Interrupt
CICR	EQU	REGB+$0540	; CP Interrupt Configuration
CIPR	EQU	REGB+$0544	; CP Interrupt Pending
CIMR	EQU	REGB+$0548	; CP Interrupt Mask
CISR	EQU	REGB+$054C	; CP Interrupt In-service
*** Port A, B, C
PADIR	EQU	REGB+$0550	; Port A Data Direction Assignment
PAPAR	EQU	REGB+$0552	; Port A Pin Function Assignment
PAODR	EQU	REGB+$0554	; Port A Open Drain Assignment
PADAT	EQU	REGB+$0556	; Port A Data Content
*
PBDIR	EQU	REGB+$06B8	; Port B Data Direction Assignment
PBPAR	EQU	REGB+$06BC	; Port B Pin Function Assignment
PBODR	EQU	REGB+$06C2	; Port B Open Drain Assignment
PBDAT	EQU	REGB+$06C4	; Port B Data Content
*
PCDIR	EQU	REGB+$0560	; Port C Data Direction Assignment
PCPAR	EQU	REGB+$0562	; Port C Pin Assignment
PCSO	EQU	REGB+$0564	; Port C Special Options
PCDAT	EQU	REGB+$0566	; Port C Data Content
PCINT	EQU	REGB+$0568	; Port C Interrupt Control
*** CP
CR	EQU	REGB+$05C0	; CP Command
RCCR	EQU	REGB+$05C4	; RISC Configuration
RTER	EQU	REGB+$05D6	; RISC Timer Event Register
RTMR	EQU	REGB+$05DA	; RISC Timer Mask Register
* BRG 1, 2, 3, 4
BRGC1	EQU	REGB+$05F0	; BRG1 Configuration
*** SPI
SPMODE  EQU     REGB+$06A0      ; SPI Mode
SPIE    EQU     REGB+$06A6      ; SPI Event
SPIM    EQU     REGB+$06AA      ; SPI Mask
SPCOM   EQU     REGB+$06AD      ; SPI Command
****** SPI Parameter RAM
RBASE  EQU     SPIPB+$000     ; SPI RX BD Base Address
TBASE  EQU     SPIPB+$002     ; SPI TX BD Base Address
RFCR   EQU     SPIPB+$004     ; SPI RX Function Code
TFCR   EQU     SPIPB+$005     ; SPI TX Function Code
MRBLR  EQU     SPIPB+$006     ; SPI MAX Buffer Length - RX
RSTATE EQU     SPIPB+$008     ; SPI RX Internal State
RBPRT  EQU     SPIPB+$010     ; SPI RX BD Pointer
TSTATE EQU     SPIPB+$018     ; SPI TX Internal State
TBPRT  EQU     SPIPB+$020     ; SPI TX BD Pointer

*** Serial Interface
SIMODE	EQU	REGB+$06E0	; SI Mode
SIGMR	EQU	REGB+$06E4	; SI Global Mode
SISTR	EQU	REGB+$06E6	; SI Status
SICMR	EQU	REGB+$06E7	; SI Command
SICR	EQU	REGB+$06EC	; SI Clock Routing
SIRP	EQU	REGB+$06F0	; SI RAM Pointer
SIRAM	EQU	REGB+$0700	; SI Routing RAM

************************ END of SIM/CPM Register MAP *******************

* Program Specific Equates
MBUFS	EQU	$0010		; Max Buffer Size = 16 bytes

*********
* Start of Program
*********

	ORG	INIT

*** Get Pointer to Base of DPRAM
	move.l	#7,d0		; "0111" is the function code for CPU Space
	movec	d0,SFC		; Store "0111" into both the Src Fcn Code Reg
	movec	d0,DFC		; and the Dest. Fcn Code Reg
	moves.l	MBAR,a0		; Move MBAR into a0
	move.l	a0,d0
	andi.l	#$ffffe000,d0	; Extract the base address from MBAR
	move.l	d0,a5		; Move it to a5 for register indexing


*** Set up SDMA Control Register for SCCs
	move.w	#$0740,SDCR(a5)	; SDMA interrupt service mask = 7,
*				;  bus arbit. priority = 4

*** Set up Port B Pins
* To enable SPI pins SPICLK SPIMOSI and SPIMISO configure Port B
* Note: Usually there is one more pin that is an output from the
* master and is an input into the SPISEL* pin.  The pin to be used
* for this is dependent upon board layout and is thus not covered
* here. (see p7-321,7-322 for more information on SPISEL)
	or.l	#$000E,PBPAR(a5)	; bits 1,2&3 must be 1
	and.l	#$fff1,PBODR(a5)	; bits 1,2&3 must be 0
	or.l	#$000E,PBDIR(a5)	; bits 1,2&3 must be 1
	

*** Set up General SPI Parameters 
	move.w	#$0000,RBASE(a5)	; Receive BDs start at 0(a5)
	move.w	#$0008,TBASE(a5)	; Transmit BDs start at 8(a5) 
	move.b	#$18,RFCR(a5)	; mot=1(msbyte first), rx function code = 1000
	move.b	#$18,TFCR(a5)	; mot=1(msbyte first), tx function code = 1000
	move.w	#MBUFS,MRBLR(a5)	; max. bytes per Buffer=MRBLR

**** Execute the INIT RX & TX Parameters for SPI
	move.w	#$0501,CR(a5)	; initialize transmit and receive parameter
*				; in the parameter ram of spi

*** Set up Receive BDs	for SPI
* (set the ready bit after the Buffer pointer & length is set up)
	movea.l	a5,a0			; get pointer to base of DPRAM
	adda.w	RBASE(a5),a0		; make pointer to Transmit BDs
* BD1
	move.w	#0,2(a0)		; length 13
	move.l	#RBUF0,4(a0)		; pointer to buffer #0
	move.w	#$b000,(a0)		; ready, wrap, int, 


*** Set up Transmit BDs	for SPI
* (set the ready bit after the Buffer pointer & length is set up)
	movea.l	a5,a0			; get pointer to base of DPRAM
	adda.w	TBASE(a5),a0		; make pointer to Transmit BDs
* BD1
	move.w	#5,2(a0)		; length 5
	move.l	#TBUF0,4(a0)		; pointer to buffer #0
	move.w	#$b800,(a0)		; ready, wrap, int,  Last



*** Final Set up
	move.b	#$ff,SPIE(a5)	; clear SPI event register
	move.b	#$00,SPIM(a5)	; disable all interrupts
	
 
	move.w	#$0370,SPMODE(a5)	; Loop-> Normal Operation
*					; CI= SPICLK def=low
*					; CP=0
*					; DIV16= BRGCLK=clock
*					; REVD= MSB first
*					; M/S=Master
*					; EN=Enabled
*					; Len=8 bits
*					; PM=no clock divider

* Note, this yields a burst data rate of BRGCLK/4 = 6Mbit/s. This is fine for
* bursts but the average data rate should not exceed 500 Kbps.

	ori.b	#$80,SPCOM(A5)		; start transfer by
*					; setting the start bit	
	
self	bra	self			; loop forever


*** When the SPI port is enabled, the data in the TX Buffer will be transmitted.
* At the same time, the Rx lines will be read into the area pointed to by the RX BD.


**** demo data
		ORG INIT+$2000
		
RBUF0:	ds.b	MBUFS*1			; reserve space for 1 buffer


TBUF0:	dc.b	'Frame 1 data'
		  
	END


