📄 hidtherm.asm
字号:
;******************************************************
;
; file: Thermometer application board firmware
; Date: 03/22/2002
; Description This code provides the functionality
; for a USB HID thermometer application.
; Target: Cypress CY7C63743
;
; Overview
; There are four main sub-systems:
; * USB
; * Thermometer
; * LED
; * Button
;
; The system is started in the reset() routine at reset.
; This routine initializes the USB variables, the IO ports,
; the Thermometer IC, and the data space. All USB
; communication occurs on an interrupt basis. First,
; reset() loops waiting for a USB reset. After receiving
; a USB reset, Main() enables the Endpoint 0 interrupt and
; loops waiting for Setups which ultimately will the
; result in the device being enumerated.
; Once the device has been enumerated on the USB, the main
; polls the thermometer, updates the LED,
; and initializes endpoint 1/2 if appropriate.
; USB
; Endpoint 0 is used to support Control Transfers and
; vendor specific requests. During enumeration setup
; commands are sent to endpoint1 to initialize the
; USB device and to extract configuration information
; from the device
;
; Endpoint 1 is used to transfer interrupt data back to
; the host. In this case we transfer button and thermometer
; data from the back to the host.
;
; Endpoint2 is used to set the state of the LED.
;
; Thermometer
; At power up the thermometer is initialized.
; After the device is configured on the USB, every
; ~256ms we transfer the output data of the thermometer
; to the host when we receive an IN on endpoint1
; LED
; After enumeration the host sets the state of the LED. The
; application also turns off the LED before the application
; closes.
; Button
; The button S5 is measured every millisecond and debounced.
; The switch on/off data is sent to the host
; every time we get an IN on endpoint1.
;
; Endpoint1 packet definition (IN endpoint)
;
; Byte Usage
; 0 button state (1=on,0=off)
; 1 low byte of temperature (Kelvin)
; 2 high byte of temperature (Kelvin)
;
;
; Endpoint 2 packet definition (OUT endpoint)
;
; Byte Usage
; 0 LED state (1=on, 0=off)
;
;
; Port Usage
;
; ---------------------
; | P0[0] P0[4] | TEMP_SS
; | P0[1] P0[5] | TEMP_SI
; | P0[2] P0[6] | TEMP_SO
; | P0[3] P0[7] | TEMP_SCK
; | P1[0] P1[1] |
; | P1[2] P1[3] | SWITCH5
; | P1[4] P1[5] |
; ACTIVE | P1[6] P1[7] |
; GND | VSS D+/SCLK | USB D+
; GND | VPP D-/SDATA| USB D-
; PULLUP | VREG VCC | +5
; | XTALIN XTALOUT |
; ---------------------
;
; Revisions:
; 3-22-2002 SEA Creation
;
;**********************************************************
;
; Copyright 2000 Cypress Semiconductor
; This code is provided by Cypress as a reference. Cypress
; makes no claims or warranties to this firmware's
; suitability for any application.
;
;**********************************************************
;**************** assembler directives *****************
CPU 63743
XPAGEON
INCLUDE "637xx.inc"
INCLUDE "USB.inc"
;**********************************
; data memory variables
; note that we start these at 15h to give more than
; adequate room for the program stack
suspend_count: equ 15h ; suspend counter (i.e. >3ms idle=suspend)
ep1_data_toggle: equ 16h ; endpoint1 data toggle
ep0_data_toggle: equ 17h ; endpoint0 data toggle
data_start: equ 18h ; start of data table for control-read transactions of standard requests
data_count: equ 19h ; requested number of bytes to return
maximum_data_count: equ 1Ah ; number of bytes returned during a control-read transaction
ep0_in_machine: equ 1Bh ; endpoint0 state machine
ep0_in_flag: equ 1Ch ; signals that something needs to happen after a no-data control transaction
configuration: equ 1Dh ; device configured/not configured status
ep1_stall: equ 1Eh ; endpoint1 stall flag
debounce_timer: equ 1Fh ; debounce counters for buttons
current_button_state: equ 20h ; current button status
button_machine: equ 21h ; buttons/optics state machine
temp: equ 22h ; temporary register
event_machine: equ 23h ; report event state machine
pending_data: equ 24h ; data pending from no-data control transactions (i.e. device address)
last_button_state: equ 25h ; last state the button(s) were in
int_temp: equ 26h ; interrupt temporary variable
temp_addr: equ 27h ; address of register inside the temperature sensor
temp_data: equ 28h ; temperature data returned from DS1722
temp_data2: equ 29h ; high byte of temperature data after conversion to Kelvin
ep0_transtype: equ 2Ah ; endpoint0 transaction type, CTRL-RD, CTRL-WR, NO-DATA
ep2_stall: equ 2Bh ; endpoint2 stall flag
report_flag: equ 2Ch ; flag to indicate there is a report available
ep2_data_toggle: equ 2Dh ; endpoint2 data toggle
led_status: equ 2Eh ; state of ACTIVE LED - 1=on,0=off
tm_timer: equ 2Fh ; temperature measurement timer
;**********************************
; STATE MACHINE CONSTANTS
; EP0 IN TRANSACTIONS
TRANS_NONE: equ 00h
TRANS_CONTROL_READ: equ 02h
TRANS_CONTROL_WRITE: equ 04h
TRANS_NO_DATA_CONTROL: equ 06h
;**********************************
; FLAG CONSTANTS
; EP0 NO-DATA CONTROL FLAGS
ADDRESS_CHANGE_PENDING: equ 00h
NO_CHANGE_PENDING: equ 02h
;**********************************
; RESPONSE SIZES
DEVICE_STATUS_LENGTH: equ 2
DEVICE_CONFIG_LENGTH: equ 1
ENDPOINT_STALL_LENGTH: equ 2
INTERFACE_STATUS_LENGTH: equ 2
INTERFACE_ALTERNATE_LENGTH: equ 1
;**********************************
; constants specific to the CY3644 board
TEMP_PORT: equ port0
TEMP_CS: equ 10h
TEMP_SI: equ 20h
TEMP_SO: equ 40h
TEMP_SCK: equ 80h
EE_PORT: equ port0
EE_CS: equ 08h
EE_SI: equ 20h
EE_SO: equ 40h
EE_SCK: equ 80h
BUTTON_PORT: equ port1
SWITCH5: equ 08h
SWITCH4: equ 20h
SWITCH3: equ 80h
LED_PORT: equ port1
ACTIVE: equ 40h
ENUM: equ 10h
AUX01: equ 04h
AUX02: equ 01h
RF_PORT: equ port0
RF_IN: equ 01h
RF_OUT: equ 04h
;**********************************
; Endpoint 1 data fields
BUTTON_DATA: equ ep1_dmabuff0 ; IN report byte positions
TEMP_DATALO: equ ep1_dmabuff1 ; in the IN endpoint fifo
TEMP_DATAHI: equ ep1_dmabuff2
;**********************************
; state machine constants
NO_BUTTON_DATA: equ 00h ; flags to indicate button data is
BUTTON_DATA_PENDING: equ 02h ; available for processing
BUTTON_DEBOUNCE: equ 20 ; button debounce time (milliseconds)
REPORT_DATA_NOT_AVAILABLE: equ 00h ; flags to indicate that report data is
REPORT_DATA_AVAILABLE: equ 01h ; available to be reported
NO_REPORT_PENDING: equ 00h ; flags to indicate pending report status
REPORT_PENDING: equ 02h ; for the IN endpoint
REPORT_PACKET_SIZE: equ 03h ; IN endpoint report size
; SPI Temperature Sensor constants
TEMP_FRAC: equ 01h ; DS1722 data registers
TEMP_INT: equ 02h
TEMP_CTRL_RD: equ 00h ; DS1722 control register
TEMP_CTRL_WR: equ 80h
1SHOT: equ 10h ; control register bit constants
R2: equ 08h
R1: equ 04h
R0: equ 02h
SD: equ 01h
TM_INTERVAL: equ 250 ; measurement intervals (under firmware control)
;*************** interrupt vector table ****************
ORG 00h
jmp Main ; reset vector
jmp Bus_reset ; USB Bus Reset / PS2 interrupt
jmp Error ; 128us interrupt
jmp 1ms_timer ; 1.024ms interrupt
jmp Endpoint0 ; endpoint 0 interrupt
jmp Endpoint1 ; endpoint 1 interrupt
jmp Endpoint2 ; endpoint 2 interrupt
jmp Error ; SPI interrupt
jmp Error ; Capture timer A interrupt
jmp Error ; Capture timer B interrupt
jmp Error ; GPIO interrupt
jmp Error ; Wake-up interrupt
;************** program listing ************************
ORG 1Ah
Error: halt
;*******************************************************
;
; Interrupt handler:Main
; Purpose: The program jumps to this routine when
; the microcontroller has a power on reset or
; a USB reset occurs (firmware controlled jmp).
;
;*******************************************************
Main:
;**********************************
; setup data memory stack pointer
mov A, 68h
swap A, dsp
;**********************************
; clear variables
mov A, 00h
mov [ep0_in_machine], A
mov [configuration], A
mov [ep1_stall], A
mov [ep2_stall], A
mov [suspend_count], A
mov [ep1_dmabuff0], A
mov [ep1_dmabuff1], A
mov [ep1_dmabuff2], A
mov [ep1_dmabuff3], A
mov [ep1_dmabuff4], A
mov [ep1_dmabuff5], A
mov [ep1_dmabuff6], A
mov [ep1_dmabuff7], A
mov [button_machine], A
mov [int_temp], A
mov [event_machine], A
mov [ep0_transtype], A
mov [tm_timer], A
mov A, BUTTON_DEBOUNCE
mov [debounce_timer], A
mov A, SWITCH5
mov [current_button_state], A
mov [last_button_state], A
mov A, FFh
mov [led_status], A
;**********************************
; set port I/O configuration
; setup SPI and RF pins
; 7 - SPI SCLK - strong
; 6 - MISO - resistive (so it's bootstrapped for suspend)
; 5 - MOSI - strong
; 4 - temperature sensor CS - strong
; 3 - EEprom CS - strong
; 2 - RF transmit - strong
; 1 - no connection - strong
; 0 - RF receive - resistive (so it's bootstrapped for suspend)
mov A, FFh
iowr port0_mode1
mov A, TEMP_SCK | TEMP_SI | TEMP_CS | EE_CS | RF_OUT | 02h | RF_IN
iowr port0_mode0
mov A, TEMP_SO | TEMP_SI | TEMP_SCK | EE_CS | RF_IN
iowr port0
; setup LED and buttons pins (everything inits to resistive pullup mode)
; 7 - switch 3 - resistive
; 6 - Active LED - resistive
; 5 - switch 4 - resistive
; 4 - Enum LED - resistive
; 3 - switch 5 - resistive
; 2 - Aux01 LED - resistive
; 1 - no connection - resistive
; 0 - Aux02 LED - resistive
mov A, FFh
iowr port1_mode1
mov A, 00h
iowr port1_mode0
mov A, FFh
iowr port1
;**********************************
; setup SPI interface
; SCLK frequency - 00 (2Mb/s)
; clock polarity - 0
; clock phase - 0
; com mode - 01 (master)
mov A, MODE0
iowr spi_control
; now set up the DS1722 for measurements
; set the control register for
; 8 bit measurements
; no 1-shot measurements
; continual measurement mode
mov A, TEMP_CTRL_WR ; control register write addres
mov [temp_addr], A
mov A, E0h ; 1-shot=0, R2..0=0 (8-bit), shutd=0
mov [temp_data], A
call Spi_temp_write ; write to the control register
mov A, [temp_data]
;**********************************
; enable USB address for endpoint 0
mov A, ADDRESS_ENABLE
iowr usb_address
;**********************************
; enable global interrupts
mov A, (1MS_INT | USB_RESET_INT)
iowr global_int
mov A, EP0_INT
iowr endpoint_int
ei
;**********************************
; enable USB pullup resistor
mov A, VREG_ENABLE
iowr usb_status
task_loop:
;**********************************
; main loop watchdog clear
iowr watchdog
;**********************************
; button debounce task
; check if there is new button data
button_task:
mov A, [button_machine]
cmp A, BUTTON_DATA_PENDING
jnz button_task_done
; if we get here then there is a new button measurement
mov A, NO_BUTTON_DATA ; clear button data event
mov [button_machine], A
; check if there was a change from the last measurement
mov A, [last_button_state]
xor A, [current_button_state]
and A, SWITCH5
cmp A, 00h
jnz new_button_state
; the button is in the same state as we left it last time
; therefore if the debounce timer reaches it's limit
; in this pass of the routine we now have button data
; to report
same_button_state:
mov A, [debounce_timer] ; check if debounce timer has max'd out
cmp A, BUTTON_DEBOUNCE
jz button_task_done
inc [debounce_timer] ; increment the debounce timer
mov A, [debounce_timer] ; check if the new incremented value
cmp A, BUTTON_DEBOUNCE ; of the debounce timer causes us
jnz button_task_done ; to report button data
; if we are here then we have button data to report
mov A, [last_button_state]
and A, SWITCH5
jnz report_button_high
report_button_low: ; report button low (i.e. active)
mov A, 01h
mov [BUTTON_DATA], A
mov A, REPORT_DATA_AVAILABLE
mov [report_flag], A
jmp button_task_done
report_button_high: ; report button high (i.e. inactive)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -