📄 usbtors232.asm
字号:
out DDRD,temp0 ;and update direction of data port
rjmp OneZeroAnswer ;acknowledge reception with single zero
;--------------------------
DoGetDataPortDirection:
in temp0,DDRB ;read direction of DDRB
sts AnswerArray,temp0 ;to array AnswerArray
in temp0,DDRC ;read direction of DDRC
sts AnswerArray+1,temp0 ;to array AnswerArray
in temp0,DDRD ;read direction of DDRD
sts AnswerArray+2,temp0 ;to array AnswerArray
ldi ZL,AnswerArray ;sending is value from AnswerArray
ldi temp0,0x81 ;RAMREAD=1 - reading from RAM
mov RAMread,temp0 ;(highest bit set to 1 - to zero RAMread immediatelly)
ldi temp0,3 ;sending are three bytes
rjmp ComposeEndXXXDescriptor ;and prepare data
;--------------------------
DoSetOutDataPort:
lds temp1,InputBufferBegin+7 ;fourth parameter - bit mask - which port(s) to change
lds temp0,InputBufferBegin+4 ;first parameter - value of data bits PORTB
andi temp0,0b00111100 ;mask unused pins
sbrc temp1,0 ;if bit0 is zero - don't change port state
out PORTB,temp0 ;and update data port
lds temp0,InputBufferBegin+5 ;second parameter - value of data bits PORTC
sbrc temp1,1 ;if bit1 is zero - don't change port state
out PORTC,temp0 ;and update data port
lds temp0,InputBufferBegin+6 ;third parameter - value of data bits PORTD
andi temp0,0b11111000 ;mask unused pins
ori temp0,0b00000011 ;mask unused pins
sbrc temp1,2 ;if bit2 is zero - don't change port state
out PORTD,temp0 ;and update data port
rjmp OneZeroAnswer ;acknowledge reception with single zero
;--------------------------
DoGetOutDataPort:
in temp0,PORTB ;read PORTB
sts AnswerArray,temp0 ;to array AnswerArray
in temp0,PORTC ;read PORTC
sts AnswerArray+1,temp0 ;to array AnswerArray
in temp0,PORTD ;read PORTD
sts AnswerArray+2,temp0 ;to array AnswerArray
ldi ZL,AnswerArray ;sending is value from AnswerArray
ldi temp0,0x81 ;RAMREAD=1 - reading from RAM
mov RAMread,temp0 ;(highest bit set to 1 - to zero RAMread immediatelly)
ldi temp0,3 ;sending are three bytes
rjmp ComposeEndXXXDescriptor ;and prepare data
;--------------------------
DoGetInDataPort:
in temp0,PINB ;read PINB
sts AnswerArray,temp0 ;to array AnswerArray
in temp0,PINC ;read PINC
sts AnswerArray+1,temp0 ;to array AnswerArray
in temp0,PIND ;read PIND
sts AnswerArray+2,temp0 ;to array AnswerArray
ldi ZL,AnswerArray ;sending is value from AnswerArray
ldi temp0,0x81 ;RAMREAD=1 - reading from RAM
mov RAMread,temp0 ;(highest bit set to 1 - to zero RAMread immediatelly)
ldi temp0,3 ;sending are three bytes
rjmp ComposeEndXXXDescriptor ;and prepare data
;------------------------------------------------------------------------------------------
DoGetIn:
ldi ZL,0 ;sending value in R0
ldi temp0,0x81 ;RAMread=1 - reading from RAM
mov RAMread,temp0 ;(highest bit set to 1 - to zero RAMread immediatelly)
ldi temp0,1 ;send only single byte
rjmp ComposeEndXXXDescriptor ;and prepare data
;------------------------------------------------------------------------------------------
DoEEPROMRead:
lds ZL,InputBufferBegin+4 ;first parameter - offset in EEPROM
lds ZH,InputBufferBegin+5
ldi temp0,2
mov RAMread,temp0 ;RAMREAD=2 - reading from EEPROM
ldi temp0,E2END+1 ;number my byte answers to temp0 - entire length of EEPROM
rjmp ComposeEndXXXDescriptor ;otherwise prepare data
;--------------------------
DoEEPROMWrite:
lds ZL,InputBufferBegin+4 ;first parameter - offset in EEPROM (address)
lds ZH,InputBufferBegin+5
lds R0,InputBufferBegin+6 ;second parameter - data to store to EEPROM (data)
out EEAR,ZL ;set the address of EEPROM
out EEARH,ZH
out EEDR,R0 ;set the data to EEPROM
cli ;disable interrupt
sbi EECR,EEMWE ;set the master write enable
sei ;enable interrupt (next instruction is performed)
sbi EECR,EEWE ;write
WaitForEEPROMReady:
sbic EECR,EEWE ;wait to the end of write
rjmp WaitForEEPROMReady ;in loop (max cca 4ms) (because of possible next reading/writing)
rjmp OneZeroAnswer ;acknowledge reception with single zero
;--------------------------
DoRS232Send:
lds temp0,InputBufferBegin+4 ;first parameter - value transmitted to RS232
out UDR,temp0 ;transmit data to UART
WaitForRS232Send:
sbis UCR,TXEN ;if disabled UART transmitter
rjmp OneZeroAnswer ;then finish - protection because loop lock in AT90S2323/2343
sbis USR,TXC ;wait for transmition finish
rjmp WaitForRS232Send
rjmp OneZeroAnswer ;acknowledge reception with single zero
;--------------------------
DoRS232Read:
rjmp TwoZeroAnswer ;only acknowledge reception with two zero
;--------------------------
DoSetRS232Baud:
lds temp0,InputBufferBegin+4 ;first parameter - value of baudrate of RS232
lds temp1,InputBufferBegin+6 ;second parameter - baudrate of RS232 - high byte
cbr temp1,1<<URSEL ;writing will be baudrate high byte (no UCSRC)
out UBRRH,temp1 ;set the speed of UART high byte
out UBRR,temp0 ;set the speed of UART low byte
rjmp OneZeroAnswer ;acknowledge reception with single zero
;--------------------------
DoGetRS232Baud:
in temp0,UBRR ;return speed of UART Lo
sts AnswerArray,temp0
in temp0,UBRRH ;return speed of UART Hi
sts AnswerArray+1,temp0 ;to array AnswerArray
ldi ZL,AnswerArray ;sending is value from AnswerArray
ldi temp0,0x81 ;RAMREAD=1 - reading from RAM
mov RAMread,temp0 ;(highest bit set to 1 - to zero RAMread immediatelly)
ldi temp0,2 ;sending are two bytes
rjmp ComposeEndXXXDescriptor ;and prepare data
;--------------------------
DoGetRS232Buffer:
cbi UCR,RXCIE ;disable interrupt from UART receiving
nop
lds temp0,RS232LengthPosPtr
lds temp1,RS232LengthPosPtr+1 ;obtain buffer length of RS232 code
sbi UCR,RXCIE ;enable interrupt from UART receiving
cpi temp0,0 ;if this isn't RS232 Buffer empty
brne SomeRS232Send ;then send it
cpi temp1,0 ;if this isn't RS232 Buffer empty
brne SomeRS232Send ;then send it
rjmp OneZeroAnswer ;otherwise nothing send and acknowledge reception with single zero
SomeRS232Send:
lds ACC,InputBufferBegin+8 ;number of requiring bytes to ACC
ldi temp2,2 ;number of possible bytes (plus word of buffer length)
add temp0,temp2
ldi temp2,0
adc temp1,temp2
cpi temp1,0 ;if is MSB>0
brne AsRequiredGetRS232Buffer ;transmit as many as requested
cp ACC,temp0 ;if no requested more that I can send
brcc NoShortGetRS232Buffer ;transmit as many as requested
AsRequiredGetRS232Buffer:
mov temp0,ACC
ldi temp1,0
NoShortGetRS232Buffer:
subi temp0,2 ;substract word length
sbci temp1,0
lds temp2,RS232ReadPosPtr ;obtain index of reading of buffer of RS232 code
lds temp3,RS232ReadPosPtr+1
add temp2,temp0 ;obtain where is end
adc temp3,temp1
cpi temp3,HIGH(RS232BufferEnd+1) ;if it would overflow
brlo ReadNoOverflow ;
brne ReadOverflow ;if yes - skip to overflow
cpi temp2,LOW(RS232BufferEnd+1) ;otherwise compare LSB
brlo ReadNoOverflow ;and do the same
ReadOverflow:
subi temp2,LOW(RS232BufferEnd+1) ;caculate how many not transfered
sbci temp3,HIGH(RS232BufferEnd+1) ;caculate how many not transfered
sub temp0,temp2 ;and with this short length of reading
sbc temp1,temp3 ;and with this short length of reading
ldi temp2,LOW(RS232FIFOBegin) ;and start from zero
ldi temp3,HIGH(RS232FIFOBegin) ;and start from zero
ReadNoOverflow:
lds ZL,RS232ReadPosPtr ;obtain index of reading of buffer of RS232 code
lds ZH,RS232ReadPosPtr+1 ;obtain index of reading of buffer of RS232 code
sts RS232ReadPosPtr,temp2 ;write new index of reading of buffer of RS232 code
sts RS232ReadPosPtr+1,temp3 ;write new index of reading of buffer of RS232 code
sbiw ZL,2 ;space for length data - transmitted as first word
cbi UCR,RXCIE ;disable interrupt from UART receiving
inc RAMread ;RAMread=1 reading from RAM
lds temp2,RS232LengthPosPtr
lds temp3,RS232LengthPosPtr+1 ;obtain buffer length of RS232 code
sub temp2,temp0 ;decrement buffer length
sbc temp3,temp1
sts RS232LengthPosPtr,temp2 ;write new buffer length of RS232 code
sts RS232LengthPosPtr+1,temp3
sbi UCR,RXCIE ;enable interrupt from UART receiving
st Z+,temp2 ;and save real length to packet
st Z,temp3 ;and save real length to packet
sbiw ZL,1 ;and set to begin
inc temp0 ;and about this word increment number of transmited bytes (buffer length)
inc temp0
rjmp ComposeEndXXXDescriptor ;and prepare data
;------------------------------------------------------------------------------------------
DoSetRS232DataBits:
lds temp0,InputBufferBegin+4 ;first parameter - data bits 0=5db, 1=6db, 2=7db, 3=8db
cpi temp0,DataBits8 ;if to set 8-bits communication
breq Databits8or9Set ;then don't change 8/9 bit communication
in temp1,UCSRB ;otherwise load UCSRB
cbr temp1,(1<<UCSZ2) ;clear 9-bit communication
out UCSRB,temp1 ;and write back
Databits8or9Set:
rcall RS232DataBitsLocal
rjmp OneZeroAnswer ;acknowledge reception with single zero
RS232DataBitsLocal:
rcall GetUCSRCtotemp1
bst temp0,0 ;set the UCSZ0
bld temp1,UCSZ0
bst temp0,1 ;set the UCSZ1
bld temp1,UCSZ1
rcall Settemp1toUCSRC
ret
GetUCSRCtotemp1:
cli ;obtain UCSRC
in temp1,UBRRH
in temp1,UCSRC ;to temp1
sei
nop ;for to enable possible interrupt waiting before ret instruction (ret has long duration)
ret
Settemp1toUCSRC:
sbr temp1,(1<<URSEL) ;will be writing to UCSRC
out UCSRC,temp1 ;and write back to register with new UCSZ0 and UCSZ1
ret
;------------------------------------------------------------------------------------------
DoGetRS232DataBits:
rcall GetUCSRCtotemp1
clr temp0 ;clear answer
bst temp1,UCSZ0 ;obtain UCSZ0
bld temp0,0 ;and save to bit 0
bst temp1,UCSZ1 ;obtain UCSZ1
bld temp0,1 ;and save to bit 1
mov R0,temp0 ;return number of databits in R0
rjmp DoGetIn ;and finish
;------------------------------------------------------------------------------------------
DoSetRS232Parity:
lds temp0,InputBufferBegin+4 ;first parameter - parity: 0=none, 1=odd, 2=even, 3=mark, 4=space
cpi temp0,3
brcc StableParity
rcall GetUCSRCtotemp1
cbr temp1,(1<<UPM1)|(1<<UPM0) ;clear parity bits
cpi temp0,ParityNone ;if none
breq SetParityOut
sbr temp1,(1<<UPM1)
cpi temp0,ParityEven ;if even
breq SetParityOut
sbr temp1,(1<<UPM0)
cpi temp0,ParityOdd ;if odd
brne ParityErrorAnswer
SetParityOut:
rcall Settemp1toUCSRC
in temp1,UCSRB ;load UCSRB
cbr temp1,(1<<UCSZ2) ;if is 9-bits communication then change it under 9 bits
out UCSRB,temp1 ;and write back
rjmp OneZeroAnswer ;acknowledge reception with single zero
StableParity:
in temp1,UCSRB ;change transmiting parity bit TXB8
bst temp0,0 ;load lowest bit
bld temp1,TXB8 ;and save to its place TXB8
sbr temp1,(1<<UCSZ2) ;set the UCSZ2 bit - 9 bits communication
out UCSRB,temp1 ;changed TXB8 and UCSZ2 write to UCSRB
ldi temp0,3 ;set the 9-databit
rcall RS232DataBitsLocal ;and return in temp1 contents UCSRC
cbr temp1,(1<<UPM1)|(1<<UPM0) ;disable parity
rcall Settemp1toUCSRC
rjmp OneZeroAnswer ;acknowledge reception with single zero
ParityErrorAnswer:
rjmp TwoZeroAnswer ;acknowledge reception with two zero
;------------------------------------------------------------------------------------------
DoGetRS232Parity:
in temp1,UCSRB ;load UCSRB
sbrc temp1,UCSZ2 ;if is 9-bits communication
rjmp ParityIsStable ;then parity is space or mark
rcall GetUCSRCtotemp1
cbr temp1,~((1<<UPM0)|(1<<UPM1)) ;and let nonzero only parity bits
cpi temp1,(1<<UPM0)|(1<<UPM1) ;if are both set
ldi temp0,ParityOdd ;this is odd parity
breq RetGetParity ;and finish
cpi temp1,(1<<UPM1) ;if is UPM1 set
ldi temp0,ParityEven ;this is even parity
breq RetGetParity ;and finish
ldi temp0,ParityNone ;otherwise is that none parity
rjmp RetGetParity ;and finish
ParityIsStable:
bst temp1,TXB8 ;obtain what is 9-th bit
ldi temp0,ParityMark ;prepare mark answer
brts RetGetParity ;if is 1 then return mark
ldi temp0,ParitySpace ;otherwise return space
RetGetParity:
mov R0,temp0 ;answer move from temp0 to R0
rjmp DoGetIn ;and finish
;------------------------------------------------------------------------------------------
DoSetRS232StopBits:
lds temp0,InputBufferBegin+4 ;first parameter - stop bit 0=1stopbit 1=2stopbits
rcall GetUCSRCtotemp1
bst temp0,0 ;and lowest bit from parameter
bld temp1,USBS ;save as stopbit
rcall Settemp1toUCSRC
rjmp OneZeroAnswer ;acknowledge reception with single zero
;------------------------------------------------------------------------------------------
DoGetRS232StopBits:
rcall GetUCSRCtotemp1
clr R0 ;clear answer
bst temp1,USBS ;and bit USBS
bld R0,0 ;write to answer
rjmp DoGetIn ;and finish
;----------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -