Peripheral hardware and interrupts

27 views
Skip to first unread message

rob...@hotmail.com

unread,
Jun 1, 2023, 2:34:54 PM6/1/23
to jallib
Hi all,

I have the following issue and I am interested in either your suggestions or if you encountered the same problem. The example is based on the sample program I made for the real time clock library DS3231.

The DS3231 has two alarms and uses the IIC interface. The device has an interrupt line that can be activated when an alarm is triggered. I connected this line to the external interrupt of the PIC.

The main program read the time and sends it to the serial port. Since the main program calls DA3231 functions, the IIC interface is used to access the DS3231. When an interrupt occurs, a register has to be read from the DS3231 to see which alarm was activated also using the IIC interface of course.

In order to prevent that halfway an IIC transmission initiated by a library call from the main program, I disable the external interrupt of the PIC at the start of the main program an enable it again at the end of the main program. In that way I am sure that the interrupt does not interrupt an IIC transmission initiated by the main program. There is a delay at the end of the main program, sufficient for any pending interrupt to be handled.

The problem is that it does not work. The PIC just hangs and does not start. The only solution I found is setting a flag in the interrupt routine and let the main program poll this flag and read the register from the DS3231 to check which alarm was activated. But in this way the whole idea of the interrupt is gone. 

Looking forward to your reactions and suggestions.

Thanks.

Kind regards,

Rob



vsurducan

unread,
Jun 1, 2023, 2:58:52 PM6/1/23
to jal...@googlegroups.com
Hi Rob,
Perhaps you should disable/enable interrupts within the I2c procedures and not for the entire main program.
The way you did it, by writing a flag in the ISR and reading it in the main is correct. If you need less delay between the main execution and interrupt flag refresh, you should have just one interrupt routine and keep it as short as possible. Nowadays the JAL libraries are using multiple ISR's which are controlled entirely by the compiler. This feature does not give too many options to the user except writing his own procedures for sensitive interrupt applications instead of using libraries with their own ISR's.

best wishes

--
You received this message because you are subscribed to the Google Groups "jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jallib+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jallib/679a0f81-03fe-4310-b401-ac69f2d2aeadn%40googlegroups.com.

Rob CJ

unread,
Jun 1, 2023, 3:01:38 PM6/1/23
to jal...@googlegroups.com
Hi Vasile,

Good suggestion. I will give it a try.

Thanks.

Kind regards,

Rob


Van: jal...@googlegroups.com <jal...@googlegroups.com> namens vsurducan <vsur...@gmail.com>
Verzonden: donderdag 1 juni 2023 20:58
Aan: jal...@googlegroups.com <jal...@googlegroups.com>
Onderwerp: Re: [jallib] Peripheral hardware and interrupts
 
You received this message because you are subscribed to a topic in the Google Groups "jallib" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jallib/13BABaIMXzs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jallib+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jallib/CAM%2Bj4qt%3DKi2pGVDwyLkzHmZJAsaX0qkoQPxM-p580W4BC%3DKNMw%40mail.gmail.com.

Rob CJ

unread,
Jun 2, 2023, 1:30:47 PM6/2/23
to jal...@googlegroups.com
Hi Vasile,

Before testing this I gave this some more thought and had a short look at the assembly file.

The issue is that as soon at I do any IIC ibrary call from an interrupt routine, all these routines become 'interrupt routines' if you know what I mean. I think that means that these routines can no longer be called from a non-interrupt location like the main program.

For example a non-interrupt routine to transmit something over the IIC looks like this:

;  102 function i2c_transmit_byte(byte in data) return bit is
l_i2c_transmit_byte
                               movlb    0
                               movwf    v___data_80
;  104    PIR1_SSPIF = false  ; clear pending flag
                               bcf      v_pir1, 3 ; pir1_ssp1if
;  105    sspbuf = data       ; write data
                               movf     v___data_80,w
                               movlb    4
                               movwf    v_ssp1buf
;  108    while ! PIR1_SSPIF loop end loop
l__l524
                               movlb    0
                               btfsc    v_pir1, 3 ; pir1_ssp1if
                               goto     l__l525
                               goto     l__l524
l__l525
;  113    if SSPCON2_ACKSTAT == low  then
                               movlb    4
                               btfsc    v_ssp1con2, 6 ; ssp1con2_ackstat
                               goto     l__l528
;  114       return true -- okay
                               movlb    0
                               bsf      v__pic_temp, 0 ; _pic_temp
                               return  

But if you do a call to the same IIC procedure from an interrupt the code becomes this:

;  102 function i2c_transmit_byte(byte in data) return bit is
l_i2c_transmit_byte
                               incf     v__ri2c_transmit_byte,f
                               decfsz   v__ri2c_transmit_byte,w
                               goto     l__l712
                               movlp    HIGH l__l713
                               goto     l__l713
l__l712
                               movf     v__pic_stkptr+1,w
                               movwf    v__fsr0h
                               movf     v__pic_stkptr,w
                               movwf    v__fsr0l
                               decf     v__pic_stkptr,f
                               decf     v__fsr0l,f
                               movf     v__fi2c_transmit_byte,w
                               movwf    v__ind
l__l713
                               movf     v__pic_temp,w
                               movwf    v___data_80
;  104    PIR1_SSPIF = false  ; clear pending flag
                               bcf      v_pir1, 3 ; pir1_ssp1if
;  105    sspbuf = data       ; write data
                               movf     v___data_80,w
                               movlb    4
                               movwf    v_ssp1buf
;  108    while ! PIR1_SSPIF loop end loop
l__l524
                               movlp    HIGH l__l525
                               movlb    0
                               btfsc    v_pir1, 3 ; pir1_ssp1if
                               goto     l__l525
                               goto     l__l524
l__l525
;  113    if SSPCON2_ACKSTAT == low  then
                               movlb    4
                               btfsc    v_ssp1con2, 6 ; ssp1con2_ackstat
                               goto     l__l528
;  114       return true -- okay
                               movlb    0
                               bsf      v__pic_temp, 0 ; _pic_temp
                               goto     l__l523
;  115    else
l__l528
;  116       sspcon1_sspen = false;
                               bcf      v_ssp1con1, 5 ; ssp1con1_sspen
;  117       sspcon1_sspen = true;
                               bsf      v_ssp1con1, 5 ; ssp1con1_sspen
;  119       return false -- no response
                               movlb    0
                               bcf      v__pic_temp, 0 ; _pic_temp
;  120    end if
;  121 end function
l__l523
                               decfsz   v__ri2c_transmit_byte,f
                               goto     l__l715
                               return  
l__l715
                               movf     v__pic_stkptr+1,w
                               movwf    v__fsr0h
                               movf     v__pic_stkptr,w
                               movwf    v__fsr0l
                               movf     v__ind,w
                               movwf    v__fi2c_transmit_byte
                               incf     v__fsr0l,w
                               movwf    v__pic_stkptr
l__l714
                               return  

I think it cannot be mixed. The only solution I can think of is making separate routines that access the IIC hardware registers directly without a call to any other - common - routine.

Kind regards,

Rob



Van: jal...@googlegroups.com <jal...@googlegroups.com> namens Rob CJ <rob...@hotmail.com>
Verzonden: donderdag 1 juni 2023 21:01

vsurducan

unread,
Jun 3, 2023, 1:07:06 AM6/3/23
to jal...@googlegroups.com
I know that calling some procedures of the same library from the main an fron an ISR may work. The NRF905 example is one which work this way if I recall correctly. However, that approach is consuming more hw stacks which is not very good (the libraries are supposed to keep their backward compatibility with old 8 hw stack pics).
I think your decision is correct. Use your own I2C procedures within ISR and not I2C libraries. Actually this is the way to build a fast and complex ISR.

Reply all
Reply to author
Forward
0 new messages