R8C/1BでI2C
1B じゃなくてもいいかも。
なにこれは
やるたびに状態遷移がよくわからなくて困るので、やり方をメモする。
... なぜディスコンになったマイコンをこれからも使い倒すつもりなんだ?
slave
- ERROR はなんとなく書いたけど、行かないと思う
- この init() だと 16 が デバイスID
- icierのビット2 (ACKE) を立てておかないとろくでもないことになりがち
- エラー (NACK とか) の処理がこれで十分かはよくわからん
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 として動かしたくなったら。