Цитата(rezident @ Dec 2 2010, 06:37)

Подробнее в
спецификации I2C. Раздел
3.16 Bus clear. Функцию Bus clear нужно выполнять после подачи питания до начала обращения мастера к слейвам и/или при большом таймауте занятости шины каким-либо слейвом.
добавил функцию bus clear...без изменений...
Цитата
In the unlikely event where the clock (SCL) is stuck LOW, the preferential procedure is to
reset the bus using the HW reset signal if your I2C devices have HW reset inputs. If the
I2C devices do not have HW reset inputs, cycle power to the devices to activate the
mandatory internal Power-On Reset (POR) circuit.
If the data line (SDA) is stuck LOW, the master should send 9 clock pulses. The device
that held the bus LOW should release it sometime within those 9 clocks. If not, then use
the HW reset or cycle power to clear the bus.
функция bus clear применяется в случаях, если залипает линия SDA в ноль. в моем случае - после резета обе линии в единице.
не с того я начал.
Дано: LPC1114+AT24C01A (больше на I2C ничего не висит). SDA и SCL не перепутаны и обе подтянуты к питанию через 3K3.
Задача: используя аппаратный I2C добиться записи/чтения от AT24
Проблема:
после ресета делаю Bus Clear (обычным дрыганием ног). START CONDITION отправляю по нажатию кнопки (так проще синхронизироваться). после отправки START CONDITION попадаю в прерывание, где анализирую STAT (он равен 8 - тут все хорошо) switch'eм. загружаю SLA+W (0xA0), сбрасываю STA и SIC - вываливаюсь из прерывания и все...в прерывание я больше не попадаю...
Код
//================================================================================
====
void Init_I2C (){
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); //Enables clock for I2C
LPC_SYSCON->PRESETCTRL |= (1<<1); //de-asserts I2C reset
LPC_IOCON->PIO0_4 = 1; //Selects I2C function SCL (open-drain pin)
LPC_IOCON->PIO0_5 = 1; //Selects I2C function SDA (open-drain pin)
LPC_I2C->SCLH = 64000;
LPC_I2C->SCLL = 64000;
LPC_I2C->CONCLR = ((1<<2) | (1<<3) | (1<<5) | (1<<6)); //CON clear;
NVIC_EnableIRQ(I2C_IRQn); //I2C IRQ enable
LPC_I2C->CONSET |= (1<<6); //I2C enable
test_i2c = LPC_I2C->STAT;
I2C_State = CLEAR_BUS;
}
//================================================================================
====
void I2C_IRQHandler (){
uint8_t StatValue = LPC_I2C->STAT;
test_i2c = StatValue;
switch(StatValue){
case 0x08: //START condition has been transmitted
LPC_I2C->DAT = 0xA0; //Load SLA+W
LPC_I2C->CONCLR |= ((1<<3) | (1<<5)); //Clear SIC, STA
break;
case 0x10: //Repeated START condition has been transmitted
LPC_I2C->DAT = 0xA0; //Load SLA+W
LPC_I2C->CONCLR |= ((1<<3) | (1<<5)); //Clear STA
break;
case 0x18: //SLA+W has been transmitted; ACK has been received
LPC_I2C->DAT = 0xFF;
LPC_I2C->CONSET |= (1<<4);
break;
case 0x20: //SLA+W has been transmitted; NOT ACK has been received
LPC_I2C->DAT = 0xFF;
LPC_I2C->CONSET |= (1<<4);
break;
case 0x28: //Data byte in DAT has been transmitted; ACK has been received
break;
case 0x30: //Data byte in DAT has been transmitted; NOT ACK has been received
break;
case 0x38: //Arbitration lost in SLA+R/W or Data bytes
break;
default:
I2C_State = CLEAR_BUS;
LPC_I2C->CONCLR |= (1<<3);
}
SW_1_TOG;
}