i2c-master.asm:
;#ASM###########################################################################################MCH# ; i2c-master.asm ; `````````````` ; ; I2C KOMUNIKACE TYPU MASTER ; ; 2.6.2018 ;--------------------------------------------------------------------------------------------------- ; ___|_ | |_____| | | _|________ ; SDA: | \__|X|_____|X| ... |__/ | ; ___|___ | | _ | | | ___|________ ; SCL: | \|_|_/ \_|_| ... |/ | ; start akcept ... stop uvolneno ;--------------------------------------------------------------------------------------------------- INCLUDE; definice konstant procesoru GLOBAL r_I2C_STATUS, r_I2C_ADR_ZARIZENI GLOBAL r_I2C_ADR_DAT_H, r_I2C_ADR_DAT_L, r_I2C_FSR_1.REG, r_I2C_POCET_BYTE GLOBAL _I2C_EEPROM_ZAPIS, _I2C_EEPROM_CTENI MEM_I2C_0 UDATA_SHR ; v bance 0 r_I2C_TMP RES 1 ; pomocny registr r_I2C_STATUS RES 1 ; HLAVICKA - behem prenosu, NULOVY - po zdarnem ukonceni r_I2C_ADR_ZARIZENI RES 1 ; 3 bitova <2~0> adresa ciloveho zarizeni napr. EEPROM r_I2C_ADR_DAT_H RES 1 ; horni cast adresy dat napr. EEPROM r_I2C_ADR_DAT_L RES 1 ; spodni cast adresy dat napr. EEPROM r_I2C_FSR_1.REG RES 1 ; ukazatel na pocatecni datovy registr r_I2C_POCET_BYTE RES 1 ; pocet byte k prenosu ! PREPISUJE SE ! #DEFINE I2C_PORT PORTC ; port pro SDA a SCL #DEFINE b_I2C_TRIS_SCL I2C_PORT,3 ; TRIS - namapovany pin pro SCL (synchro) #DEFINE b_I2C_PORT_SCL I2C_PORT,3 ; PORT - namapovany pin pro SCL (synchro) #DEFINE b_I2C_TRIS_SDA I2C_PORT,4 ; TRIS - namapovany pin pro SDA (data) #DEFINE b_I2C_PORT_SDA I2C_PORT,4 ; PORT - namapovany pin pro SDA (data) I2C CODE ;################################################################################################### ; CTENI DAT Z I2C EEPROM PAMETI ; ; a) odeslani start bitu k zahajeni spojeni ; b) odeslani byte hlavicky s adresou EEPROM zarizeni dle (r_I2C_ADR_ZARIZENI) a atributem zapisu ; c) odeslani byte horni casti adresy dat v EEPROM (r_I2C_ADR_DAT_H) ; d) odeslani byte dolni casti adresy dat v EEPROM (r_I2C_ADR_DAT_L) ; e) odeslani start bitu k zahajeni spojeni ; f) odeslani byte hlavicky s adresou EEPROM zarizeni dle (r_I2C_ADR_ZARIZENI) a atributem cteni ; g) prijem dat z EEPROM do registru s sdresou v (r_I2C_FSR_1.REG) o poctu (r_I2C_POCET_BYTE) ; h) odeslani stop bitu k ukonceni spojeni ; ; Uspesny zapis je indikovan vynulovanym registrem (r_I2C_STATUS), pri neuspesnem obsahuje hlavicku ; Registr poctu byte ke cteni (r_I2C_POCET_BYTE) se prepisuje ! ;--------------------------------------------------------------------------------------------------- _I2C_EEPROM_CTENI: CALL _I2C_HLAVICKA ; sestaveni hlavicky ; _________________________________________________________ ; ODESLANI 1 BYTE HLAVICKY: ADRESA ZARIZENI + ATRIBUT ZAPIS CALL _I2C_START_BIT ; zahajeni spojeni, obsazeni sbernice BCF STATUS,RP0 ; BANKA 0 MOVLW r_I2C_STATUS ; --. MOVWF FSR ; <-' (r_I2C_STATUS) ulozena hlavicka CALL _I2C_SDA_TX ; <-' odeslani hlavicky DECFSZ r_I2C_TMP,f ; ?? PROBEHLO ODESLANI BYTE OK ?? GOTO _I2C_STOP_BIT ; 'NE' ukonceni spojeni, uvolneni sbernice ; ________________________________ ; ODESLANI 1 BYTE HORNI ADRESY DAT MOVLW r_I2C_ADR_DAT_H ; --. MOVWF FSR ; <-' (r_I2C_ADR_DAT_H) CALL _I2C_SDA_TX ; <-' DECFSZ r_I2C_TMP,f ; ?? PROBEHLO ODESLANI BYTE OK ?? GOTO _I2C_STOP_BIT ; 'NE' ukonceni spojeni, uvolneni sbernice ; ________________________________ ; ODESLANI 1 BYTE DOLNI ADRESY DAT INCF FSR ; (r_I2C_ADR_DAT_L) CALL _I2C_SDA_TX ; <-' DECFSZ r_I2C_TMP,f ; ?? PROBEHLO ODESLANI BYTE OK ?? GOTO _I2C_STOP_BIT ; 'NE' ukonceni spojeni, uvolneni sbernice ; _________________________________________________________ ; ODESLANI 1 BYTE HLAVICKY: ADRESA ZARIZENI + ATRIBUT CTENI CALL _I2C_START_BIT ; zahajeni spojeni, obsazeni sbernice MOVLW r_I2C_STATUS ; --. MOVWF FSR ; <-' (r_I2C_STATUS) ulozena hlavicka BSF INDF,0 ; nastavi pro cteni, bit:0 CALL _I2C_SDA_TX ; <-' DECFSZ r_I2C_TMP,f ; ?? PROBEHLO ODESLANI BYTE OK ?? GOTO _I2C_STOP_BIT ; 'NE' ukonceni spojeni, uvolneni sbernice ; __________ ; PRIJEM DAT MOVF r_I2C_FSR_1.REG,w ; ukazatel na prvni datovy registr MOVWF FSR ; <-' _I2C_EEPROM_CTENI_SMYCKA: CALL _I2C_SDA_RX ; nacteni 1 byte dat z EEPROM do registru dle FSR INCF FSR,f ; ukazatel na nasledujici datovy registr DECFSZ r_I2C_POCET_BYTE ; ?? PRENESEN PLNY POCET REGISTRU ?? GOTO _I2C_EEPROM_CTENI_SMYCKA ; 'NE' CALL _I2C_STOP_BIT ; ukonceni spojeni, uvolneni sbernice ; ___________ ; STATUS - OK CLRF r_I2C_STATUS ; vynulovani statusu RETURN ;################################################################################################### ; ZAPIS DAT DO I2C EEPROM PAMETI ; ; Data do EEPROM jdou prvne do jeho zasobniku a az ukoncenim spojeni STOP BITEM se trvale zapisi, ; po tuto dobu zapisu cca 4ms EEPROM nekomunikuje. ; ; a) odeslani start bitu k zahajeni spojeni ; b) odeslani byte hlavicky s adresou EEPROM zarizeni dle (r_I2C_ADR_ZARIZENI) a atributem zapisu ; c) odeslani byte horni casti adresy dat v EEPROM (r_I2C_ADR_DAT_H) ; d) odeslani byte dolni casti adresy dat v EEPROM (r_I2C_ADR_DAT_L) ; e) odeslani dat z registru s sdresou v (r_I2C_FSR_1.REG) a naslednych v poctu (r_I2C_POCET_BYTE) ; f) odeslani stop bitu k ukonceni spojeni a zahajeni cca 4ms interniho zapisu v EEPROM ; ; Uspesny zapis je indikovan vynulovanym registrem (r_I2C_STATUS), pri neuspesnem obsahuje hlavicku ; Registr poctu byte k zapisu (r_I2C_POCET_BYTE) se prepisuje ! ;--------------------------------------------------------------------------------------------------- _I2C_EEPROM_ZAPIS: CALL _I2C_HLAVICKA ; sestaveni hlavicky ; _________________________________________________________ ; ODESLANI 1 BYTE HLAVICKY: ADRESA ZARIZENI + ATRIBUT ZAPIS CALL _I2C_START_BIT ; zahajeni spojeni, obsazeni sbernice MOVLW r_I2C_STATUS ; --. MOVWF FSR ; <-' (r_I2C_STATUS) ulozena hlavicka CALL _I2C_SDA_TX ; <-' DECFSZ r_I2C_TMP,f ; ?? PROBEHLO ODESLANI BYTE OK ?? GOTO _I2C_STOP_BIT ; 'NE' ukonceni spojeni, uvolneni sbernice ; ________________________________ ; ODESLANI 1 BYTE HORNI ADRESY DAT MOVLW r_I2C_ADR_DAT_H ; --. MOVWF FSR ; <-' (r_I2C_ADR_DAT_H) CALL _I2C_SDA_TX ; <-' DECFSZ r_I2C_TMP,f ; ?? PROBEHLO ODESLANI BYTE OK ?? GOTO _I2C_STOP_BIT ; 'NE' ukonceni spojeni, uvolneni sbernice ; ________________________________ ; ODESLANI 1 BYTE DOLNI ADRESY DAT INCF FSR ; (r_I2C_ADR_DAT_L) CALL _I2C_SDA_TX ; <-' DECFSZ r_I2C_TMP,f ; ?? PROBEHLO ODESLANI BYTE OK ?? GOTO _I2C_STOP_BIT ; 'NE' ukonceni spojeni, uvolneni sbernice ; ____________ ; ODESLANI DAT MOVF r_I2C_FSR_1.REG,w ; ukazatel na prvni datovy registr MOVWF FSR ; <-' _I2C_EEPROM_ZAPIS_SMYCKA: CALL _I2C_SDA_TX ; zapis 1 byte dat z registru dle FSR do EEPROM DECFSZ r_I2C_TMP,f ; ?? PROBEHLO ODESLANI BYTE OK ?? GOTO _I2C_STOP_BIT ; 'NE' ukonceni spojeni, uvolneni sbernice INCF FSR,f ; ukazatel na nasledujici datovy registr DECFSZ r_I2C_POCET_BYTE ; ?? PRENESEN PLNY POCET REGISTRU ?? GOTO _I2C_EEPROM_ZAPIS_SMYCKA ; 'NE' CALL _I2C_STOP_BIT ; ukonceni spojeni, uvolneni sbernice ; ___________ ; STATUS - OK CLRF r_I2C_STATUS ; vynulovani statusu RETURN ;################################################################################################### ; PRIJEM 1 BYTE DAT Z I2C DO (INDF) ;--------------------------------------------------------------------------------------------------- _I2C_SDA_RX: ; _________________________________________________________ ; PRIJMUTI 8 BITU ZE SERIOVE LINKY SDA DO DATOVEHO REGISTRU CLRF INDF MOVLW 0x08 MOVWF r_I2C_TMP _I2C_SDA_RX_SMYCKA: CALL _I2C_PAUZA CALL _I2C_SCL_UP ; SCL: -> 1, AKCEPTACE CALL _I2C_PAUZA BCF STATUS,C ; C: prednastaveni 0 BTFSC b_I2C_PORT_SDA ; ?? JE PRIJMUTY BIT Z SDA V 1 ?? BSF STATUS,C ; 'ANO' C: 1 RLF INDF ; bit:0 <- C posuvny registr CALL _I2C_SCL_DOWN ; SCL: -> 0 DECFSZ r_I2C_TMP,f ; ?? BYLO PRENESENO 8 BITU ?? GOTO _I2C_SDA_RX_SMYCKA ; 'NE' ; _______________ ; VYSLANI 9. BITU DECF r_I2C_POCET_BYTE,w BSF STATUS,RP0 ; BANKA 1 BTFSS STATUS,Z ; ?? JDE O POSLEDNI BYTE ?? BCF b_I2C_TRIS_SDA ; 'NE' SDA: -> 0 BCF STATUS,RP0 ; BANKA 0 BCF b_I2C_PORT_SDA ; SDA: -> 0 CALL _I2C_PAUZA CALL _I2C_SCL_UP ; SCL: -> 1, AKCEPTACE CALL _I2C_PAUZA CALL _I2C_SCL_DOWN ; SCL: -> 0 BSF STATUS,RP0 ; BANKA 1 BSF b_I2C_TRIS_SDA ; SDA: -> 1, uvolneni datove linky BCF STATUS,RP0 ; BANKA 0 CALL _I2C_PAUZA RETURN ;################################################################################################### ; ODESLANI 1 BYTE DAT Z (INDF) DO I2C ;--------------------------------------------------------------------------------------------------- _I2C_SDA_TX: ; __________________________________________________________________ ; ODESLANI 8 BIT DATOVEHO REGISTRU DO SERIOVE LINKY SDA ROTACI VLEVO MOVLW 0x08 MOVWF r_I2C_TMP _I2C_SDA_TX_SMYCKA: BCF STATUS,C ; C: prednastaveni 0 BTFSC INDF,7 ; ?? JE 7 BIT DATOVEHO REGISTRU V 1 ?? BSF STATUS,C ; 'ANO' C: 1 RLF INDF,f ; C <- bit:7~0 <- C posuvny registr ; BSF STATUS,RP0 ; BANKA 1 BTFSS STATUS,C ; ?? 0 ?? BCF b_I2C_TRIS_SDA ; SDA: -> 0 BTFSC STATUS,C ; ?? JE NACTENY BIT Z SDA V 1 ?? BSF b_I2C_TRIS_SDA ; 'ANO' SDA: -> 1 BCF STATUS,RP0 ; BANKA 0 BCF b_I2C_PORT_SDA ; SDA: -> 0 CALL _I2C_PAUZA CALL _I2C_SCL_UP ; SCL: -> 1, AKCEPTACE CALL _I2C_PAUZA CALL _I2C_SCL_DOWN ; SCL: -> 0 DECFSZ r_I2C_TMP,f ; ?? BYLO PRENESENO 8 BITU ?? GOTO _I2C_SDA_TX_SMYCKA ; 'NE' ; _______________________________ ; PRIJMUTI A KONTROLA 9. BITU ACK BSF STATUS,RP0 ; BANKA 1 BSF b_I2C_TRIS_SDA ; SDA: -> 1, uvolneni datove linky CALL _I2C_PAUZA CALL _I2C_SCL_UP ; SCL: -> 1, AKCEPTACE CALL _I2C_PAUZA BTFSS b_I2C_PORT_SDA ; ?? PROBEHLO ODESLANI BYTE OK ?? INCF r_I2C_TMP,f ; 'NE' 0x01 ->(r_I2C_TMP) CALL _I2C_SCL_DOWN ; SCL: -> 0 CALL _I2C_PAUZA RETURN ;################################################################################################### ; SESTAVENI HLAVICKY K NAVAZANI KOMUNIKACE ;--------------------------------------------------------------------------------------------------- _I2C_HLAVICKA: BCF STATUS,RP0 ; BANKA 0 RLF r_I2C_ADR_ZARIZENI,w ; nacteni adr zarizeni, posun o bit vlevo ANDLW b'00001110' ; maska na 3 bitovou adresu zarizeni IORLW b'10100000' ; pridani hlavicky pro zapis MOVWF r_I2C_STATUS ; <-' RETURN ;################################################################################################### ; ODESLANI START BITU PRO OBSAZENI SBERNICE A ZAHAJENI SPOJENI : PRI SCL V 1 PREJDE SDA Z 1 DO 0 ;--------------------------------------------------------------------------------------------------- _I2C_START_BIT: BSF STATUS,RP0 ; BANKA 1 BSF b_I2C_TRIS_SDA ; SDA: -> 1 CALL _I2C_PAUZA BSF b_I2C_TRIS_SCL ; SCL: -> 1, AKCEPTACE CALL _I2C_PAUZA BCF b_I2C_TRIS_SDA ; SDA: -> 0 BCF STATUS,RP0 ; BANKA 0 BCF b_I2C_PORT_SDA ; SDA: -> 0 CALL _I2C_PAUZA BSF STATUS,RP0 ; BANKA 1 BCF b_I2C_TRIS_SCL ; SCL: -> 0 BCF STATUS,RP0 ; BANKA 0 BCF b_I2C_PORT_SCL ; SCL: -> 0 CALL _I2C_PAUZA RETURN ;################################################################################################### ; ODESLANI STOP BITU PRO UKONCENI SPOJENI A UVOLNENI SBERNICE : PRI SCL V 1 PREJDE SDA Z 0 DO 1 ;--------------------------------------------------------------------------------------------------- _I2C_STOP_BIT: BSF STATUS,RP0 ; BANKA 1 BCF b_I2C_TRIS_SCL ; SCL: -> 0 BCF STATUS,RP0 ; BANKA 0 BCF b_I2C_PORT_SCL ; SCL: -> 0 BSF STATUS,RP0 ; BANKA 1 BCF b_I2C_TRIS_SDA ; SDA: -> 0 BCF STATUS,RP0 ; BANKA 0 BCF b_I2C_PORT_SDA ; SDA: -> 0 CALL _I2C_PAUZA BSF STATUS,RP0 ; BANKA 1 BSF b_I2C_TRIS_SCL ; SCL: -> 1, AKCEPTACE CALL _I2C_PAUZA BSF b_I2C_TRIS_SDA ; SDA: -> 1, uvolneni datove linky CALL _I2C_PAUZA BCF STATUS,RP0 ; BANKA 0 RETURN ;################################################################################################### ; SCL: 0 -> 1 PRECHOD AKCEPTACNI ;--------------------------------------------------------------------------------------------------- _I2C_SCL_UP: BSF STATUS,RP0 ; BANKA 1 BSF b_I2C_TRIS_SCL ; SCL: 0 -> 1 BCF STATUS,RP0 ; BANKA 0 RETURN ;################################################################################################### ; SCL: 1 -> 0 PRECHOD NAVRATOVY ;--------------------------------------------------------------------------------------------------- _I2C_SCL_DOWN: BSF STATUS,RP0 ; BANKA 1 BCF b_I2C_TRIS_SCL ; SCL: 1 -> 0 BCF STATUS,RP0 ; BANKA 0 BCF b_I2C_PORT_SCL ; SCL: -> 0 RETURN ;################################################################################################### ; PAUZA CELKEM 20 INSTRUKCNICH CYKLU, 20us PRI 4 MHz, 10us PRI 8 MHz, ... ;--------------------------------------------------------------------------------------------------- _I2C_PAUZA: NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP RETURN ;################################################################################################### END
