2023-12-08 22:56:35 +01:00
|
|
|
.include "spi.h65"
|
2023-12-27 16:56:14 +01:00
|
|
|
.include "system.h65"
|
2023-10-26 19:51:20 +02:00
|
|
|
|
2023-12-31 01:58:47 +01:00
|
|
|
Export spi_p, init, irq_handler, status, buffer_size, recv_size
|
|
|
|
ExportZp spi_p, buffer_ptr
|
|
|
|
Export spi_p, begin_read, end_read, irq_read_byte, recv_bytes
|
|
|
|
Export spi_p, begin_write, end_write, irq_write_byte, sent_bytes
|
2023-10-30 22:14:33 +01:00
|
|
|
|
2023-12-08 00:13:10 +01:00
|
|
|
.zeropage
|
2023-12-31 01:58:47 +01:00
|
|
|
buffer_ptr: .res 2
|
2023-11-11 12:13:47 +01:00
|
|
|
.bss
|
2023-12-23 14:17:49 +01:00
|
|
|
recv_bytes:
|
|
|
|
sent_bytes: .res 2
|
|
|
|
status: .res 1
|
|
|
|
buffer_size: .res 2
|
2023-12-31 01:58:47 +01:00
|
|
|
recv_size:
|
|
|
|
send_size: .res 2
|
2023-12-23 14:17:49 +01:00
|
|
|
irq_handler: .res 2
|
|
|
|
|
2023-12-08 00:13:10 +01:00
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
SPI_IO := spi_p::SPI_IO
|
2023-12-08 00:13:10 +01:00
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
; spi-transferred code will be placed here
|
2023-12-08 00:13:10 +01:00
|
|
|
; SPI_P = as peripheral
|
2023-11-11 12:13:47 +01:00
|
|
|
.code
|
2023-12-27 16:56:14 +01:00
|
|
|
|
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Begin listening for SPI transfers
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc init
|
|
|
|
lda #spi_p::STATUS::DONE
|
|
|
|
sta status
|
2023-12-31 01:58:47 +01:00
|
|
|
stz recv_bytes
|
|
|
|
stz recv_bytes+1
|
|
|
|
stz buffer_size
|
|
|
|
stz buffer_size+1
|
|
|
|
stz recv_size
|
|
|
|
stz recv_size+1
|
|
|
|
rts
|
2023-12-27 16:56:14 +01:00
|
|
|
.endproc
|
2023-12-23 14:17:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Begin listening for SPI transfers
|
|
|
|
;; @details
|
|
|
|
;; The transfer must be: <SIZE, >SIZE, data (SIZE bytes)
|
|
|
|
;;
|
|
|
|
;; - initialize variables
|
|
|
|
;; - configure shift register to shift in under external clock
|
|
|
|
;; - enable shift register interrupts
|
|
|
|
;; @param ARG0-1: Start address of the buffer
|
|
|
|
;; @param ARG2-3: Size of the buffer
|
|
|
|
;; @todo: Use irq register handler
|
|
|
|
;; @note: The buffer must be large enough for the received data.
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc begin_read
|
|
|
|
stz recv_bytes
|
|
|
|
stz recv_bytes+1
|
2023-12-31 01:58:47 +01:00
|
|
|
stz recv_size
|
|
|
|
stz recv_size+1
|
2023-12-27 16:56:14 +01:00
|
|
|
lda #spi_p::STATUS::XFER_SIZEL
|
2023-12-23 14:17:49 +01:00
|
|
|
sta status
|
|
|
|
|
2023-12-08 00:13:10 +01:00
|
|
|
; store address in zp
|
2023-12-31 01:58:47 +01:00
|
|
|
lda ARG0
|
|
|
|
sta buffer_ptr
|
|
|
|
lda ARG1
|
|
|
|
sta buffer_ptr+1
|
2023-12-23 14:17:49 +01:00
|
|
|
|
|
|
|
; load irq handler
|
|
|
|
lda #<irq_read_byte
|
|
|
|
sta irq_handler
|
|
|
|
lda #>irq_read_byte
|
|
|
|
sta irq_handler+1
|
2023-10-30 22:14:33 +01:00
|
|
|
|
2023-12-23 14:17:49 +01:00
|
|
|
; temporarily store the low byte in buffer, will be checked later
|
2023-12-31 01:58:47 +01:00
|
|
|
lda ARG2
|
|
|
|
sta buffer_size
|
|
|
|
lda ARG3
|
2023-12-23 14:17:49 +01:00
|
|
|
sta buffer_size+1
|
|
|
|
; set Shift register to shift in under external clock on CB1
|
|
|
|
MaskedWrite SPI_IO+IO::ACR, #IO::ACR::SR_SIN_PHIE, #IO::ACR_MASK::SR
|
2023-10-30 22:14:33 +01:00
|
|
|
; enable SR interrupts
|
2023-11-01 13:13:23 +01:00
|
|
|
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
|
|
|
sta SPI_IO + IO::IER
|
2023-12-08 00:13:10 +01:00
|
|
|
; load SR to reset
|
|
|
|
lda SPI_IO + IO::SR
|
2023-10-30 22:14:33 +01:00
|
|
|
rts
|
|
|
|
.endproc
|
|
|
|
|
2023-12-08 22:56:35 +01:00
|
|
|
|
2023-12-23 14:17:49 +01:00
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Stop reading/writing from/to SPI
|
|
|
|
;; @details
|
|
|
|
;; Disables shift register interrupts
|
|
|
|
;; @modifies A
|
|
|
|
;;********************************************************************************
|
2023-12-31 01:58:47 +01:00
|
|
|
end_write:
|
|
|
|
.proc end_read
|
2023-12-08 00:13:10 +01:00
|
|
|
; disable SR interrupts
|
|
|
|
lda #IO::IRQ::SR
|
|
|
|
sta SPI_IO + IO::IER
|
2023-12-31 01:58:47 +01:00
|
|
|
lda #spi_p::STATUS::DONE
|
|
|
|
sta status
|
2023-12-08 00:13:10 +01:00
|
|
|
rts
|
|
|
|
.endproc
|
|
|
|
|
|
|
|
|
2023-12-23 14:17:49 +01:00
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Read a byte from SPI
|
|
|
|
;; @details
|
|
|
|
;; Reads a byte from the shift register and stores it in the SPI code buffer
|
|
|
|
;; The first two bytes must be the size of the incumong data (LE).
|
|
|
|
;; The spi_p:status is updated according to the current stage of the transfer.
|
|
|
|
;; If the buffer size given in begin_read is too small too fit the incoming data,
|
|
|
|
;; the status is set to ERROR and spi (shift register) interrupts are disabled before
|
|
|
|
;; the first real byte is read.
|
|
|
|
;; @modifies A,Y
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc irq_read_byte
|
2023-11-01 13:13:23 +01:00
|
|
|
lda SPI_IO + IO::SR
|
2023-12-31 01:58:47 +01:00
|
|
|
; Printf "%x",
|
2023-12-23 14:17:49 +01:00
|
|
|
bit status
|
2023-12-31 01:58:47 +01:00
|
|
|
bmi @read_size1 ; bit7 set => XFER_SIZEL
|
|
|
|
bvs @read_size2 ; bit6 set => XFER_SIZEH
|
2023-12-23 14:17:49 +01:00
|
|
|
ldy recv_bytes
|
2023-12-31 01:58:47 +01:00
|
|
|
sta (buffer_ptr),y
|
2023-12-23 14:17:49 +01:00
|
|
|
inc recv_bytes
|
2023-12-08 00:13:10 +01:00
|
|
|
beq @new_page
|
|
|
|
rts
|
2023-12-31 01:58:47 +01:00
|
|
|
@new_page: ; increment high bytes
|
2023-12-23 14:17:49 +01:00
|
|
|
inc recv_bytes+1
|
2023-12-31 01:58:47 +01:00
|
|
|
inc buffer_ptr+1
|
2023-12-23 14:17:49 +01:00
|
|
|
rts
|
2023-12-31 01:58:47 +01:00
|
|
|
|
2023-12-23 14:17:49 +01:00
|
|
|
@read_size1:
|
2023-12-31 01:58:47 +01:00
|
|
|
sta recv_size
|
2023-12-23 14:17:49 +01:00
|
|
|
lda #spi_p::STATUS::XFER_SIZEH
|
|
|
|
sta status
|
|
|
|
rts
|
2023-12-31 01:58:47 +01:00
|
|
|
|
2023-12-23 14:17:49 +01:00
|
|
|
@read_size2:
|
2023-12-31 01:58:47 +01:00
|
|
|
sta recv_size+1
|
|
|
|
; check if the buffer is large enough
|
2023-12-23 14:17:49 +01:00
|
|
|
cmp buffer_size+1
|
|
|
|
beq @hieq
|
2023-12-31 01:58:47 +01:00
|
|
|
bcc @enough ; recv_size+1 < buffer_size+1
|
2023-12-23 14:17:49 +01:00
|
|
|
bra @not_enough
|
|
|
|
@hieq: ; high bytes are equal, check lo
|
2023-12-31 01:58:47 +01:00
|
|
|
lda buffer_size
|
|
|
|
cmp recv_size
|
2023-12-23 14:17:49 +01:00
|
|
|
bcs @enough
|
|
|
|
@not_enough:
|
|
|
|
lda #spi_p::STATUS::ERROR
|
|
|
|
sta status
|
|
|
|
; disable SR interrupts
|
|
|
|
lda #IO::IRQ::SR
|
|
|
|
sta SPI_IO + IO::IER
|
|
|
|
rts
|
|
|
|
@enough:
|
|
|
|
lda #spi_p::STATUS::XFER
|
|
|
|
sta status
|
|
|
|
rts
|
|
|
|
.endproc
|
|
|
|
|
|
|
|
|
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Begin writing to spi
|
|
|
|
;; @details
|
|
|
|
;; - initialize variables
|
|
|
|
;; - configure shift register to shift in under external clock
|
|
|
|
;; - enable shift register interrupts
|
|
|
|
;; @param ARG0-1: Start address of the buffer
|
|
|
|
;; @param ARG2-3: Size of the buffer
|
|
|
|
;; @todo: Use irq register handler
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc begin_write
|
|
|
|
stz recv_bytes
|
|
|
|
stz recv_bytes+1
|
|
|
|
; store address in zp
|
|
|
|
lda #<ARG0
|
2023-12-31 01:58:47 +01:00
|
|
|
sta buffer_ptr
|
2023-12-23 14:17:49 +01:00
|
|
|
lda #>ARG1
|
2023-12-31 01:58:47 +01:00
|
|
|
sta buffer_ptr+1
|
2023-12-23 14:17:49 +01:00
|
|
|
; store size
|
|
|
|
lda #<ARG2
|
|
|
|
sta buffer_size
|
|
|
|
lda #>ARG3
|
|
|
|
sta buffer_size+1
|
|
|
|
; load irq handler
|
|
|
|
lda #<irq_read_byte
|
|
|
|
sta irq_handler
|
|
|
|
lda #>irq_read_byte
|
|
|
|
sta irq_handler+1
|
|
|
|
; set Shift register to shift out under external clock on CB1
|
|
|
|
MaskedWrite SPI_IO+IO::ACR, #IO::ACR::SR_SOUT_PHIE, #IO::ACR_MASK::SR
|
|
|
|
; enable SR interrupts
|
|
|
|
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
|
|
|
sta SPI_IO + IO::IER
|
|
|
|
; write the first byte
|
|
|
|
@write_size1:
|
|
|
|
lda buffer_size
|
2023-12-27 16:56:14 +01:00
|
|
|
sta SPI_IO+IO::SR
|
2023-12-23 14:17:49 +01:00
|
|
|
lda #spi_p::STATUS::XFER_SIZEH
|
|
|
|
sta status
|
|
|
|
rts
|
2023-10-30 22:14:33 +01:00
|
|
|
.endproc
|
|
|
|
|
2023-12-23 14:17:49 +01:00
|
|
|
;;;********************************************************************************
|
|
|
|
;;; @function Write a byte
|
|
|
|
;;; @details
|
|
|
|
;;; Write a byte to the spi shift reister
|
|
|
|
;;; @modifies A,Y
|
|
|
|
;;;********************************************************************************
|
|
|
|
;.proc irq_write_byte
|
|
|
|
; ldy sent_bytes
|
2023-12-31 01:58:47 +01:00
|
|
|
; lda (buffer_ptr),y
|
2023-12-23 14:17:49 +01:00
|
|
|
; sta SPI_IO + IO::SR
|
|
|
|
; inc sent_bytes
|
|
|
|
; beq @new_page
|
|
|
|
; rts
|
|
|
|
;@new_page:
|
|
|
|
; inc sent_bytes+1
|
2023-12-31 01:58:47 +01:00
|
|
|
; inc buffer_ptr+1
|
2023-12-23 14:17:49 +01:00
|
|
|
; rts
|
|
|
|
;.endproc
|
|
|
|
|
|
|
|
|
|
|
|
;;********************************************************************************
|
|
|
|
;; @function Write a byte to SPI
|
|
|
|
;; @details
|
|
|
|
;; Write a byte from the buffer to the (spi) shift register.
|
|
|
|
;; The first two bytes are the size of the data (LE).
|
|
|
|
;; The spi_p:status is updated according to the current stage of the transfer.
|
|
|
|
;; @modifies A,Y
|
|
|
|
;;********************************************************************************
|
|
|
|
.proc irq_write_byte
|
|
|
|
bit status
|
|
|
|
bvs @write_size2 ; bit 6 set -> XFER_SIZEH
|
|
|
|
ldy sent_bytes
|
2023-12-31 01:58:47 +01:00
|
|
|
lda (buffer_ptr),y
|
2023-12-23 14:17:49 +01:00
|
|
|
sta SPI_IO + IO::SR
|
|
|
|
inc sent_bytes
|
|
|
|
beq @new_page
|
|
|
|
rts
|
|
|
|
@new_page:
|
|
|
|
inc sent_bytes+1
|
2023-12-31 01:58:47 +01:00
|
|
|
inc buffer_ptr+1
|
2023-12-23 14:17:49 +01:00
|
|
|
rts
|
|
|
|
@write_size2:
|
|
|
|
lda buffer_size+1
|
2023-12-27 16:56:14 +01:00
|
|
|
sta SPI_IO+IO::SR
|
2023-12-23 14:17:49 +01:00
|
|
|
lda #spi_p::STATUS::XFER
|
|
|
|
sta status
|
|
|
|
rts
|
2023-10-30 22:14:33 +01:00
|
|
|
.endproc
|