⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_tc.s

📁 ATMELurl通用应用一例,可在不同开发中用
💻 S
字号:
;------------------------------------------------------------------------------
;-			ATMEL Microcontroller Software Support  -  ROUSSET -
;------------------------------------------------------------------------------
;- File source				: spi_tc.s
;- Librarian				: Not applicable
;- Translator				: ARM Software Development Toolkit V2.11
;-
;- Treatments				: SPI software emulator using TC channels 1 and 2.
;-
;- Imported Resources   : None
;- Exported Resources   : 
;- 	spi_tc_init
;-		spi_tc_transfer
;-
;- 1.0 JCZ 19/06/98		: Creation
;------------------------------------------------------------------------------

				AREA			AsmCode, CODE, READONLY, INTERWORK

; -------------------------- List of Included Files ---------------------------

				INCLUDE		tc.inc
				INCLUDE		pio.inc

; ------------------------ List of constants and types ------------------------

MR1_INIT		EQU		WAVE:OR:TC_XC1:OR:BURST_XC2:OR:EEVT_XC0
MR2_INIT		EQU		TC_MCK2:OR:WAVE:OR:EEVT_XC0:OR:CPCTRG:OR:ACPA_SET:OR:BCPC_SET:OR:ASWTRG_SET:OR:BSWTRG_SET

; SPI pins definition
TCLK2			EQU		(&1<<6)
TIOA2			EQU		(&1<<7)
TIOB2			EQU		(&1<<8)

MISO			EQU		TCLK2
MOSI			EQU		TIOB2
SCK			EQU		TIOA2

; Baud rate by Default
BAUD_RATE	EQU		0x10

; ------------------------ List of Imported resources -------------------------
; None

; ------------------------ List of Internal resources -------------------------
PtTCBBase
				DCD		TCBBase
PtPIOBase
				DCD		PIOBase
PtMR1Init
				DCD		MR1_INIT
PtMR2Init
				DCD		MR2_INIT

; ------------------------ List of Exported resources -------------------------

;------------------------------------------------------------------------------
;- Function				: spi_tc_init
;- Treatments			: SPI Initialization function.
;- Input Parameters	:
;-			r0 = Register C Value : period in number of twice MCK period
;- Output Parameters	: None
;- Registers lost		: None
;- Called Functions	: None
;- Called Macros		: None
;------------------------------------------------------------------------------
				EXPORT	spi_tc_init
;- Begin
spi_tc_init
				ldr		r1, PtTCBBase
				ldr		r2, PtPIOBase

;- | Configure SPI lines as PIO
				mov		r3, #MOSI:OR:SCK
				str		r3, [r2, #PIO_SODR]
				str		r3, [r2, #PIO_OER]
				mov		r3, #MOSI:OR:SCK:OR:MISO
				str		r3, [r2, #PIO_PER]

;- | TCC 1 and 2 : Disable current state
;- | . Disable all interrupts
				mov		r3, #0xFF
				str		r3, [r1, #(1*TC_SIZE)+TC_IDR]
				str		r3, [r1, #(2*TC_SIZE)+TC_IDR]
;- | . Disable the clock
				mov		r3, #CLKDIS
				str		r3, [r1, #(1*TC_SIZE)+TC_CCR]
				str		r3, [r1, #(2*TC_SIZE)+TC_CCR]

;- | Initialise TCC1 :
;- | . Enable TIOA2 (SCK) as the channel clock
				mov		r3, #XC1_TIOA2
				str		r3, [r1, #TC_BMR]
;- | . Initialize the Mode Register
				ldr		r3, PtMR1Init
				str		r3, [r1, #(1*TC_SIZE)+TC_CMR]
;- | . Enable and trig the clock
				mov		r3, #CLKEN:OR:SWTRG
				str		r3, [r1, #(1*TC_SIZE)+TC_CCR]

;- | Set Default baud rate (1Mbit/sec @ 32MHz) if applicable
				cmp		r0, #0
				moveq		r0, #BAUD_RATE

;- | Initialise TCC2 :
;- | . Setup the Mode Register
				ldr		r3, PtMR2Init
				str		r3, [r1, #(2*TC_SIZE)+TC_CMR]
;- | . Initialize the A, B and C counter registers
				str		r0, [r1, #(2*TC_SIZE)+TC_RC]
				mov		r3, r0, LSR #1
				str		r3, [r1,#(2*TC_SIZE)+TC_RA]
;- | . Enable the clock and trig to set the output signals
				mov		r3, #CLKEN:OR:SWTRG
				str		r3, [r1, #(2*TC_SIZE)+TC_CCR]
;- | . Disable the clock
				mov		r3, #CLKDIS
				str		r3, [r1, #(2*TC_SIZE)+TC_CCR]

;- | Configure SPI lines as peripheral
				mov		r3, #MOSI:OR:SCK:OR:MISO
				str		r3, [r2, #PIO_PDR]

;- End
				mov		pc, r14

;------------------------------------------------------------------------------
;- Function				: spi_tc_transfer
;- Treatments			: SPI Transfer function.
;- Input Parameters	:
;-		r0 = Address of Data to be transmitted
;-		r1 = Address of Data to be received
;-		r2 = Number of bits to transfer
;- Output Parameters	: None
;- Registers lost		: None
;- Called Functions	: None
;- Called Macros		: None
;------------------------------------------------------------------------------
;- During treatment :
;-		r0  = Address of Data to be transmitted
;-		r1  = Address of Data to be received
;-		r2  = Number of bits to transfer
;-		r3  = Current sent byte
;-		r4  = Current received byte
;-		r5  = Tx Transfer Bit Mask
;-		r6  = Rx Transfer Bit Mask
;-		r7  = TC2 Mode register with BCPC to set TIOB
;-		r8  = TC2 Mode register with BCPC to clear TIOB
;-		r9  = TC2 Mode register with TIOA and TIOB set
;-		r10 = TC1 counter register
;-		r11 = TC Block Base Address
;-		r14 = Working register
;-----------------------------------------------------------------------------
                        EXPORT  spi_tc_transfer
;- Begin
spi_tc_transfer
				stmdb		sp!, {r4-r11,r14}

;- | Get TC Block Base Address
				ldr		r11, PtTCBBase

;- | Save the current value of Timer Counter 1
				ldr		r10, [r11, #(1*TC_SIZE)+TC_CV]

;- | Initialize the Tx and Rx Masks
				ldr		r5, =0x80808080
				mov		r6, r5

;- | SCK falling edge at software trig and RC Compare
				ldr		r7, [r11, #(2*TC_SIZE)+TC_CMR]
				bic		r7, r7, #ASWTRG
				orr		r7, r7, #ASWTRG_CLEAR
				orr		r7, r7, #ACPC_CLEAR

;- | Calculate Mode Register values to set or clear data
				bic		r7, r7, #BCPC
				orr		r8, r7, #BCPC_CLEAR
				orr		r7, r7, #BCPC_SET

;- | Initialize the received byte (0)
				mov		r4, #0

;- | Get first byte to transmit
				ldrb		r3, [r0], #1

;- | TIOB (MOSI) set/cleared at SWTRG following first bit
				ands		r14, r3, r5
				bic		r14, r7, #BSWTRG
				orreq		r14, r14, #BSWTRG_CLEAR
				orrne		r14, r14, #BSWTRG_SET
				str		r14, [r11, #(2*TC_SIZE)+TC_CMR]

;- | Read TC2 Status (clear events)
				ldr		r14, [r11, #(2*TC_SIZE)+TC_SR]

;- | Enable and trig TC2 Clock
				mov		r14, #(CLKEN | SWTRG)
				str		r14, [r11, #(2*TC_SIZE)+TC_CCR]

;- | While (all bits not transfered)
				b			RepeatEnd										; 3
RepeatBegin1
;- | | If bit before last one
;- | | | force TIOA2 (SCK) unchanged at RC compare
				biceq		r7, r7, #ACPC							; 1
				moveq		r8, r7									; 1
;- | | Endif
RepeatBegin2

;- | | Prepare next Tx bit : Right Shift Tx Mask
				movs		r5, r5, ROR #1									; 1
;- | | If (last bit of the byte)
;- | | | get next byte
				ldrcsb	r3, [r0], #1									; 3
;- | | EndIf

;- | | Wait RA compare (rising edge of SCK)
WaitSCKhigh
				ldr		r14, [r11, #(2*TC_SIZE)+TC_SR]			; 3
				ands		r14, r14, #CPAS								; 1
				beq		WaitSCKhigh										; 3 (worst)

;- | | TIOB (MOSI) set/cleared at next RC compare following current bit
				ands		r14, r3, r5										; 1
				streq		r8, [r11, #(2*TC_SIZE)+TC_CMR]			; 2
				strne		r7, [r11, #(2*TC_SIZE)+TC_CMR]			; 2

;- | | If (TC1 Counter Value modified)
				mov		r14, r10											; 1
				ldr		r10, [r11, #(1*TC_SIZE)+TC_CV]			; 3
				cmp		r14, r10											; 1
;- | | | Set Rx Data Bit (current bit set)
				orrne		r4, r4, r6										; 1
;- | | EndIf

;- | | Prepare next bit to receive : Right Shift Rx Mask
				movs		r6, r6, ROR #1									; 1
;- | | If (last bit of the byte)
;- | | | store byte
				strcsb	r4, [r1], #1									; 2
;- | | | Initialize the received byte (0)
				movcs		r4, #0											; 1
;- | | EndIf

RepeatEnd
;- | EndWhile
				subs		r2, r2, #1										; 1
;				beq		RepeatBegin1 									; 1 (best)
				bpl		RepeatBegin1										; 3 (worst)

;- | store last byte (if needed)
				ands		r14, r6, #0x80									; 1
				streqb	r4, [r1], #1									; 2

;- | Wait end of last bit ( RC Compare )
WaitEnd
				ldr		r14, [r11, #(2*TC_SIZE)+TC_SR]			; 3
				ands		r14, r14, #CPCS								; 1
				beq		WaitEnd											; 1

;- | Disable TC2 Clock
				mov		r14, #CLKDIS
				str		r14, [r11, #(2*TC_SIZE)+TC_CCR]

;- End
				ldmia		sp!, {r4-r11,pc}

				END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -