не могу понять логику i2c вот такой платки...

Тема в разделе "Arduino & Shields", создана пользователем djdance, 5 ноя 2012.

  1. djdance

    djdance Нерд

    есть вот такая платка и к ней единственный типа "даташит" , а также пример на бейсике.
    Припаял ноги, подтянул A4 & A5 к питанию 1.5кОм, ардуина видит i2c-адрес 96, устройство даже включается по команде, но дальше никак.

    Поясню. Судя по скупой инструкции и примерам на вражеском языке, в шину надо кидать либо номер регистра и слово, либо 5 регистров подряд по слову на каждое.
    Слова состоят из 2 байт. (об этом тут в файле RDA5807SS_Driver2.spin).

    Вопрос 1.
    Сколько бы я ни делал Wire.write(n), функция возвращает 1, то есть передан 1 байт. Даже если операнд n типа word. Так и должно разве быть?
    Кидаю последовательно write(n >> 8) и write (n), но тогда устройство не слушается.

    Вопрос 2.
    Я кидаю все 2*5 байт между единственной парой begin и endTransmition. Устройство более-менее реагирует.
    Но, судя по бейсику, они кидают каждый байт отдельно, через акноледж. АСК у нас приходит только по endTransmition. Но если обрамлять трансмишнами каждый write, устройство не слушается. Где правда? :)
     
  2. djdance

    djdance Нерд

    приведу куски кода на бейсике с некоторыми пояснениями

    Код (Text):

    //например процедура Mute on:
     
    ConfigRegs(0)=ConfigRegs(0)& %1011111111111111 // [I]байт 14 отвечает за мьют[/I]
    GOSUB Write_ConfigRegs
     
    ///////////////
    Write_ConfigRegs:                              ' Write Data to Configure Registers
      GOSUB DeviceStart                            ' Start
      Temp=%00100000                              ' Device Address - [I]у меня такой не откликается, кстати[/I]
      GOSUB SendOut                                ' Send out the Device Address information
     
      FOR index= 0 TO 4                            ' Write 10 bytes of Configure data
        WData = ConfigRegs(index)>>8
        GOSUB Write_Data
        WData = ConfigRegs(index)
        GOSUB Write_Data
      NEXT
     
      GOSUB DeviceStop                            ' Release I2C Bus
    ////////////////////////
    DeviceStart:                                  ' I2C Start
      INPUT SDA                                    ' While the SCL is high, the SDA will
      INPUT SCL                                    ' change from HIGH TO LOW
    // ... [I]тут они поднимают уровни по стандарту i2c , СТОП оформлен так же[/I]
    ///////////////////////////
    SendOut:                                      ' Send out a byte and get the acknowledge
        SHIFTOUT SDA,SCL,MSBFIRST,[Temp\8]
        SHIFTIN SDA,SCL,MSBPRE,[I2CAck\1]
    ////////////////////////////
    Write_Data:
      Temp=WData
      GOSUB SendOut
     
  3. nailxx

    nailxx Официальный Нерд Администратор

    Вопрос 1.

    Если вы передаёте единственное значение по Wire, оно будет приведено к одному `byte` каким бы ни был первоначальный тип: функция Wire.write принимает byte и всё тут. Если хотите передать, скажем 2 байта, переменной `int myValue`, используйте передачу через указатель и длину:

    Wire.write(&myValue, 2);

    Имейте в виду, однако, что данные пойдут в порядке Little Endian. То есть сначала уйдёт младший байт, а потом старший. Если хотите наоборот, используйте передачу байт за байтом в ручную:

    Wire.write((myValue >> 8) & 0xFF);
    Wire.write(myValue & 0xFF);

    Вопрос 2.

    Если одним скопом всё работает, зачем пытаться сделать запись побайтно?! Это ведь будет медленнее, кривее и т.п. Только потому что сами parallax так сделали?
     
  4. djdance

    djdance Нерд

    1. А зачем & 0xFF ?

    2. Я пока тыком пробую, потому что устрйоство "работает" абы как: включается, но на прочие команды не реагирует. В частности, в даташите указаны номера регистров 0x02..0x0B. Но как передать средствами Wire два байта в конкретный регистр? Мне бы пример. Скажем, слово 0010000000000001 в регистр 0x02

    Сейчас пробую вот такую библу.
     
  5. nailxx

    nailxx Официальный Нерд Администратор

    0xFF — отсекает всё кроме младшего байта. Если myValue — число со знаком, в старшем байте после сдвига будут единицы.

    Просто вот так, двумя write'ами вы можете передать два байта.
     
  6. djdance

    djdance Нерд

    но как передать их в определенный регистр?
     
  7. djdance

    djdance Нерд

    ох. В общем, вопрос "как в I2C передать 2 байта в определенный регистр?" - остается, напишите!

    а в целом устройство победил
    оказывается, не надо ему слать слова в регистры, а надо тупо слать подряд 5 байт (или читать 5 байт). Байты расшифровываются по табличкам (вот тут, в конце файла, там же пример). Да, купленная мной параллаксова шилда на RDA5807SS - плохо документированный клон TEA5767. Если кому интересно :)
     
  8. nailxx

    nailxx Официальный Нерд Администратор

    AFAIK, протокол I²C не включает в себя понятия регистра на конкретном устройстве. Есть только адреса устройств. Регистры данных — это просто удобная идиома и поэтому о том как нужно передавать данные в конкретный регистр следует смотреть в документации на устройства.

    Для большинства: сначала шлём байт-имя регистра, а затем байт за байтом данные: столько, сколько положено по протоколу для конкретного устройства.