• AVR Freaks

Hot!PIC 16F15344 I2C perpherial issue with acknowledgment assembly code

Page: 12 > Showing page 1 of 2
Author
The alchmiste
Starting Member
  • Total Posts : 70
  • Reward points : 0
  • Joined: 2018/03/14 02:55:48
  • Location: France
  • Status: offline
2020/11/05 16:46:07 (permalink)
0

PIC 16F15344 I2C perpherial issue with acknowledgment assembly code

Hi there,
 
I'm locked on the code below writen in asm.
The debugger get stucked on the ackknowledge transmission sub routine.
I've tried to add a clr of the interupt regiter to see if it have any impact on the ACKEN bit but it Don't.
Any one have an idea?
 
 
Thanks
Thealchimiste

    list p=16f15344 , r=dec
 #include <p16f15344.inc>


; CONFIG1
; __config 0x3E8C
 __CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _FCMEN_ON
; CONFIG2
; __config 0x279C
 __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_ON & _LPBOREN_OFF & _BOREN_NSLEEP & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_OFF
; CONFIG3
; __config 0xFFFF
 __CONFIG _CONFIG3, _WDTCPS_WDTCPS_31 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_SC
; CONFIG4
; __config 0x1FE0
 __CONFIG _CONFIG4, _BBSIZE_BB64K & _BBEN_OFF & _SAFEN_ON & _WRTAPP_OFF & _WRTB_OFF & _WRTC_OFF & _WRTSAF_OFF & _LVP_OFF
; CONFIG5
; __config 0x3FFF
 __CONFIG _CONFIG5, _CP_OFF

; _RSTOSC_HFINT32 -> permet l'activation de l'oscillateur interne a une frequence de 32Mhz soit 31,25 nanoS/osccillation-> 25 interuption / seconde avec: postdiviseur=10, prediviseur=128, seuil timer2=249,
; _LVP_OFF -> permet la programmation a faible tenssion
; _CP_OFF -> Ne cache pas le code
; _WDT_OFF -> Desactive le Watch Dog
 ; Definition des differentes variable du programme à partir de l'adresse 0x20

cblock 0X20
 
 
; // Variables utiles pour rtc
Dataa : 1 ; Valeur de la data I2C envoyé
 
secondes : 1 ; Valeur recupéré par l'I2C sur RTC en seconde

minutes : 1 ; Valeur recupéré par l'I2C sur RTC en minutes

heures : 1 ; Valeur recupéré par l'I2C sur RTC en heures

jourh : 1 ; Valeur recupéré par l'I2C sur RTC en jour hebdomadaire

jourm : 1 ; Valeur recupéré par l'I2C sur RTC en jour mensuel
 
mois : 1

année : 1 ; Valeur recupéré par l'I2C sur RTC en année

problem : 1 ; Valeur recupéré en cas de problem d'acknowlede non recu par l'esclave

    endc

;*******************************************************************************
; Reset Vector
;*******************************************************************************

    org 00H ; processor reset vector
    goto RTCI2C ; go to beginning of program

; TODO INSERT ISR HERE

;*******************************************************************************
; Routine d'interuption
;*******************************************************************************
    org 0x004 ; interrupt vector location
    RETFIE
    ;*******************************************************************************
; Macro I2C
;*******************************************************************************
 
; Parametrage I2C ( reglage vitesse, reglage des ports associé au SCK et SDA,
; reglage du peripherique MSSP, reglage du nombre de bit par adresse, reglage
; reglage des port en entré ou sortie, verrifier s'il est necessaire d'activer
; les pull-up resitor pour l'I2C et desactiver les pull-up resistor pour les
; autres ports, verrifier la fin de chaque procedure apres chaque procedure lancé)

; Configuration I2C
 
RTCI2C
   
banksel Dataa
CLRF Dataa ; Valeur de la data I2C envoyé
CLRF secondes ; Valeur recupéré par l'I2C sur RTC en seconde
CLRF minutes ; Valeur recupéré par l'I2C sur RTC en minutes
CLRF heures ; Valeur recupéré par l'I2C sur RTC en heures
CLRF jourh ; Valeur recupéré par l'I2C sur RTC en jour hebdomadaire
CLRF jourm ; Valeur recupéré par l'I2C sur RTC en jour mensuel
CLRF mois
CLRF année ; Valeur recupéré par l'I2C sur RTC en année
CLRF problem ; Valeur recupéré en cas de problem d'acknowlede non recu par l'esclave

banksel RB4PPS
movlw 0x16 ;On associe SDA a RB4 ( les données transmises)
movwf RB4PPS

banksel RB5PPS
movlw 0x15 ;On associe SCL a RB5 (l'horloge)
movwf RB5PPS

banksel TRISB
movlw B'11111111' ;RB4, RB5 en entrée
movwf TRISB
 
banksel SSP1STAT
movlw B'10000000' ;// On parametre SMP a 1 pour informer que l'horloge travaillera
 ; a 1Mhz ou 100Khz et CKE a 0 pour indiquer qu'on travail en mode I2C
movwf SSP1STAT
  
banksel SSP1ADD
movlw B'01001111' ;// On charge la valeur 79 afin de faire fonctionner l'horloge SCL
; à 100Khz formule: (Fosc/4*Fscl)-1
movwf SSP1ADD

banksel SSP1CON1
movlw B'00101000' ;// On Active le module SSPM avec le bit 5 et on le paramettre
; avec les 4 premiers en mode I2C maitre
movwf SSP1CON1
 
 ; 1) configuration I2C -> OK

 ;// a) on parametre et fixe les valeurs des registres du RTC avant de lancer les aquisitions
 call i2cstart
 call adressebyteecriture
 call Acknowledge
 
        ; - les secondes
a
 banksel problem
 bcf problem,0
 movlw d'0'
 banksel Dataa
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto a
 
 c
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'0'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto c
 
         ; - les minutes
d
 banksel problem
 bcf problem,0
 movlw d'1'
 banksel Dataa
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto d
 
 e
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'0'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto e
 
          ; - les heures et le format
 f
 banksel problem
 bcf problem,0
 movlw d'2'
 banksel Dataa
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto f
 
 g
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'4'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto g
 
 ; - le jour de la semaine
 h
 banksel problem
 bcf problem,0
 movlw d'3'
 banksel Dataa
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto h
 
 i
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'5'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto i
 
        ; - le jour du mois
 k
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'4'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto k
 
 l
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'1'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto l
 
        ; - le mois
 m
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'5'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto m
 
 n
 banksel problem
 bcf problem,0
 movlw d'10'
 banksel Dataa
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto n
 
        ; - l'année
 o
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'6'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto o
 
 p
 banksel problem
 bcf problem,0
 banksel Dataa
 movlw d'32'
 movwf Dataa
 call Databyte
 call Acknowledge
 banksel problem
 btfsc problem,0
 goto p
 
 call i2cstop
       
 ;// b) on interoge le rtc tout le temps quand on se situe dans le program principale
       ; - On interroge l'heure (sous routine heure)
       ; - On interroge la date (sous routine date)

heure
 call i2cstart ;// on fait un restart pour pointer sur l'adresse du premier registre
 call adressebyteecriture
 call Acknowledge
 
 movlw d'0' ;// on pointe sur l'adresse du premier registre
 banksel Dataa
 movwf Dataa
 call Databyte
 call Acknowledge
 
 call i2crestart ;// on fait un restart pour commencer la lecture des registre
 call adressebyte ;// les uns à la suite des autre et stockage dans les
 call Acknowledge ;// variables appropriés
 
 call lectureI2C
 banksel PIR3
 bcf PIR3,SSP1IF
 banksel SSP1BUF
 movfw SSP1BUF
 call sendAcknowledge
 banksel secondes ;// aquisition des secondes
 movwf secondes
 
 call lectureI2C
 banksel PIR3
 bcf PIR3,SSP1IF
 banksel SSP1BUF
 movfw SSP1BUF
 call sendAcknowledge
 banksel minutes ;// aquisition des minutes
 movwf minutes
 
 call lectureI2C
  banksel PIR3
 bcf PIR3,SSP1IF
 banksel SSP1BUF
 movfw SSP1BUF
 call sendAcknowledge
 banksel heures ;// aquisition des heures
 movwf heures
 
banksel heures
btfss heures,5
goto heure
banksel heures
btfss heures,2
goto heure
banksel heures
btfss minutes,6
goto heure
banksel heures
btfss minutes,4
goto heure
banksel heures
btfss minutes,3
goto heure
banksel heures
btfss minutes,0
goto heure
 
 
date
 
 call lectureI2C
  banksel PIR3
 bcf PIR3,SSP1IF
 banksel SSP1BUF
 movfw SSP1BUF
 call sendAcknowledge
 banksel jourh ;// aquisition des jours hebdomadaire
 movwf jourh
 
 call lectureI2C
  banksel PIR3
 bcf PIR3,SSP1IF
 banksel SSP1BUF
 movfw SSP1BUF
 call sendAcknowledge
 banksel jourm ;// aquisition des jours mensuels
 movwf jourm
 
 call lectureI2C
 banksel PIR3
 bcf PIR3,SSP1IF
 banksel SSP1BUF
 movfw SSP1BUF
 call sendAcknowledge
 banksel mois ;// aquisition des mois
 movwf mois
 
 call lectureI2C
  banksel PIR3
 bcf PIR3,SSP1IF
 banksel SSP1BUF
 movfw SSP1BUF
 call sendAcknowledge
 banksel année ;// aquisition des années
 movwf année
 
 call noAcknowledge ;// fin de la lecture
 call i2cstop ;// fin du bus

goto heure
; goto AffichageNOKIA
     
;// On arrete d'interroger uniquement lors d'une interruption liée à
       ; - timmer d'arrosage
       ; - interruption externe sur ADC: cellule photosensible
 
 ; 2) lancement aquisition -> OK
 
; Start condition bit
 i2cstart
 banksel SSP1CON2
 bsf SSP1CON2,SEN
 attentefinstart
 btfsc SSP1CON2,SEN
 goto attentefinstart
 return
 
 
 ; reapeated Start condition bit
 i2crestart
 banksel SSP1CON2
 bsf SSP1CON2,RSEN
 attentefinrestart
 btfsc SSP1CON2,RSEN
 goto attentefinrestart
 return
 
 ; Stop condition bit
 i2cstop
 banksel SSP1CON2
 bsf SSP1CON2,PEN
 attentefinstop
 btfsc SSP1CON2,PEN
 goto attentefinstop
 return
 
 
; Adresse byte en mode ecriture
 adressebyteecriture
 banksel SSP1BUF
 movlw b'01101000'*2 ;// On decale vers la gauche pour mettre 0 au 1er bit
                                  ; indiquant que ce qui suit sera une ecriture
 movwf SSP1BUF
 testfinadresseecriture
 banksel SSP1STAT
 btfsc SSP1STAT,R_W
 goto testfinadresseecriture
 return
 
 
 ; Adresse byte en mode lecture
 adressebyte
 banksel SSP1BUF
 movlw b'01101000'|1 ;// On decale vers la gauche pour mettre 1 au 1er bit
                                ; indiquant que ce qui suit sera une lecture par le maitre
 movwf SSP1BUF
 testfinadresse
 banksel SSP1STAT
 btfsc SSP1STAT,R_W
 goto testfinadresse
 return
 
 ; Lecture esclave
 lectureI2C
 banksel SSP1CON2
 bsf SSP1CON2,RCEN
 veriflecture
 btfsc SSP1CON2,RCEN
 goto veriflecture
 return
 
 ; verification Acceptance bit received
 
 Acknowledge
 banksel SSP1CON2
 btfss SSP1CON2,ACKSTAT
 return
 banksel problem
 bsf problem,0 ;// endroit ou reprendre la derniere adresse pour recomencer l'envoie
 return
 
 
 ; Envoie Acceptance bit
 sendAcknowledge
 banksel SSP1CON2
 bsf SSP1CON2,ACKDT
 bsf SSP1CON2,ACKEN
 checkACK
 btfsc SSP1CON2,ACKEN
 goto checkACK ;// endroit ou reprendre la derniere adresse
 return
 
  ; Envoie No Acceptance bit
 
 noAcknowledge
 banksel SSP1CON2
 bsf SSP1CON2,ACKDT
 bsf SSP1CON2,ACKEN
 checknoACK
 btfsc SSP1CON2,ACKEN
 goto checknoACK ;// endroit ou reprendre la derniere adresse
 return
 
 ; Data byte
 
 Databyte
 banksel Dataa
 movfw Dataa ;// On deverse la data dans w
 banksel SSP1BUF
 movwf SSP1BUF
 testfindata
 banksel SSP1STAT
 btfsc SSP1STAT,R_W
 goto testfindata
 return
 
 end

 
#1

32 Replies Related Threads

    ric
    Super Member
    • Total Posts : 29435
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/05 16:56:39 (permalink)
    0
    I'm not sure about your ACKEN problem, but looking at the rest of your code, your handling of received ACK/NAK when you are sending data is totally wrong.
    If you ever get a NAK from the slave, you must abandon the current transaction, and start from scratch.
    i.e. send a STOP condition, and go back to before you sent the START.
    You can NOT simply try to re-send the byte that was NAKed.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    The alchmiste
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2018/03/14 02:55:48
    • Location: France
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/05 17:57:53 (permalink)
    0
    Thanks Ric for your feedback,
     
    As of now, I've not received any NACK.
    What is the issue of not going back to a start condition?
     
    For now the only issue is related to the acknowledgment who do not want to make the ACKEN bit trigered off, so I do not get the Reason of this issue, I've tried an other pic it'the same story...
     
    Thanks 
    Thealchimiste
    #3
    ric
    Super Member
    • Total Posts : 29435
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/05 18:06:30 (permalink)
    0
    The alchmiste
    As of now, I've not received any NACK.

    Just as well, as your code will get stuck in  an endless loop, e.g. if the slave chip is not there.

    What is the issue of not going back to a start condition?

    It simply won't work. In general, if you do get a NAK from a slave, it means the slave is not there at all, or you are trying to access it when it is busy (only happens on memory chips if you try to access them straight after doing a write).
    The only correct action is to abort the entire cycle.
     

    For now the only issue is related to the acknowledgment who do not want to make the ACKEN bit trigered off, so I do not get the Reason of this issue, I've tried an other pic it'the same story...

    How exactly are you testing this?
    In a simulator?
    Debugging a real chip?
    Is it stopping the first time you call "sendAcknowledge" ?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #4
    Mysil
    Super Member
    • Total Posts : 4062
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/05 18:19:17 (permalink)
    0
    Hi,
     
    If the Slave have got into a state where SCL line is pulled Low, in clock stretch, and do not release the SCL line,
    then you may have to wait forever,
    or until the slave device is power cycled.
     
    When do this happen?  in the first Read transfer?  in the last Read transfer, any other time?
    Have Write transfer been successfully completed?
     
    When this happen, what are the state of I2C signal lines?  Value in PORTB register?
     
    PIC16F15344       I2C signals:
    SDA output seem to be mapped to RB4
    SCL output seem to be mapped to RB5
    What about input mapping?
     
    From Datasheet DS40001889C-page 196,  
    default selection for input pins on 20 pin device seem to be:
    SCK1/SCL1    SSP1CLKPPS    RB6    0b01110  is 0x8 + 0x6
    SDI1/SDA1    SSP1DATPPS    RB4   0b01100  is 0x8 + 0x4
    ; This do not match with output settings,  you may try
    ; SSP1CLKPPS = 0x8 + 0x5
        banksel  SSP1CLKPPS
        movlw    0xD    ; 8+5
        movwf    SSP1CLKPPS
     
    Regards,
        Mysil
     
    Edit:
    PORTB have Analog input properties, make sure that ANSELB bits for I2C signal pins are Cleared to enable digital input.
     
        Mysil
     
    post edited by Mysil - 2020/11/05 18:31:34
    #5
    The alchmiste
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2018/03/14 02:55:48
    • Location: France
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/06 02:08:45 (permalink)
    0
    Thanks ric

    Ok I got the point for the restart I’ll send the program back with a NACK and stop and start in case of problem bit 0 set.

    For the mode I´m testing the code, it is in real chip debugging mode.
    The issue do happât the first ack sent after first temp tentative et to read the RTC .

    Thanks
    Thealchimiste
    post edited by The alchmiste - 2020/11/06 02:10:37
    #6
    The alchmiste
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2018/03/14 02:55:48
    • Location: France
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/06 19:45:20 (permalink)
    0
    Hi Mysil,
     
    Thanks for your clr explaination.
    It seems that I've not configured the input pps mapping and that I2C need to be remaped only to RB1, RB2, RC3, RC4, therfore, I've used C Port, 3 FOR SCK and 4 for SDA.
     
    After making below adding :
     

    banksel SSP1DATPPS
    movlw 0x14 ;On associe SDA a RC4 ( les données transmises)
    movwf SSP1DATPPS
    banksel SSP1CLKPPS
    movlw 0x13 ;On associe SCL a RC3 (l'horloge)
    movwf SSP1CLKPPS
     
    I still have the program looping on the ACKEN check of the first reading from the slave:
     
    checkACK
    btfsc SSP1CON2,ACKEN
    goto checkACK 
     
    I've cleared the ANSELC before to enter the reading section of the code this is what I see for the different registers during the looping in the picture below.
    For instance I still have the same issue of looping...
     
    Thanks
    Thealchimiste
     

    Attached Image(s)

    #7
    The alchmiste
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2018/03/14 02:55:48
    • Location: France
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/08 13:45:37 (permalink)
    0
    Hi Mysil,

    Do you have any other tips to look at I’m not progressing and don’t know where to look at?

    Thanks
    Thealchimiste
    #8
    Mysil
    Super Member
    • Total Posts : 4062
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/09 04:01:07 (permalink)
    0
    Hi,
    You may:
    A:  Go thru all the nitty gritty details with a fine comb,
          and verify signal level and Input port register value,
          and SSP status and control register values,  for every step.
     
          In this connection, a Logic Analyzer, or a two channel oscilloscope may be useful.
          See this thread: https://www.microchip.com/forums/FindPost/1156906  
          In pinch,  two small LED may help, each with a suitable series resistor,
          connected in parallel with the pull-up resistors for SCL and SDA signal lines.
          LEDs must be connected between Vdd and signal, so as to act together with pull-up.
     
    B:   Package a small, complete, compileable example, that may be run in debugger.
          Use 'Package'  facility in MPLAB, it make a .zip file with all files needed to restore the project.
          and attach it to your next message. Use  'Open Full Version' in Forum editor to upload attachment.
     
    Regards,
        Mysil
         
    #9
    The alchmiste
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2018/03/14 02:55:48
    • Location: France
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/13 01:01:37 (permalink)
    0
    Mysil
    Hi,
    You may:
    A:  Go thru all the nitty gritty details with a fine comb,
          and verify signal level and Input port register value,
          and SSP status and control register values,  for every step.
     
          In this connection, a Logic Analyzer, or a two channel oscilloscope may be useful.
          See this thread: https://www.microchip.com/forums/FindPost/1156906  
          In pinch,  two small LED may help, each with a suitable series resistor,
          connected in parallel with the pull-up resistors for SCL and SDA signal lines.
          LEDs must be connected between Vdd and signal, so as to act together with pull-up.
     
    B:   Package a small, complete, compileable example, that may be run in debugger.
          Use 'Package'  facility in MPLAB, it make a .zip file with all files needed to restore the project.
          and attach it to your next message. Use  'Open Full Version' in Forum editor to upload attachment.
     
    Regards,
        Mysil
         


    Hi Mysil,
     
    I have found what is causing the issue, it is the bus collision, is just earasing the 2nd bit of PIR3 and continuing the operation enough or should I restart the entire operations?
    below a print screen of the collision I'm getting during the start condition, sometimes it's happening during the sending of ackowledgment to the slave.
     
    Thanks
    Thealchimiste

    Attached Image(s)

    #10
    ric
    Super Member
    • Total Posts : 29435
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/13 01:33:59 (permalink)
    +1 (1)
    If you get a bus collision you have to start again from scratch.
    However, why are you getting it? If there isn't another device driving the bus, it's more likely a pullup isn't working, or an I2C pin is in analog mode.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #11
    The alchmiste
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2018/03/14 02:55:48
    • Location: France
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/13 01:50:32 (permalink)
    0
    Hi Ric,
     
    I've clred the ANSELC before to go through the program.
    Here is the updated code:

        list p=16f15344 , r=dec
     #include <p16f15344.inc>


    ; CONFIG1
    ; __config 0x3E8C
     __CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _FCMEN_ON
    ; CONFIG2
    ; __config 0x279C
     __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_ON & _LPBOREN_OFF & _BOREN_NSLEEP & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_OFF
    ; CONFIG3
    ; __config 0xFFFF
     __CONFIG _CONFIG3, _WDTCPS_WDTCPS_31 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_SC
    ; CONFIG4
    ; __config 0x1FE0
     __CONFIG _CONFIG4, _BBSIZE_BB64K & _BBEN_OFF & _SAFEN_ON & _WRTAPP_OFF & _WRTB_OFF & _WRTC_OFF & _WRTSAF_OFF & _LVP_OFF
    ; CONFIG5
    ; __config 0x3FFF
     __CONFIG _CONFIG5, _CP_OFF

    ; _RSTOSC_HFINT32 -> permet l'activation de l'oscillateur interne a une frequence de 32Mhz soit 31,25 nanoS/osccillation-> 25 interuption / seconde avec: postdiviseur=10, prediviseur=128, seuil timer2=249,
    ; _LVP_OFF -> permet la programmation a faible tenssion
    ; _CP_OFF -> Ne cache pas le code
    ; _WDT_OFF -> Desactive le Watch Dog
     ; Definition des differentes variable du programme à partir de l'adresse 0x20

    cblock 0X20
     
     
    ; // Variables utiles pour rtc
    Dataa : 1 ; Valeur de la data I2C envoyé
     
    secondes : 1 ; Valeur recupéré par l'I2C sur RTC en seconde

    minutes : 1 ; Valeur recupéré par l'I2C sur RTC en minutes

    heures : 1 ; Valeur recupéré par l'I2C sur RTC en heures

    jourh : 1 ; Valeur recupéré par l'I2C sur RTC en jour hebdomadaire

    jourm : 1 ; Valeur recupéré par l'I2C sur RTC en jour mensuel
     
    mois : 1

    année : 1 ; Valeur recupéré par l'I2C sur RTC en année

    problem : 1 ; Valeur recupéré en cas de problem d'acknowlede non recu par l'esclave

        endc

    ;*******************************************************************************
    ; Reset Vector
    ;*******************************************************************************

        org 00H ; processor reset vector
        goto RTCI2C ; go to beginning of program

    ; TODO INSERT ISR HERE

    ;*******************************************************************************
    ; Routine d'interuption
    ;*******************************************************************************
        org 0x004 ; interrupt vector location
        RETFIE
        ;*******************************************************************************
    ; Macro I2C
    ;*******************************************************************************
     
    ; Parametrage I2C ( reglage vitesse, reglage des ports associé au SCK et SDA,
    ; reglage du peripherique MSSP, reglage du nombre de bit par adresse, reglage
    ; reglage des port en entré ou sortie, verrifier s'il est necessaire d'activer
    ; les pull-up resitor pour l'I2C et desactiver les pull-up resistor pour les
    ; autres ports, verrifier la fin de chaque procedure apres chaque procedure lancé)

    ; Configuration I2C
     
    RTCI2C
       
    banksel Dataa
    CLRF Dataa ; Valeur de la data I2C envoyé
    CLRF secondes ; Valeur recupéré par l'I2C sur RTC en seconde
    CLRF minutes ; Valeur recupéré par l'I2C sur RTC en minutes
    CLRF heures ; Valeur recupéré par l'I2C sur RTC en heures
    CLRF jourh ; Valeur recupéré par l'I2C sur RTC en jour hebdomadaire
    CLRF jourm ; Valeur recupéré par l'I2C sur RTC en jour mensuel
    CLRF mois
    CLRF année ; Valeur recupéré par l'I2C sur RTC en année
    CLRF problem ; Valeur recupéré en cas de problem d'acknowlede non recu par l'esclave
        
    banksel SSP1BUF
    clrf SSP1BUF

    banksel RC4PPS
    movlw 0x16 ;On associe SDA a RC4 ( les données transmises)
    movwf RC4PPS

    banksel RC3PPS
    movlw 0x15 ;On associe SCL a RC3 (l'horloge)
    movwf RC3PPS

    banksel SSP1DATPPS
    movlw 0x14 ;On associe SDA a RC4 ( les données transmises)
    movwf SSP1DATPPS

    banksel SSP1CLKPPS
    movlw 0x13 ;On associe SCL a RC3 (l'horloge)
    movwf SSP1CLKPPS
        
    banksel TRISC
    movlw B'11111111' ;RC4, RC3 en entrée
    movwf TRISC
        
    banksel SSP1STAT
    movlw B'10000000' ;// On parametre SMP a 1 pour informer que l'horloge travaillera
     ; a 1Mhz ou 100Khz et CKE a 0 pour indiquer qu'on travail en mode I2C
    movwf SSP1STAT
      
    banksel SSP1ADD
    movlw B'01001111' ;// On charge la valeur 79 afin de faire fonctionner l'horloge SCL
    ; à 100Khz formule: (Fosc/4*Fscl)-1
    movwf SSP1ADD

    banksel SSP1CON1
    movlw B'00101000' ;// On Active le module SSPM avec le bit 5 et on le paramettre
    ; avec les 4 premiers en mode I2C maitre
    movwf SSP1CON1
     
     
     banksel LATC
     clrf LATC
     
     BANKSEL ANSELC
     CLRF ANSELC
     
     ; 1) configuration I2C -> OK

     ;// a) on parametre et fixe les valeurs des registres du RTC avant de lancer les aquisitions
     call i2cstart
     call adressebyteecriture
     call Acknowledge
     
            ; - l'iniialisation du pointeur à l'adresse 0
    a
     banksel problem
     bcf problem,0
     movlw d'0'
     banksel Dataa
     movwf Dataa
     call Databyte
     call Acknowledge
     banksel problem
     btfsc problem,0
     goto a
     
            ; - les secondes
     c
     banksel problem
     bcf problem,0
     banksel Dataa
     movlw d'0'
     movwf Dataa
     call Databyte
     call Acknowledge
     banksel problem
     btfsc problem,0
     goto c
     
             ; - les minutes
    d
     banksel problem
     bcf problem,0
     movlw d'1'
     banksel Dataa
     movwf Dataa
     call Databyte
     call Acknowledge
     banksel problem
     btfsc problem,0
     goto d
     
              ; - les heures et le format
     f
     banksel problem
     bcf problem,0
     movlw 0x59
     banksel Dataa
     movwf Dataa
     call Databyte
     call Acknowledge
     banksel problem
     btfsc problem,0
     goto f
     
     
     ; - le jour de la semaine
     h
     banksel problem
     bcf problem,0
     movlw d'4'
     banksel Dataa
     movwf Dataa
     call Databyte
     call Acknowledge
     banksel problem
     btfsc problem,0
     goto h
     
            ; - le jour du mois
     k
     banksel problem
     bcf problem,0
     banksel Dataa
     movlw 0x12
     movwf Dataa
     call Databyte
     call Acknowledge
     banksel problem
     btfsc problem,0
     goto k
      
            ; - le mois
     m
     banksel problem
     bcf problem,0
     banksel Dataa
     movlw 0x11
     movwf Dataa
     call Databyte
     call Acknowledge
     banksel problem
     btfsc problem,0
     goto m
     
            ; - l'année
     o
     banksel problem
     bcf problem,0
     banksel Dataa
     movlw 0x20
     movwf Dataa
     call Databyte
     call Acknowledge
     banksel problem
     btfsc problem,0
     goto o
     
     call i2cstop
           
     ;// b) on interoge le rtc tout le temps quand on se situe dans le program principale
           ; - On interroge l'heure (sous routine heure)
           ; - On interroge la date (sous routine date)

    heure
     call i2cstart ;// on fait un restart pour pointer sur l'adresse du premier registre
     call adressebyteecriture
     call Acknowledge
     
     movlw d'0' ;// on pointe sur l'adresse du premier registre
     banksel Dataa
     movwf Dataa
     call Databyte
     call Acknowledge
     
     call i2crestart ;// on fait un restart pour commencer la lecture des registre
     call adressebyte ;// les uns à la suite des autre et stockage dans les
     call Acknowledge ;// variables appropriés
     
     call lectureI2C
     banksel SSP1BUF
     movfw SSP1BUF
     call sendAcknowledge
     banksel secondes ;// aquisition des secondes
     movwf secondes
     
     call lectureI2C
     banksel SSP1BUF
     movfw SSP1BUF
     call sendAcknowledge
     banksel minutes ;// aquisition des minutes
     movwf minutes
     
     call lectureI2C
     banksel SSP1BUF
     movfw SSP1BUF
     call sendAcknowledge
     banksel heures ;// aquisition des heures
     movwf heures
     
    banksel heures
    btfss heures,5
    goto heure
    banksel heures
    btfss heures,2
    goto heure
    banksel heures
    btfss heures,1
    goto heure
    banksel heures
    btfss minutes,6
    goto heure
    banksel heures
    btfss minutes,4
    goto heure
    banksel heures
    btfss minutes,3
    goto heure
    banksel heures
    btfss minutes,0
    goto heure
     
     
    date
     
     call lectureI2C
     banksel SSP1BUF
     movfw SSP1BUF
     call sendAcknowledge
     banksel jourh ;// aquisition des jours hebdomadaire
     movwf jourh
     
     call lectureI2C
     banksel SSP1BUF
     movfw SSP1BUF
     call sendAcknowledge
     banksel jourm ;// aquisition des jours mensuels
     movwf jourm
     
     call lectureI2C
     banksel SSP1BUF
     movfw SSP1BUF
     call sendAcknowledge
     banksel mois ;// aquisition des mois
     movwf mois
     
     call lectureI2C
     banksel SSP1BUF
     movfw SSP1BUF
     call sendAcknowledge
     banksel année ;// aquisition des années
     movwf année
     
     call noAcknowledge ;// fin de la lecture
     call i2cstop ;// fin du bus

    goto heure
    ; goto AffichageNOKIA
         
    ;// On arrete d'interroger uniquement lors d'une interruption liée à
           ; - timmer d'arrosage
           ; - interruption externe sur ADC: cellule photosensible
     
     ; 2) lancement aquisition -> OK
     
    ; Start condition bit
     i2cstart
     banksel PIR3
      bcf PIR3,1
     banksel SSP1CON2
     bsf SSP1CON2,SEN
     interuptionflag
     banksel PIR3
     BTFSC PIR3,1
     GOTO i2cstart
     BANKSEL PIR3
     btfss PIR3,0
     goto interuptionflag
     bcf PIR3,0
     attentefinstart
     btfsc SSP1CON2,SEN
     goto attentefinstart

     return
     
     
     ; reapeated Start condition bit
     i2crestart
     banksel SSP1CON2
     bsf SSP1CON2,RSEN
     attentefinrestart
     btfsc SSP1CON2,RSEN
     goto attentefinrestart
     BANKSEL PIR3
     interuptionflag1
     btfss PIR3,0
     goto interuptionflag1
     bcf PIR3,0
     return
     
     ; Stop condition bit
     i2cstop
     banksel SSP1CON2
     bsf SSP1CON2,PEN
     attentefinstop
     btfsc SSP1CON2,PEN
     goto attentefinstop
     BANKSEL PIR3
     interuptionflag2
     btfss PIR3,0
     goto interuptionflag2
     bcf PIR3,0
     return
     
     
    ; Adresse byte en mode ecriture
     adressebyteecriture
     banksel SSP1STAT
     bcf SSP1STAT,R_W
     
     movlw b'11010000' ;// On decale vers la gauche pour mettre 0 au 1er bit
     banksel SSP1BUF ; indiquant que ce qui suit sera une ecriture
     movwf SSP1BUF
     interuptionflag3
     banksel PIR3
     btfss PIR3,0
     goto interuptionflag3
     bcf PIR3,0
     banksel SSP1STAT
     testfinadresseecriture
     btfsc SSP1STAT,BF
     goto testfinadresseecriture

     return
     
     
     ; Adresse byte en mode lecture
     adressebyte
     banksel SSP1STAT
     bsf SSP1STAT,R_W
     banksel SSP1BUF
     movlw b'11010000' ;// On decale vers la gauche pour mettre 1 au 1er bit
                                    ; indiquant que ce qui suit sera une lecture par le maitre
     movwf SSP1BUF
     banksel SSP1STAT
     interuptionflag4
     banksel PIR3
     btfss PIR3,0
     goto interuptionflag4
     bcf PIR3,0
     testfinadresse
     btfsc SSP1STAT,BF
     goto testfinadresse

     return
     
     ; Lecture esclave
     lectureI2C
     banksel SSP1CON2
     bsf SSP1CON2,RCEN
     testfinlecture
     banksel SSP1STAT
     btfsc SSP1STAT,BF
     goto testfinlecture
     interuptionflag6
     banksel PIR3
     btfss PIR3,0
     goto interuptionflag6
     bcf PIR3,0
     return
     
     ; verification Acceptance bit received
     
     Acknowledge
     banksel SSP1CON2
     btfss SSP1CON2,ACKSTAT
     return
     banksel problem
     bsf problem,0 ;// endroit ou reprendre la derniere adresse pour recomencer l'envoie
     return
     
     
     ; Envoie Acceptance bit
     sendAcknowledge
      banksel PIR3
      bcf PIR3,1
     banksel SSP1CON2
     bsf SSP1CON2,ACKDT
     bsf SSP1CON2,ACKEN
     banksel PIR3
     BTFSC PIR3,1
     GOTO sendAcknowledge
     interuptionflag7
     banksel PIR3
     btfss PIR3,0
     goto interuptionflag7
     bcf PIR3,0 ;// endroit ou reprendre la derniere adresse
     return
     
      ; Envoie No Acceptance bit
     
     noAcknowledge
     banksel SSP1CON2
     bsf SSP1CON2,ACKDT
     bsf SSP1CON2,ACKEN
     checknoACK
     btfsc SSP1CON2,ACKEN
     goto checknoACK ;// endroit ou reprendre la derniere adresse
     return
     
     ; Data byte
     
     Databyte
     banksel Dataa
     movfw Dataa ;// On deverse la data dans w
     banksel SSP1BUF
     movwf SSP1BUF
     interuptionflag5
     banksel PIR3
     btfss PIR3,0
     goto interuptionflag5
     bcf PIR3,0
     testfindata
     banksel SSP1STAT
     btfsc SSP1STAT,BF
     goto testfindata

     return


     
     end

    #12
    The alchmiste
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2018/03/14 02:55:48
    • Location: France
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/13 14:43:01 (permalink)
    +1 (1)
    Hi Ric,

    Is a 1k resistor ok for each line ?

    Thanks
    Thealchimiste
    #13
    ric
    Super Member
    • Total Posts : 29435
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/13 15:51:56 (permalink)
    0
    Do you mean pullups on SDA and SCL?
    Yes, they should be fine.
     
    Just an aside, do NOT clear SSPBUF in your init code.
    Any write to SSPBUF will try to start a transfer in whatever mode the SSP peripheral happens to be in. That is not a good idea.
     
    Your "send start" function looks way too complicated. You have not commented it, so I don't know what you think you are doing, but try cutting it down to just:

    i2cstart:
            banksel SSP1CON2
            bsf     SSP1CON2,SEN    ;start sending a START cycle
    i2cstart_wait:
            btfsc   SSP1CON2,SEN    ;has the cycle completed yet?
            goto    i2cstart_wait   ;no, keep waiting
            return

    This code is not checking for a bus collision, but your version is not either.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #14
    Mysil
    Super Member
    • Total Posts : 4062
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/13 16:54:29 (permalink)
    0
    Hi,
    1 kOhm resistor for pull-up to Vdd for each of SCL and and SDA lines will give a rather strong pull-up current,
    and is Not a reason for the problem experienced.
     
    You may do the following test:
    With Debugger, set a breakpoint before Start instruction. Measure with Multimeter or Oscilloscope the voltage on SDA and SCL pins: signal voltage on SCL and SDA should both be near Vdd power voltage.
    Then also observe PORT register bits for SCL and SDA pins, both should be 1.
     
    Then step the debugger past:     bsf SSP1CON2,SEN    
    and examine     PIR3,BCL1IF  ; If this bit have been set, then problem have already occurred.
    Run or step the program until    SSP1CON2,SEN    go back to 0.
    Measure voltage on SCL and SDA pins,  if voltage is less than 0.4 V, then signal is good, and pull-up current is not too high.
    Again examine  PORTx  register in debugger,  value shall be 0 for both SCL and SDA bits. If this is Not the case, then problem have already occurred.
     
    If all is correct at this point, then you may proceed with address transfer.
     
    If PORT bits react as expected to voltage on SCL and SDA pins,
    but  BCL1IF bit still get 1,  then problem may be in PPS settings.
     
    When trying to assemble the program shown in message #12, then there are a large number of warnings about instructions starting in column 1, and about labels not starting in column 1.
    Also, there are a lot of labels, that are not delimited with a colon:     
    This seem sloppy to me, and make the code more difficult to understand.
    Some of the bad formatting may come from whitespace beeing garbled by forum editor, but not everything.
     
        Mysil
    #15
    Mysil
    Super Member
    • Total Posts : 4062
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/15 09:17:54 (permalink)
    0
    Hi,
    I have found a bug in code shown in message #12
     
    Function to send Acknowledge from master to slave,
    set wrong value to ACKDT bit. ACK signal shall have ACKDT = 0;
    Bit value 1 is NACK

    ; Envoie Acceptance bit
    sendAcknowledge:
        banksel PIR3
        bcf PIR3,1
        banksel SSP1CON2
        bsf SSP1CON2,ACKDT  ; /* Should be  bcf SSP1CON2, ACKDT */
        bsf SSP1CON2,ACKEN
     ...

    This cause a Read transfer to terminate after 1 data byte, see attached image.
     
    Also function to send Read address have a mistake, there is no 1 bit  for Read address,
    address byte should be:  b'11010001'

    ; Adresse byte en mode lecture
    adressebyte:
        banksel SSP1STAT
        bsf SSP1STAT,R_W
        banksel SSP1BUF
        movlw b'11010000' ;// On decale vers la gauche pour mettre 1 au 1er bit
                          ; indiquant que ce qui suit sera une lecture par le maitre
        movwf SSP1BUF
     ...

     
    There may be other bugs,
    I have done a lot of changes to run the code with debugger on a different chip,
    PIC16F1718 and using a EEPROM as stand-in for the RTC.
     
        Mysil
    post edited by Mysil - 2020/11/15 12:24:52

    Attached Image(s)

    #16
    Mysil
    Super Member
    • Total Posts : 4062
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/15 12:23:02 (permalink)
    0
    Hi,
    There is another bug. After reading 3 data bytes, containing seconds, minutes and hours,
    there is something causing  Read transfer to be stopped without a NACK issued from master code.
    Such a truncated transfer cause the Slave device to hold the SDA line,
    and cause following transfer to detect bus collision problem.
    This is caused by a big block of logic that try to decode the hours value,
    and jump away from the read sequence, without continue reading date and following values.
     
    Then there is this sequence that Read one data byte,
    and then try to send Two acknowledge signals, one ACK and one NACK.
    This cannot work, there must be exactly One acknowledge signal,
    either NACK or ACK.

        call lectureI2C
        banksel SSP1BUF
        movfw SSP1BUF
        call sendAcknowledge
        banksel année ;// aquisition des années
        movwf année
     
        call noAcknowledge ;// fin de la lecture
        call i2cstop ;// fin du bus



        Mysil
     
    #17
    Mysil
    Super Member
    • Total Posts : 4062
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/16 05:00:10 (permalink)
    0
    Hi,
    Here is program project using your code with corrections and modifications to make it work. 
    I do not have your RTC device, or the same PIC device,
    so have used a EEPROM device as stand-in.
    There are a number of differences since PIC16F1718 use PIR1 and PIR2 registers for interrupt flags,
    different from PIR3 in the PIC16f15344 device.
    Corrections and modifications are done in Experiment_PIC16F1718.asm.
    Experiment.asm   have not been corrected, other than to make it possible to read.
     
        Mysil
     
     
     
    post edited by Mysil - 2020/11/16 05:20:17

    Attached Image(s)

    #18
    The alchmiste
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2018/03/14 02:55:48
    • Location: France
    • Status: offline
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/16 13:21:29 (permalink)
    0
    Hi Mysil,
     
    Really apreciate your help.
    Just to explain you my logic on this big logic block.
    What I'm doing is to avoide going for a read the date since I've not past 23h59 to update the value of the date, this will save some machine time. So I test each relevant bits of the time intervening in the value of 23h59:
     
        banksel heures ; 
        btfss heures,5 ; -> decimal value 2
        goto heure  ;  -> If not set Don't bother with the other bits and continue updating the time
        banksel heures
        btfss heures,1 ; -> decimal value 2
        goto heure  ; 
        banksel heures
        btfss heures,0 ; -> decimal value 1
        goto heure
        banksel heures
        btfss minutes,6 -> decimal value 4
        goto heure
        banksel heures
        btfss minutes,4 -> decimal value 1
        goto heure
        banksel heures
        btfss minutes,3 -> decimal value 8
        goto heure
        banksel heures
        btfss minutes,0 -> decimal value 1
        goto heure
     
    I'll go through your comments in the code and make the test and provide a feedback. 
    I see that you really took the time to go through my code I appreciate it a lot!!
     
    Thanks
    Thealchimiste
    #19
    ric
    Super Member
    • Total Posts : 29435
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code 2020/11/16 13:57:51 (permalink)
    +1 (1)
    why do it such a convoluted way, rather than just comparing with "23" and "59" ?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2021 APG vNext Commercial Version 4.5