STMPE811 + софтовый I2C

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

Дано:
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 (выделено зеленным), да еще и ублюдок прижал девятый бит (Выделено красным)
Ну и стоповое условие выделено синим:
Изображение


Второй день бьюсяголовойобстену и не могу понять, в чем косяк.
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

Короче, еле разобрался. Оказывается ляпы в даташите.

Изображение


И такой хрени там полно.
И даже с разрядностью регистров намудрили.
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

Понимаю Ваше негодование. К документации ST надо привыкать. Подобное было при разборе аппаратного i2c в STM8L. В итоге после более тщательного разбора даташита (надо его читать, а не отдельные картинкии рассматривать), оказалось что я сам дурак и все там работает правильно.
Не очень верится, что первая датаграмма не работает. (Вы заметили, что там сначала R/W=0, а потом R/W=1?)
А по поводу последней датаграммы можно сказать, что это просто копи-паст. Если посмотреть на название рисунка, то становится понятно, что в нем должно присутствовать и чтение и запись двух видов. Можно догадаться, что последняя датаграмма для записи, поскольку в датаграммах чтения R/W=1, а в последних двух R/W=0.
Ставим плюсы: )
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

На осциллограммах отрабатывается именно первая датаграмма. Там я отдельно выделил этот бит (R\W).
Третья работает, да и видно, что это просто кусок четвертой датаграммы.

То есть, у меня работают только три датаграммы. Первая так и не заработала. Ну и фиг бы на нее забить.

Остальное тоже читал. В основном там описываются регистры и работа модулей.
Про связь там очень мало. Это все было перечитано несколько раз. Даже ревизия даташита была проверена.

В итоге контроллер я завел. Сделал грубую настройку и прочитал координаты.
Далее, настрою его более тонко внимательно изучив даташит на тему его возможностей.
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Ответить

Вернуться в «Периферия»