• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Как конфигурировать GPIO для I2C?

Aviator

New member
Хочу перезадать пины i2c в библиотеке i2c_master, чтобы было как в библиотеке Wire Ардуино (GPIO 4 и 5 ). Модуль у меня 12E Witty Cloud. Изменил в i2_master.h , как показано ниже, но не работает. Где и что ещё нужно исправить?

Код:
/*
#define I2C_MASTER_SDA_MUX PERIPHS_IO_MUX_GPIO2_U
#define I2C_MASTER_SCL_MUX PERIPHS_IO_MUX_MTMS_U
#define I2C_MASTER_SDA_GPIO 2
#define I2C_MASTER_SCL_GPIO 14
#define I2C_MASTER_SDA_FUNC FUNC_GPIO2
#define I2C_MASTER_SCL_FUNC FUNC_GPIO14
*/

#define I2C_MASTER_SDA_MUX PERIPHS_IO_MUX_GPIO4_U
#define I2C_MASTER_SCL_MUX PERIPHS_IO_MUX_GPIO5_U
#define I2C_MASTER_SDA_GPIO 4
#define I2C_MASTER_SCL_GPIO 5
#define I2C_MASTER_SDA_FUNC FUNC_GPIO4
#define I2C_MASTER_SCL_FUNC FUNC_GPIO5
Хотя бы подскажите, как вместо GPIO2 задать GPIO15 в примере blinky?
 

vad7

Active member
vad7, а как правилбьно подключить вашу библиотеку?
скопировал i2c.c i2c.h в папку user, в user_main написал #include "i2c.h", в void ICACHE_FLASH_ATTR user_init(void) пишу i2c_init(100);
и при all выдаёт
implicit declaration of function 'i2c_init'
разобрался с этим. теперь выдаются ошибки
Код:
user/i2c.c:40:33: error: implicit declaration of function 'ets_get_cpu_frequency' [-Werror=implicit-function-declaration]
   i2c_delay_time = 35750 / 80 * ets_get_cpu_frequency() / freq; // 89=400Khz, 250=143Khz, 357=100Khz, 500=75Khz
                                 ^
user/i2c.c:42:2: error: implicit declaration of function 'ets_intr_lock' [-Werror=implicit-function-declaration]
  ets_intr_lock();
  ^
user/i2c.c:43:2: error: implicit declaration of function 'GPIOx_PIN' [-Werror=implicit-function-declaration]
  GPIOx_PIN(I2C_SDA_PIN) = GPIO_PIN_DRIVER; // Open-drain
  ^
user/i2c.c:43:27: error: 'GPIO_PIN_DRIVER' undeclared (first use in this function)
  GPIOx_PIN(I2C_SDA_PIN) = GPIO_PIN_DRIVER; // Open-drain
                           ^
user/i2c.c:43:27: note: each undeclared identifier is reported only once for each function it appears in
user/i2c.c:45:2: error: implicit declaration of function 'SET_PIN_FUNC' [-Werror=implicit-function-declaration]
  SET_PIN_FUNC(I2C_SDA_PIN, (MUX_FUN_IO_PORT(I2C_SDA_PIN) | (1 << GPIO_MUX_PULLUP_BIT))); // Pullup
  ^
user/i2c.c:45:29: error: implicit declaration of function 'MUX_FUN_IO_PORT' [-Werror=implicit-function-declaration]
  SET_PIN_FUNC(I2C_SDA_PIN, (MUX_FUN_IO_PORT(I2C_SDA_PIN) | (1 << GPIO_MUX_PULLUP_BIT))); // Pullup
                             ^
user/i2c.c:45:66: error: 'GPIO_MUX_PULLUP_BIT' undeclared (first use in this function)
  SET_PIN_FUNC(I2C_SDA_PIN, (MUX_FUN_IO_PORT(I2C_SDA_PIN) | (1 << GPIO_MUX_PULLUP_BIT))); // Pullup
                                                                  ^
user/i2c.c:47:2: error: 'GPIO_OUT_W1TS' undeclared (first use in this function)
  GPIO_OUT_W1TS = (1<<I2C_SDA_PIN) | (1<<I2C_SCL_PIN); // Set HI (WO)
  ^
user/i2c.c:48:2: error: 'GPIO_ENABLE_W1TS' undeclared (first use in this function)
  GPIO_ENABLE_W1TS = (1<<I2C_SDA_PIN) | (1<<I2C_SCL_PIN); // Enable output (WO)
  ^
user/i2c.c:49:2: error: implicit declaration of function 'ets_intr_unlock' [-Werror=implicit-function-declaration]
  ets_intr_unlock();
  ^
user/i2c.c:50:6: error: "DEBUGSOO" is not defined [-Werror=undef]
  #if DEBUGSOO > 2
      ^
user/i2c.c: In function 'i2c_Stop':
user/i2c.c:24:23: error: 'GPIO_OUT_W1TC' undeclared (first use in this function)
#define SET_SDA_LOW   GPIO_OUT_W1TC = (1<<I2C_SDA_PIN)
                       ^
user/i2c.c:62:2: note: in expansion of macro 'SET_SDA_LOW'
  SET_SDA_LOW;
  ^
user/i2c.c:28:22: error: 'GPIO_OUT_W1TS' undeclared (first use in this function)
#define SET_SCL_HI   GPIO_OUT_W1TS = (1<<I2C_SCL_PIN)
                      ^
user/i2c.c:65:2: note: in expansion of macro 'SET_SCL_HI'
  SET_SCL_HI; // release
  ^
user/i2c.c: In function 'i2c_WriteBit':
user/i2c.c:25:22: error: 'GPIO_OUT_W1TS' undeclared (first use in this function)
#define SET_SDA_HI   GPIO_OUT_W1TS = (1<<I2C_SDA_PIN)
                      ^
user/i2c.c:76:3: note: in expansion of macro 'SET_SDA_HI'
   SET_SDA_HI;
   ^
user/i2c.c:24:23: error: 'GPIO_OUT_W1TC' undeclared (first use in this function)
#define SET_SDA_LOW   GPIO_OUT_W1TC = (1<<I2C_SDA_PIN)
                       ^
user/i2c.c:78:3: note: in expansion of macro 'SET_SDA_LOW'
   SET_SDA_LOW;
   ^
user/i2c.c:26:21: error: 'GPIO_IN' undeclared (first use in this function)
#define GET_SDA    (GPIO_IN & (1<<I2C_SDA_PIN))
                     ^
user/i2c.c:83:14: note: in expansion of macro 'GET_SDA'
   if(bit && (GET_SDA) == 0) return 1; // other master active
              ^
user/i2c.c: In function 'i2c_ReadBit':
user/i2c.c:25:22: error: 'GPIO_OUT_W1TS' undeclared (first use in this function)
#define SET_SDA_HI   GPIO_OUT_W1TS = (1<<I2C_SDA_PIN)
                      ^
user/i2c.c:91:2: note: in expansion of macro 'SET_SDA_HI'
  SET_SDA_HI;
  ^
user/i2c.c:26:21: error: 'GPIO_IN' undeclared (first use in this function)
#define GET_SDA    (GPIO_IN & (1<<I2C_SDA_PIN))
                     ^
user/i2c.c:95:17: note: in expansion of macro 'GET_SDA'
  uint8_t bit = (GET_SDA) != 0;
                 ^
user/i2c.c:27:23: error: 'GPIO_OUT_W1TC' undeclared (first use in this function)
#define SET_SCL_LOW   GPIO_OUT_W1TC = (1<<I2C_SCL_PIN)
                       ^
user/i2c.c:96:2: note: in expansion of macro 'SET_SCL_LOW'
  SET_SCL_LOW;
  ^
user/i2c.c: In function 'i2c_Start':
user/i2c.c:25:22: error: 'GPIO_OUT_W1TS' undeclared (first use in this function)
#define SET_SDA_HI   GPIO_OUT_W1TS = (1<<I2C_SDA_PIN)
                      ^
user/i2c.c:135:3: note: in expansion of macro 'SET_SDA_HI'
   SET_SDA_HI;
   ^
user/i2c.c:26:21: error: 'GPIO_IN' undeclared (first use in this function)
#define GET_SDA    (GPIO_IN & (1<<I2C_SDA_PIN))
                     ^
user/i2c.c:139:7: note: in expansion of macro 'GET_SDA'
   if((GET_SDA) == 0) {
       ^
user/i2c.c:24:23: error: 'GPIO_OUT_W1TC' undeclared (first use in this function)
#define SET_SDA_LOW   GPIO_OUT_W1TC = (1<<I2C_SDA_PIN)
                       ^
user/i2c.c:142:3: note: in expansion of macro 'SET_SDA_LOW'
   SET_SDA_LOW;
   ^
я понимаю что не ватает подкючения какогото хидера, можешь подсказать какого?
 
Последнее редактирование:

vad7

Active member
Это все на вебсвалке работает, нужно либо использовать ее, либо все описания и дописанные функции перенести.
 
Это все на вебсвалке работает, нужно либо использовать ее, либо все описания и дописанные функции перенести.
А можно поподробнее, какие файлы и функции перенести?
Эту либу беру потомучто можно для i2c любые выводы использовать.
Компилятор упираелся в определения gpio. Перенёс хидеры со свалки в проект, теперь uint32 в каждой функции не принимает.
 

vad7

Active member
Ставите рядом исходный проект, ищете в нем символ на который в вашем проекте ругается компилятор, жмете на нем ctrl+кн.мыши и видите модуль, в котором он описан.
и т.д.
 

Сергей_Ф

Moderator
Команда форума
@vad7 мне кажется, Вы все слишком усложняете. Я запускал i2c на разных пинах под Ардуино ИДЕ без проблем и даже без правок хидера. Сейчас нет под рукой компьютера (до понедельника), посмотреть не могу. Но точно на ESP-Easy запускал на tx, rx.
 
Ставите рядом исходный проект, ищете в нем символ на который в вашем проекте ругается компилятор, жмете на нем ctrl+кн.мыши и видите модуль, в котором он описан.
и т.д.
отличный метод, спасибо!

теперь вся понятно: в качестве донора я использовал проект esphttpd. у него файл esp8266.h почти пустой (вложение) и второй с кучей нужных определений.
простым копированием содержимого совместить не получается....
буду думать. кто какие советы может дать?
upd: товарищ vad7, а можете объяснить почему всё завязано на папочку bios и файл bios.h и чем тие файлы сильно отличаются от тех что есть в SDK и UDK?
 

Вложения

Последнее редактирование:

vad7

Active member
@Сергей_Ф, если вы про i2c драйвер из примеров UDK, то он мне не нравится - не оптимально написано, нет контроля ошибок, нет возможности выбора скорости на лету.
 
vad7, разобрался я со свалкой теперь за библиоекту I2C взялся.
поправьте если что-то где то ошибаюсь(а я ошибаюсь ибо не работает):
подключил к PCF8583 (адрес 0xA0), подтягивающие резисторы 10кОм.
определил выводы:
Код:
#define I2C_SDA_PIN 12 // SDA on GPIO12
#define I2C_SCL_PIN 13 // SCL on GPIO13
инициализацию i2c_init(0); делаю в процедуре void ICACHE_FLASH_ATTR user_init(void);
затем просто ради проверки делаю так(в той же инициализации но после поднятия и2ц):
Код:
void ICACHE_FLASH_ATTR SaClockUartTx (void)
{
    uint8_t ClockBuffer[3] = {5,6,7};
    uart0_tx(0x00);
    uart0_tx(i2c_eeprom_read_block( 0xA0, 0x02, ClockBuffer, 3)); // адрес, начальная ячейка памяти откуда читаем, куда складываем, сколько байт читаем.//
    uart0_tx(0x00);
    uart0_tx(ClockBuffer[0]);
    uart0_tx(ClockBuffer[1]);
    uart0_tx(ClockBuffer[2]);
}
вывод в терминал: 0,3,0,5,6,7 а должно быть по идее 0,0,0,SS,MM,HH

то есть функция не отработала. в чём может быть косяк?
 
Последнее редактирование:

vad7

Active member
SDA читается как 0, а должен как 1 при старте.
i2c_init можно попробовать сразу перед вашей функцией.
esp на 80Мгц?
 
SDA читается как 0, а должен как 1 при старте.
i2c_init можно попробовать сразу перед вашей функцией.
esp на 80Мгц?
про SDA я так и понял. не понял отчего только именно так, вроде 10kOm резисторы стоят (плата отладочная).
i2c_init сунул в общую кучу инициализаций аппаратных, следом идут пользовательские. для удобства чтения кода.
нет - 160
#define USE_CPU_SPEED 160 // установить частоту CPU по умолчанию 80 или 160 MHz

нарисую 80, попробую, посмотрю что получится
 

vad7

Active member
если логического анализатора нет, то проверяется просто оставить только i2c_init(100) и померять вольтметром на SDA, если не 3V, то смотреть дальше железо или в коде где-то изменились настройки портов.
 
если логического анализатора нет, то проверяется просто оставить только i2c_init(100) и померять вольтметром на SDA, если не 3V, то смотреть дальше железо или в коде где-то изменились настройки портов.
всё сработало! спасибо!
теперь осталось только понять почему вместо простого чтения времени (шести байт) происходит сброс первого байта в очереди?
читаю вот так(не судить это всего лишь отладка):
Код:
void ICACHE_FLASH_ATTR SaClockUartTx (void)
{
    uint8_t ClockBuffer[6] = {6,5,4,3,2,1};
    uart0_tx(0x00);
    uart0_tx(i2c_eeprom_read_block( 0x68, 0x00, ClockBuffer, 6));
    uart0_tx(0x00);
    uart0_tx(ClockBuffer[0]);
    uart0_tx(ClockBuffer[1]);
    uart0_tx(ClockBuffer[2]);
    uart0_tx(ClockBuffer[3]);
    uart0_tx(ClockBuffer[4]);
    uart0_tx(ClockBuffer[5]);

}
и при этом постоянно обнуляется байт секунд. или байт времени если сделать [inline]uart0_tx(i2c_eeprom_read_block( 0x68, 0x01, ClockBuffer, 6));[/inline]
 

vad7

Active member
Для PCF8583 эти функции (i2c_eeprom_*_block) не подходят.
Они для eeprom с 2-х байтной адресацией.
 

vad7

Active member
Sam_Arcanum, так функция то отсылает двух-байтный адрес, а вышеуказанные чипы ждут один.
Плюс протокол отличается от доступа к eeprom.
 
Сверху Снизу