Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru
Партнеры:
otladka.com.ua - г.Киев

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:3
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:7
Форум » starterkit.ru » Embedded Linux
помогите с генератором меандра
Franky
Добавлено 10.06.2012 00:08 Редактировалось 10.06.2012 00:08 Сообщение: 11
Franky
5

Пункты: 5030
Регистрация: 29.06.2010
Таймер никак не хотел выдавать нужную частоту! пока я не удалил из конфига ядра драйвер таймера. Но без него не работает режим Full Realtime. Замкнутый круг.(((
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 10.06.2012 11:14 Редактировалось 10.06.2012 11:19 Сообщение: 12
sasamy
4.70

Пункты: 77331
Регистрация: 14.08.2009
Цитата

Но без него не работает режим Full Realtime. Замкнутый круг.(((


замкнутый, если примеры "влоб" копировать и надеяться что все заработает как Вам надо. Кто вам мешает поменять tc0 например на tc3,4,5 ? вам прерывания от них не нужно генериовать так что никакой проблемы нет подправить.
Спуститься к концу Подняться к началу
Персональная информация
Franky
Добавлено 12.06.2012 12:08 Сообщение: 13
Franky
5

Пункты: 5030
Регистрация: 29.06.2010
В том то и дело, что вам код, работавший прекрасно с TC0 не работает с TC1:

#include <mach/at91_tc.h>
...
#define at91_tc_read(reg) __raw_readl(tc1_base + (reg))
#define at91_tc_write(reg, val) __raw_writel((val), tc1_base + (reg))
...
static int clock_1khz(void)
{
void __iomem *tc1_base;
struct clk *tc1_clk;

tc0_base = ioremap_nocache(AT91SAM9260_BASE_TC1, 256);
if (!tc1_base) {
printk("Can't remap TC1 register area\n");
return -1;
}

tc1_clk = clk_get(NULL, "tc0_clk");
if (IS_ERR(tc1_clk)) {
iounmap(tc0_base);
printk("Error: can't find tc1_clk\n");
return -1;
}

clk_enable(tc1_clk);

at91_set_A_periph(AT91_PIN_PA27, 0);

at91_tc_write(AT91_TC_CMR,
AT91_TC_WAVE | AT91_TC_WAVESEL_UP_AUTO
| AT91_TC_ACPA_SET | AT91_TC_ACPC_CLEAR
| AT91_TC_TIMER_CLOCK1 ); // делитель для MCK, см даташит

at91_tc_write(AT91_TC_RC, 4); // число импульсов на период (делитель входящей частоты)
at91_tc_write(AT91_TC_RA, 2); // половина AT91_TC_RC если импульс/пауза 50/50
at91_tc_write(AT91_TC_IDR, -1);
at91_tc_write(AT91_TC_CCR, AT91_TC_SWTRG | AT91_TC_CLKEN);

iounmap(tc0_base);
return 0;
}


Консоль не выдаёт никаких тревожных сообщений. Но сигнала на ноге нет. В файле борды нога PA27 больше нигде не упоминается.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 12.06.2012 13:09 Редактировалось 12.06.2012 13:56 Сообщение: 14
sasamy
4.70

Пункты: 77331
Регистрация: 14.08.2009
tc1_clk = clk_get(NULL, "tc0_clk");
if (IS_ERR(tc1_clk)) {
iounmap(tc0_base);
printk("Error: can't find tc1_clk\n");
return -1;
}

как же он заработает если вы включаете tc0 :) это у sam9g45 все шесть таймеров сидят на одном прерывании и включаются одним битом в PMC - в 9260 они раздеьно включаются/генерируют прервания. Еще учитывайте что в -rt патче используется не только tc0 но и tc1,tc2 для hrtimer.
clk_get(NULL, "tc0_clk") - получает информацию в виде указателя на структуру для соответствующего периферийного модуля по его наименованию, которое передается вторым аргументом ф-ции
clk_enable(tc1_clk) - устанавливает соответствующий этой периферии бит в регистре PMC Peripheral Clock Enable Register
поэтому для 9260 наименование для каждого таймера должно быть свое, в g45 было бы достаточно одного tc0_clk чтобы включить все таймеры.
Спуститься к концу Подняться к началу
Персональная информация
Franky
Добавлено 12.06.2012 22:47 Редактировалось 12.06.2012 22:54 Сообщение: 15
Franky
5

Пункты: 5030
Регистрация: 29.06.2010
Вы не поверите но это тоже не работает:

#define at91_tc_read(reg) __raw_readl(tc1_base + (reg))
#define at91_tc_write(reg, val) __raw_writel((val), tc1_base + (reg))

static int __init set_clk_dev(void)
{
void __iomem *tc1_base;
struct clk *tc1_clk;

tc1_base = ioremap_nocache(AT91SAM9260_BASE_TC1, 256);
if (!tc1_base) {
printk("Can't remap TC1 register area\n");
return -1;
}

tc1_clk = clk_get(NULL, "tc1_clk");
if (IS_ERR(tc1_clk)) {
iounmap(tc1_base);
printk("Error: can't find tc1_clk\n");
return -1;
}

на ноге просто ничего нет. Но как вы уже писали, tc1 тоже используется в rt патче. Все остальные таймеры висят на ногах SPI1, который мне позарез нужен.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 12.06.2012 23:56 Редактировалось 13.06.2012 11:56 Сообщение: 16
sasamy
4.70

Пункты: 77331
Регистрация: 14.08.2009
Цитата

tc1 тоже используется в rt патче. Все остальные таймеры висят на ногах SPI1, который мне позарез нужен.


там масса вариантов - у каждого таймера ,если вы не заметили, два независимых канала - RA/TIOA и RB/TIOB к тому же на 9260 помоему можно выбрать какой из блоков использовать tc0,1,2 или tc3,4,5 в драйвере clocksource через menuconfig.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 13.06.2012 11:57 Редактировалось 13.06.2012 12:07 Сообщение: 17
sasamy
4.70

Пункты: 77331
Регистрация: 14.08.2009
Цитата

к тому же на 9260 помоему можно выбрать какой из блоков использовать tc0,1,2 или tc3,4,5 в драйвере clocksource через menuconfig.


Device Drivers ---> [*] Misc devices ---> (0) TC Block (NEW)

CONFIG_ATMEL_TCB_CLKSRC_BLOCK:

Some chips provide more than one TC block, so you have the
choice of which one to use for the clock framework. The other
TC can be used for other purposes, such as PWM generation and
interval timing.

так что ставите тут 1 и можете спокойно использовать tc0 который у вас уже работал. Чтобы не было путаницы напомню: TCB0 - tc0,1,2 а TCB1 - tc3,4,5.
Спуститься к концу Подняться к началу
Персональная информация
Franky
Добавлено 13.06.2012 22:50 Редактировалось 13.06.2012 22:52 Сообщение: 18
Franky
5

Пункты: 5030
Регистрация: 29.06.2010
переписал всё для TC3

static int __init set_clk_device(void)
{
void __iomem *tc3_base;
struct clk *tc3_clk;

tc3_base = ioremap_nocache(AT91SAM9260_BASE_TC3, 256);
if (!tc3_base) {
printk("Can't remap TC3 register area\n");
return -1;
}

tc3_clk = clk_get(NULL, "tc3_clk");
if (IS_ERR(tc3_clk)) {
iounmap(tc3_base);
printk("Error: can't find tc3_clk\n");
return -1;
}

clk_enable(tc3_clk);

at91_set_A_periph(AT91_PIN_PB0, 0);

at91_tc_write(AT91_TC_CMR,
AT91_TC_WAVE | AT91_TC_WAVESEL_UP_AUTO
| AT91_TC_ACPA_SET | AT91_TC_ACPC_CLEAR
| AT91_TC_TIMER_CLOCK2); // делитель для MCK, см даташит

at91_tc_write(AT91_TC_RC, 125); // число импульсов на период (делитель входящей частоты)
at91_tc_write(AT91_TC_RA, 62); // половина AT91_TC_RC если импульс/пауза 50/50
at91_tc_write(AT91_TC_IDR, -1);
at91_tc_write(AT91_TC_CCR, AT91_TC_SWTRG | AT91_TC_CLKEN);

iounmap(tc3_base);
return 0;
}

На ноге PB0 пусто... Не пойму в чём дело.
я видел в исходниках функции at91_add_device_tc. Эта функция добавляет драйвер таймера в /sys/... Зачем? можно ли через эитот драйвер динамически менять частоту?
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 14.06.2012 00:47 Сообщение: 19
Jury093
4.5

Пункты: 54233
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
интерфейс SPI1 случайно не задействован? PB0 может быть заблокирован им..
в логах ничего интересного не видно?

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
Dub
Добавлено 14.06.2012 08:50 Редактировалось 14.06.2012 08:50 Сообщение: 20
Dub
5

Пункты: 1141
Регистрация: 14.05.2012
для общего развития: есть ли готовые решения в виде драйвер для управления частотой генерации сигнала таймером через user space?
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux