Koluchiy 0 18 февраля, 2014 Опубликовано 18 февраля, 2014 · Жалоба Здравствуйте, уважаемые гуру. Имеем девайс IIC (датчик температуры), висящий на Kintex 7. Все это подключается к стандартному контроллеру IIC в XPS и Microblaze. И вроде как все оно работает, НО. Если попробовать сделать обмен типа "прочитать температуру": 1. Записать адрес датчика температуры 2. Записать регистр датчика температуры (0 - MSB темперетары) 3. Repeated Start 4. Записать адрес датчика температуры 5. Прочитать температуру 6. Стоп То до п. 4 включительно все нормально, а потом контроллер IIC вылетает с ошибкой "потеря арбитража". При этом, если вместо "Repeated Start" поставить "Stop", а затем "Start", то все нормально работает. Внимание, вопрос: кто-нибудь сталкивался с подобным? Какие могут быть причины, и как бороть? Соединение точка-точка, никаких других мастеров на этой шине нет. Датчик мастером быть не умеет и не пытается. На Чипскопе и осцилле до п. 4 включительно все выглядит как надо. Всем заранее спасибо за помощь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
madgarry 0 18 февраля, 2014 Опубликовано 18 февраля, 2014 · Жалоба Попробуйте поменять антиглитчевые задержки. Когда-то и где-то видел задержку SDA относительно SCL но в приложенной картинке этой задержки нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Koluchiy 0 18 февраля, 2014 Опубликовано 18 февраля, 2014 · Жалоба Пробовал, не помогает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexadmin 0 19 февраля, 2014 Опубликовано 19 февраля, 2014 · Жалоба Я долго бился со стандартным API, но оно меня в итоге победило (точно так же зависало в процессе). В конце концов я написал вручную две функции доступа, немного пошаманил, помухлевал и в итоге работает, хотя тут тоже есть нюансы. // Simple user-created API to IIC controller // http://forums.xilinx.com/t5/Embedded-Processor-System-Design/Why-the-IIC-can-t-be-stopped/td-p/295693 u32 iic_write(u32 baseaddr, u32 daddr, u32 waddr, u32 wdata) { int stat2; u32 timeout; int stat = (Xil_In32(baseaddr + 0x104)); if(stat != 0xc0) { // print("Bad stat."); Xil_Out32((baseaddr + 0x100), 0xc0|0x02); // reset tx fifo // Xil_Out32((baseaddr + 0x100), 0xc0|0x03); // enable iic } Xil_Out32((baseaddr + 0x100), 0xc0|0x00); // disable iic Xil_Out32((baseaddr + 0x100), 0xc0|0x01); // enable iic Xil_Out32((baseaddr + 0x100), 0xc0|0x0d); // Start; Transmit Xil_Out32((baseaddr + 0x108), (0x100 | (daddr & 0xFE))); // send slave address for write Xil_Out32((baseaddr + 0x108), waddr); // send register address Xil_Out32((baseaddr + 0x108), (0x200 | (wdata & 0xFF))); // send data byte with stop bit timeout = 100; // timeout while(1) // ToDo: add timeout to avoid hang up when I2C slave is not responding (no ACK) { stat2 = Xil_In32(baseaddr + 0x104); // wait for TX FIFO empty if( ((stat2 & 0x80) ) && ((stat2 & 0x04)== 0) ) // TX FIFO empty && Bus not busy break; if (timeout == 0) { xil_printf("iic write timed out %x %x\n\r", waddr, wdata); return 0xFFFFFFFF; // data not valid } timeout--; usleep(200); } return 0; } u32 iic_read(u32 baseaddr, u32 daddr, u32 raddr) { int stat2; u32 rdata, timeout; int stat = (Xil_In32(baseaddr + 0x104)); if(stat != 0xc0) { // print("Bad stat."); Xil_Out32((baseaddr + 0x100), 0x002); // reset tx fifo Xil_Out32((baseaddr + 0x100), 0x003); // enable iic } Xil_Out32((baseaddr + 0x100), 0x000); // disable iic Xil_Out32((baseaddr + 0x100), 0x001); // enable iic Xil_Out32((baseaddr + 0x108), (0x100 | (daddr & 0xFE))); // send slave address for write Xil_Out32((baseaddr + 0x108), raddr); // send register address Xil_Out32((baseaddr + 0x108), (0x101 | (daddr & 0xFE))); // send slave address for read Xil_Out32((baseaddr + 0x108), 0x201); // set stop after 1 data byte timeout = 100; // timeout while(1) { stat2 = Xil_In32(baseaddr + 0x104); if ((((stat2 & 0x40) == 0x0)) || (timeout == 0)) // (RX FIFO not empty && Bus not busy) or timeout // && ((stat2 & 0x04)== 0) break; //(((Xil_In32(IIC_BASEADDR + 0x104) & 0x40) == 0x40) && (timeout != 0)) { // wait for read FIFO not empty timeout--; delay_ms(1); } rdata = Xil_In32(baseaddr + 0x10C) & 0xFF; // read data byte delay_ms(1); if (timeout == 0) { xil_printf("iic read timed out %x %x\n\r", raddr, rdata); return 0xFFFFFFFF; // data not valid } return (rdata); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Koluchiy 0 19 февраля, 2014 Опубликовано 19 февраля, 2014 · Жалоба Если читать Ваши комментарии так, как они написаны, то после записи адреса регистра Вы делаете стоп. Мне надо добиться, чтобы работал Repeated start, т.е. без стопа между записью номера регистра и чтением данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexadmin 0 19 февраля, 2014 Опубликовано 19 февраля, 2014 · Жалоба Если читать Ваши комментарии так, как они написаны, то после записи адреса регистра Вы делаете стоп. Мне надо добиться, чтобы работал Repeated start, т.е. без стопа между записью номера регистра и чтением данных. Где? Xil_Out32((baseaddr + 0x108), (0x100 | (daddr & 0xFE))); // send slave address for write Xil_Out32((baseaddr + 0x108), raddr); // send register address Вот тут идет рестарт с отправкой физического адреса устройства Xil_Out32((baseaddr + 0x108), (0x101 | (daddr & 0xFE))); // send slave address for read А теперь идет чтение (в данном случае одного байта) и после этого стоп Xil_Out32((baseaddr + 0x108), 0x201); // set stop after 1 data byte Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Koluchiy 0 19 февраля, 2014 Опубликовано 19 февраля, 2014 · Жалоба Извиняюсь, был неправ. Да, вроде работает :). Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Koluchiy 0 27 февраля, 2014 Опубликовано 27 февраля, 2014 · Жалоба Ах да, в итоге прицепил контроллер с Opencores (тот самый, который Altera рекомендует). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Koluchiy 0 7 марта, 2014 Опубликовано 7 марта, 2014 · Жалоба ...И тут выяснилось, что этот контроллер только мастер... Граждане, понасоветуйте культурный I2C slave контроллер (с исходниками желательно на Verilog), чтобы к процессору хорошо цеплялся и библиотеки на Си чтоб были :). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться