1. Плата TE-STM32F407 с соответствующим МК (STM32F407VET6)
2. Плата LCD дисплея DM-LCD35RT с дисплеем на контроллере SSD2119 и контроллером тачскрина STMPE811.
С LCD проблем нет. Перепаял резисторы R1 - R8 на плате согласно даташиту, чтобы переключить с параллельного интерфейса LCD на SPI.
LCD запустился с полпинка и все работает, а вот с контроллером тача затык.
В виду того, что разработчики платы неизвестно чем думали, когда проектировали ее, все аппаратные интерфейсы I2C оказались недоступными даже с ремапом.
По этому пришлось поднимать софтовый интерфейс. Вроде как проблем нет. По внешнему прерыванию можно прочитать координаты прикосновения, благо чип это позволяет, что и было реализовано.
К МК подключены три вывода: Это SDI, SDA и ITR - линия прерывания. Ноги I2C настроены как выход с открытым коллектором и подтяжкой на плюс. (да-да, такое возможно, только их оказалось мало и пришлось добавлять внешнюю подтяжку, а иначе фронты сильно заваливаются.) ITR настроена как плавающий вход с прерыванием (подтяжка уже есть на плате).
Теперь собственно сама проблема:
Формирую стартовое условие i2c.
Отправляю адрес ведомого. По даташиту это 0x82, если нога A0 контроллера тача притянута к земле.
Получаю ACK = 0 от ведомого. То есть контроллер проглотил байт и все ОК.
Отправляю адрес регистра 0x02. В нем хранится ревизия чипа.
Получаю ACK = 0 от ведомого. То есть контроллер проглотил байт и все ОК.
Отправляю снова адрес чипа, но уже 0x83. Младший бит, это бит R\W (чтение - запись)
Получаю ACK = 0 от ведомого. То есть контроллер проглотил байт и все ОК.
Далее, выставляю лог.1 на линии SDA и генерирую импульсы на SCL.
Чип нихрена не присылает в ответ. То есть принятый байт 0xFF, а должно быть 0x03.
И самое главное, на последнем этапе он еще и умудряется прижать девятый бит, типа отправил ACK, в то время, как он его должен был читать (Я отправляю ему в конце NACK)
Формирую стоповое условие.
Вывод: Возникает ощущение, что он не понимает бит R\W или где-то я затупил и в упор не вижу проблемы.
По осциллографу вроде все нормально.
Ниже прилагаю временный код реализации i2c
Спойлер
Код: Выделить всё
/////////////////////////////////////////////////////////////////////////////////
void ic_delay(uint16_t dl)
{
for(uint32_t i = 0; i < (10 * dl); i++){asm("nop");}
//asm("nop");
}
/////////////////////////////////////////////////////////////////////////////////
uint8_t i2c_send(uint_fast8_t data, uint8_t ack)
{
uint8_t ack_fl = 1;
for(int8_t i = 7; i >= 0; i--)
{
RST_SCL;
ic_delay(5);
if ( (data & (1<<i)) == 0){RST_SDA;}
else{SET_SDA;}
ic_delay(5);
SET_SCL;
ic_delay(10);
}
RST_SCL;
ic_delay(5);
if (ack == 0){RST_SDA;}
else{SET_SDA;}
ic_delay(5);
SET_SCL;
ic_delay(5);
if((GPIOD->IDR & TS_SDA)==0)
{
ack_fl = 0;
}
ic_delay(5);
return ack_fl;
}
/////////////////////////////////////////////////////////////////////////////////
void i2c_start(void)
{
SET_SDA;
SET_SCL;
ic_delay(10);
RST_SDA;
ic_delay(10);
}
/////////////////////////////////////////////////////////////////////////////////
void i2c_stop(void)
{
RST_SCL;
ic_delay(10);
SET_SCL;
ic_delay(10);
SET_SDA;
ic_delay(120);
}
/////////////////////////////////////////////////////////////////////////////////
uint_fast8_t i2c_read(uint8_t ack)
{
uint_fast8_t data = 0xFF;
ic_delay(5);
RST_SCL;
ic_delay(5);
SET_SDA;
ic_delay(5);
for(int8_t i = 7; i >= 0; i--)
{
SET_SCL;
ic_delay(5);
if((GPIOD->IDR & TS_SDA)==0)
{
data &= (~(1<<i));
}
else
{
data |= (1<<i);
}
ic_delay(5);
RST_SCL;
ic_delay(10);
}
if (ack == 0){RST_SDA;}
else{SET_SDA;}
ic_delay(5);
SET_SCL;
ic_delay(10);
return data;
}
Спойлер
Код: Выделить всё
i2c_start();
i2c_send(0x82, 1);
i2c_send(0x02, 1);
i2c_send(0x83, 1);
i2c_read(0);
i2c_stop();
Стартовое и стоповое условия в уменьшенном виде:
Стартовое условие в увеличенном виде:
Стоповое условие в увеличенном виде:
Старший бит адреса (первый байт посылки):
Последний бит первого байта посылки. То есть R\W бит (выделен зеленным) R\W = 0
и девятый бит ACK от чипа (выделен красным):
Бит ACK от чипа (второй байт) Выделено красным:
Последний бит третьего байта (выделен зеленным) R\W=1
и бит ACK от чипа (выделен красным):
Собственно последний байт. Тут должно быть 0x03 от чипа,
но тут 0xFF (выделено зеленным), да еще и ублюдок прижал девятый бит (Выделено красным)
Ну и стоповое условие выделено синим:
Второй день бьюсяголовойобстену и не могу понять, в чем косяк.

