Cómo hacer que I2C se apague mientras espera datos en el modo de transmisión maestra en LPC1114

Tengo un LPC1114 (FN28) para el que estoy escribiendo un código. Actualmente estoy tratando de proporcionar una vista asíncrona de la interfaz I2C a mi código (el chip tiene un controlador I2C incorporado). El controlador en sí es básicamente una máquina de estado, pero dado que la especificación I2C no especifica tiempo de espera u otras restricciones en la velocidad del reloj SCL, debería poder retrasar el envío (no tiene que ser perfectamente sincrónico) siempre que el controlador controle SCL correctamente cuando se envían datos y lo mantiene bajo cuando no se envían datos.

La idea es poder almacenar en búfer los datos que se enviarán en el bus I2C. Algunas bibliotecas que veo se ocupan de esto simplemente almacenando en búfer todo y bitbanging todo a la vez, lo cual está bien la mayor parte del tiempo ya que generalmente no envía muchos datos a través de I2C, pero quiero hacerlo correctamente.

Configuré el código base y el problema que tengo al transmitir datos es que cada vez que el controlador ingresa al modo "transmitir datos a esclavo", activa una interrupción que requiere que complete un byte de datos para enviar (o enviar una señal de PARADA). El problema es que si no hago nada, inmediatamente emite la misma interrupción, ¡así que mi código principal ni siquiera puede tener la oportunidad de ejecutarse! ¡Lo que quiero es la capacidad de decirle al controlador "No tengo bytes para enviar en este momento, así que no emita otra interrupción hasta que se lo indique desde mi código principal"!

He arreglado algo que funciona (¿ab?) usando NVIC para deshabilitar la interrupción I2C cuando estoy esperando datos y volver a habilitarlo cuando estoy listo para enviar en la interfaz I2C, pero esto parece muy poco ortodoxo y No sé si es realmente confiable o incluso correcto, especialmente si mientras tanto le suceden cosas malas al autobús (error de autobús, etc.)

Aquí está el manual para el chip , los documentos para el controlador I2C están en la página 239. Pensé que podría usar el bit de control SI para decirle que no emita una interrupción hasta que lo borre nuevamente, pero aparentemente no es para eso.

¿Alguien tiene experiencia con este o controladores I2C similares y sabe cómo puedo lograr lo que estoy buscando? Claramente debe ser posible, ya que un protocolo en el que necesita tener todos los datos listos por adelantado cada vez no me parece viable.

"un protocolo en el que necesita tener todos los datos listos por adelantado cada vez que no me parece viable" Probablemente haya formas de evitarlo, por ejemplo, sondear el estado del registro en lugar de ejecutarlo en modo de interrupción. Pero en realidad, preparar todos los datos por adelantado describiría la gran mayoría de los usos típicos: si observa el controlador de NXP, normalmente entrega una transacción completa a la vez y toma decisiones solo entre ellas.
"Quiero hacerlo bien". IMO bit-banging es la forma correcta de hacer las cosas, a menos que necesite algunas de las ventajas del soporte de hardware (velocidad, operación sin intervención). Pero pierde portabilidad, que en mi opinión es una gran pérdida.
@WoutervanOoijen No considero que la portabilidad sea un gran problema para mí en este momento, probablemente trabajaré con los chips Cortexes y NXP en el futuro previsible, así que si hay un buen hardware integrado en el chip, quiero usarlo maldita sea :) sin embargo en A la luz de sus comentarios y los de Chris, pensaré en mejores formas de estructurar mi código para no tener que saltar a través de los aros.

Respuestas (1)

Deshabilitar la interrupción cuando no tiene datos para enviar es exactamente el enfoque correcto a seguir con un controlador maestro I2C de hardware.

Cuando los datos estén disponibles, vuelva a habilitar la interrupción e inmediatamente la tomará, lo que transferirá el byte al controlador.

Gracias, eso me tranquiliza un poco. ¿Es común en el desarrollo integrado simplemente activar y desactivar las interrupciones todo el tiempo? Hasta ahora solo he necesitado habilitarlos una vez y listo, pero aún no he ido muy lejos.
¡Absolutamente! ¡Para eso están ahí! Por ejemplo, haría lo mismo con una interrupción de transmisión UART cuando no tenga nada que enviar.
Oh, tienes un buen punto... No he usado la interrupción de transmisión para UART pero estoy enviando sincrónicamente en este momento, si lo hubiera usado probablemente habría tenido el mismo problema que tuve para I2C... eso se borra arriba ¡Gracias!