📄 hidtherm.asm
字号:
mov A, 00h
mov [BUTTON_DATA], A
mov A, REPORT_DATA_AVAILABLE
mov [report_flag], A
jmp button_task_done
; the button is in a new state so we need to reset the debounce timer
; and set the new state
new_button_state:
mov A, 00h ; reset the debounce timer
mov [debounce_timer], A
mov A, [current_button_state] ; set the new button state
mov [last_button_state], A
button_task_done:
;**********************************
; Temperature Read Task
; reads the current temperature
; from the DS1722 sensor
; check to see if the timer has reached the report timing interval
; we only want to report temperature data about every 1/4 second or so
mov A, [tm_timer]
cmp A, TM_INTERVAL
jnz hid_report_task
; reset the temperature measurement interval timer
mov A, 00h
mov [tm_timer], A
; read the temperature data from the DS1722
mov A, TEMP_INT ; read integer part of temperature
mov [temp_addr], A
call Spi_temp_read
mov A, [temp_data]
; add 273 to the temperature for conversion to Kelvin
mov A, 00h ; clear high value before adding during the conversion
mov [temp_data2], A
mov A, [temp_data] ; test if temperature is negative
and A, 80h
jz kelvin_conversion
; if the temperature is negative then we have to sign-extend the data
mov A, FFh
mov [temp_data2], A
kelvin_conversion:
mov A, 11h ; add lower half of temperature
add A, [temp_data]
mov [temp_data], A
jc conversion_carry
mov A, 01h
add A, [temp_data2]
mov [temp_data2], A
jmp report_temp_data
conversion_carry:
mov A, 02h
add A, [temp_data2]
mov [temp_data2], A
jmp report_temp_data
report_temp_data:
mov A, REPORT_DATA_AVAILABLE
mov [report_flag], A
;**********************************
; HID report task
; this task sends data out endpoint 1 if the endpoint
; is configured and not set to stall
hid_report_task:
mov A, [event_machine]
cmp A, REPORT_PENDING
jz HID_report_task_done
no_data_report_pending:
; if not configured then skip data transfer
mov A, [configuration]
cmp A, 01h
jnz HID_report_task_done
; if stalled then skip data transfer
mov A, [ep1_stall]
cmp A, FFh
jz HID_report_task_done
; check if report data is available
mov A, [report_flag]
cmp A, REPORT_DATA_AVAILABLE
jnz HID_report_task_done
; if we get here then there is some new data to report. This
; may either be a button press/release or new temp. sensor data
; add the newest temperature measurment data to the ep1 buffer
; we do this here so the operation can be guaranteed to be atomic
; for both parts of the temperature measurement. If we did this
; in the temperature measurement task ep1 could get serviced in the
; middle of the task with 1/2 of the wrong data.
mov A, [temp_data] ; temperature measurement low
mov [ep1_dmabuff1], A
mov A, [temp_data2] ; temperature measurement high
mov [ep1_dmabuff2], A
mov A, REPORT_PACKET_SIZE ; set endpoint 1 to send reports
or A, [ep1_data_toggle]
iowr ep1_count
iord ep1_mode
and A, F0h
or A, ACK_IN ; set to ack on endpoint 1
iowr ep1_mode
mov A, REPORT_DATA_NOT_AVAILABLE
mov [report_flag], A ; clear report flag
mov A, REPORT_PENDING ; set a flag to indicate that data is pending
mov [event_machine], A ; on endpoint 1. The endpoint 1 handler will
; clear this flag
HID_report_task_done:
jmp task_loop
;*******************************************************
;
; Interrupt: bus_reset
; Purpose: The program jumps to this routine when
; the microcontroller has a bus reset.
;
;*******************************************************
Bus_reset:
mov A, STALL_IN_OUT ; set to STALL INs&OUTs
iowr ep0_mode
mov A, ADDRESS_ENABLE ; enable USB address 0
iowr usb_address
mov A, DISABLE ; disable endpoint1
iowr ep1_mode
mov A, 00h ; reset program stack pointer
mov psp,a
jmp Main
;*******************************************************
;
; Interrupt: 1ms_timer
; Purpose: Every 1ms we get switch data and check
; for USB suspend.
;
;*******************************************************
1ms_timer:
push A
; increment the temperature measurement timer
inc [tm_timer]
;**********************************
; poll buttons for button on/off state.
; The button state updates every millisecond
; and the pending flag is monitored by the
; main tasks.
iord BUTTON_PORT
mov [current_button_state], A
mov A, BUTTON_DATA_PENDING
mov [button_machine], A
;**********************************
; check for no bus activity/usb suspend
1ms_suspend_timer:
iord usb_status ; read bus activity bit
and A, BUS_ACTIVITY ; mask off activity bit
jnz bus_activity
inc [suspend_count] ; increment suspend counter
mov A, [suspend_count]
cmp A, 04h ; if no bus activity for 3-4ms,
jz usb_suspend ; then go into low power suspend
jmp clear_activity_bit
usb_suspend:
; shut down temp sensor
mov A, (E0H | SD)
mov [temp_data], A
mov A, TEMP_CTRL_WR
mov [temp_addr], A
call Spi_temp_write
; turn off LEDs and buttons
mov A, ACTIVE | ENUM | AUX01 | AUX02
iowr LED_PORT
; disable 1ms interrupt
mov A, USB_RESET_INT
iowr global_int
; suspend execution, see uC docs for explanation of 'nop'
iord control
or A, SUSPEND
ei
iowr control
nop
; look for bus activity, if none go back into suspend
iord usb_status
and A, BUS_ACTIVITY
jz usb_suspend
; re-enable interrupts
mov A, (1MS_INT | USB_RESET_INT)
iowr global_int
; re-enable temperature sensor
mov A, E0h
mov [temp_data], A
mov A, TEMP_CTRL_WR
mov [temp_addr], A
call Spi_temp_write
; re-enable the buttons and LEDs
mov A, [led_status]
iowr LED_PORT
bus_activity:
mov A, 00h ; reset suspend counter
mov [suspend_count], A
clear_activity_bit:
iord usb_status
and A, ~BUS_ACTIVITY ; clear bus activity bit
iowr usb_status
ms_timer_done:
pop A
reti
;*******************************************************
;
; Interrupt: endpoint0
; Purpose: Usb control endpoint handler. This interrupt
; handler formulates responses to SETUP and
; CONTROL READ, and NO-DATA CONTROL transactions.
;
;*******************************************************
Endpoint0:
push X
push A
iord ep0_mode
and A, EP0_ACK
jz ep0_done
iord ep0_mode
asl A
jc ep0_setup_received
asl A
jc ep0_in_received
asl A
jc ep0_out_received
ep0_done:
pop A
pop X
reti
ep0_setup_received:
mov A, NAK_IN_OUT ; clear setup bit to enable
iowr ep0_mode ; writes to EP0 DMA buffer
mov A, [ep0_dmabuff + BMREQUESTTYPE] ; compact bmRequestType into 5 bit field
and A, E3h ; clear bits 4-3-2, these unused for our purposes
push A ; store value
asr A ; move bits 7-6-5 into 4-3-2's place
asr A
asr A
mov [int_temp], A ; store shifted value
pop A ; get original value
or A, [int_temp] ; or the two to get the 5-bit field
and A, 1Fh ; clear bits 7-6-5 (asr wraps bit7)
asl A ; shift to index jumptable
jacc bmRequestType_jumptable ; jump to handle bmRequestType
h2d_std_device:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc h2d_std_device_jumptable
h2d_std_interface:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc h2d_std_interface_jumptable
h2d_std_endpoint:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc h2d_std_endpoint_jumptable
h2d_class_interface:
mov A, [ep0_dmabuff + BREQUEST]
sub A, 9
asl A
jacc h2d_class_interface_jumptable
d2h_std_device:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc d2h_std_device_jumptable
d2h_std_interface:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc d2h_std_interface_jumptable
d2h_std_endpoint:
mov A, [ep0_dmabuff + BREQUEST]
cmp A, GET_STATUS
jz get_endpoint_status
jmp request_not_supported
;;************ DEVICE REQUESTS **************
set_device_address: ; SET ADDRESS
mov A, ADDRESS_CHANGE_PENDING ; set flag to indicate we
mov [ep0_in_flag], A ; need to change address on
mov A, [ep0_dmabuff + WVALUELO]
mov [pending_data], A
jmp initialize_no_data_control
set_device_configuration: ; SET CONFIGURATION
mov A, [ep0_dmabuff + WVALUELO]
cmp A, 01h
jz configure_device
unconfigure_device: ; set device as unconfigured
mov [configuration], A
mov A, DISABLE ; disable endpoints 1/2
iowr ep1_mode
iowr ep2_mode
mov A, EP0_INT ; turn off endpoint 1 interrupts
iowr endpoint_int
jmp set_device_configuration_done
configure_device: ; set device as configured
mov [configuration], A
ep1_set_config:
mov A, [ep1_stall] ; if endpoint 1 is stalled
and A, FFh
jz ep1_nak_in_out
mov A, STALL_IN_OUT ; set endpoint 1 mode to stall
iowr ep1_mode
jmp ep2_set_config
ep1_nak_in_out:
mov A, NAK_IN ; otherwise set it to NAK IN
iowr ep1_mode
ep2_set_config:
mov A, [ep2_stall] ; check if endpoint2 is stalled
and A, FFh
jz ep2_ack_out
mov A, STALL_IN_OUT
iowr ep2_mode
jmp ep_set_int
ep2_ack_out: ; otherwise set to ACK OUTs
mov A, ACK_OUT
iowr ep2_mode
ep_set_int:
mov A, EP0_INT | EP1_INT | EP2_INT ; enable endpoint 1/2 interrupts
iowr endpoint_int
mov A, 00h
mov [ep1_data_toggle], A ; reset the data toggle
mov [ep2_data_toggle], A
mov [ep1_dmabuff0], A ; reset endpoint 1 fifo values
mov [ep1_dmabuff1], A
mov [ep1_dmabuff2], A
mov [ep1_dmabuff3], A
set_device_configuration_done:
mov A, NO_CHANGE_PENDING
mov [ep0_in_flag], A
jmp initialize_no_data_control
get_device_descriptor: ; GET DESCRIPTOR
mov A, [ep0_dmabuff + WVALUEHI]
asl A
jacc get_device_descriptor_jumptable
send_device_descriptor:
mov A, 00h
index device_desc_table
mov [maximum_data_count], A
mov A, (device_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
send_configuration_descriptor:
mov A, 02h
index config_desc_table:
mov [maximum_data_count], A
mov A, (config_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
send_string_descriptor:
mov A, [ep0_dmabuff + WVALUELO]
asl A
jacc string_jumptable:
language_string:
mov A, 00h
index ilanguage_string
mov [maximum_data_count], A
mov A, (ilanguage_string - control_read_table)
mov [data_start], A
jmp initialize_control_read
manufacturer_string:
mov A, 00h
index imanufacturer_string
mov [maximum_data_count], A
mov A, (imanufacturer_string - control_read_table)
mov [data_start], A
jmp initialize_control_read
product_string:
mov A, 00h
index iproduct_string
mov [maximum_data_count], A
mov A, (iproduct_string - control_read_table)
mov [data_start], A
jmp initialize_control_read
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -