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

Таймер и gpio

jcmvbkbc

New member
Ещё не ясно вот это:
WRITE_PERI_REG(PERIPHS_GPIO_BASEADDR + GPIO_OUT_W1TS_ADDRESS, TEST_PIN_IO); // SET_PIN_IO (*((volatile uint32_t *)(0x60000300 + 0x04))) = (uint32_t)(0x00001000)
40100c3a: fcfa21 l32r a2, 40100024
40100c3d: fff831 l32r a3, 40100c20
40100c40: 0020c0 memw
40100c43: 0329 s32i.n a2, a3, 0
WRITE_PERI_REG(PERIPHS_GPIO_BASEADDR + GPIO_OUT_W1TC_ADDRESS, TEST_PIN_IO); //СLR_PIN_IO (*((volatile uint32_t *)(0x60000300 + 0x08))) = (uint32_t)(0x00001000)
40100c45: fff731 l32r a3, 40100c24
40100c48: 0020c0 memw
40100c4b: 0329 s32i.n a2, a3, 0
40100c4d: f00d ret.n


1) Почему не работает оптимизация у транслятора - два раза грузится адрес: 0x60000304 и 0x60000308. Можно было использовать смещение.
Я посмотрю, но не слишком скоро.

2) Время между SET_PIN_IO и СLR_PIN_IO равно 75ns при CLK у CPU 160MHz (осциллограмма дана выше). Не ясно кто дает задержку в 12 тактов CPU.
При 80MHz у CPU имеем строб 100.4ns.
Как минимум memw, ненужный тут совсем. Лучше весь этот кусок переписать на ассемблере, например так:

asm volatile (
"s32i %0, %1, 4\n\t"
"s32i %0, %1, 8"
: : "r"(0x00001000), "r"(0x60000300) : "memory");

Получите 1 такт + задержку внешней шины.
 

pvvx

Активный участник сообщества
Код:
    register uint32 *ioaddr = (uint32 *)(PERIPHS_GPIO_BASEADDR + GPIO_OUT_W1TS_ADDRESS);
    register uint32 iobits = TEST_PIN_IO;
    *ioaddr++ = iobits;
40100c3a:    fcfa21           l32r    a2, 40100024
40100c3d:    fff831           l32r    a3, 40100c20
40100c40:    0329         s32i.n    a2, a3, 0
    *ioaddr = iobits;
40100c42:    fff831           l32r    a3, 40100c24
40100c45:    0329         s32i.n    a2, a3, 0
40100c47:    f00d         ret.n
???
Код:
    volatile register uint32 *ioaddr = (uint32 *)(PERIPHS_GPIO_BASEADDR + GPIO_OUT_W1TS_ADDRESS);
    register uint32 iobits = TEST_PIN_IO;
    *ioaddr++ = iobits;
40100c3a:    fcfa21           l32r    a2, 40100024 <call_user_start+0x20>
40100c3d:    fff831           l32r    a3, 40100c20 <dhcp_timer_coarse+0x2c>
40100c40:    0020c0           memw
40100c43:    0329         s32i.n    a2, a3, 0
    *ioaddr = iobits;
40100c45:    fff731           l32r    a3, 40100c24 <dhcp_timer_coarse+0x30>
40100c48:    0020c0           memw
40100c4b:    0329         s32i.n    a2, a3, 0
40100c4d:    f00d         ret.n
Так вылазит memw
 
Последнее редактирование:

jcmvbkbc

New member
Мне конечно льстит, что вы считаете меня столь проницательным, но лучше было бы, если бы вы явно писали текст своего вопроса.

Так вылазит memw
Ну да, он вставляется перед каждым обращением к volatile памяти.
 
Последнее редактирование:

pvvx

Активный участник сообщества
asm volatile (
"s32i %0, %1, 4\n\t"
"s32i %0, %1, 8"
: : "r"(0x00001000), "r"(0x60000300) : "memory");

Получите 1 такт + задержку внешней шины.
При 160 и 80 MHz CPU I/O строб = 75ns (такая вот шина или что-там в I/O)
Код:
    asm volatile (
40100c36:    fffa31           l32r    a3, 40100c20
40100c39:    fcfa21           l32r    a2, 40100024
40100c3c:    1329         s32i.n    a2, a3, 4
40100c3e:    2329         s32i.n    a2, a3, 8
40100c40:    f00d         ret.n
 
Последнее редактирование:

pvvx

Активный участник сообщества
Мне конечно льстит, что вы считаете меня столь проницательным, но лучше было бы, если бы вы явно писали текст своего вопроса.
Почему оно странслировало загрузку нового значения, а не inc регистра или смещение?
 

jcmvbkbc

New member
Почему оно странслировало загрузку нового значения, а не inc регистра или смещение?
Потому что константы. Надо смотреть, почему он решил, что так дешевле.
Если uint32 *ioaddr передать как параметр функции -- обращается по смещениям.
 

pvvx

Активный участник сообщества
Потому что константы. Надо смотреть, почему он решил, что так дешевле.
Возможно просто не стоит проверка значений...
PS: (Могу ещё написать сотню вопросов по куску, завершенному “???”. Они поставлены для того, чтобы вы могли выбрать вопрос и ответ на свое усмотрение, а не льстить себе :) Интересна любая информация, т.к. на форуме присутствуют люди с разными знаниями и настроениями :) )
 

pvvx

Активный участник сообщества
Код:
    volatile register uint32 *ioaddr = (uint32 *)(PERIPHS_GPIO_BASEADDR + GPIO_OUT_W1TS_ADDRESS);
    register uint32 iobits = TEST_PIN_IO;
    *ioaddr++ = iobits;
40100c51:    0020c0           memw
40100c54:    0429         s32i.n    a2, a4, 0
    *ioaddr-- = iobits;
40100c56:    0020c0           memw
40100c59:    0329         s32i.n    a2, a3, 0
    *ioaddr++ = iobits;
40100c5b:    0020c0           memw
40100c5e:    0429         s32i.n    a2, a4, 0
    *ioaddr-- = iobits;
40100c60:    0020c0           memw
40100c63:    0329         s32i.n    a2, a3, 0
    *ioaddr++ = iobits;
40100c65:    0020c0           memw
40100c68:    0429         s32i.n    a2, a4, 0
    *ioaddr-- = iobits;
40100c6a:    0020c0           memw
40100c6d:    0329         s32i.n    a2, a3, 0
40100c6f:    f00d         ret.n
Данное не проходит без volatile (оно и понятно).
75ns.gif
Похоже, что GPIO напрямую от 26МГц кварца работает :)
Не может. там четок 25ns (в одном случае 75.1ns, во втором 100.4ns, но учитывая, что я для этих замеров не согласовывал вход осла и использовал простой щуп на "соплях")
И используются регистры AND и OR логики, включенной к портам. Что там натворили - тьма.
 
Последнее редактирование:

jcmvbkbc

New member
Могу ещё написать сотню вопросов по куску, завершенному “???”. Они поставлены для того, чтобы вы могли выбрать вопрос и ответ на свое усмотрение.
Если вы будете просто задавать по одному чёткому вопросу за раз -- будет нормально. Если вы сначала зададите более важные вопросы -- будет совсем хорошо.
 

pvvx

Активный участник сообщества
Если вы будете просто задавать по одному чёткому вопросу за раз -- будет нормально. Если вы сначала зададите более важные вопросы -- будет совсем хорошо.
А с данной темой все вопросы уже исчерпаны.
Таймер кое как зарядить можем (выложенного описания бит и примера хватает), биты управления I/O работают и описаны в ESP8266_GPIO_Register_141105.xls
Скорость работы I/O и прерываний при настройках периферии SDK показана.
Варианты как "описать" обращения к I/O в СИ рассмотрены.
Полностью соответствовать I2C на 400кГц программно, используя I/O порты и по аппаратным прерываниям от таймера, данный чип не успевает.
-------
Описания бит таймера, gpio, spi, uart тут http://esp8266.ru/forum/attachments/esp8266_reg-xlsx-zip.167/
 
Последнее редактирование:

sasasa

Member
Сколько тиков самый короткий интервал, который можно установить на хард таймер чтобы не гавкал wdt? Есть какое то отличие какой таймер использоватль 0-ой или 1-ый? timer0_write(value) или timer1_write(value) . Пользуюсь Ардуино иде 1.6.6 + esp2.0.0
 
Сверху Снизу