;======================================================================= ;======================================================================= ; SERIAL PERIPHERAL INTERFACE (SPI) VIRTUAL PERIPHERALS ; SPIS (Authentic SPI Slave) Virtual Peripheral Demo Program ; Revision 1.02, 07.21.98 ; Developed by Authentic Engineering for Scenix Semiconductor, Inc. ; Authentic Engineering // http://www.authenticeng.com // ak@silcom.com ; ;======================================================================= ; ; Authentic SPIS (SPI Slave) Virtual Peripheral ; ; SPIS is a part of the Authetic SPI virtual peripherals for SX micro. ; This VP provides simple and efficient way to send/get one word of ; data to/from SPI compatible MASTER device. ; ; SPIS is developed to work with relatively fast SPI devices. It ; occupies the CPU during the entire data transfer. ; Maximum clock rate is 1.1 MHz (900 nsec clock period). The clock ; rate may vary during data transfer cycle. The minimum clock rate ; is limited by the watchdog timer if it's enabled; or is unlimited ; otherwise. ; ; Word length can be set to anywhere from 1 to 16 bits. Longer word ; lengths could be easily implemented if needed. ; ; Clock polarity is configurable by using the appropriate command byte. ; ; Four I/O signal lines are associated with any SPI communication: ; ; Master-Out-Slave-In MOSI signal line ; Master-In-Slave_Out MISO signal line ; Serial Clock SCLK signal line ; Slave Select SS signal line ; ; SPIS does not make any diffenece between read and write cycles. ; The data is clocked in and out simultaneously. ; ; If necessary, user may want to add more sophistication to the data ; transfer by adding Read/Write and handshaking signals. All that ; can be easily implemented without affecting the core SPIS program. ; ; SPIS makes use of the Wake-UP interrupt from the SS signal, ; for this reason the SS signal must be assigned to one of the ; Port B pins. Other signals may use any pins of SX-28. ; ; To initialize the SPIS user must disable the RTCC interrupt and ; enable the appropriate edge wakeup interrupt from the SS pin. ; SPIS will then wait for the the interrupt from the SS input. ; When the interrupt occures, SPIS will start execution of the ; send/receive loop, waiting for SPI Clock signals and processing ; the incoming and outgoing data lines. After the predefined number ; of clock pulses SPIS will finish the communication cycle and ; exit the interrupt. In order to prevent locking of the driver ; in case of communication error, SPIS uses it's internal ; SPIS_WATCHDOG counter, which would expire if SPIS has not ; received the clock pulse for too long and the data transfer ; will be aborted. ; ; The two-byte (16 bits) send/receive buffer is allocated in ; memory as SPIS_LSB and SPIS_MSB. Data are shifted starting ; from the most significant bit. ; In case of less than 16-bit long data word, the SPIS will ; automatically align the MSBit of the word to the MSBit of ; the buffer before shifting. No user intervention is required. ; The contents of SPIS_LSB and SPIS_MSB are not preserved ; during the driver operation since the bits are always shifted in. ; ; ; -- SPIS control, status and I/O DATA registers -- ; ; SPIS_WATCHDOG. This byte defines the timeout period for ; the SPI slave (see above). If SPIS will not receive the clock signal ; within this waiting period, the communication will be aborted and the ; error flag will be set. The actual timeout can be calculated as ; 160 nsec multiplied by SPIS_WATCHDOG. ; ; SPIS_PORTA_MASK, SPIS_PORTB_MASK, SPIS_PORTC_MASK. These ; bytes are the images of SX I/O ports direction registers. ; They are written to corresponding ports direction registers ; during SPIS initialisation. ; ; SPIS_WKUP_MASK - SPIS writes SPIS_WKUP_MASK into Wakeup Enable ; register of PortB ; ; SPIS_CMD - command and configuration byte. This byte defines: ; - SPI Clock polarity ; - direction (Read/Write) ; - number of bits to send/receive ; ; SPIS supports 4 commands, specified by the 4 MSBits of the ; SPIS_CMD byte: ; ; $1 - GET BYTE in SLAVE mode, define FALLING edge ; $5 - GET BYTE in SLAVE mode, define RISING edge ; $9 - SEND BYTE in SLAVE mode, define FALLING edge ; $D - SEND BYTE in SLAVE mode, define RISING edge ; ; Practically there is no difference between the GET and SEND commands. ; When the I/O buffer is shifted out, the input data is always ; shifted in. The different commands are provided for user convinience ; and confusion. The contents of SPIS_LSB and SPIS_MSB are ; not preserved during the driver operation since the bits are ; always shifted in even if they don't make any sense. ; ; Four LSBits of the command byte define the word length. ; $00 sets the length to 16 bits ; $01 sets the length to 1 bit ; ... ; $0F sets the length to 15 bits ; ; The SPIS_CMD byte also serves as a ready flag. SPIS will clear this ; byte upon the success of data transfer. ; ; SPIS_STATUS byte provides the error status information to the user ; program. It has 2 error flags: ; bit 4 - set to 1 when the SPIS_CMD byte contains an unsupported command ; bit 7 - set to 1 when the data transfer was not completed successfully ; ; -- SPIS ENTRY POINTS -- ; ; SPIS_INIT - Initialization subroutine.It provides appropriate configuration ; for SX I/O ports. ; ; SPIS_EXECUTE - This is the actual VP entry point which is normally ; called from the interrupt service routine. ; ; SPIS_ORG. This is the base address of SPIM VP. Typically it will be ; next ROM location, after the user program. ; ; -- How to use SPIS from the user program -- ; ; 1. Verify that the execution parameters are configured properly: ; SPIS_WATCHDOG ; SPIS_PORT_A_MASK ; SPIS_PORT_B_MASK ; SPIS_PORT_C_MASK ; SPIS_WKUP_MASK ; SPIS_CMD ; ; 2. Call SPIS_INIT ; ; 2. Verify that SPIS is ready for execution by testing the SPIS_CMD byte. ; ; 4. Place the outgoing data into SPIS_LSB and SPIS_MSB ; ; 5. Disable the RTCC interrupt and enable the SS interrupt from Port B. ; ; 6. Call SPIS_EXECUTE from the interrupt. ; ; 7. Test SPIS_CMD for completion and SPIS_STATUS for errors. ; Unload the data from SPIS_LSB and SPIS_MSB ; ; Your SPIS is now ready for reuse. Repeat from step 4. ; ;======================================================================= ;**************************** CODE START ******************************* ;;recommended SX device configuration ; device pins28, pages4, banks8,oschs ; device turbo, stackx, optionx ; id 'SPIS_D3' ;reset reset_entry ;***************************** I/O PINS ******************************** ;;example of SX I/O pins assingment ;spis_clk_pin = rb.0 ;SPI clock line ;spis_out_pin = rb.1 ;master_in slave_out line ;spis_in_pin = rb.2 ;master_out slave_in line ;spis_MCU_cs_pin = rb.3 ;slave select/slave request micro ; ;*********************************************************************** ;************************** Authentic SPI SLAVE VP ********************* org 10h spis_ram_bank = $ ;SPIS control data spis_cmd ds 1 ;SPIS command byte fast_ON equ spis_cmd.4 ;always set to 1 for SPIS master_ON equ spis_cmd.5 ;set to 1 if MASTER rising_ON equ spis_cmd.6 ;set to 1 if RISING transmit_ON equ spis_cmd.7 ;set to 1 if TRANSMIT spis_watchdog ds 1 ;clock receive timeout spis_port_b_mask ds 1 ;PortA direction register image spis_port_a_mask ds 1 ;PortB direction register image spis_port_c_mask ds 1 ;PortC direction register image spis_wkup_mask ds 1 ; ;SPIS status data spis_status ds 1 ;SPIS status byte spis_cmd_error equ spis_status.4 ;error - unsupported command spis_transfer_error equ spis_status.7 ;error - transfer aborted ;SPIS I/O buffer spis_msb ds 1 ;I/O buffer MSByte spis_lsb ds 1 ;I/O buffer LSByte ;SPIS private data spis_bits_total ds 1 ;number of bits to transfer spis_shift_counter ds 1 ;bit shift counter spis_shifts_init ds 1 ;number or alignment shifts for the buffer spis_watch_counter ds 1 ;watchdog counter org spis_org ;********************* SPIS INITIALIZATION ROUTINE ********************* spis_init mov m,#$0f ;set up data direction registers mov !rb,spis_port_b_mask ;configure ports mov !ra,spis_port_a_mask mov !rc,spis_port_c_mask ;configure the wakeup interrupt mov m,#$0a ;set WKUP interrupt to FALLING edge mov w,spis_wkup_mask not w mov !rb,w mov m,#$0b ;enable interrupt mov !rb,spis_wkup_mask mov m,#$0f ret ;************************* SPIS DATA TRANSFER ************************** spis_execute bank spis_ram_bank ;set SPIS RAM bank mov m,#$09 ;clear pending interrupts clr w mov !rb,w sb master_ON ;decode SPIS_CMD jb fast_ON,spis_cmd_proc setb spis_cmd_error ;set command error flag and exit spis_exit clr spis_cmd ;clear SPIS_CMD and exit ret spis_cmd_proc mov w,spis_cmd ;decode number of bits to transfer and w,#$0f mov spis_bits_total,w test spis_bits_total snz mov spis_bits_total,#$10 mov spis_shift_counter,spis_bits_total mov spis_shifts_init,#$10 ;decode number of bits to transfer sub spis_shifts_init,spis_bits_total test spis_shifts_init jz :spis ;no initial shifts required :set_bit_position ;align the word clc rl spis_lsb rl spis_msb djnz spis_shifts_init,:set_bit_position :spis test spis_shift_counter ;data transfer loop jz :spis_execute_exit jb rising_ON,:slave_rising ;jmp to rizing edge clock detection :slave_falling ;falling edge active transfer mov spis_watch_counter,spis_watchdog :falling_send jb spis_clk_pin,:shift_bit_out_on_fall djnz spis_watch_counter,:falling_send jmp :spis_error_exit ;exit when watchdog is zero :shift_bit_out_on_fall ;shift bit out movb spis_out_pin,spis_msb.7 rl spis_lsb rl spis_msb mov spis_watch_counter,spis_watchdog :falling_get ;wait for falling edge to shift bit in jnb spis_clk_pin,:shift_bit_in_on_fall djnz spis_watch_counter,:falling_get jmp :spis_error_exit ;exit when watchdog is zero :shift_bit_in_on_fall movb spis_lsb,spis_in_pin ;shift bit in dec spis_shift_counter jmp :spis ;next clock pulse :slave_rising ;rising edge active data transfer mov spis_watch_counter,spis_watchdog :rising_send ;wait for falling edge to shift bit out jnb spis_clk_pin,:shift_bit_out_on_rise djnz spis_watch_counter,:rising_send jmp :spis_error_exit ;exit when watchdog is zero :shift_bit_out_on_rise movb spis_out_pin,spis_msb.7 ;shift bit out rl spis_lsb rl spis_msb mov spis_watch_counter,spis_watchdog :rising_get ;wait for rising edge to shift bit in jb spis_clk_pin,:shift_bit_in_on_rise djnz spis_watch_counter,:rising_get jmp :spis_error_exit ;exit when watchdog is zero :shift_bit_in_on_rise movb spis_lsb,spis_in_pin ;shift bit in dec spis_shift_counter jmp :spis ;next clock pulse :spis_error_exit setb spis_transfer_error ;exit on transfer error mov w,#$01 ;error code is set :spis_execute_exit jmp spis_exit ;normal exit ret ;TO CLOSE THE LABEL SCOPE ;***************************** END OF SPIS VP **************************
file: /Techref/scenix/spis.src, 11KB, , updated: 1999/2/20 12:23, local time: 2024/11/5 20:35,
3.137.170.241:LOG IN ©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!
|
©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? <A HREF="http://linistepper.com/techref/scenix/spis.src"> scenix spis</A> |
Did you find what you needed? |