;**************************************************************************************** ; RX_GEN_PT2240B.ASM ; ; ; RECEPTOR RF PARA CONTROLE REMOTOS (CHAVEIRINHOS) COM CI PT2240B ; ; PARA DECODIFICAR UTILIZA UM PIC 12F675 (OPCIONALMENTE UM 12F629, DES- ; COMENTANDO/COMENTANDO AS LINHAS CITADAS NO TEXTO). ; ; CLAUDIO LÁRIOS INICIO: 25-10-2013 TERMINO:25-10-2013 ; ;*************************************************************************************** ; ; GRAVAR CONTROLE: APERTE O BOTÃO DO CONTROLE REMOTO QUE VOCÊ DESEJA QUE SEJE O QUE ; ACIONARÁ ESTE RECEPTOR E MANTENHA APERTADO. ; APERTE TAMBÉM O BOTÃO 'LEARN' NA PLACA QUE DESEJA 'APRENDER'(PINO 7 DO PIC 12F675 ; A MASSA)E SOLTE-O EM MENOS DE 1 SEGUNDOS. O LED 'LEARN' PISCARÁ 1 VEZ, PARA INDICAR ; 'CODE APRENDIDO'. ; APAGAR TODOS OS CONTROLES DA MEMÓRIA: APERTAR BOTÃO 'LEARN' NA PLACA E ; MANTENHA PRESSIONADO POR MAIS DE 10 SEGUNDOS. O LED 'LEARN' PISCARÁ ; 5 VEZES , INDICANDO O PLENO APAGAMENTO DE TODOS OS CONTROLES DA MEMÓRIA. ; APÓS ISTO, CADA CONTROLE DEVERÁ SER 'REAPRENDIDO' NOVAMENTE PARA OPERAR. ; OBS. USO APENAS DIDÁTICO. ;================================================================================================ ; OPÇÕES DO USUÁRIO ;************************************************************************************************ ; DESCOMENTAR/COMENTAR CONFORME MODELO ESCOLHIDO #DEFINE F675 ;#DEFINE F629 ;************************************************************************************************ ;OPÇÃO DE ATUAÇÃO DA SAÍDAS (MODO PULSO OU RETENÇÃO) #DEFINE S0_RET ;PARA RETENÇÃO (PARA PULSO NA SAÍDA S0, COMENTE ESTA LINHA COM ';' NO COMEÇO) #DEFINE S1_RET ;PARA RETENÇÃO (PARA PULSO NA SAÍDA S1, COMENTE ESTA LINHA COM ';' NO COMEÇO) #DEFINE S2_RET ;PARA RETENÇÃO (PARA PULSO NA SAÍDA S2, COMENTE ESTA LINHA COM ';' NO COMEÇO) #DEFINE S3_RET ;PARA RETENÇÃO (PARA PULSO NA SAÍDA S3, COMENTE ESTA LINHA COM ';' NO COMEÇO) ;************************************************************************************************* ;OPÇÃO DE MICROCONTROLADOR IFDEF F675 INCLUDE "P12F675.INC" LIST P=12f675 , R=DEC ENDIF IFDEF F629 LIST P=12f629 , R=DEC INCLUDE "P12F629.INC" ENDIF ERRORLEVEL -302 ;ELIMINA MENSAGEM DE ERRO PÓS COMPILAÇÃO ;================================================================================================= ; PALAVRA DE CONFIGURAÇÃO ;================================================================================================= __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_ON & _MCLRE_OFF ;================================================================================================= ; DEFINES ;================================================================================================= #DEFINE BANK0 BCF STATUS,RP0 ;SETA BANK0 DE MEMORIA #DEFINE BANK1 BSF STATUS,RP0 ;SETA BANK1 #DEFINE FLAGH FLAGS,0 ;FLAG DE SITUAÇÃO #DEFINE FLAGL FLAGS,1 ;FLAG DE SITUAÇÃO #DEFINE FLAG1 FLAGS,2 ;FLAG DE NOVA LEITURA #DEFINE FLAGGR FLAGS,3 ;FLAG DE 'LEARN' APRENDER #DEFINE FLAG_S0 FLAGS,4 ;FLAG AUX #DEFINE FLAG_S1 FLAGS,5 ;FLAG AUX #DEFINE FLAG_S2 FLAGS,6 ;FLAG AUX #DEFINE FLAG_S3 FLAGS,7 ;FLAG AUX #DEFINE TRIS_LEARN TRISIO,0 ;IN /OUT 'LEARN' #DEFINE SIN GPIO,3 ;PINO 4 IN RF #DEFINE LRN GPIO,0 ;PINO 7 IN LEARN BOTTON #DEFINE LED GPIO,0 ;PINO 7 SAIDA LED 'LEARN' #DEFINE S3 GPIO,1 ;PINO 6- SAIDA DO RELE 4 #DEFINE S2 GPIO,2 ;PINO 5- SAIDA DO RELE 3 #DEFINE S1 GPIO,4 ;PINO 3- SAIDA DO RELE 2 #DEFINE S0 GPIO,5 ;PINO 2- SAIDA DO RELE 1 ;================================================================================================= ; RAM ;================================================================================================= CBLOCK 0X20 BT ; SALVA INFORMAÇÕES DOS BOTÕES RES2,RES1,RES0 ; BUFFER DE RECEPÇÃO DOS BITS TRANSMITIDOS RES2A,RES1A,RES0A ;BUFFER PARA SALVAR PRIMEIRA RECEPÇÃO BITCOUNTER ;CONTADOR DE NÚMERO DE BITS A RECEBER (24 BITS) FLAGS ;USADO BITS INDIVIDUAIS COMO 'FLAGS' DE CONTROLE Z2,Z1 ;USADO PARA CONTAR TEMPO DE BOTÃO LEARN APERTADO (APAGAMENTO) LC,HC ;USADO PARA CONTAR TEMPO EM '1'(HC) E '0'(LC) ADDRESS,TMP,AUX ;USADO EM OPERAÇÕES NA EEPROM Y1,Y2 ;USADO PARA CONTAR TEMPO PARA DESLIGAR SAÍDAS APÓS SOLTURA DOS BOTÕES TEMP ;TEMPORÁRIO DE USO GERAL R0,R1,R2 ;USADO EM ROTINAS DE DELAY ENDC ;================================================================================================= ; EQUATES ;================================================================================================= SETRIS EQU B'001001' ; PORTA: TRI-STATE VALUE TMAX EQU .50 ;TEMPO MAXIMO DO SINAL LOW PARA RECEPÇÃO QBITS EQU .24 ;QUANTIDADE DE BITS A SER RECEBIDO (20 ADRESS+ 4 DADOS+ 1 SYNC-> DESPREZADO) TGR EQU .255 ;TEMPO DE BOTÃO APERTADO PARA APAGAR GRAVAÇAO T_DESL_LED EQU .20 ;TEMPO MÁXIMO QUE LEDS FICAM ACESOS APÓS CESSAR TRANSMISSÃO ;================================================================================================= ; RESET DO PROGRAMA ;================================================================================================= ORG 0X00 GOTO START ORG 0X04 RETFIE ;================================================================================================= ; SETUP DE REGISTRADORES ;================================================================================================= START: MOVLW 0X07 MOVWF CMCON ;DESLIGA COMPARADORES CLRF GPIO ; RESET PORT BANK1 MOVLW SETRIS ; SETUP PORTA MOVWF TRISIO IFDEF F675 CLRF ANSEL ;LIBERA PORTAS DO AD (SOMENTE 12f675) ENDIF BANK0 CLRF FLAGS ;APAGA REGISTRADOR DE FLAGS MOVLW TGR MOVWF Z2 CLRF Z1 ;LIMPA REGISTRADORES ;================================================================================================= ; LOOP PRINCIPAL ;================================================================================================= INICIO: CLRF RES2 ;LIMPA BUFFER DE RECEPÇÃO DE BITS TRANSMITIDOS CLRF RES1 CLRF RES0 MOVLW QBITS ;PREPARA PARA A RECEPÇÃO COM NUMERO DE BITS A RECEBER MOVWF BITCOUNTER L0 BCF FLAGH ;LIMPA FLAGS E CONTADORES DE BITS HIGH E LOW BCF FLAGL CLRF HC CLRF LC L1 ;================================================================================================= ; TESTA POR APAGAMENTO DOS TRANSMISSORES DA MEMÓRIA ;================================================================================================= BTFSS LRN ;TESTA BOTÃO 'LEARN' APERTADO GOTO TAPAGAMENTO ;APERTADO, COMEÇA A CONTAR TEMPO MAX. DE APAGAMENTO MOVLW TGR MOVWF Z2 ;RECARGA DO TEMPO DE APAGAMENTO CLRF Z1 ;LIMPA REGISTRADORES L1H GOTO RECEBE_PT2240B ;VAI PARA ROTINA DE RECEPÇÃO ;================================================================================================= ; APAGAMENTO DA EEPROM (APAGAR CONTROLES GRAVADOS) ;================================================================================================= TAPAGAMENTO ;APAGAR TODOS OS CONTROLES DA MEMÓRIA DECFSZ Z1,F GOTO L1H DECFSZ Z2,F GOTO L1H CALL APAGAEEPROM ;ATINGIU TEMPO MAXIMO: APAGAR MEMÓRIA BANK1 BCF TRIS_LEARN ;SAIDA PARA LED LEARN BANK0 MOVLW .5 MOVWF TEMP ;================================================================================================= ; PISCA LED 'LEARN' 5 VEZES PARA INDICAR APAGAMENTO DA EEPROM ;================================================================================================= DN7 BSF LED ;ACENDE LED MOVLW .10 CALL DELAYM BCF LED ;APAGA LED MOVLW .10 CALL DELAYM DECFSZ TEMP,F GOTO DN7 BANK1 BSF TRIS_LEARN ;VIRA ENTRADA PARA BOTÃO 'LEARN' BANK0 BTFSS LRN ;AGUARDA SOLTAR BOTÃO 'LEARN' GOTO $-1 GOTO INICIO ;================================================================================================= ; ROTINA DE RECEPÇÃO PARA PT2240B ;================================================================================================= RECEBE_PT2240B SS5: BTFSS SIN ;SIN ? TESTA SINAL DE ENTRADA DO RECEPTOR DE RF GOTO INC_LC ; SIN=0 BTFSS FLAGL ;SIN=1 GOTO INC_HC BTFSS FLAGH GOTO INC_HC GOTO M0 ;================================================================================================= ; INCREMENTA CONTADOR HC ;================================================================================================= INC_HC MOVFW LC ;TESTA SE NÃO PASSOU DO LIMITE MAXIMO DE TEMPO EM LOW NA ENTRADA DE RF SUBLW TMAX BTFSS STATUS,C GOTO INICIO ;C=0 (-) - LC>TMAX (REJEITAR DADO - PAUSA INICIAL) BSF FLAGH INCF HC,F BTFSC STATUS,Z DECF HC,F GOTO LA2 ;VAI CONTAR TEMPO DE 50 MICRO SEGUNDOS ;================================================================================================= ; INCREMENTA CONTADOR LC ;================================================================================================= INC_LC BSF FLAGL ;SIN=0 INCF LC,F ;INCREMENTA REGISTRADOR DE LOW SIGNAL NA ENTRADA RF BTFSC STATUS,Z DECF LC,F ;================================================================================================= ; ROTINA PARA O DESLIGAMENTO DAS SAÍDA APÓS SOLTAR BOTÕES (PULSO) OU LIBERAÇÃO DE FLAGS (RETENÇÃO) ;================================================================================================= LA2 DECFSZ Y1,F ;CONTADOR DE TEMPO DE DESLIGAMENTO DE SAIDAS GOTO J0 DECFSZ Y2,F ;CONTADOR DE TEMPO DE DESLIGAMENTO DE SAIDAS GOTO J0 IFDEF S0_RET ;CONFERE A ESCOLHA DO USUÁRIO ANTES DE COMPLIAR BCF FLAG_S0 ELSE BCF S0 ENDIF IFDEF S1_RET BCF FLAG_S1 ELSE BCF S1 ENDIF IFDEF S2_RET BCF FLAG_S2 ELSE BCF S2 ENDIF IFDEF S3_RET BCF FLAG_S3 ELSE BCF S3 ENDIF INCF Y1,F INCF Y2,F ;================================================================================================= ; DELAY ENTRE AMOSTRAGENS DO PINO DE ENTRADA DE SINAL RF DO RECEPTOR ;================================================================================================= J0 MOVLW .11 ;.11 = 50 MICROSEG (ACERTA TEMPO ENTRE LEITURAS DA ENTRADA DE RF) MOVWF TEMP DECFSZ TEMP,F GOTO $-1 GOTO L1 ;================================================================================================= ; CAPTURA VALOR DO BIT ENVIADO NOS REGISTRADORES DE BUFFER 'RES2 ... RES0' ;================================================================================================= M0 MOVFW LC ;TESTA SE NÃO PASSOU DO LIMITE MAXIMO DE TEMPO EM LOW NA ENTRADA DE RF SUBLW TMAX BTFSS STATUS,C GOTO INICIO ;C=0 (-) - LC>TMAX (REJEITAR DADO - PAUSA INICIAL) MOVFW LC ;OBTEM O VALOR DE 'CARRY'(HUM OU ZERO) SUBWF HC,W RRF RES2,F ;DESLOCA O 'CARRY' NOS REGISTRADORES DE RESULTADO RRF RES1,F RRF RES0,F DECFSZ BITCOUNTER,F ;DECREMENTA O CONTADOR DE BITS A SER RECEBIDO GOTO L0 ;LE PROXIMO BIT ;================================================================================================= ; RECEPÇÃO CONCLUIDA - TESTA SE É A PRIMEIRA OU SEGUNDA RECEPÇÃO ;================================================================================================= BTFSC FLAG1 ;TESTA SE É A PRIMEIRA OU A SEGUNDA RECEPÇÃO GOTO PULA1 MOVFW RES2 ;SALVA A PRIMEIRA LEITURA PARA COMPARAÇÃO COM UMA SEGUNDA MOVWF RES2A ;ISTO DETECTA ERROS NA TRANSMISSÃO E MANTÉM INTEGRIDADE DA TRANSMISSÃO MOVFW RES1 MOVWF RES1A MOVFW RES0 MOVWF RES0A BSF FLAG1 ;SETA FLAG DE PRIMEIRA RECEPÇÃO GOTO INICIO ;VAI RECEBER A SEGUNDA TRANSMISSÃO ;================================================================================================= ; COMPARA A SEGUNDA TRANSMISSÃO COM A PRIMEIRA ;================================================================================================= PULA1 BCF FLAG1 ;SEGUNDA RECEPÇÃO, COMPARA COM A PRIMEIRA MOVFW RES2 XORWF RES2A,W BTFSS STATUS,Z GOTO RESETAC MOVFW RES1 XORWF RES1A,W BTFSS STATUS,Z GOTO RESETAC MOVFW RES0 XORWF RES0A,W BTFSS STATUS,Z GOTO RESETAC ;ERRO DE RECEPÇÁO GOTO AÇÃO ;OK - BOA RECEPÇÃO ;================================================================================================= ; ERRO NA TRANSMISSÃO - VAI RECEBER MAIS 2 NOVAS TRANSMISSÕES POR SEGURANÇA ;================================================================================================= RESETAC CLRF RES2A ;APAGA BUFFERS DE COMPARAÇÃO CLRF RES1A CLRF RES0A GOTO INICIO ;================================================================================================= ; RECEPÇÃO CORRETA DE DADOS ;================================================================================================= AÇÃO MOVFW RES2 MOVWF BT ;SALVA OS BITS DOS BOTÕES ANDLW B'00001111' MOVWF RES2 ;ZERA OS BITS DOS BOTÕES PARA GRAVAR UNICO ENDEREÇO BTFSS LRN ;BOTÃO ESTÁ APERTADO? BSF FLAGGR CALL PPT SUBLW .0 BTFSC STATUS,Z ; É '0'? GOTO APRENDER ;NENHUM CONTROLE FOI GRAVADO ;================================================================================================= ; VERIFICA SE O CONTROLE RECEBIDO JÁ FOI GRAVADO NA EEPROM ;================================================================================================= BUSCA_CONTROLE MOVFW TMP MOVWF ADDRESS CALL EEREAD XORWF RES2,W ;COMPARA COM RES2 BTFSS STATUS,Z GOTO PROXIMO DECF ADDRESS,F MOVFW ADDRESS CALL EEREAD XORWF RES1,W ;COMPARA COM RES1 BTFSS STATUS,Z GOTO PROXIMO DECF ADDRESS,F MOVFW ADDRESS CALL EEREAD XORWF RES0,W ;COMPARA COM RES0 BTFSC STATUS,Z GOTO ACIONAR ;ENCONTRADO CONTROLE NA MEMÓRIA PROXIMO ;VAI PARA O PROXIMO ENDEREÇO DE MEMÓRIA PROCURAR.... MOVFW ADDRESS MOVWF TMP MOVLW .3 SUBWF TMP,F ;ACERTA DE 3 EM 3 A POSIÇÃO DE BUSCA NA MEMÓRIA BTFSS STATUS,C GOTO APRENDER BTFSS STATUS,Z GOTO BUSCA_CONTROLE ;VOLTA A BUSCA ;================================================================================================= ; CONTROLE NÃO ENCONTRADO - TESTA SE DEVE APRENDER O CONTROLE RECEBIDO ;================================================================================================= APRENDER BTFSS FLAGGR ;TESTA SE BOTÃO 'LEARN' ESTÁ PRESSIONADO GOTO INICIO ;NÃO ESTÁ. CALL PPT ;ESTÁ, PEGA PONTEIRO MOVWF ADDRESS ;PEGA O ENDEREÇO APONTADO SUBLW 0X7E ;LIMITE MAXIMO DA EEPROM (128-1 /3= 42 BOTÕES OU 24 CONTROLES) BTFSS STATUS,C CLRF ADDRESS ;INICIA SOBREGRAVAÇÃO INCF ADDRESS,F ;SOMA 1 MOVFW RES0 MOVWF TMP ;COLOCA EM 'TMP' MOVFW ADDRESS ;DA O POSIÇÃO DE MEMORIA A SER GRAVADO CALL EEWRITE ;ROTINA DE ESCRITA NA EEPROM INCF ADDRESS,F ;PROXIMA POSIÇÃO DE ESCRITA NA EEPROM MOVFW RES1 MOVWF TMP MOVFW ADDRESS CALL EEWRITE INCF ADDRESS,F MOVFW RES2 MOVWF TMP MOVFW ADDRESS CALL EEWRITE MOVFW ADDRESS MOVWF TMP MOVLW .0 CALL EEWRITE ;GRAVA NOVO ENDEREÇO DE PONTEIRO BCF FLAGGR BTFSS LRN GOTO $-1 MOVLW .10 ;TEMPO DE ATRASO CALL DELAYM BSF LED ;LIGA LED MOVLW .10 ;TEMPO DE ATRASO CALL DELAYM BCF LED ;DESLIGA ;======================================================================= ; ACIONAR SAÍDAS ;======================================================================= ACIONAR IFDEF S0_RET BTFSS BT,7 ;TESTA BIT7 POR 'D0' =1 GOTO SAI_S0 BTFSC FLAG_S0 GOTO SAI_S0 BSF FLAG_S0 ;TRAVA BTFSS S0 GOTO LIGA_S0 BCF S0 GOTO SAI_S0 LIGA_S0 BSF S0 SAI_S0 ELSE BTFSC BT,7 ;TESTA BIT7 POR 'D0' =1 BSF S0 ;LIGA SAIDA S0 BTFSS BT,7 ;TESTA BIT7 POR 'D0' =0 BCF S0 ;DESLIGA SAIDA S0 ENDIF IFDEF S1_RET BTFSS BT,6 ;TESTA BIT7 POR 'D0' =1 GOTO SAI_S1 BTFSC FLAG_S1 GOTO SAI_S1 BSF FLAG_S1 ;TRAVA BTFSS S1 GOTO LIGA_S1 BCF S1 GOTO SAI_S1 LIGA_S1 BSF S1 SAI_S1 ELSE BTFSC BT,6 ;TESTA BIT6 POR 'D1' =1 BSF S1 ;LIGA SAIDA S1 BTFSS BT,6 ;TESTA BIT6 POR 'D1' =0 BCF S1 ;DESLIGA SAIDA S1 ENDIF IFDEF S2_RET BTFSS BT,5 ;TESTA BIT5 POR 'D2' =1 GOTO SAI_S2 BTFSC FLAG_S2 GOTO SAI_S2 BSF FLAG_S2 ;TRAVA BTFSS S2 GOTO LIGA_S2 BCF S2 GOTO SAI_S2 LIGA_S2 BSF S2 SAI_S2 ELSE BTFSC BT,5 ;TESTA BIT5 POR 'D2' =1 BSF S2 ;LIGA SAIDA S2 BTFSS BT,5 ;TESTA BIT5 POR 'D2' =0 BCF S2 ;DESLIGA SAIDA S2 ENDIF IFDEF S3_RET BTFSS BT,4 ;TESTA BIT4 POR 'D3' =1 GOTO SAI_S3 BTFSC FLAG_S3 GOTO SAI_S3 BSF FLAG_S3 ;TRAVA BTFSS S3 GOTO LIGA_S3 BCF S3 GOTO SAI_S3 LIGA_S3 BSF S3 SAI_S3 ELSE BTFSC BT,4 ;TESTA BIT4 POR 'D3' =1 BSF S3 ;LIGA SAIDA S3 BTFSS BT,4 ;TESTA BIT4 POR 'D3' =0 BCF S3 ;DESLIGA SAIDA S3 ENDIF ;================================================================================================= ; TESTA SE DEVE DESLIGAR AS SAÍDAS ACIONADAS ;================================================================================================= TEMPO_SAIDA MOVLW T_DESL_LED ;RECARGA DO TEMPORIZADOR DE DESLIGAMENTO MOVWF Y2 MOVLW .255 MOVWF Y1 GOTO INICIO ;================================================================================================= ; ROTINAS DE DELAYS ;================================================================================================= DELAYM MOVWF R0 XC CALL AGUARDE DECFSZ R0,F GOTO XC RETURN AGUARDE ;ROTINA DE ATRASO MOVLW .64 MOVWF R1 CG2 CLRWDT MOVLW .255 MOVWF R2 DECFSZ R2,F GOTO $-1 DECFSZ R1,F GOTO CG2 RETURN ;================================================================================================= ; PEGA PONTEIRO DA EEPROM ;================================================================================================= PPT MOVLW .0 CALL EEREAD ;LE PONTEIRO DA EEPROM RETURN ;================================================================================================= ; ROTINA DE ESCRITA NA EEPROM ;================================================================================================= EEWRITE ;ENDEREÇO EM 'W' E DADO A ESCREVER EM 'TMP' BANK1 movwf EEADR BANK0 MOVFW TMP ;PEGA PRIMEIRO DADO BANK1 movwf EEDATA bcf EECON1, EEIF bsf EECON1, WREN ; AUTORIZA ESCRITA movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1, WR WRITE_SN_A btfsc EECON1, WR ; ACABOU? goto WRITE_SN_A bcf EECON1, WREN ; IMPEDE A ESCRITA BANK0 RETURN ;================================================================================================= ; ROTINA DE LEITURA DA EEPROM ;================================================================================================= EEREAD ;COLOQUE ENDEREÇO EM 'W' E DADO RETORNA EM 'W' E 'TMP' BANK1 movwf EEADR bsf EECON1, RD clrwdt btfsc EECON1, RD goto $-1 movf EEDATA,W BANK0 MOVWF TMP ;RECUPERA PRIMEIRO NUMERO DA EEPROM RETURN ;================================================================================================= ; ROTINA DE APAGAMENTO DA EEPROM ;================================================================================================= APAGAEEPROM MOVLW 0X80 ;TOTAL DE 128 + 1 BYTES DE EEPROM MOVWF AUX RET6 CLRWDT MOVFW AUX MOVLW .1 ;ACERTA ENDEREÇO TIRANDO 1 SUBWF AUX,W BANK1 movwf EEADR MOVLW 0XFF movwf EEDATA bcf EECON1, EEIF bsf EECON1, WREN ; AUTORIZA A ESCRITA movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1, WR WRITE_SN_C btfsc EECON1, WR ; ACABOU? goto WRITE_SN_C bcf EECON1, WREN ; IMPEDE A ESCRITA BANK0 DECFSZ AUX,F GOTO RET6 RETLW 0H ;================================================================================================= ; CONDIÇÃO INICIAL PAR EEPROM ;================================================================================================= ORG H'2100' DE .0 ;================================================================================================= ; FIM DO PROGRAMA ;================================================================================================= end