R8C/1BでI2C

1B じゃなくてもいいかも。

なにこれは

やるたびに状態遷移がよくわからなくて困るので、やり方をメモする。 ... なぜディスコンになったマイコンをこれからも使い倒すつもりなんだ?

slave

void init(){
    sar = 16 << 1;
    pmr = 0b10000000;
    iccr1 = 0b10000000;
    icmr = 0b00000111;
    icsr; icsr = 0;
    icier = 0b10100100;
    iic2aic = 4;
}

uint8_t iic_tx_test(uint8_t offset){
    return offset < 1;
}
uint8_t iic_tx_data(uint8_t offset){
    return 0;
}
void iic_rx_data(uint8_t offset, uint8_t data){
}

#define IIC_INTBIT_TX_EMPTY 0x80
#define IIC_INTBIT_TX_END   0x40
#define IIC_INTBIT_RX       0x20
#define IIC_INTBIT_NACK     0x10
#define IIC_INTBIT_STOP     0x08
#define IIC_ACKENABLE       0x04
#define IIC_STABIT_NACK     0x01
void iic_int(void) __attribute__((interrupt));
void iic_int(void){
    static int8_t offset = 0;
    uint8_t state = icsr;
    if(state & IIC_INTBIT_STOP){
        offset = 0;
        state = 0; icsr = state;
        icier = IIC_INTBIT_TX_EMPTY | IIC_INTBIT_RX | IIC_ACKENABLE;
    }else if(state & IIC_INTBIT_TX_END){
        state &= ~IIC_INTBIT_TX_END; icsr = state;
        iccr1 = 0b10000000;
        icdrr;
        state &= ~IIC_INTBIT_TX_EMPTY; icsr = state;
        icier = IIC_INTBIT_TX_EMPTY | IIC_INTBIT_RX
            | IIC_INTBIT_STOP | IIC_ACKENABLE;
    }else if(state & IIC_INTBIT_NACK){
        state &= ~IIC_INTBIT_NACK; icsr = state;
        iccr1 = 0b10000000;
        icdrr;
        state &= ~IIC_INTBIT_TX_EMPTY; icsr = state;
        icier = IIC_INTBIT_TX_EMPTY | IIC_INTBIT_RX
            | IIC_INTBIT_STOP | IIC_ACKENABLE;
    }else if(state & IIC_INTBIT_TX_EMPTY){
        if(offset > 0) offset = 0;
        if(iic_tx_test(-offset)){
            icdrt = iic_tx_data(-(offset--));
            state &= ~IIC_INTBIT_TX_EMPTY;
            icier = IIC_INTBIT_TX_EMPTY | IIC_INTBIT_RX | IIC_INTBIT_NACK
                | IIC_INTBIT_STOP | IIC_ACKENABLE;
        }else{
            icier = IIC_INTBIT_TX_END | IIC_INTBIT_NACK
                | IIC_INTBIT_STOP | IIC_ACKENABLE;
        }
    }else if(state & IIC_INTBIT_RX){
        if(offset < 0) offset = 0;
        if(offset = 0){
            icdrr;
            offset++;
            state &= ~IIC_INTBIT_RX;
            icier = IIC_INTBIT_TX_EMPTY | IIC_INTBIT_RX
                | IIC_INTBIT_STOP | IIC_ACKENABLE;
        }else{
            iic_rx_data(offset++, icdrr);
            state &= ~IIC_INTBIT_RX;
            icier = IIC_INTBIT_TX_EMPTY | IIC_INTBIT_RX
                | IIC_INTBIT_STOP | IIC_ACKENABLE;
        }
        state &= ~IIC_INTBIT_RX;
    }else{
        goto ERROR;
    }
    return;

ERROR:
    iccr1 = 0b10000000;
    iccr2 = 0b01010010;     // reset iic I/F
    iccr1 = 0b10000000;
    icmr = 0b00000111;
    icsr; icsr = 0;
    icier = IIC_INTBIT_TX_EMPTY | IIC_INTBIT_RX | IIC_ACKENABLE;
}
    

master

master として動かしたくなったら。