;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