La interrupción PIC16 I2C no ocurre si el puerto serie está habilitado

Estoy usando un PIC de rango medio PIC16F1825 y lo he usado con UART y SPI durante un buen tiempo sin problemas. Cuando agregué código para manejar I2C (en lugar de SPI, es uno u otro en esta PIC), tuve problemas al no recibir la interrupción de I2C, por lo que SCL permanecería estirado para siempre.

Después de una depuración considerable, descubrí que eliminar el código que activó el puerto serie solucionó el problema: se llama al ISR I2C y actúa normalmente.

Todo lo que estoy haciendo en el serial init es configurar SPBRG y luego:

 bcf         TXSTA, SYNC             ; Async (default)
 bsf         RCSTA, SPEN             ; Active serial port

 bsf         TXSTA, TXEN             ; Enable TX
 bsf         RCSTA, CREN             ; Enable RX

eso. No hay interrupciones habilitadas (solo configuré la bandera en transmisión)

He buscado en los documentos y las erratas y no encuentro ningún indicio de que habilitar el puerto serie dañaría la funcionalidad I2C como esta. ¿Es este mi malentendido o hay un error de silicio real aquí?

No veo esto en la lista de erratas del dispositivo. Para descartar un error de programación, ¿podrías pegar tu ISR también? Sin embargo, no es imposible que haya encontrado un nuevo problema de silicio.
No puedo pegar el código completo debido a problemas de la empresa, etc. El código es similar a mi código PIC16F88 ( github.com/conoror/picmicro ). Sin embargo, no soy un novato en asm :-) Realmente estaba tratando de ver si alguien más había visto esto antes. Lo que haré (tendrá que ser en unos días) es alternar bits de puerto en el ISR para ver a dónde llega, si es que llega a algún lugar. Me pregunto si Microchip aceptará informes de errores (de un no aficionado).
Siempre he encontrado que Microchip es muy receptivo a los informes de errores cuando los contacté con errores del compilador en el pasado. Tengo una cuenta registrada en su sitio y aunque mi empresa ciertamente no es lo suficientemente grande como para estar en su 'radar', todavía me han tomado en serio.
@brhans: Es bueno saberlo, gracias. Mi empresa es de 3 personas, por lo que no es grande en absoluto. ¡Sin embargo, voy a encontrar un analizador lógico para asegurarme antes de perder el tiempo! Voy a poner una respuesta aquí cuando me entere.

Respuestas (1)

Esto no es un error de silicio. Este soy yo siendo un completo idiota.

Lo que sucede es que mi código uart se escribió hace un año y se basó en el hecho de que PIR1, TXIF era alto si el búfer de transmisión UART estaba vacío . Mi código recoge los datos señalados por FSR0 hasta que llega a "\0" y luego desactiva TXIE. Por lo tanto, cuando cargo FSR y configuro TXIE, los datos se transmiten automáticamente. Pasa un año y escribo un ISR como este:

    .intr   CODE        4

    ; Enhanced Midrange CPU does a context save on:
    ; W, STATUS, BSR, FSR, PCLATH
    ; retfie restores context

    pagesel     $

    ifbset      INTCON, TMR0IF          ; Timer0
      goto      Timer0_Entry

    banksel     PIR1                    ; Bank #0
    ifbset      PIR1, TXIF              ; Serial transmit
      goto      SerialTX_Entry

    ifbset      PIR1, SSP1IF
      goto      I2C_Entry               ; I2C Peripheral

    retfie                              ; Nothing else

Bueno, eso es una tontería total y absoluta. Si se recibe alguna interrupción que no sea una del temporizador, ya sea UART o I2C, se llamará a SerialTX_Entry. TXIF siempre se establece si el UART está habilitado y no se retiene ningún carácter para la transmisión. Entonces, en el ejemplo anterior, nunca se alcanzará I2C_Entry.

Aquí hay una lección: ¡publique el código! Cuando le mostré a otra persona el ISR, lo vio de inmediato.