• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Таймеры RTL8711

Seeker

New member
Согласно имеющейся здесь документации, минимальный интервал времени таймера 32 микросекунды? Что есть 31.25 кГц, а это мало. Поправьте если не так.
 

Вложения

pvvx

Активный участник сообщества
Согласно имеющейся здесь документации, минимальный интервал времени таймера 32 микросекунды? Что есть 31.25 кГц, а это мало. Поправьте если не так.
У GTimer 32,768 кГц (30.5 us) (hal_timer.h):
[HASHTAG]#define[/HASHTAG] GTIMER_CLK_HZ (32768)
[HASHTAG]#define[/HASHTAG] GTIMER_TICK_US (1000000/GTIMER_CLK_HZ)
 

Seeker

New member
Спасибо за более полный ответ. К сожалению 32кГц это всё же детский сад для создания ик NEC сигналов. Необходимо было ровно 76кГц.
 

pvvx

Активный участник сообщества
Спасибо за более полный ответ. К сожалению 32кГц это всё же детский сад для создания ик NEC сигналов. Необходимо было ровно 76кГц.
Есть ещё _LONG_CALL_ u32 HalDelayUs(u32 us) в ROM.
Но модуля пока нет и не разбирался к кому он привязан...
 

pvvx

Активный участник сообщества
@Seeker - HalDelayUs() тоже обращается к gtimer :( :
Код:
00000898 <HalDelayUs>:
     898:    f241 0385     movw    r3, #4229    ; 0x1085
     89c:    b570         push    {r4, r5, r6, lr}
     89e:    f240 3518     movw    r5, #792    ; 0x318
     8a2:    f6c0 0342     movt    r3, #2114    ; 0x842
     8a6:    f2c1 0500     movt    r5, #4096    ; 0x1000 -> 0x10000318 -> структура HalTimerOp
     8aa:    fba3 2300     umull    r2, r3, r3, r0
     8ae:    1ac6         subs    r6, r0, r3
     8b0:    eb03 0656     add.w    r6, r3, r6, lsr #1
     8b4:    0936         lsrs    r6, r6, #4
     8b6:    f04f 0001     mov.w    r0, #1
     8ba:    68ab         ldr    r3, [r5, #8]; HalTimerOp->HalTimerReadCount
     8bc:    bf08         it    eq
     8be:    4606         moveq    r6, r0
     8c0:    4798         blx    r3
     8c2:    4604         mov    r4, r0
     8c4:    68ab         ldr    r3, [r5, #8]; HalTimerOp->HalTimerReadCount 
     8c6:    2001         movs    r0, #1
     8c8:    4798         blx    r3;  gtimer_read_tick(1)
     8ca:    4284         cmp    r4, r0
     8cc:    eba4 0300     sub.w    r3, r4, r0
     8d0:    bf34         ite    cc
     8d2:    f103 30ff     addcc.w    r0, r3, #4294967295
     8d6:    1a20         subcs    r0, r4, r0
     8d8:    42b0         cmp    r0, r6
     8da:    d9f3         bls.n    8c4 <HalDelayUs+0x2c>
     8dc:    2000         movs    r0, #0
     8de:    bd70         pop    {r4, r5, r6, pc}
[code][/SPOILER]
 

Olegator

New member
Выглядит как грусть печаль, из PWM больше 16Khz не выжать.
Код:
#define MAX_PWM_CTRL_PIN        4
// the minimum tick time for G-timer is 61 us (clock source = 32768Hz, reload value=1 and reload takes extra 1T)
//#define GTIMER_TICK_US            31   // micro-second, 1000000/32768 ~= 30.5
#define MIN_GTIMER_TIMEOUT    61  // in micro-sec, use this value to set the g-timer to generate tick for PWM. 61=(1000000/32768)*2
#define PWM_GTIMER_TICK_TIME    61  // in micro-sec, use this value to set the g-timer to generate tick for PWM. 61=(1000000/32768)*2
Как вариант - юзай UART, они в HAL кажется обмазали драйвер UART возможностью передавать IR коды, вот кусок hal_uart.c

Код:
// Pre-Defined Supported Baud Rate Table for CPU 166 MHz
const u32 DEF_BAUDRATE_TABLE[] = {
        110,     300,     600,    1200,
       2400,    4800,    9600,   14400,
      19200,   28800,   38400,   57600,
      76800,  115200,  128000,  153600,
     230400,  380400,  460800,  500000,
     921600, 1000000, 1382400, 1444400,
    1500000, 1843200, 2000000, 2100000,
    2764800, 3000000, 3250000, 3692300,
    3750000, 4000000, 6000000,

      56000,  256000,

    // For UART to IR Carrier
      66000,   72000,   73400,   76000,
      80000,  112000,

    // End of the table
    0xffffffff
};
 

pvvx

Активный участник сообщества
Выглядит как грусть печаль, из PWM больше 16Khz не выжать.
Пишут, что переферия по регистрам совпадает с описанием от http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/quark-d2000-datasheet.pdf :)
Но там эти таймеры тактируются от CLK_CPU - 32 MHz.
Скорее всего у RTL есть переключатель тактирования таймеров на CLK_CPU... Но будет больше жрать и надо переписать пару файлов в SDK...

Есть ещё бяка - тактирование от OSC32K содержит какую-то калибровку (
[HASHTAG]#ifdef[/HASHTAG] CONFIG_TIMER_MODULE ... VOID En32KCalibration(VOID) ), т.е. таймер может 'плыть', если в чипе используется простой генератор, а не кварц... :(
 
Последнее редактирование:

Olegator

New member
Пишут, что переферия по регистрам совпадает с описанием от http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/quark-d2000-datasheet.pdf :)
Но там эти таймеры тактируются от CLK_CPU - 32 MHz.
Скорее всего у RTL есть переключатель тактирования таймеров на CLK_CPU... Но будет больше жрать и надо переписать пару файлов в SDK...
32Mhz больше похоже на правду, согласен - давно уже не видел MCU с таким огромным тиком таймера.
 

pvvx

Активный участник сообщества
32Mhz больше похоже на правду, согласен - давно уже не видел MCU с таким огромным тиком таймера.
В 'Амёбе' могли привязать такт таймера и к RTC источнику... SDK позволяет менять тактовую CPU и всякие PLL (что необходимо для WiFi), а тогда при изменении CLK_CPU возможна завязка с таймерами, да чип будет горячее и выбрали такт от 32K :(
Пока не нашел и счетчика тиков CPU... В данной модели ARM он обычно не штатный...
 

Olegator

New member
Неужели они ARM-овский SysTick из ядра выпилили?

Уже не терпится получить посылку с модулями, что бы руками пощупать, что они там накрутили :)
 

pvvx

Активный участник сообщества
Неужели они ARM-овский SysTick из ядра выпилили?
Да, sdk-ameba1-v3.4b3_without_NDA\component\soc\realtek\8195a\fwlib\rtl8195a\rtl8195a.h:
Код:
#define __Vendor_SysTickConfig         1         /**< Vendor specific implementation of SysTickConfig is defined */
-> в sdk-ameba1-v3.4b3_without_NDA\component\soc\realtek\8195a\cmsis\core_cm3.h
отключен [inline]__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)[/inline]
 
Последнее редактирование:

pvvx

Активный участник сообщества
Есть 32-х битный счетчик тактов CPU в +.
Без включенной отладки [0хe0001004] он выключен:
Код:
#ATSD=E0001000
[ATSD]: _AT_SYSTEM_DUMP_REGISTER_
E0001000:    40000000    40000000    40000000    40000000
Инициализируем:
Код:
             CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // открыть доступ
            if(!(DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk)) { // уже включен?
                DWT->CYCCNT = 0; // обнулить и запустить
                DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // запустить счет
            }
            // Сравнение с HalDelayUs(10000);
                uint32_t t0 = DWT->CYCCNT;
                HalDelayUs(10000);
                printf("t = %u\r\n", DWT->CYCCNT-t0);
 

shangdawei

New member
tutorials:f401_f429_disco:cycle_counter:implementation [EmBlocks]

Код:
/*
**
**                           CycleCounter.c
**
**
**********************************************************************/
/*
   Last committed:      Rev 1.0
   Last changed by:     Olavi Kamppari
   Last changed date:   Feb 17, 2014
   Platform:            STM32F4
   Processor:           F429 and F401
   Board:               STM32F429I/STM32F401C Discovery
   Description:         Provide access to core debugger cycle counter.
                        the counter is incremented at CPU clock speed
                        - 180 MHz with F429
                        - 84 MHz with F401
   Note:                This counter is not used with EmBlocks GDB, but
                        could be used in some other M4 IDE.
**********************************************************************/
#include "common.h"
#include "CycleCounter.h"
uint32_t    prevCount;
void        inline initCycleCounter() {
    prevCount           = 0;
    CoreDebug->DEMCR   |= CoreDebug_DEMCR_TRCENA_Msk;   // Enable core debugger for tracing
    DWT->CYCCNT         = 0;                            // Reset debugger trace counter
    DWT->CTRL          |= DWT_CTRL_CYCCNTENA_Msk;       // Enable cycle counter
}
uint32_t    inline currentCount() {
    prevCount           = DWT->CYCCNT;
    return prevCount;
}
uint32_t    inline deltaCount() {
    return DWT->CYCCNT-prevCount;
}
uint32_t    inline deltaMicros() {
    return (DWT->CYCCNT-prevCount)/clockFreqMHz;
}
uint32_t    inline measureMicros(uint32_t startCount, uint32_t endCount) {
    return (endCount-startCount)/clockFreqMHz;
}
uint32_t    inline measureNanos(uint32_t startCount, uint32_t endCount) {
    return (TenTo3*(endCount-startCount))/clockFreqMHz;
}
void        busyWaitMicros(uint32_t micros) {
    assert_check(micros<=MAX_MICROS,"Too large delay in microseconds");
    currentCount();
    while (deltaMicros()<micros);
}
void        busyWaitMillis(uint32_t millis) {
    assert_check(millis<=MAX_MILLIS,"Too large delay in milliseconds");
    busyWaitMicros(millis*TenTo3);
}
void        busyWaitSeconds(uint32_t seconds) {
    assert_check(seconds<=MAX_SECONDS,"Too large delay in seconds");
    busyWaitMicros(seconds*TenTo6);
}
 

shangdawei

New member
Код:
extern uint32_t SystemCoreClock;
void CycleCounterInit( void )
{
  if ( !( CoreDebug->DEMCR &CoreDebug_DEMCR_TRCENA_Msk ))
  {
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    DWT->CYCCNT = 0;
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
  }
}
void CycleCounterDelayUs( uint32_t Us )
{
  int32_t Done = DWT->CYCCNT + Us * ( SystemCoreClock / 1000000 );
  while ( ( ( int32_t )DWT->CYCCNT - Done ) < 0 )
    ;
}
 

pvvx

Активный участник сообщества
Неужели они ARM-овский SysTick из ядра выпилили?
Он работает на тактирование RTOS и корректируется на режимы Sleep. Но там нашлись странности:
Все загружаемые счетчики и коррекции в RTOS (счет тиков) рассчитаны только на 166 MHz CLK CPU, а модуль RTL00 при загрузке с Flash в sdk-ameba-rtl8710af-v3.5a_without_NDA_GCC_V1.0 от PADI IoT Stamp Resources – PINE64 запускает код с 83MHz CLK CPU. При этом при перезагрузке после разных sleep и загрузке с RAM (отладка) стартует с 166MHz. Короче у pine64 в SDK ошибки... но они корректируемы, т.к. уже "реверс" основных закрытых частей библиотек у меня завершен (кроме низкого уровня библиотеки wifi - изменения её пока не требуются).
Часть с разными CLK CPU уже переписал для всех HAL и т.д.
У меня оно теперь устанавливается в platform_autoconf.h:
#define CONFIG_CPU_CLK 1
#define CONFIG_CPU_166_6MHZ 1 // RUN/IDLE ~62/21 mA
//#define CONFIG_CPU_83_3MHZ 1 // RUN/IDLE ~55/15 mA
//#define CONFIG_CPU_41_6MHZ 1 // RUN/IDLE ~51/11 mA
...
//#define CONFIG_CPU_4MHZ // IDLE ~8 mA
(Замеры питания даны при включенном приеме WiFi в режиме Station)
При 10MHz модуль как-то ещё работает c WiFi :)
 
Последнее редактирование:

KomX

Member
Где можно почерпнуть информацию о таймерах (TIMERx)?
В частности интересует информация о доступе к регистрам, их назначению, структуре и незанятостью операционкой.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Где можно почерпнуть информацию о таймерах (TIMERx)?
В частности интересует информация о доступе к регистрам, их назначению, структуре и незанятостью операционкой.
Описание регистров таймеров смотрите тут:
http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/quark-d2000-datasheet.pdf
Базовый адрес в RTL00MP3/hal_platform.h at master · pvvx/RTL00MP3 · GitHub
описание остальных регистров в RTL00MP3/rtl8195a_timer.h at master · pvvx/RTL00MP3 · GitHub
ОС использует всего один таймер. Mbed api другой...

Если включен блок WiFi, то работает 64-битный аппаратный счетчик микросекунд TSF:
Код:
#include "hal_com_reg.h"

#define ReadTSF_Lo32() (*((volatile unsigned int *)(WIFI_REG_BASE + REG_TSFTR)))
#define ReadTSF_Hi32() (*((volatile unsigned int *)(WIFI_REG_BASE + REG_TSFTR1)))

LOCAL uint64_t get_tsf(void)
{
    return *((uint64_t *)(WIFI_REG_BASE + REG_TSFTR));
}
 
Последнее редактирование:

KomX

Member
@pvvx, благодарю за информацию.

Структура регистров в rtl8195a_timer.h соответствует описанию 1-го таймера в D2000 (их в доках всего 2).
Обращения из кода к структуре через макросы HAL_TIMER_READ32(addr) и HAL_TIMER_WRITE32(addr, value) в основном происходит через функцию HalTimerInitRtl8195a_Patch(), в которой в качестве адреса используется TIMER_INTERVAL*pHalTimerAdap->TimerId + смещение требуемого регистра.
TIMER_INTERVAL*pHalTimerAdap->TimerId для 8 значений TimerId (0-7) даёт 8 адресов:
0x40002000 для TimerId=0; //RTC
0x40002014 для TimerId=1; //
0x40002028 для TimerId=2; // PWM_3
0x4000203c для TimerId=3; // PWM_0
0x40002050 для TimerId=4; // PWM_1
0x40002064 для TimerId=5; // PWM_2
0x40002078 для TimerId=6; //
0x4000208c для TimerId=7. //
Дамп регистров снятый в JLink при инициализации мною PWM сигнала на PC_2 верно отображает регистры для TimerId=5, а также инициированный с TimerId=1 таймер. При этом вся структура таймерных регистров повторяется с шагом 0x100 (4 блока).

В принципе это всё, что нарыл в SDK. Это ни на грамм не приблизило меня к аппаратному управлению состоянием pwm пина от таймера в режиме PWM Mode.
Поэтому, если это возможно, хотелось бы получить помощь в конфигурации предделителя(-лей) таймеров и как выходы таймеров подключить в пинам?
Очень хочется иметь аппаратную реализацию 2-х выходов с импульсом в 1 мксек следующим с частотой от 50 Гц до 50 кГц.
 
Сверху Снизу