Vous êtes sur la page 1sur 53

;quitar la eeprom del PCB

;Opera con impreso EMP20.PCB


;para FRECUENCIA 16 MHz VECT4 cada 1.024 us
;para los BITS DE CONFIGURACION ver
;adobe pag. 26 y pag 282
;No olvidar para el USB posible, el ejemplo SERAD.ASM
LIST B=8, N=88, P=18F4550
#include <p18F4550.inc>
;#include <usb_defs.inc> se adiciono luego de CBLOCK reg. de trabajo
#include <ENGR2210.inc>
;define macros: repeat, until, case, caseset, break, ends
#define SHOW_ENUM_STATUS
BLOCK ;define bits de BC1
M0,M1,M2,VM01,M3,LS,AOP,EPR
NDC
;b0,b1,b2=M0,M1,M2 numero del mensaje en 2 linea
;b3=VM01 seleciona VME0 VME1 en MDIS
;b4=M3 mensaje en 1 linea|
;b5=LS habilita men. 1 linea
;b6=AOP para alternar el ONF y el TRPW
;b7=EPR programar eeprom dato (TRE, MINR)
BLOCK ;define bits de SAL1
ONF,OPW,SSE,PWO
NDC
;2^0=ONF identica el estado ON-OFF del sauna
;2^1=OPW =0 PWO por teclado(+/-) =1 por ERR1
;2^2=SSE se complementa cada SEgundo
;==============================================
;definen registros de trabajo. Hay desde 20 a 7F
BLOCK
SAW ;en cualquier banco
SAS ;salva Status en Banco_1
SPD ;salva PORTD
;registros en Banco_0
SW ;estado sw leidos en VECT4
T5ms ;tiempo para display
T10m ;unidades en 10 ms
;Controlados pot T10m:
TSEG ;ctrol segundos
TMIN ;ctrl minutos
TATE ;teclado
TMEN ;mensajes
TEPR ;espera para prog. eeprom (seg)
TTEM ;para leer muestras de TEMperatura (pot)
THUM ;para leer muestras de HUMedad del HIH5030 (seg)
;Otros registros
ATE ;ctrl acelera teclado
C1 ;banderas
;termina orden reg. por mensaje
TEPW ;ejecuatado del PWM on (seg.)
EPW ;ejecutado del perodo PWM
;Para calculo del PWM on la diferencia TRE-TLE en ERR1
SAL1 ;salida al reg. SAL1.
SAL2 ;por el PCB
SAL3 ;por el PCB
; registros cuyo orden se usa en los mensajes
MINF ;minutos que faltan sauna ON
MINR ;Minutos referencia sauna ON
RPW ;Perodo referencia PWM seg.
TRPW ;tiempo ON en PWM seg. (se calcula)
HUMH
HUML ;Humedad leida
TLEH ;Temp. actual-leida Vo - alto
TLEL
TLHH ;Tem. leida HEX alto
TLHL ;Temp. leida HEX bajo
TREH ;Temperatura referencia - alto
TREL
;temporales prog. pripal
T23,T24,T25,T26,T27,T28
T29,T2A,T2B,T2C,T2D,T2E
T2F
;para codigo absoluta en ASM se usa CBLOCK para el USB
T30 ;,no se usa
USB_buffer_desc ;res 4
USB_buffer_desc_1
USB_buffer_desc_2
USB_buffer_desc_3 ;cuarto byte
USB_buffer_data ;res 8
USB_buffer_data_1
USB_buffer_data_2
USB_buffer_data_3
USB_buffer_data_4
USB_buffer_data_5
USB_buffer_data_6
USB_buffer_data_7 ;octavo byte
USB_error_flags ;res 1
USB_curr_config ;res 1
USB_device_status ;res 1
USB_protocol ;res 1
USB_idle_rate ;res 1
USB_dev_req ;res 1
USB_address_pending ;res 1
USB_desc_ptr ;res 1
USB_bytes_left ;res 1
USB_loop_index ;res 1
USB_packet_length ;res 1
USB_USTAT ;res 1
USB_USWSTAT ;res 1
OUNTER ;res 1
eature_buffer ;res 2
eature_buffer_1
trl_io_buffer ;res 2
trl_io_buffer_1
Int_io_buffer ;res 2
nt_io_buffer_1
Report_type ;res 1
;para los ejemplos en DOC...GENHID.ASM pag 39/54 y siguientes
;tiene los USB_buffer_desc (4) y USB_buffer_data (8)
;USB_USTAT(1), USB_USWSTAT(1), COUNTER(1)
;Feature_buffer(2), Ctrl_io_buffer(2), Int_io_buffer(2)
;Report_type (1)
My_Value ;res 1

NDC
;definicion otras variables de => usb_defs.inc <=
#define NUM_INTERFACES
#define NUM_STRINGS
; Define the states that the USB interface can be in
#define POWERED_STATE x00
#defineEFAULT_STATE x01
#defineDDRESS_STATE x02
#defineONFIG_STATE x03
; Define the states for Control EndPoints
#defineP_IDLE_STATE x00
#defineP_SETUP_STATE x01
#defineP_DISABLED_STATE xff
#defineNDPT_DISABLED x00
#define ENDPT_IN_ONLY x12
#define ENDPT_OUT_ONLY x14
#define ENDPT_CONTROL x16 ; enable for in, out and setup
#define ENDPT_NON_CONTROL x1E ; enable for in, and out
#define INT_STAT_MASK_RESET x01
#define INT_STAT_MASK_ERROR x02
#define INT_STAT_MASK_TOKEN_DONE x04
#define INT_STAT_MASK_SLEEP x08
#define INT_STAT_MASK_STALL x10
#define TOKEN_OUT (0x01<<2)
#define TOKEN_ACK (0x02<<2)
#define TOKEN_IN (0x09<<2)
#define TOKEN_SETUP (0x0D<<2)
#define USB_Buffer x0480 ; Register location after last buffer de
scriptor register
#define UOWN x07
; offsets from the beginning of the Buffer Descriptor
#define BYTECOUNT x01
#defineDDRESSL x02
#define ADDRESSH x03
; standard descriptor types
#defineEVICE
#defineONFIGURATION
#define STRING
#define INTERFACE
#defineNDPOINT
; HID class descriptor types
#define HID x21
#define REPORT x22
#define PHYSICAL x23
; HID class report types
#define INPUT x01
#define OUTPUT x02
#define FEATURE x03
; offsets from the beginning of the setup data record
#definemRequestType x00
#defineRequest x01
#define wValue x02
#define wValueHigh x03
#define wIndex
#define wIndexHigh x05
#define wLength x06
#define wLengthHigh x07
; Standard USB requests
#define NO_REQUEST xFF
#define GET_STATUS x00
#defineLEAR_FEATURE x01
#define SET_FEATURE x03
#define SET_ADDRESS x05
#define GET_DESCRIPTOR x06
#define SET_DESCRIPTOR x07
#define GET_CONFIGURATION x08
#define SET_CONFIGURATION x09
#define GET_INTERFACE x0A
#define SET_INTERFACE x0B
#define SYNCH_FRAME x0C
; HID Class requests
#define GET_REPORT x01
#define GET_IDLE x02
#define GET_PROTOCOL x03
#define SET_REPORT x09
#define SET_IDLE x0A
#define SET_PROTOCOL x0B
#define GET_STRING_DESCRIPTOR x66
#define HID_SET_REPORT x21
#define VEND_SET_MEMORY x80
#define SVCUSBINT x01 << 2
#define SVCTOKENDONE x02 << 2
#define SVCRESET x03 << 2
#define SVCSLEEP << 2
#define SVCSTALL x05 << 2
#define SVCERROR x06 << 2
#define SVCACTIVITY x07 << 2
#define TOKENOUT x08 << 2
#define TOKENIN x09 << 2
#define TOKENSETUP x0A << 2
#defineLEARFEATURE x0B << 2
#define GETCONFIG x0C << 2
#define GETDESCRIPTOR x0D << 2
#define GETINTERFACE x0E << 2
#define GETSTATUS x0F << 2
#define SETADDRESS x10 << 2
#define SETCONFIG x11 << 2
#define SETFEATURE x12 << 2
#define SETINTERFACE x13 << 2
#defineINISHSETADDRESS x14 << 2
#defineOPYDESC2EP0 x15 << 2
#defineOPYSTRINGDESC2EP0 x16 << 2
#define ZEROLENPACKET x17 << 2
#define EP0 x00 << 3
#define EP1 x01 << 3
#define EP2 x02 << 3
#define STANDARD x00 << 5
#define CLASS x01 << 5
#define VENDOR x02 << 5
#define RECIPIENT_DEVICE x00
#define RECIPIENT_INTERFACE x01
#define RECIPIENT_ENDPOINT x02
#define DEVICE_REMOTE_WAKEUP x01
#define ENDPOINT_HALT x00
BLOVK x400
; Define buffer descriptor table register mapping for no ping-pong buffers
D0OST
BD0OBC
BD0OAL
BD0OAH
BD0IST
BD0IBC
BD0IAL
BD0IAH
BD1OST
BD1OBC
BD1OAL
BD1OAH
BD1IST
BD1IBC
BD1IAL
BD1IAH
BD2OST
BD2OBC
BD2OAL
BD2OAH
BD2IST
BD2IBC
BD2IAL
BD2IAH
BD3OST
BD3OBC
BD3OAL
BD3OAH
BD3IST
BD3IBC
BD3IAL
BD3IAH
BD4OST
BD4OBC
BD4OAL
BD4OAH
BD4IST
BD4IBC
BD4IAL
BD4IAH
BD5OST
BD5OBC
BD5OAL
BD5OAH
BD5IST
BD5IBC
BD5IAL
BD5IAH
BD6OST
BD6OBC
BD6OAL
BD6OAH
BD6IST
BD6IBC
BD6IAL
BD6IAH
BD7OST
BD7OBC
BD7OAL
BD7OAH
BD7IST
BD7IBC
BD7IAL
BD7IAH
BD8OST
BD8OBC
BD8OAL
BD8OAH
BD8IST
BD8IBC
BD8IAL
BD8IAH
BD9OST
BD9OBC
BD9OAL
BD9OAH
BD9IST
BD9IBC
BD9IAL
BD9IAH
BD10OST
BD10OBC
BD10OAL
BD10OAH
BD10IST
BD10IBC
BD10IAL
BD10IAH
BD11OST
BD11OBC
BD11OAL
BD11OAH
BD11IST
BD11IBC
BD11IAL
BD11IAH
BD12OST
BD12OBC
BD12OAL
BD12OAH
BD12IST
BD12IBC
BD12IAL
BD12IAH
BD13OST
BD13OBC
BD13OAL
BD13OAH
BD13IST
BD13IBC
BD13IAL
BD13IAH
BD14OST
BD14OBC
BD14OAL
BD14OAH
BD14IST
BD14IBC
BD14IAL
BD14IAH
BD15OST
BD15OBC
BD15OAL
BD15OAH
BD15IST
BD15IBC
BD15IAL
BD15IAH
;INICIA AREA DE DEFINICION DE DESCRIPTORES
;______________________________________________
;se inicia programa - CADA instruccion son 2 bytes
;______________________________________________
;Revizar datos de la EEPROM (MINR a TREL .11 Bytes)
ORG
NOP
LRF WDTCON ;no habilta WDT
CF TRISA,RA4 ;Solo RA4 como OUT
GOTO SAUN
;___________________________________________
;comienza para VECT4 (0x0008). TMR0 con prescalar 1:16
;Fos=16Mhz es cada 1.02400
VECT4
CF INTCON,GIE
TFSC INTCON,GIE
RA VECT4
;al ocurrir INT automticamente en el STACK:dir. retorno, W y STATUS
TFSC INTCON,TMR0IF ;T0IF
RA VEC2
;antes de retirarse se debe recuperar el STATUS
VEC1
MOVLW
MOVWF INTCON
RETFIE
;____________________________
;actualiza tiempos cada 4.095 ms
;salva registros
VEC2
CF PORTC,RC0 ;E del LTN
CF INTCON,TMR0IF ;TOIF
;Actualiza las salidas SALi
MOVF SAL1,W
NDLW x0F
MOVWF PORTD
SF PORTA,RA4 ;SAL1
CF PORTA,RA4
MOVF SAL2,W
MOVWF PORTD
SF PORTC,RC5 ;SAL2
CF PORTC,RC5
MOVF SAL3,W
MOVWF PORTD
SF PORTC,RC1 ;SAL3
CF PORTC,RC1
;actualiza tiempos
MOVF T5ms,F
TFSS STATUS,Z
ECF T5ms,F
ECFSZ T10m,F
RA VEC1
;pasaron 10.24 ms
MOVLW .10
MOVWF T10m
MOVF TATE,F ;TATE
TFSS STATUS,Z
ECF TATE,F
MOVF TMEN,F ;TMEN
TFSS STATUS,Z
ECF TMEN,F
MOVF TEPR,F ;TEPR
TFSS STATUS,Z
ECF TEPR,F
MOVF TTEM,F ;TTEM
TFSS STATUS,Z
ECF TTEM,F
ECFSZ TSEG,F ;TSEG
RA VEC1
;paso un segundo aprox. (1.024000)
SFC1,LS
;con =.100 da 1.023999 =.98 da 1.003519
MOVLW .98
MOVWF TSEG
;complementa SAL1 bit 2^2=SSE (cada segundo)
TG SAL1,SSE
;para muestra de humedad
MOVF THUM,F ;THUM
TFSS STATUS,Z ;puede ser BZ n con n=0
ECF THUM,F
;actualiza tiempos del PWM
MOVFEPW,F
TFSS STATUS,Z
ECFEPW,F
MOVF TRPW,F
TFSS STATUS,Z
ECF TRPW,F
;no hay actualizacion calendario. Minutos para SAUNA
ECFSZ TMIN,F
RA VEC1
MOVLW .60
MOVWF TMIN
MOVF MINF,F
TFSS STATUS,Z
ECF MINF,F
RA VEC1
;_____________________________________________________
; RUTINAS
;_____________________________________________________
ORG0
VME0
LRF PCLATH,0
SF PCLATH,0
DDWF PCL,F
;Para alternar en 1 fila-16 caracteres
MOVET "Ovelma@epm.net.c",0ff
MCOFT "Sauna estado OFF",0ff ;con AOP=0 y ONF=0
MCON T "Sauna estado ON ",0ff ;con AOP=0 y ONF=1
MPW1T "PWM fijado tecla",0ff ;con AOP=1 y OPW=0
MPW2T "PWM calculo ERR ",0ff ;con AOP=1 y OPW=1
;para acelerar teclado
DACTT .70,.67,.63,.58
T .53,.45,.38,.25
T .20,.20,.20,.18
T .16,.14,.13,.12
T .10
ORG0
VME1
LRF PCLATH
SF PCLATH,1
DDWF PCL,F
;para la 2 fila-13 caracteres. El orden de mens. se usa en TECLi
MDUET "Faltan (min):",0ff ;mensaje 000 con MINF
MDURT "Tiempo SAUNA:",0ff ;mensaje 001 con MINR
MCPWT "Ciclo PWM (s)",0ff ;mensaje 010 con CRPW
MONPT "TiempON pwm :",0ff ;mensaje 011 con TRPW
;para mensajes con datos mayor a un byte. Mensaje de 11 caracteres
MHUMT " Humedad: ",0ff ;mensaje 100 con HUML
MTLET "Temp. Vo : ",0ff ;mensaje 101 con TLEH,TEML
MTLHT "T.Act.HEX: ",0ff ;mensaje 110 con TLHH,TLHL
MTRET "Temp. Ref: ",0ff ;mensaje 111 con TREH,TREL
;__________________________________________
;Los mensajes terminas con 0FF
;llega en W el offset en VME0
MDIS
MOVWF T27
TFSCC1,VM01
RA MDI2
ALL VME0
MDI1
DDLW
TFSC STATUS,Z
RETURN
DDLW -1
ALLADI
INCF T27,F
INCF T27,W ;CADA DATO SON DOS BYTES
RA MDIS
MDI2
ALL VME1
RA MDI1
;_____________________________________
;LLevara W=x1,x0 a el LTN
CDIW
MOVWF T2E
SWAPF T2E,W
ALLDIS
MOVF T2E,W
CDIS
NDLW
DDLW ;con el valor ASCII
CADI
SF PORTC,RC2 ;para RS=1
;_____________________________________________________
;llega en W=DATO para DISPLAY
DLTN
MOVWF PORTD
SF PORTC,RC0 ;E del LTN
MOVLW
ALL TMP0
CF PORTC,RC0
RETURN
;________________________________________
PLTN
CF PORTC,RC2 ;dispone RS=0
ALLLTN
TMPR
MOVLW
TMP0
MOVWF T5ms
TMP1
MOVF T5ms,W
TFSS STATUS,Z
RA TMP1
RETURN
;_____________________________________________________
;valor T2E,2F (alto,bajo) a BCD
;resultado ajustado izquierda en:
;T2B,2C,2D,2E,2F=0x4,0x3,0x2,0x1,0x0
;y tambien W=T2F
;valor cero no significativo es F0h
;usa W,FSR0,T28,29,2A,2B,2C,2D,2E,2F
BCD
MOVLW .16
MOVWF T28 ;long. bits
;en T2B,T2C,T2D=x4x3x2x1x0 el BCD
LRF T2D
LRF T2C
LRF T2B
;correcion datos T2B,T2C,T2D
BD1
MOVLW T2B
MOVWFSR0L
MOVLW
MOVWF T29
BD2
MOVLW0 ;correcion byte-alto
NDWF INDF0,W
MOVWF T2A
SUBLW
TFSC STATUS,C
RAD3
MOVLW
DDWF T2A,F ;T2A=x1 0
BD3
MOVLW ;correcion byte-bajo
NDWF INDF0,W
MOVWF INDF0 ;IND0=0 x0
SUBLW
TFSC STATUS,C
RAD4
MOVLW
DDWF INDF0,F
BD4
MOVF T2A,W
DDWF INDF0,F ;recupera dato
INCFSR0L,F
ECFSZ T29,F
RAD2
;FSR0 apunta T2E e inicia rotacion
;el binario se destruye
MOVLW
MOVWF T29
INCFSR0L,F
INCFSR0L,F
BD5
CFSNZSR0L,F ;DECF altera el CY en el 4550
NOP
RLCF INDF0,F
ECFSZ T29,F ;no altera el CY
RAD5
;proximo bit a convertir
ECFSZ T28,F
RAD1
;En T2B,2C,2D el bcd = 0x4 x3x2 x1x0
;se separaran cada bcd en un byte (bcd=T2B,2C,2D,2E,2F)
;el T2B es un solo valor BCD
BD6
SWAPF T2D,W
MOVWF T2E
MOVF T2D,W
MOVWF T2F
MOVLW
NDWF T2E,F
NDWF T2F,F
MOVF T2C,W
MOVWF T2D
SWAPF T2C,F
MOVLW
NDWF T2C,F
NDWF T2D,F
;separados se ordena cero significativo
MOVLW
MOVWF T29
BD7
MOVF T2B,W
TFSS STATUS,Z
RETURN
;llega cuando primer valor es cero
;Se rotaran datos a la izq.
MOVF T2C,W
MOVWF T2B
MOVF T2D,W
MOVWF T2C
MOVF T2E,W
MOVWF T2D
MOVF T2F,W
MOVWF T2E
MOVLW -10 ;podra ser 20H
MOVWF T2F
ECFSZ T29,F
RAD7
;para ver 00 com 0
LRF T2B
RETURN
;========================================
BCDm
MOVWF T2F
LRF T2E
RACD
BCD2
ALLCDm
MOVLW
RAD8
;para enviar los tres primeros digitos
BCD3
ALLCDm
MOVLW
RAD8
;para enviar los cinco digitos
BCD5
ALLCD
MOVLW
BD8
MOVWF T29
MOVLW T2B
MOVWFSR0L
BD9
MOVLW
DDWF INDF0,W
ALLADI
INCFSR0L,F
ECFSZ T29,F
RAD9
RETURN
;========================================
;realiza la suma T2E,T2D,2C=T2E,2D,2C+T2B,2A,29 ( alto,bajo)
SUMA
MOVF T2C,W
DDWF T2E,F
TFSC STATUS,C
INCF T2F,F
MOVF T2D,W
DDWF T2F,F
RETURN
;========================================
;realiza la diferencia T2E,T2D,2C=T2E,2D,2C+T2B,2A,29 ( alto,bajo)
DIFE
MOVF T29,W
SUBWF T2C,F
TFSS STATUS,C
RAIF2
;continua 2 byte
DIF1
MOVF T2A,W
SUBWF T2D,F
TFSS STATUS,C
ECF T2E,F
MOVF T2B,W
SUBWF T2E,F
RETURN
;primer prestamo
DIF2
MOVLW -1
DDWF T2D,F
TFSS STATUS,C
DDWF T2E,F
RAIF1
;========================================
;no ALTERA los T2B,2A
;rutina para MULTiplicar...MNDO*MDOR=PROD
;MNDO=T2B,2A=alto,bajo MDOR=T2D,2C=alto,bajo
;... PROD=T2F,2E,2D,2C=alto....bajo
;registros temporales T29
MULT2
LRF T2E
LRF T2F
MOVLW .16
MOVWF T29
;comienza analisis de ceros
MUL21
TFSS T2C,0
RA MUL22
;llega el T2F,0 en uno
MOVF T2A,W
DDWF T2E,F
TFSC STATUS,C
INCF T2F,F
MOVF T2B,W
DDWF T2F,F
;llego el bit menos significativo en cero
MUL22
CF STATUS,C ;viene el CARRY definido
RRCF T2F,F ;mayor peso
RRCF T2E,F
RRCF T2D,F
RRCF T2C,F ;menor peso
ECFSZ T29,F ;si faltan bits
RA MUL21
RETURN
;========================================
;rutina para MULT=T2D*T2C = T2F,2E (alto,bajo)
;registros temporales T29. No altera el T2C
MULT
LRF T2F
LRF T2E
MOVLW
MOVWF T29
MOVF T2C,W
CF STATUS,C
;comienza analisis de ceros
MUL1
RRCF T2D,F
TFSC STATUS,C
DDWF T2F,F
RRCF T2F,F ;mayor peso
RRCF T2E,F
ECFSZ T29,F ;si faltan bits
RA MUL1
RETURN
;========================================
;rutina para DIVIDIR
;..(T2F,2E,2D,2C)/(T2B,2A,29,28)=T2F,2E,2D,2C
;R1 en T24,25,26,27 y Y es T2B,2A,29,28
;el formato dos bytes es ALTO-BAJO
;RESULTADO en T2F,2E,2D,2C=alto,...,bajo
;sale W con T3B ( si resultado es un byte )
DIV
LRF T24 ;inicia el "R1"
LRF T25
LRF T26
LRF T27
MOVLW .33 ;long bits+1 es 8*4+1
MOVWF T23
DIV1
ECFSZ T23,F
RAIV2
;al terminar W con valor bajo del resultado
INCF T2C,W
RETURN
;continua con division
DIV2
CF STATUS,C
RLCF T2C,F
RLCF T2D,F
RLCF T2E,F
RLCF T2F,F
RLCF T27,F
RLCF T26,F
RLCF T25,F
RLCF T24,F
;"R1"=T24,25,26,27 y Y=T2B,2A,29,28 en orden MSB,.,LSB
;calculara si requiere ajuste(si "R1" mayor "Y")
MOVF T24,W
SUBWF T2B,W
TFSC STATUS,Z
RAIV5
;T2A("R1a") no es igual a T27("Ya")
DIV3
TFSC STATUS,C
RAIV1
;Debe corregir "R1"="R1"-"Y"
DIV4
MOVF T28,W ;"Yb"
SUBWF T27,F
TFSS STATUS,C
ECF T26,F
MOVF T29,W ;"Ym"
SUBWF T26,F
TFSS STATUS,C
ECF T25,F
MOVF T2A,W ;"Ya"
SUBWF T25,F
TFSS STATUS,C
ECF T24,F
MOVF T2B,W
SUBWF T24,F
SF T2C,0 ;correcion
RAIV1
;altos M son iguales y chequea con altos m
DIV5
MOVF T25,W
SUBWF T2A,W
TFSS STATUS,Z
RAIV3
;altos m son iguales y chequea con medios
MOVF T26,W
SUBWF T29,W
TFSS STATUS,Z
RAIV3
;altos y medios son iguales y chequea con bajos
MOVF T27,W
SUBWF T28,W
TFSC STATUS,C
RAIV1
RAIV4
;==============================================
; RUTINAS y DATOS PARA LA USB
;==============================================
;la indicacion de estado, inicio, etc. del USB en SLA2
;los bits que la definen son:
BLOCK
LEUS,SERU
NDC
;2^0 = LEUS se INI_USB
;2^1= SERU esta en ServiceUSB
;2^2=
;2^3=
;2^4=
;2^5=
;2^6=
;2^7=
;_______________________________________________________________________________
_________________
;define el estado para ControlEndPoints ver doc genhid 21/54. Se encuentran en u
sb_defs.inc
;_______________________________________________________________________________
_________________
;la tabla Descriptor_begin esta a luego de USBSTUFF
;el "USBSTUFF code" pasa los DB en memoria de programa a la ram. usando los reg.
TBLPTRU, H, L y TABLAT
;termina cuando encuetra la expresin Descriptor_end
;USBSTUFFode
Descriptor
USBSTUFF
MOVLW UPPER Descriptor_begin ;movlw upper Descriptor_begin
MOVWF TBLPTRU ;movwfTBLPTRU
MOVLW HIGH Descriptor_begin ;movlwhigh Descriptor_begin
MOVWF TBLPTRH ;movwfTBLPTRH
MOVLW LOW Descriptor_begin ;movlwlow Descriptor_begin
anksel USB_desc_ptr
DDWF USB_desc_ptr ;addwfUSB_desc_ptr, W
TFSS STATUS,C ;ifset STATUS, C
INCF TBLPTRH ;incfTBLPTRH, F
TFSS STATUS,Z ;ifset STATUS, Z
INCF TBLPTRU ;incfTBLPTRU, F
MOVWF TBLPTRL ;movwfTBLPTRL
TBLRD* ;tblrd*
;ver adobe pag 81 a 85, 300
MOVF TABLAT,W ;movfTABLAT, W
RETURN ;return
;_______________________________________________________________________________
_________________
;el DB 0x02, 0X01 se almacena 0x01 y luego el 0x02. ATENCIN AL ORDEN
;no opera como el DT
;El ControlEndPoints, DEVICE, NUM_CONFIGURATION , etc.
;estan definidos en - usb_defs.inc
;ver pag 19/54 a la 21/54 del documento expl. del genhid.asm
;Seccion Adobe 17.10.6.5 pg 187
Descriptor_begin
Device
b x12, DEVICE ; bLength, bDescriptorType
b x00, 0x02 ; bcdUSB (low byte), bcdUSB (high byte)
b x00, 0x00 ; bDeviceClass, bDeviceSubClass
b x00, 0x08 ; bDeviceProtocl, bMaxPacketSize
b x25, 0x09 ; idVendor (low byte), idVendor (high byte)
b x99, 0x12 ; idProduct (low byte), idProduct (high byte)
b x01, 0x00 ; bcdDevice (low byte), bcdDevice (high byte)
b x01, 0x02 ; iManufacturer, iProduct
b x00, NUM_CONFIGURATIONS ; iSerialNumber (none), bNumConfigurations
Configuration1
b x09, CONFIGURATION ; bLength, bDescriptorType
b x29, 0x00 ; wTotalLength (low byte), wTotalLength (high byte)
b NUM_INTERFACES, 0x01 ; bNumInterfaces, bConfigurationValue
b x00, 0xA0 ; iConfiguration (none), bmAttributes
b x32, 0x09 ; bMaxPower (100 mA), bLength (Interface1 descriptor sta
rts here)
b INTERFACE, 0x00 ; bDescriptorType, bInterfaceNumber
b x00, 0x02 ; bAlternateSetting, bNumEndpoints (excluding EP0)
b x03, 0x00 ; bInterfaceClass (HID code), bInterfaceSubClass
b x00, 0x00 ; bInterfaceProtocol, iInterface (none)
HID1
b x09, HID ; bLength, bDescriptorType
b x01, 0x01 ; bcdHID (low byte), bcdHID (high byte)
b x00, 0x01 ; bCountryCode (none), bNumDescriptors
b REPORT, 0x2F ; bDescriptorType, wDescriptorLength (low byte)
b x00, 0x07 ; wDescriptorLength (high byte), bLength (Endpoint1 desc
ritor starts here)
bNDPOINT, 0x81 ; bDescriptorType, bEndpointAddress (EP1 IN)
b x03, 0x08 ; bmAttributes (Interrupt), wMaxPacketSize (low byte)
b x00, 0x01 ; wMaxPacketSize (high byte), bInterval (1 ms)
Endpoint2
b x07, ENDPOINT; bLength, bDescriptorType
b x01, 0x03 ; bEndpointAddress (EP1 OUT), bmAttributes (Interrupt)
b x08, 0x00 ; wMaxPacketSize (low byte), wMaxPacketSize (high byte)
b x01 ; bInterval
;el bInterval es el intervalo para polling endpoint data transfer
Report1
b x06, 0xA0 ; Usage Page (Vendor Defined),
b xFF, 0x09 ; ..., Usage ID (Vendor Defined)
b x01, 0xA1 ; ..., Collection (Application)
b x01, 0x09 ; ..., Usage ID (Vendor Defined) ; The Input Re
port
b x03, 0x15 ; ..., Logical Minimum (0)
b x00, 0x26 ; ..., Logical Maximum (255)
b x00, 0xFF ; ...,
b x75, 0x08 ; Report Size (8 bits),
b x95, 0x02 ; Report Count (2 fields),
b x81, 0x02 ; Input (Data, Variable, Absolute),
b x09, 0x04 ; Usage ID (Vendor Defined), ; The Output R
eport
b x15, 0x00 ; Logical Minimum (0),
b x26, 0x00 ; Logical Maximum (255)
b xFF, 0x75 ; ..., Report Size (8 bits)
b x08, 0x95 ; ..., Report Count (2 fields)
b x02, 0x91 ; ..., Output (Data, Variable, Absolute)
b x02, 0x09 ; ..., Usage ID (Vendor Defined) ; The Feature
Report
b x05, 0x15 ; ..., Logical Minimum (0)
b x00, 0x26 ; ..., Logical Maximum (255)
b x00, 0xFF ; ...,
b x75, 0x08 ; Report Size (8 bits),
b x95, 0x02 ; Report Count (2 fields),
b xB1, 0x02 ; Feature (Data, Variable, Absolute),
b xC0 ; End Collection
String0
b String1-String0, STRING ; bLength, bDescriptorType
b x09, 0x04 ; wLANGID[0] (low byte), wLANGID[0] (high byte)
String1
b String2-String1, STRING ; bLength, bDescriptorType
;el bStrng
T "Microchip USB Connection"
String2
bescriptor_end-String2, STRING ; bLength, bDescriptorType
T "USB Generico con 18F4550"
Descriptor_end
;_______________________________________________________________________________
_________________
;rutina para iniciar el USB. ver doc genhid pag 15/54
INI_USB
LRF UIR ;pag 180 - clear las banderas de interrupcin por USB
LRF UIE ;pag 181 - disable las interrupciones por USB
MOVLW x14
MOVWF UCFG ;pag 167-168
;USB para FULL-speed transfers y usa el on-chip transciever y resistencias pull-
up. Even/Odd ping-pong buffer disable (pag 177)
MOVLW x08
MOVWF UCON ;pag 166
;habilita modulo USB y los circuitos asociados.
;Los Ping-Pong BD Indicator (PPBI tambien en reg. USTAT) en la tabla BD se lleva
n a 0
LRF USB_curr_config
LRF USB_idle_rate
LRF USB_USWSTAT ;default to powered state
MOVLW x01
MOVWF USB_device_status
MOVWF USB_protocol ;default protocol to report protocol initially
MOVLW NO_REQUEST ;con valor 0xFF en usb_defs.inc
MOVWF USB_dev_req ;No device requests in process
;habilita indicador LED en SAL2,LEUS
SF SAL2,LEUS
RETURN
;_______________________________________________________________________________
_________________
;es importante elENGR2210.INC en esta rutina
ServiceUSB
select ;macro en ENGR2210.inc
aseset UIR,UERRIF,ACCESS ;macro en ENGR2210.inc
LRF UEIR ;USB error de interrupciones
reak ;MACRO
aseset UIR, SOFIF,ACCESS
CF UIR,SOFIF ;inicia START OF FRAME token receiver
reak
aseset UIR, IDLEIF,ACCESS
CF UIR,IDLEIF ;IDLE detect interrupt
;USB modulo y circuitos en POWER CONSERVE, SIE clock inactivo
SF UCON,SUSPND
#ifdef SHOW_ENUM_STATUS
MOVLW xE0
NDWF SAL2,F ;andwf PORTA, F
;inicia testigo en SAL2
SF SAL2,4 ;bsf PORTA, 4
#endif
reak
aseset UIR, ACTVIF,ACCESS
CF UIR,ACTVIF ;inicia actividad detectada en D+/D-
CF UCON,SUSPND ;opera normalmente cxtos del USB y el SIE
#ifdef SHOW_ENUM_STATUS
MOVLW xE0
NDWF SAL2,F ;andwf PORTA, F
anksel USB_USWSTAT
MOVF USB_USWSTAT,W
;define banderas para SAL2 de acuerdo al STATUS del USB
select
ase POWERED_STATE
MOVLW x01
reak
aseEFAULT_STATE
MOVLW x02
reak
aseDDRESS_STATE
MOVLW x04
reak
aseONFIG_STATE
MOVLW x08
nds
;Termina la directiva select - case
IORWF SAL2,F
#endif
reak
aseset UIR, STALLIF,ACCESS
CF UIR,STALLIF ;inica el handshake del STALL
reak
aseset UIR, URSTIF,ACCESS
anksel USB_curr_config
LRF USB_curr_config
;inicia banderas TRNIS en cuatro veces para inicar el USTAT FIFO
CF UIR,TRNIF
CF UIR,TRNIF
CF UIR,TRNIF
CF UIR,TRNIF
ankselD0OBC
MOVLW x08
MOVWFD0OBC
MOVLW LOW USB_Buffer ; EP0 OUT gets a buffer...
MOVWFD0OAL
MOVLW HIGH USB_Buffer
MOVWFD0OAH ; ...set up its address
MOVLW x88 ; set UOWN bit (USB can write)
MOVWFD0OST
MOVLW LOW (USB_Buffer+0x08) ;; EP0 IN gets a buffer...
MOVWFD0IAL
MOVLW HIGH (USB_Buffer+0x08)
MOVWFD0IAH ; ...set up its address
MOVLW x08 ;clear UOWN bit (MCU can write)
MOVWFD0IST
LRF UADDR ; set USB Address to 0
LRF UIR ;clear all the USB interrupt flags
MOVLWNDPT_CONTROL
MOVWF UEP0 ;EP0 is a control pipe and requires an ACK
MOVLW xFF ;enable all error interrupts
MOVWF UEIE
anksel USB_USWSTAT
MOVLWEFAULT_STATE
MOVWF USB_USWSTAT
MOVLW x01
MOVWF USB_device_status ; self powered, remote wakeup disabled
#ifdef SHOW_ENUM_STATUS
MOVLW xE0
NDWF SAL2,F ;andwf PORTA, F
;activa bandera SAL2,LEUS
SF SAL2,1 ;para indicar Powered state
#endif
reak
aseset UIR, TRNIF,ACCESS
MOVLW x04
MOVWFSR0H
MOVF USTAT,W
MOVWFSR0L
anksel USB_buffer_desc
MOVF POSTINC0,W
MOVWF USB_buffer_desc
MOVF POSTINC0,W
MOVWF USB_buffer_desc+1
MOVF POSTINC0,W
MOVWF USB_buffer_desc+2
MOVF POSTINC0,W
MOVWF USB_buffer_desc+3
MOVF POSTINC0,W
MOVWF USB_USTAT ; save the USB status register
CF UIR,TRNIF ;clear TRNIF interrupt flag
#ifdef SHOW_ENUM_STATUS
NDLW x18 ;extract EP bits
select
ase EP0
MOVLW x20
reak
ase EP1
MOVLW x40
reak
ase EP2
MOVLW x80
reak
nds
XORWF SAL2,F ;toggle bit 5, 6, or 7 of PORTA to reflect EP activity
#endif
MOVF USB_buffer_desc,w
NDLW X3c ;extract PID bits
select
ase TOKEN_SETUP
ALL ProcessSetupToken
reak
ase TOKEN_IN
ALL ProcessInToken
reak
ase TOKEN_OUT
ALL ProcessOutToken
reak
nds
reak
nds
RETURN
;_______________________________________________________________________________
_________________
;Una vez que DESCRIPTOR del dispositivo ha sido enviado, un STATUS TRANSACTION s
igue:
;El sector de accesar cdigo al USB_buffer_data es el ProcessSetupToken. (Pag23-24
/54)
ProcessSetupToken
anksel USB_buffer_data
MOVF USB_buffer_desc+ADDRESSH,W
MOVWFSR0H
MOVF USB_buffer_desc+ADDRESSL,W
MOVWFSR0L
MOVF POSTINC0,W
MOVWF USB_buffer_data
MOVF POSTINC0,W
MOVWF USB_buffer_data+1
MOVF POSTINC0,W
MOVWF USB_buffer_data+2
MOVF POSTINC0,W
MOVWF USB_buffer_data+3
MOVF POSTINC0,W
MOVWF USB_buffer_data+4
MOVF POSTINC0,W
MOVWF USB_buffer_data+5
MOVF POSTINC0,W
MOVWF USB_buffer_data+6
MOVF POSTINC0,W
MOVWF USB_buffer_data+7
ankselD0OBC
MOVLW x08
MOVWFD0OBC ;reset the byte count
MOVWFD0IST ;return the in buffer to us (dequeue any pending request
s)
anksel USB_buffer_data+bmRequestType
ifl USB_buffer_data+bmRequestType, ==, 0x21
movlw xC8
otherwise
movlw x88
ndi
ankselD0OST
MOVWFD0OST
;set EP0 OUT UOWN back to USB and DATA0/DATA1 packet according to request type
CF UCON,PKTDIS
;assuming there is nothing to dequeue, clear the packet disable bit
anksel USB_dev_req
MOVLW NO_REQUEST
MOVWF USB_dev_req ; clear the device request in process
MOVF USB_buffer_data+bmRequestType,W
NDLW x60 ;extract request type bits
select
ase STANDARD
ALL StandardRequests
reak
ase CLASS
ALLlassRequests
reak
ase VENDOR
ALL VendorRequests
reak
efault
SF UEP0,EPSTALL ;set EP0 protocol stall bit to signify Request E
rror
nds
RETURN
;_______________________________________________________________________________
_________________
ProcessInToken
anksel USB_USTAT
MOVF USB_USTAT,W
NDLW x18 ; extract the EP bits
select
ase EP0
MOVF USB_dev_req,w
select
ase SET_ADDRESS
MOVF USB_address_pending,W
MOVWF UADDR
select
ase 0
MOVLWEFAULT_STATE
MOVWF USB_USWSTAT
#ifdef SHOW_ENUM_STATUS
movlw xE0
ndwf SAL2,F ;PORTA, F
sf SAL2,1 ;PORTA, 1
#endif
reak
efault
movlwDDRESS_STATE
movwf USB_USWSTAT
#ifdef SHOW_ENUM_STATUS
movlw xE0
ndwf SAL2,F ;PORTA, F
sf SAL2,2 ;PORTA, 2
#endif
nds
reak
ase GET_DESCRIPTOR
ALL SendDescriptorPacket
reak
nds
reak
aseP1
reak
aseP2
reak
nds
RETURN
;_______________________________________________________________________________
_________________
;Cuando el host desea enviar data interrumpiendo al al dispositivo, el recurre a
un OUT token seguido de un paquete de datos conteniendo wl dato
;de la interrupcin. (Pag 25/54)
ProcessOutToken
anksel USB_USTAT
movf USB_USTAT, W
ndlw x18 ; extract the EP bits
select
aseP0
movf USB_dev_req, W
select
ase SET_REPORT
movlw NO_REQUEST
movwf USB_dev_req ; clear device request
ankselD0OBC
ifl BD0OBC, ==, 0x02
movfD0OAH, W ; put EP0 OUT buffer pointer...
movwfSR0H
movfD0OAL, W
movwfSR0L ; ...into FSR0
anksel Report_type
movf Report_type, W
select
ase OUTPUT
movf POSTINC0, W ; get the first byte in the buffer and...
movwftrl_io_buffer ; ...put it in the conrtol I/O report buffer
movf INDF0, W ; get the second byte in the buffer and...
movwftrl_io_buffer+1 ; ...put it the control I/O report buffer
reak
aseEATURE
movf POSTINC0, W ; get the first byte in the buffer and...
movwfeature_buffer ; ...put it in the feature report buffer
movf INDF0, W ; get the second byte in the buffer and...
movwfeature_buffer+1 ; ...put it the feature report buffer
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
nds
ankselD0OBC
movlw x08
movwfD0OBC
movlw x88
movwfD0OST
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
ase EP1
reak
ase EP2
reak
nds
RETURN
;_______________________________________________________________________________
_________________
StandardRequests
movf USB_buffer_data+bRequest, W
select
ase GET_STATUS
movf USB_buffer_data+bmRequestType, W
ndlw x1F ; extract request recipient bits
select
ase RECIPIENT_DEVICE
ankselD0IAH
movfD0IAH, W
movwfSR0H
movfD0IAL, W ; get buffer pointer
movwfSR0L
anksel USB_device_status
movf USB_device_status, W ; copy device status byte to EP0 buffer
movwf POSTINC0
lrf INDF0
ankselD0IBC
movlw x02
movwfD0IBC ; set byte count to 2
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
ase RECIPIENT_INTERFACE
movf USB_USWSTAT, W
select
aseDDRESS_STATE
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
reak
aseONFIG_STATE
ifl USB_buffer_data+wIndex, <, NUM_INTERFACES
ankselD0IAH
movfD0IAH, W
movwfSR0H
movfD0IAL, W ; get buffer pointer
movwfSR0L
lrf POSTINC0
lrf INDF0
movlw x02
movwfD0IBC ; set byte count to 2
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
nds
reak
ase RECIPIENT_ENDPOINT
movf USB_USWSTAT, W
select
aseDDRESS_STATE
movf USB_buffer_data+wIndex, W ; get EP
ndlw x0F ; strip off direction bit
ifset STATUS, Z, ACCESS ; see if it is EP0
ankselD0IAH
movfD0IAH, W ; put EP0 IN buffer pointer...
movwfSR0H
movfD0IAL, W
movwfSR0L ; ...into FSR0
ifset UEP0, EPSTALL, ACCESS
movlw x01
otherwise
movlw x00
ndi
movwf POSTINC0
lrf INDF0
movlw x02
movwfD0IBC ; set byte count to 2
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
aseONFIG_STATE
ankselD0IAH
movfD0IAH, W ; put EP0 IN buffer pointer...
movwfSR0H
movfD0IAL, W
movwfSR0L ; ...into FSR0
movlw high UEP0 ; put UEP0 address...
movwfSR1H
movlw low UEP0
movwfSR1L ; ...into FSR1
anksel USB_buffer_data+wIndex
movf USB_buffer_data+wIndex, W ; get EP and...
ndlw x0F ; ...strip off direction bit
ifclr PLUSW1, EPOUTEN, ACCESS
ndifclr PLUSW1, EPINEN, ACCESS
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
otherwise
ifset PLUSW1, EPSTALL, ACCESS
movlw x01
otherwise
movlw x00
ndi
movwf POSTINC0
lrf INDF0
ankselD0IBC
movlw x02
movwfD0IBC ; set byte count to 2
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
ndi
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
ase CLEAR_FEATURE
reak
ase SET_FEATURE
movf USB_buffer_data+bmRequestType, W
ndlw x1F ; extract request recipient bits
select
ase RECIPIENT_DEVICE
movf USB_buffer_data+wValue, W
select
ase DEVICE_REMOTE_WAKEUP
ifl USB_buffer_data+bRequest, ==, CLEAR_FEATURE
cf USB_device_status, 1
otherwise
sf USB_device_status, 1
ndi
ankselD0IBC
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
reak
ase RECIPIENT_ENDPOINT
movf USB_USWSTAT, W
select
aseDDRESS_STATE
movf USB_buffer_data+wIndex, W ; get EP
ndlw x0F; strip off direction bit
ifset STATUS, Z, ACCESS ; see if it is EP0
ifl USB_buffer_data+bRequest, ==, CLEAR_FEATURE
cf UEP0, EPSTALL
otherwise
sf UEP0, EPSTALL
ndi
ankselD0IBC
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
aseONFIG_STATE
movlw high UEP0 ; put UEP0 address...
movwfSR0H
movlw low UEP0
movwfSR0L ; ...into FSR0
movf USB_buffer_data+wIndex, W ; get EP
ndlw x0F ; strip off direction bit
ddwfSR0L, F ; add EP number to FSR0
ifset STATUS, C, ACCESS
incfSR0H, F
ndi
ifclr INDF0, EPOUTEN, ACCESS
ndifclr INDF0, EPINEN, ACCESS
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
otherwise
ifl USB_buffer_data+bRequest, ==, CLEAR_FEATURE
cf INDF0, EPSTALL
otherwise
sf INDF0, EPSTALL
ndi
ankselD0IBC
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
ndi
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
reak
ase SET_ADDRESS
ifset USB_buffer_data+wValue, 7, BANKED; if new device address is ille
gal, send Request Error
sf UEP0, EPSTALL; set EP0 protocol stall bit to signify Request Error
otherwise
movlw SET_ADDRESS
movwf USB_dev_req ; processing a SET_ADDRESS request
movf USB_buffer_data+wValue, W
movwf USB_address_pending ; save new address
ankselD0IBC
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
ndi
reak
ase GET_DESCRIPTOR
movwf USB_dev_req ; processing a GET_DESCRIPTOR request
movf USB_buffer_data+(wValue+1), W
select
aseEVICE
movlw low (Device-Descriptor_begin)
movwf USB_desc_ptr
ALLescriptor ; get descriptor length
movwf USB_bytes_left
ifl USB_buffer_data+(wLength+1), ==, 0
ndiff USB_buffer_data+wLength, <, USB_bytes_left
movf USB_buffer_data+wLength, W
movwf USB_bytes_left
ndi
ALL SendDescriptorPacket
reak
aseONFIGURATION
cf USB_error_flags, 0
movf USB_buffer_data+wValue, W
select
ase 0
movlw low (Configuration1-Descriptor_begin)
reak
efault
sf USB_error_flags, 0
nds
ifclr USB_error_flags, 0, BANKED
ddlw x02 ; add offset for wTotalLength
movwf USB_desc_ptr
ALLescriptor ; get total descriptor length
movwf USB_bytes_left
movlw x02
subwf USB_desc_ptr, F ; subtract offset for wTotalLength
ifl USB_buffer_data+(wLength+1), ==, 0
ndiff USB_buffer_data+wLength, <, USB_bytes_left
movf USB_buffer_data+wLength, W
movwf USB_bytes_left
ndi
ALL SendDescriptorPacket
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
ase STRING
cf USB_error_flags, 0
movf USB_buffer_data+wValue, W
select
ase
movlw low (String0-Descriptor_begin)
reak
ase
movlw low (String1-Descriptor_begin)
reak
ase
movlw low (String2-Descriptor_begin)
reak
efault
sf USB_error_flags, 0
nds
ifclr USB_error_flags, 0, BANKED
movwf USB_desc_ptr
ALLescriptor ; get descriptor length
movwf USB_bytes_left
ifl USB_buffer_data+(wLength+1), ==, 0
ndiff USB_buffer_data+wLength, <, USB_bytes_left
movf USB_buffer_data+wLength, W
movwf USB_bytes_left
ndi
ALL SendDescriptorPacket
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
ase HID
cf USB_error_flags, 0
movf USB_buffer_data+wValue, W
select
ase
movlw low (HID1-Descriptor_begin)
reak
efault
sf USB_error_flags, 0
nds
ifclr USB_error_flags, 0, BANKED
movwf USB_desc_ptr
ALLescriptor ; get descriptor length
movwf USB_bytes_left
ifl USB_buffer_data+(wLength+1), ==, 0
ndiff USB_buffer_data+wLength, <, USB_bytes_left
movf USB_buffer_data+wLength, W
movwf USB_bytes_left
ndi
ALL SendDescriptorPacket
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
ase REPORT
cf USB_error_flags, 0
movf USB_buffer_data+wValue, W
select
ase
movlw x2F
movwf USB_bytes_left ; set descriptor length
movlw low (Report1-Descriptor_begin)
reak
efault
sf USB_error_flags, 0
nds
ifclr USB_error_flags, 0, BANKED
movwf USB_desc_ptr
ifl USB_buffer_data+(wLength+1), ==, 0
ndiff USB_buffer_data+wLength, <, USB_bytes_left
movf USB_buffer_data+wLength, W
movwf USB_bytes_left
ndi
ALL SendDescriptorPacket
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
reak
ase GET_CONFIGURATION
ankselD0IAH
movfD0IAH, W
movwfSR0H
movfD0IAL, W
movwfSR0L
anksel USB_curr_config
movf USB_curr_config, W
movwf INDF0 ; copy current device configuration to EP0 IN buffer
ankselD0IBC
movlw x01
movwfD0IBC ; set EP0 IN byte count to 1
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
ase SET_CONFIGURATION
ifl USB_buffer_data+wValue, <=, NUM_CONFIGURATIONS
movf USB_buffer_data+wValue, W
movwf USB_curr_config
select
ase
movlwDDRESS_STATE
movwf USB_USWSTAT
#ifdef SHOW_ENUM_STATUS
movlw xE0
ndwf SAL2,F ;PORTA, F
sf SAL2,2 ;PORTA, 2
#endif
reak
efault
movlwONFIG_STATE
movwf USB_USWSTAT
ankselD1OBC
movlw x08
movwfD1OBC ; set EP1 OUT byte count to 8
movlw low (USB_Buffer+0x10) ; EP1 OUT gets a buffer...
movwfD1OAL
movlw high (USB_Buffer+0x10)
movwfD1OAH ; ...set its address
movlw xC8
movwfD1OST ; set UOWN bit (USB can write EP1 OUT buffer)
movlw x08
movwfD1IBC ; set EP1 IN byte count to 8
movlw low (USB_Buffer+0x18) ; EP1 IN gets a buffer...
movwfD1IAL
movlw high (USB_Buffer+0x18)
movwfD1IAH ; ...set its address
movlw x48
movwfD1IST ; clear UOWN bit (PIC can write EP1 IN buffer)
movlwNDPT_NON_CONTROL
movwf UEP1 ; enable EP1 for interrupt in transfers
#ifdef SHOW_ENUM_STATUS
movlw xE0
ndwf SAL2,f ;PORTA, F
sf SAL2,3 ;PORTA, 3
#endif
nds
ankselD0IBC
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
ase GET_INTERFACE
movf USB_USWSTAT, W
select
aseONFIG_STATE
ifl USB_buffer_data+wIndex, <, NUM_INTERFACES
ankselD0IAH
movfD0IAH, W
movwfSR0H
movfD0IAL, W; get buffer pointer
movwfSR0L
lrf INDF0 ; always send back 0 for bAlternateSetting
movlw x01
movwfD0IBC ; set byte count to 1
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
reak
ase SET_INTERFACE
movf USB_USWSTAT, W
select
aseONFIG_STATE
ifl USB_buffer_data+wIndex, <, NUM_INTERFACES
movf USB_buffer_data+wValue, W
select
ase ; currently support only bAlternateSetting of 0
ankselD0IBC
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
otherwise
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
ndi
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
reak
ase SET_DESCRIPTOR
reak
ase SYNCH_FRAME
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
reak
nds
RETURN
;_______________________________________________________________________________
_________________
SendDescriptorPacket
anksel USB_bytes_left
ifl USB_bytes_left, <, 8
movlw NO_REQUEST
movwf USB_dev_req, BANKED; sending a short packet, so clear device req
uest
movf USB_bytes_left, W, BANKED
otherwise
movlw x08
ndi
subwf USB_bytes_left, F, BANKED
movwf USB_packet_length, BANKED
ankselD0IBC
movwfD0IBC, BANKED ; set EP0 IN byte count with packet size
movfD0IAH, W, BANKED; put EP0 IN buffer pointer...
movwfSR0H, ACCESS
movfD0IAL, W, BANKED
movwfSR0L, ACCESS ; ...into FSR0
anksel USB_loop_index
orlf USB_loop_index, 1, USB_packet_length
ALLescriptor ; get next byte of descriptor being sent
movwf POSTINC0 ; copy to EP0 IN buffer, and increment FSR0
incf USB_desc_ptr, F, BANKED ; increment the descriptor pointer
next USB_loop_index
ankselD0IST
movlw x40
xorwfD0IST, W, BANKED; toggle the DATA01 bit
ndlw x40 ; clear the PIDs bits
iorlw x88 ; set UOWN and DTS bits
movwfD0IST, BANKED
RETURN
;_______________________________________________________________________________
_________________
ClassRequests
movf USB_buffer_data+bRequest, W
select
ase GET_REPORT
movf USB_buffer_data+wValueHigh, W
select
ase INPUT
ankselD0IAH
movfD0IAH, W ; put EP0 IN buffer pointer...
movwfSR0H
movfD0IAL, W
movwfSR0L ; ...into FSR0
ankseltrl_io_buffer
movftrl_io_buffer, W ; copy first byte...
movwf POSTINC0 ; ...to EP0 IN buffer
movftrl_io_buffer+1, W ; copy second byte...
movwf INDF0 ; ...to EP0 IN buffer
ankselD0IBC
movlw x02
movwfD0IBC ; set EP0 IN buffer byte count to 2
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
aseEATURE
ankselD0IAH
movfD0IAH, W ; put EP0 IN buffer pointer...
movwfSR0H
movfD0IAL, W
movwfSR0L ; ...into FSR0
ankseleature_buffer
movfeature_buffer, W ; copy first byte...
movwf POSTINC0 ; ...to EP0 IN buffer
movfeature_buffer+1, W ; copy second byte...
movwf INDF0 ; ...to EP0 IN buffer
ankselD0IBC
movlw x02
movwfD0IBC ; set EP0 IN buffer byte count to 2
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
reak
ase SET_REPORT
movwf USB_dev_req; processing a SET_REPORT request
movf USB_buffer_data+wValueHigh, W
movwf Report_type; save type of report requested
reak
ase GET_PROTOCOL
ankselD0IAH
movfD0IAH, W; put EP0 IN buffer pointer...
movwfSR0H
movfD0IAL, W
movwfSR0L ; ...into FSR0
anksel USB_protocol
movf USB_protocol, W
movwf INDF0
ankselD0IBC
movlw x01
movwfD0IBC ; set byte count to 1
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
ase SET_PROTOCOL
movf USB_buffer_data+wValue, W
movwf USB_protocol ; update the new protocol value
ankselD0IBC
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
ase GET_IDLE
ankselD0IAH
movfD0IAH, W; put EP0 IN buffer pointer...
movwfSR0H
movfD0IAL, W
movwfSR0L ; ...into FSR0
anksel USB_idle_rate
movf USB_idle_rate, W
movwf INDF0
ankselD0IBC
movlw x01
movwfD0IBC ; set byte count to 1
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
ase SET_IDLE
movf USB_buffer_data+wValue, W
movwf USB_idle_rate ; update the new idle rate
ankselD0IBC
lrfD0IBC ; set byte count to 0
movlw xC8
movwfD0IST ; send packet as DATA1, set UOWN bit
reak
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
RETURN
;_______________________________________________________________________________
_________________
VendorRequests
movf USB_buffer_data+bRequest, W
select
efault
sf UEP0, EPSTALL ; set EP0 protocol stall bit to signify Request Error
nds
RETURN
;_______________________________________________________________________________
_________________
;ontinua con programa principal
;Con OPTI=3 (*16) VECT4 cada 4.1 ms en 4MHz
;_______________________________________________________________________________
_________________
SAUN
;Define inicio operacion A/D
MOVLW ;RA0 Analogo
MOVWFDCON0
MOVLW x0E
MOVWFDCON1 ;solo AN0 es analoga
MOVLW xB5
MOVWFDCON2 ;just. derecha-20 tad-Fosc/16
;continua otros puertos
LRF TRISD
LRF TRISE
MOVLW xF0
MOVWF TRISB ;OUT en RB0 a RB3
;para PORTC
MOVLW x98 ;ver pag 235
MOVWF TRISC
;RC7,RC4,RC3= IN para la serial y el i2c
;transmite 9 bits, TX habilitado, asincrono, BRGH=0
MOVLW x60
MOVWF TXSTA
;Baudios=Fosc/(16[ X+1])=2404 baudios para 16 Mhz
MOVLW .103
MOVWF SPBRG
;Serial habilitad, recibe 9 bits, recepcion cont. - PAG 237
MOVLW xD0
MOVWF RCSTA
;lectura analoga ajustada a la derecha (6 bms de ADRESH en0
;en PORTA solo AN0-RA0 es analoga, los demas son digitales
;PARA PRESCALAR 4550 EN PDF PAG 127
MOVLW xC3 ;8 bits sin prescalar. (16 bits-CK0 en 81)
MOVWF T0CON ;prescalar a TMR0 1:4
;DEFINE INTERRUPCIONES
MOVLW x80 ;IPEN=1 pag 110
MOVWF RCON ;
;inicia valores reg programa en cero
MOVLW T5ms
MOVWFSR0L
MOVLW MINF-T5ms+1
MOVWF T24
SAU1
LRF INDF0
INCFSR0L,F
ECFSZ T24,F
RA SAU1
INCF T10m,F
;Inicia TMIN y TSEG
MOVLW .98
MOVWF TSEG
MOVLW .60
MOVWF TMIN
;define vect4 por TMR0
MOVLW xA0 ;pag 101
MOVWF INTCON ;hab. int. por TMR0
;otros reg. que definen interrupciones
;INTCON2=0xFF por power reset-disable PortB pull up- TMR0 prioridad alta
;INTCON3=0xC0 por pwoer reset-disable INT1 INT2
;PIR1=00
;PIR2=00
;PIE1=00
;PIE2=00
;IPR1=0xFF
;IPR2=0xFF
;lee de eeprom los valores para TRE, MINR, CRPW y TRPW
LRFEADR
MOVLW MINR
MOVWFSR0L
SAU2
CFECON1,EEPGD
CFECON1,CFGS
SFECON1,RD ;lee dato eeprom
MOVFEDATA,W
MOVWF INDF0
INCFEADR,F
INCFSR0L,F
TFSSEADR,4 ;para 16 valores
RA SAU2
;POWER UP al LTN
MOVLW x38
ALL PLTN ;RS=W=0 y DATO=3
MOVLW x38
ALL PLTN
MOVLW x38
ALL PLTN ;cumple los tres ciclos
MOVLW x38
ALL PLTN ;define Funtion Set
MOVLW x0E
ALL PLTN ;Disp ON cursor no parpadea
MOVLW
ALL PLTN ;dir. cursor incr y no shift disp
;el display esta iniciado
SFC1,LS
SFC1,AOP
SF SAL1,OPW
;__________________________________________________________________________
;__________________________________________________________________________
;INICIA Disposicion del USB
;con base en el moty22.co.uk
ALL INI_USB
ALL ServiceUSB
;espera que el HOST configure el perifrico
;o sea que USB_USWSTAT sea igual a CONFIG_STATE
;se sealiza en SAL2
SAU3
TG SAL2,0
ALL TMPR
MOVF USB_USWSTAT,W
SUBLWONFIG_STATE
TFSS STATUS,Z
GOTO SAU3
;Configurado el PIC se inician reg.
LRFeature_buffer
LRFeature_buffer+1
LRFtrl_io_buffer
LRFtrl_io_buffer+1
LRF Int_io_buffer
LRF Int_io_buffer+1
;esta dispuesto el pic para transferencias del USB
;lo que se realiza en USBP
;__________________________________________________________________________
;__________________________________________________________________________
;ctualisa mensaje en display
;para 1 fila controla LS=1 - que se ajusta cada segundo en VECT4
;para 2 fila controla TMEN y datos M2,M1,M0 de BC1
MENS
TFSSC1,LS ;LS=1 cada seg en lnea 300
RA MEN3
;para la 1fila:
;Si M3=0 mensaje MOVE=Ovelma@epm.net.co
; M3=1 y AOP=0 y ONF=0 para el MCOF=Sauna estado OFF
; y AOP=0 y ONF=1 el MCON=Sauna estado ON
; y AOP=1 y OPW=0 el MPW1 con PWM fiajdo tecla +/-
; y AOP=1 y OPW=1 el MPW2 con PWM calculado por TRE-TLE
;OJO los bits ONF y OPW se ajustan por teclado
MOVLW x80 ;RETURN HOME
ALL PLTN
MOVLW
TFSSC1,M3
RA MEN2
;llega con M3=1
TGC1,AOP
TFSCC1,AOP
RA MEN1
;llega para mensaje AOP=0 y lo definir ONF
MOVLW MCOF-MOVE
TFSC SAL1,ONF
MOVLW MCON-MOVE
CFC1,M3 ;en MEN2 lo hara 1
RA MEN2
;para mensajes del PWM
MEN1
MOVLW MPW1-MOVE
TFSC SAL1,OPW
MOVLW MPW2-MOVE
;en W offset mensaje 1 fila - 16 caracteres
MEN2
ALL MDIS
CFC1,LS
;Proximo mensaje de M3
TGC1,M3
;Inicia la 2a linea display
MEN3
MOVF TMEN,F
TFSS STATUS,Z
RA TECL
;para la 2 fila: (mensajes localizados en VME1)
MOVLW xC0
ALL PLTN
;lo controla M2,M1,M0 de BC1
MOVLW MINF
MOVWFSR0L
MOVFC1,W
NDLW
MOVWF T23
;Buscara mensaje Dde VME1-C/U de 14 caracteres
SFC1,VM01
;para la 2 fila-11 caracteres.
;"Tiempo SAUNA:" ;mensaje 000 con MINR
;"Faltan (min):" ;mensaje 001 con MINF
;"Ciclo PWM (s)" ;mensaje 010 con CRPW
;"TiempON pwm :" ;mensaje 011 con TRPW
;para mensajes con datos mayor a un byte. Mensaje de 11 caracteres
;" Humedad: " ;mensaje 100 con HUMH,HUML
;"Temp. Vo : " ;mensaje 101 con TLEH,TEML
;"T.Act.HEX: " ;mensaje 110 con TLHH,TLHL
;"Temp. Ref: " ;mensaje 111 con TREH,TRE
TFSC T23,2
RA MEN6
;llega para mensajes de 13 caracteres-dato 1 byte
MOVLW ;mensaje inicial en VME1
MEN4
MOVF T23,F
TFSC STATUS,Z
RA MEN5
INCFSR0L,F
DDLW .28 ;son doble byte
ECF T23,F
RA MEN4
;En W el offset mens. y en FSR0L el dato
MEN5
ALL MDIS
MOVF INDF0,W
ALLCD3
RA MEN9
;para mensaje 11 caracteres y dato de 1.5 bytes
MEN6
MOVLW HUMH
MOVWFSR0L
MOVLW MHUM-MDUE
;offset en VME1 mens. inicial de los de 1.5 byte
CF T23,2
MEN7
MOVF T23,F
TFSC STATUS,Z
RA MEN8
INCFSR0L,F
INCFSR0L,F
DDLW .24 ;DATOS TIENE 2 BYTES
ECF T23,F
RA MEN7
;llegan FSR0L con dir dato y W con offset mensaje
MEN8
ALL MDIS
MOVF INDF0,W ;dir dato H
MOVWF T2E
INCFSR0L,F
MOVF INDF0,W
MOVWF T2F
ALLCD5
;llevado mensaje actualiza tiempo y prox. mens
MEN9
MOVLW .220
MOVWF TMEN
;prximo mensaje
CFC1,VM01 ;ya no se produce XF
INCFC1,F
CFC1,VM01 ;y anula el posible 2^3
;Sigue evaluacin estado sw rwclas
;SW-TECL1 (2^5 en ESW) PWM por teclado por ERR. 1 (mens 1 FILA) y 2 con TRPW
;SW-TECL3 (2^3 en ESW) alterna ON-OFF el SAUNA (si CATE=0)-dispone mensaje MCOF-
MCON
;SW-TECL4 (2^1 en ESW) varia CRPW +/- de acuerdo al estado de SW-TECL7
;SW-TECL5 (2^6 en ESW) varia TREH,TREL " " " " " " "
;SW-TECL6 (2^0 en ESW) varia MINR " " " " " " "
;SW-TECL7 (2^4 en ESW) dispone para INC DEC datos
;SW-TECL8 (2^2 en ESW) varia TRPW (+/-) y tiene OPW=0
;terminado mensaje sigue teclado
TECL
MOVF TATE,W
TFSS STATUS,Z
RATA
;Leera los sw en 4051-S y los asigna en ESW
LRF PORTB
TEC1
CF STATUS,C
TFSC PORTA,RA2
SF STATUS,C
RRCFSW,F
INCF PORTB,F
TFSS PORTB,RB3
RA TEC1
;en ESW estan estados de sw
MOVLW MINR
MOVWFSR0L
LRF T23
INCF T23,F ;posible M2M1M0 de la tecla
;evalua estados SW
;posible SW-TECL6 en 2^0
TFSCSW,RB0
RA TEC6
;llegan para:
;SW-TECL6 (2^0 en ESW) varia MINR. +/- (de acuerdo al estado de SW-TECL7)
;SW-TECL4 (2^1 en ESW) " CRPW " " " " " " "
;SW-TECL8 (2^2 en ESW) varia TRPW (+/-) y tiene OPW=0
TEC2
TFSSSW,4 ;con SW-TECL7 para +/-
RA TEC5
;orden de incr apuntado por FSR0L
INCF INDF0,F
TFSC STATUS,Z
ECF INDF0,F
TEC3
;presiono tecla y debe programar eeprom
;define valor mensaje (en T23)
MOVLW xF0
NDWFC1,W
IORWF T23,W
MOVWFC1 ;con nuevo M2M1M0
TEC31
LRF TMEN
;para acelerar teclado y disponer grabar eeprom
TEC4
SFC1,7 ;asigna EPR=1
MOVLW .200 ;espera aprox. 2 seg
MOVWF TEPR
;Acelera teclado
MOVLWACT-MOVE
DDWFATE,W
ALL VME0
MOVWF TATE
INCFATE,F
INCFATE,F ;SON DOS BYTES
TFSCATE,5 ;hasta 0x20 = .32 bytes
ECFATE,F
RATA
;orden de decr apuntado por FSR0L
TEC5
ECF INDF0,F
TFSC STATUS,Z
INCF INDF0,F
RA TEC3
;para posiciones mayores a 2^0
TEC6
INCFSR0L,F ;posible CRPW
INCF T23,F ;y su mensaje
;posible SW-TECL4 en 2^1
TFSSSW,RB1
RA TEC2 ;cont. para +/- el CRPW
;posible SW-TECL8 en 2^2
TFSCSW,RB2
RA TEC7
;SW-TECL8 (2^2 en ESW) varia TRPW si OPW=0
;si esta OPW=0 puede variar PWM por teclado
INCFSR0L,F ;posible TPRW
INCF T23,F
TFSS SAL1,OPW
RA TEC2 ;puede +/- el TRPW
;posible SW-TECL3 en 2^3
TEC7
TFSCSW,RB3
RA TEC9
;con SW-TECL3 alterna ON-OFF el SAUNA (si CATE=0) y dispone mensaje MPWi
MOVFATE,W
TFSS STATUS,Z
RA TEC8
;complementa estado anterior del ONF
TG SAL1,ONF
;Si ONF=1 es ON y MINF.=MINR
;Si ONF=0 es OFF y MINF. =0
MOVF MINR,W
TFSS SAL1,ONF
MOVLW
MOVWF MINF
;en TEC91 define para mensajes
;estan definidos el MINF y el ONF
;dispone mensaje estado Sauna
TEC8
;dispone mensaje MCOF / MCON => (LS=1 AOP=0 y M3=1)
SFC1,AOP ;en MENS ser 0
RA TEC91
;para posiciones mayores a 2^4
TEC9
TFSCSW,RB5
RA TEC92
;con SW-TECL1 y en la 1a presion compl, OPW
;El PWM se ajusta con ERR (OPW=1) variar por SW-TECL8 (OPW=0)
INCF T23,F
MOVLW xF0
NDWFC1,W
IORWF T23,W
MOVWFC1
;con nuevo M2M1M0=3 para mensaje valor TRPW en la 2 fila
;para definir OPW. Se compl. si CATE=0 (1 ATENCIN)
MOVFATE,F
TFSC STATUS,Z
;se permite complementar OPW
TG SAL1,OPW
;dispone para MENS en fila 1
CFC1,AOP ;en MENS quedar en 1
;dispone mensaje MPWi (LS=1 AOP=1 y M3=1)
TEC91
SFC1,M3
SFC1,LS
;TATE es menor que TSEG
SF TATE,6 ;TATE en 0x40
MOVLW .98
MOVWF TSEG
LRF TMEN
SFATE,2 ; no repite con la misma presion
RATA
;falta evaluar SW-TECL5=2^6 varia TREH,TREL
TEC92
TFSCSW,RB6
RA TECc
MOVLW
MOVWF T23
MOVLW x03
NDWF TREH,F ;mximo en 0x03
;Controla que no llegue en 0x0000
MOVF TREL,W
IORWF TREH,W
TFSC STATUS,Z
;LLega en cero
SF TREL,0
TEC93
TFSSSW,4 ;con SW-TECL7 para +/-
RA TECa
;para incr TREH,L
INCF TREL,F
TFSC STATUS,Z
INCF TREH,F
CF TREH,2 ;se tenia 0x03FF quedar en 0x0000
MOVF TREL,W
IORWF TREH,W
TFSS STATUS,Z
RA TEC3
;limita el mximo al incr.
MOVLW
MOVWF TREH
ECF TREL,F ;queda en 0xFF
RA TEC3
;para decr TRE.
TECa
MOVLW -1
DDWF TREL,F
TFSS STATUS,C
DDWF TREH,F
;chequea que no quede en cero
MOVF TREH,W
IORWF TREL,W
TFSC STATUS,Z ;es cero
INCF TREL,F
RA TEC3
;El sw2 no se tiene definido
;No presiono tecla
TECc
LRFATE
;Cada THUM (en seg) hay nueva lectura A/D
ATA
MOVF THUM,F
TFSS STATUS,Z
RATA2
SF THUM,2 ;aprox. cada 4 s
MOVLW ;pin 1 del 4051-A
MOVWF PORTE
;El A/D esta configurado para leer el RA0 - lnea 714
;la conversin consume aprox 27 us
SFDCON0,GO
ATA1
TFSS PIR1,ADIF
RATA1
CF PIR1,ADIF
;En ADRESh,l se tiene el valor leido de la seal analoga de HUMEDAD
MOVFDRESL,W
MOVWF HUML
MOVFDRESH,W
MOVWF HUMH
;Cada TTEM toma muestra de TEMperatura (PORTE=6)
; y si OPW=1 puede actualizar TRPW
ATA2
MOVF TTEM,F
TFSS STATUS,Z
RATA5
;Leera la Temperatura (AD en pin AN8) y si OPW=1 corrige TRPW
SF TTEM,2 ;nvo tiempo aprox. cada 40 ms
MOVLW ;pin 2 del 4051-A
MOVWF PORTE
;El A/D esta configurado para leer el RA0 - lnea 714
;la conversin consume aprox 27 us
SFDCON0,GO
;PIR1,ADIF termino conversion A/D pag 104
ATA3
TFSS PIR1,ADIF
RATA3
CF PIR1,ADIF
;En ADRESh,l se tiene el valor analogo leido
;En TLEH,L = T2D,T2C se guardara el valor Temperatura LEida. en HEX
MOVFDRESL,W
MOVWF TLHL
MOVWF T2C
MOVFDRESH,W
MOVWF TLHH
MOVWF T2D
;calcula TLEH,L = (5*HEX)/1023 en HEX
;para mostrar dos decimales (3.45 ser 345) el 5 ser 500 (4.65=0x01D1)
;entonces calcula TLEH,L = (500*HEX)/1023=(1F4*HEX)/3FF en HEX
;valor en HEX leido en TLEH,L = T2D,T2C
;inicia MULT = 500*HEX
MOVLW
MOVWF T2B ;valor H
MOVLW xF4
MOVWF T2A ;formando T2B,2A=500=0x1F4
ALL MULT2
;PROD=T2F,2E,2D,2C=alto....bajo. Valor mximo es 0x07d000
;prepara la DIV = PROD/0x03FF
LRF T2B
LRF T2A
MOVLW
MOVWF T29
MOVLW xFF
MOVWF T28
ALLIV
;resultado en T2F,2E,2D,2C maximo 00,00,01,F4
MOVF T2C,W
MOVWF TLEL
MOVF T2D,W
MOVWF TLEH
;en TLE esta el valor de temperatura leido -mximo 2 bytes
TFSS SAL1,OPW
RATA5
;Con el OPW=1 se debe actualizar ERR1 y el TRPW
;define ERR1=TREH,TREL - TLEH,TLEL
;para rutina de MULT usar los T2B,T2A
MOVF TLEL,W
SUBWF TREL,W ;F-W - dispone el CY
MOVWF T2A
TFSS STATUS,C ;el CY de TRE - TLE
MOVLW ;el Cy sera +1 para el TLEH
;T2A = TREL - TREL y W con prestamo
;continua 2 byte
DDWF TLEH,W
SUBWF TREH,W ;F-W
MOVWF T2B
;EN T2B,2A = ERR1 y sale CY=1 si TEL>TRE
;Evalua resultado para construir TPRW
;llega CY=1 s TEL>TRE se define TRPW=0 para salida en OFF
TFSC STATUS,C
RATA4
LRF TRPW
RATA5 ;definido TRPW
;llega con TLE < TRE y calcula nuevo TRPW de acuerdo a:
; se tienen dos puntos de la recta de formacin del TPRW
; son ERR=0 con TRPW=CRPW y ERR=TREH con TRPW=0
; err/trpw = treh/crpw entonces TRPW=(ERR*CRPW)/TREH
ATA4
MOVFRPW,W
MOVWF T2C
LRF T2D
ALL MULT2
;PROD=T2F,2E,2D,2C=alto....bajo
;rutina para DIVIDIR => T2F,2E,2D,2C / T2B,2A,29,28=T2F,2E,2D,2C
LRF T2B
LRF T2A
LRF T29
MOVF TREH,W
MOVWF T28
ALLIV
MOVF T2C,W
MOVWF TRPW
;se tiene definido el valor del TRPW con la lectura de Temp.
;Para control del estado del SAUNA.
;Con SW-TECL3 si ONF=0 se inicia SAUNA en ON y ONF=1
;Aqui solo se llevar PNF=0 si MINR=0
ATA5
TFSC SAL1,ONF
RATA9
;Sauna esta OFF
ATA6
CF SAL1,ONF
ATA7
CF SAL1,PWO
RA PEPR
;SAUNA en ON y chequea fin de tiempo programado
ATA9
MOVF MINF,W ;controlado en VECT4
TFSC STATUS,Z
RATA6
;No ha terminado MINF. Continua SAUNA en ON
MOVF TEPW,W ;Ton PWM. Se lleva a cero en vect4
TFSC STATUS,Z
RATAb
;esta en TON del PWM
ATAa
SF SAL1,PWO
RA PEPR
;paso el TRPW pero espera el fin de ciclo PWM
ATAb
MOVFEPW,F
TFSS STATUS,Z
RATA7
;esta en TOFF del PWM y puede reiniciar nvo ciclo PWM
MOVFRPW,W ;en segundos
MOVWFEPW
MOVF TRPW,W
MOVWF TEPW
RATAa
;posibilidad de programar eeprom
PEPR nop
TFSSC1,EPR
RA USBP
MOVF TEPR,F
TFSS STATUS,Z
RA MENS
;se dan las condiciones EPR=1 y TEPR=0
LRFEADR
MOVLW MINR
MOVWFSR0L
PEP1
MOVF INDF0,W
MOVWFEDATA
CFECON1,EEPGD
CFECON1,CFGS
SFECON1,WREN
CF INTCON,GIE
MOVLW x55
MOVWFECON2
MOVLW xAA
MOVWFECON2
SFECON1,WR ;inicia escritura
TFSCECON1,WR ;demora 4 ms
RA $-2
SF INTCON,GIE
CFECON1,WREN
INCFSR0L,F
INCFEADR,F
TFSSEADR,2
RA PEP1
CFC1,EPR
;_______________________________________________________________________________
__
;_______________________________________________________________________________
__
;para cheque estado de la USB (Main en GENHID-MOTY22 etc.)
;basados en moty2 con el usb io.asm - Genhid.asm (28/54). Ver lnaes 116 de ste pro
g.
;las direcciones de los BDn en pg 177 Adobe
;Resumen del USB_bffer descriptor pg 173-176, 178
; 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
;BDnSTAT UOWN DTS PID3 PID2 PID1 PID0 BC9 BC8
; KEN INCDIS DTSEN BSTALL
;antes de UOWN sea clear, los bits 5 a 2 del BDnSTAT
;son configurados a KEN, etc.
;2^7=UWON en 1=El SIE tiene el BD y su correspondiente buffer
;2^5-2^2=PIDi Identificador- El token recibido lyima transfer.
;2^1-2^0= Byte count. Update por el SIE
;2^6=DTS Data Toggle Sincronizacion.
;2^5=KEN BD keep enable
;2^4=INCDIS Address Increment Disable
;2^3=DTSEN Data Toggle Sync Enable
;2^2=BSTALL Buffer Stall Enable
;2^1-0=DTS
;BDnADRL, BDnADRH son los reg. de la dir. del buffer.
;Las direcciones de los regidstros de la USB estan en usb_defs.inc
USBP
NOP ;para colocar break en debugger
ALL ServiceUSB
;no opera - ERROR- si BD1OST, UOWN= 0
USB1
;puede esperar unos 10 ms
ALL TMPR
TG SAL2,7 ;indicador
ANKSELD1OST
TFSCD1OAH, UOWN
GOTO USB1
SF SAL2,7
;chequea si el PIC tiene el bufer EP1 OUT
MOVFD1OAH,W, BANKED
MOVWFSR0H
MOVFD1OAL,W, BANKED
MOVWFSR0L
;FSR0 apunta al buffer EP1 OUT
;lo lleva al buffer I/O de interrupciones
MOVF POSTINC0,W
MOVWF Int_io_buffer, A
MOVF INDF0,W
MOVWF Int_io_buffer+1, A
;toma el status reg. de EP1 OUT
MOVFD1OST,W, BANKED
NDLW x40 ;extrae el bit DATA01
XORLW x40 ;compl. DATA01
IORLW x88 ;Sset los bits UOWN y DTS
MOVWFD1OST, BANKED
USB2
ALL ServiceUSB ; service USB requests...
ANKSELD1IST
;espera que UOWN =0
TFSCD1IST, UOWN, BANKED ; ...until the PIC owns the EP1 IN buffer
RA USB2
MOVFD1IAH, W, BANKED ; put EP1 IN buffer pointer...
MOVWFSR0H, ACCESS
MOVFD1IAL, W, BANKED
MOVWFSR0L, ACCESS ; ...into FSR0
;llenara buffer (apuntado por FSR0) primero con valores analogos
MOVLW ;RA0 Analogo
MOVWFDCON0
MOVLW x0E
MOVWFDCON1 ;solo AN0 es analoga
;se definio solo RA0 analoga en ADCON0 y ADCON1
;PORTB llega en 0x00, para input AN3
USB3
TFSSDCON0, GO_DONE, ACCESS ; ...until A/D conversion is done
RA USB3
;tomara el valor analogo de AN3
MOVFDRESL, W, ACCESS ;send ADC to EP1 IN buffer
MOVWF POSTINC0
MOVFDRESH, W, ACCESS
MOVF POSTINC0
;prxima es AN4
INCF PORTB
USB4
TFSSDCON0, GO_DONE, ACCESS ; ...until A/D conversion is done
RA USB4
;tomara el valor analogo de AN4
MOVFDRESL, W, ACCESS ;send ADC to EP1 IN buffer
MOVWF POSTINC0
MOVFDRESH, W, ACCESS
MOVF POSTINC0
;prxima es AN7
INCF PORTB
USB5
TFSSDCON0, GO_DONE, ACCESS ; ...until A/D conversion is done
RA USB5
;tomara el valor analogo de AN7
MOVFDRESL, W, ACCESS ;send ADC to EP1 IN buffer
MOVWF POSTINC0
MOVFDRESH, W, ACCESS
MOVF POSTINC0
;prxima es AN2
INCF PORTB
USB6
TFSSDCON0, GO_DONE, ACCESS ; ...until A/D conversion is done
RA USB6
;tomara el valor analogo de AN2
MOVFDRESL, W, ACCESS ;send ADC to EP1 IN buffer
MOVWF POSTINC0
MOVFDRESH, W, ACCESS
MOVF POSTINC0
ANKSEL Int_io_buffer
MOVF Int_io_buffer+1, W, BANKED ;copy received byte to SAL3 output
s
MOVWF SAL3, ACCESS
;en ESW estan estados de sw
MOVFSW,W,ACCESS
NDLW'11110000' ;read digital inputs
IORWFDRESH, W, ACCESS ;add digital inputs to ADRESH of an3
MOVWF INDF0 ;send byte to EP1 IN buffer
ANKSELD1IBC
MOVLW x08
MOVWFD1IBC, BANKED ; set EP1 IN buffer byte count to 8
MOVFD1IST, W, BANKED ; get EP1 IN status register
NDLW x40 ; extract the DATA01 bit
XORLW x40 ; toggle the DATA01 bit
IORLW x88 ; set UOWN and DTS bits
MOVWFD1IST, BANKED ; send packet
;o de acuerdo a GENHID.ASM tenemos:
MOVF Int_io_buffer, W ; copy the first byte in the interrupt I
/O buffer...
MOVWF POSTINC0 ; ...to EP1 IN buffer
MOVF Int_io_buffer+1, W ; copy the second byte in the interrupt
I/O buffer...
MOVWF INDF0 ; ...to EP1 IN buffer
ANKSELD1IBC
MOVLW x02
MOVWFD1IBC, BANKED ; set EP1 IN buffer byte count to 8
MOVFD1IST, W, BANKED ; get EP1 IN status register
NDLW x40 ; extract the DATA01 bit
XORLW x40 ; toggle the DATA01 bit
IORLW x88 ; set UOWN and DTS bits
MOVWFD1IST, BANKED ; send packet
;se tornaran ON los leds dependiendo del valor del Host via la aplicacion V.B.6.
0
RA MENS
;_________________________________________________
ND

Vous aimerez peut-être aussi