Согласно имеющейся здесь документации, минимальный интервал времени таймера 32 микросекунды? Что есть 31.25 кГц, а это мало. Поправьте если не так.
Вложения
-
4.4 KB Просмотры: 21
У GTimer 32,768 кГц (30.5 us) (hal_timer.h):Согласно имеющейся здесь документации, минимальный интервал времени таймера 32 микросекунды? Что есть 31.25 кГц, а это мало. Поправьте если не так.
Есть ещё _LONG_CALL_ u32 HalDelayUs(u32 us) в ROM.Спасибо за более полный ответ. К сожалению 32кГц это всё же детский сад для создания ик NEC сигналов. Необходимо было ровно 76кГц.
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]
#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
// 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
};
Пишут, что переферия по регистрам совпадает с описанием от http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/quark-d2000-datasheet.pdfВыглядит как грусть печаль, из PWM больше 16Khz не выжать.
32Mhz больше похоже на правду, согласен - давно уже не видел MCU с таким огромным тиком таймера.Пишут, что переферия по регистрам совпадает с описанием от http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/quark-d2000-datasheet.pdf
Но там эти таймеры тактируются от CLK_CPU - 32 MHz.
Скорее всего у RTL есть переключатель тактирования таймеров на CLK_CPU... Но будет больше жрать и надо переписать пару файлов в SDK...
В 'Амёбе' могли привязать такт таймера и к RTC источнику... SDK позволяет менять тактовую CPU и всякие PLL (что необходимо для WiFi), а тогда при изменении CLK_CPU возможна завязка с таймерами, да чип будет горячее и выбрали такт от 32K32Mhz больше похоже на правду, согласен - давно уже не видел MCU с таким огромным тиком таймера.
Да, sdk-ameba1-v3.4b3_without_NDA\component\soc\realtek\8195a\fwlib\rtl8195a\rtl8195a.h:Неужели они ARM-овский SysTick из ядра выпилили?
#define __Vendor_SysTickConfig 1 /**< Vendor specific implementation of SysTickConfig is defined */
#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);
/*
**
** 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);
}
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 )
;
}
Он работает на тактирование RTOS и корректируется на режимы Sleep. Но там нашлись странности:Неужели они ARM-овский SysTick из ядра выпилили?
Всё это не годится, т.к. нарушите работу RTOS.
Описание регистров таймеров смотрите тут:Где можно почерпнуть информацию о таймерах (TIMERx)?
В частности интересует информация о доступе к регистрам, их назначению, структуре и незанятостью операционкой.
#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));
}