#include "lamp_i2c_clock.h"
#include "lamp_i2c_pins.h"
#include "stm32g0xx.h"
static bool initialized;
#define SELECT (2u << RCC_CCIPR_I2C1SEL_Pos)
#define HSI_READY (RCC_CR_HSION|RCC_CR_HSIRDY)
#define LINES ((1u<<6)|(1u<<7))
#define PENDING (I2C_ISR_BUSY|I2C_ISR_RXNE|I2C_ISR_TC|I2C_ISR_TCR|I2C_ISR_STOPF|I2C_ISR_NACKF|I2C_ISR_BERR|I2C_ISR_ARLO|I2C_ISR_OVR|I2C_ISR_TIMEOUT)
bool lamp_i2c_clock_available(void){
    return initialized && lamp_i2c_pins_available() &&
        (RCC->APBENR1&RCC_APBENR1_I2C1EN)!=0u &&
        (RCC->CR&HSI_READY)==HSI_READY &&
        (RCC->CCIPR&RCC_CCIPR_I2C1SEL)==SELECT &&
        I2C1->TIMINGR==LAMP_I2C_TIMING_CANDIDATE &&
        I2C1->CR1==I2C_CR1_PE && I2C1->OAR1==0u &&
        I2C1->OAR2==0u && I2C1->TIMEOUTR==0u;
}
bool lamp_i2c_clock_init(void){
    initialized=false;
    /* No reconfiguration of a live/unowned engine, and no busy wait. */
    if(!lamp_i2c_pins_available() ||
       (RCC->APBENR1&RCC_APBENR1_I2C1EN)==0u ||
       (RCC->CR&HSI_READY)!=HSI_READY ||
       (GPIOB->IDR&LINES)!=LINES || I2C1->CR1!=0u ||
       I2C1->CR2!=0u || I2C1->OAR1!=0u || I2C1->OAR2!=0u ||
       I2C1->TIMEOUTR!=0u || (I2C1->ISR&PENDING)!=0u)return false;
    /* RM0454: I2C1SEL=10 is undivided HSI16. Preserve all other muxes. */
    RCC->CCIPR=(RCC->CCIPR&~RCC_CCIPR_I2C1SEL)|SELECT;
    I2C1->TIMINGR=LAMP_I2C_TIMING_CANDIDATE;
    __DSB();
    I2C1->CR1=I2C_CR1_PE; /* Analog filter on, DNF=0, no IRQ/DMA/slave. */
    __DSB();initialized=true;
    if(!lamp_i2c_clock_available()){
        initialized=false;I2C1->CR1&=~I2C_CR1_PE;return false;
    }
    return true;
}
