Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

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

User Info


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

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

Ник:
Пароль:

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

ОбновитьПодробнееВсегоВсего:5
Форум » starterkit.ru » Отладочные платы » SK-iMX53
Генерация меандра с помощью PWM
Maxim
Добавлено 14.12.2013 18:29
0
Сообщение: 1
Maxim
0

Пункты: 722
Регистрация: 14.12.2013
Здравствуйте.
Пытаюсь подключить к плате SK-iMX53 v3.B АЦП. Для работы АЦП нужен тактовый сигнал 12 МГц. Для генерации меандра планировал использовать PWM. На основе примера работы с GPIO сделал программу. Но на выводе PWM1(на схеме платы разъем Х1) сигнала нет. Есть подозрение что вывод не настроен на работу с PWM. В каком файле с исходниками ядра это можно посмотреть?
Может быть есть другой способ сгенерировать меандр?

При работе с этим выводом как с GPIO на выходе есть сигнал.

Текст программы:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

//-------------------------------------------------------------

#define IMX_PWM1 0x53fb4000 /* PWM 1 registers */

#define PWM_PWMCR 0x00 /* Control register */
#define PWM_PWMSR 0x04 /* Status register */
#define PWM_PWMIR 0x08 /* Interrupt register */
#define PWM_PWMSAR 0x0c /* Sample register */
#define PWM_PWMPR 0x10 /* Period register */
#define PWM_PWMCNR 0x14 /* Counter register */

//-------------------------------------------------------------

#define MAP_BASE_PWM (IMX_PWM1)
#define MAP_SIZE 4096Ul
#define MAP_MASK (MAP_SIZE - 1)

void *mapped_base_pwm;

//-----------------------------------------------------------------------

int main(void)
{
int fd;

// try open /dev/mem ===============================================

if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
printf("Cannot open /dev/mem.\n");
exit(EXIT_FAILURE);
}

printf("/dev/mem opened.\n");

// try mapped memory A =============================================

mapped_base_pwm = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE_PWM & ~MAP_MASK);
if (mapped_base_pwm == (void *) -1)
{
printf("Memory mapping error.\n");
exit(EXIT_FAILURE);
}

printf("A Memory block mapped at address %p.\n", mapped_base_pwm);
mapped_base_pwm+=(MAP_BASE_PWM & MAP_MASK);
printf("A Target address mapped 0x%08x-->0x%08x\n",(int) MAP_BASE_PWM,(int)mapped_base_pwm);

//==================================================================

printf("Initing PWM 1 Module\n");

*(int*)(mapped_base_pwm+PWM_PWMCR) = 0; // Disable PWM
*(int*)(mapped_base_pwm+PWM_PWMCR) = 0xFC20000;
*(int*)(mapped_base_pwm+PWM_PWMSR) = 0;
*(int*)(mapped_base_pwm+PWM_PWMIR) = 0;
*(int*)(mapped_base_pwm+PWM_PWMSAR) = 1000;
*(int*)(mapped_base_pwm+PWM_PWMPR) = 2000;

*(int*)(mapped_base_pwm+PWM_PWMCR) |= 1; // Enable PWM

printf("PWM 1 Module - Enabled\n");

while(1)
{

}

close(fd);
printf("Bye!\n");
return 0;
}
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 14.12.2013 19:40 Сообщение: 2
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
Есть подозрение что вывод не настроен на работу с PWM. В каком файле с исходниками ядра это можно посмотреть?
Может быть есть другой способ сгенерировать меандр?

ход ваших мыслей разумен и подозрения про пин правильные..
вариант в лоб - если всё делать из своей программы, то в даташите смотрите раздел с описанием работы с GPIO и что нужно записать в регистры для правильного инита..
потом, сначала делаете mmap для блока GPIO, интите нужный пин в режим MF PWM, далее mmap на блок работы с PWM и всё должно взлететь..
есть вариант с ядром - прописываете пин и нужные структуры в файле ядра, включаете поддержку через менюконфиг и после пересборки ядро само будет всё делать и пин пэвээмить..
еще есть вариант с фиксированной частотой - прописываете структуру для таймера (разумеется с инитом пинов) в файле борды и на выхлопе фиксированная частота..

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
Pavel Ivanchenko
Добавлено 15.12.2013 11:41 Сообщение: 3
Pavel Ivanchenko
Admin
4.39

Пункты: 92788
Регистрация: 24.03.2009
Пол: Мужчина
Цитата
Может быть есть другой способ сгенерировать меандр?
На звуковой кодек с процессора выходит тактовый 12МГц.
Спуститься к концу Подняться к началу
Персональная информация
Maxim
Добавлено 19.12.2013 19:01 Сообщение: 4
Maxim
0

Пункты: 722
Регистрация: 14.12.2013
Спасибо за ответы.

После изучения документации на процессор возник вопрос. На схеме платы 3.В есть линии PWM1 и PWM2 (разъем Х1 и Х2), но в содержимом регистров IOMUX таких вариантов подключения выводов нет. Относятся ли названия выводов на схеме к модулям PWM процессора?

В каком файле в исходниках ядра можно посмотреть конфигурацию выводов процессора?

В программу добавил настройку IOMUX, но на нужном выводе эффекта не наблюдается:
*(int*)(mapped_base_iomuxc+IOMUXC_SW_MUX_CTL_PAD_GPIO9) = 4; // GPIO9 -> PWM
Может быть нужно еще какой то регистр настроить?

Можете подробнее рассказать про вариант с структурой для таймера.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 19.12.2013 23:42 Сообщение: 5
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
Относятся ли названия выводов на схеме к модулям PWM процессора?

не всегда и не везде - всегда надо проверять соответствие имени шарика(контакта) тому, что написано в даташите на конкретный процессор..
если кратко - сначала берется даташит от производителя (где уже могут быть ошибки), потом рисуется элемент в библиотеку (и тут могут быть ошибки),потом делается футпринт элемента и потом это попадает в финальную электросхему и монтаж..
по счастью, у Павла мне не припомнится ни одного бажного элемента - снимаю шляпу..
никогда не рисовали чип на 600 копыт? я на третий день после третьей верификации готов был всех разорвать..

Цитата
В каком файле в исходниках ядра можно посмотреть конфигурацию выводов процессора?

/arch/arm/mach-mx5/mx53_loco.c

в старых исходниках нашел, как прикручивал управление яркостью и задействовал pwm (разъем {2, контакт 38)
в файле борды в структуре пинов прописано:
Код
MX53_PAD_GPIO_9__PWM1_PWMO,

структура для подсветки
Код
static struct platform_pwm_backlight_data mxc_pwm_backlight_data = {
.pwm_id = 0,
.max_brightness = 255,
.dft_brightness = 128,
.pwm_period_ns = 50000,
};

ну и в ините:
Код
mxc_register_device(&mxc_pwm1_device, NULL);
mxc_register_device(&mxc_pwm1_backlight_device, &mxc_pwm_backlight_data);


Цитата
Можете подробнее рассказать про вариант с структурой для таймера.

не-а, ибо не владею нужными знаниями..
имхо, если нужно 12МГц "здесь и сейчас", то я бы прислушался к совету Павла и через буфер взял нужную частоту..
всегда можно сгородить на рассыпухе или в монокорпусе генератор на 12МГц частоту..
кстати, для pwm надо почитать характеристики стабильности сигнала, иначе у АЦП может крышу снести от плавающей частоты..

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
Maxim
Добавлено 20.12.2013 14:53 Сообщение: 6
Maxim
0

Пункты: 722
Регистрация: 14.12.2013
К сожалению вариант с сигналом от кодека не подходит. В конечном устройстве возможно будет аудио, а тактовый сигнал АЦП может быть от 7 до 34 МГц в зависимости от требований.
Пробовал запускать АЦП от контроллера, тактовый сигнал генерировался внутренним модулем PWM, АЦП работало, частота была достаточно стабильна. С процессорами от Freescale пока не работал, но судя по описанию PWM должен генерировать достаточно стабильную частоту.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 22.12.2013 03:10 Редактировалось 22.12.2013 04:05 Сообщение: 7
sasamy
4.71

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

*(int*)(mapped_base_pwm+PWM_PWMCR) = 0xFC20000;


Клок судя по настройке вы берете с ipg_clk_highfreq

Цитата

High frequency Clock (ipg_clk_highfreq) pat_ref or CKIH


скорей всего в настройках выставлено в качестве источника как раз CKIH - посмотрел на своей плате V3.А (пин CKIH1) - генератор DA9 не запаян и частота у него штатная 22_5792 МГц. Попробуйте ipg_clk

*(int*)(mapped_base_pwm+PWM_PWMCR) = 0xFC10000;

но штатно вы даже с него не получите 34 МГц на PWM-е
ipg clock: 66 666 666 Hz

Цитата

*(int*)(mapped_base_iomuxc+IOMUXC_SW_MUX_CTL_PAD_GPIO9) = 4; // GPIO9 -> PWM
Может быть нужно еще какой то регистр настроить?


стандартно там надо 3 регистра проинициализировать на каждый пин, я как-то давно с этим разбирался, уже не помню - проще взять хидеры и код из майнстримного убута - там все достаточно компактно сделано.
Спуститься к концу Подняться к началу
Персональная информация
lexx666
Добавлено 23.12.2013 07:07 Редактировалось 23.12.2013 07:08 Сообщение: 8
lexx666
3.83

Пункты: 11780
Регистрация: 28.07.2011
Пол: Мужчина
Из: Барнаул
http://www.armadeus.com/wiki/index.php?title=PWM
неплохой драйвер шима
грузил модулем под imx6q
правил некоторые функции, ибо есть ньансы
Спуститься к концу Подняться к началу
Персональная информация
Maxim
Добавлено 25.12.2013 19:18 Сообщение: 9
Maxim
0

Пункты: 722
Регистрация: 14.12.2013
ШИМ заработал. Нужно было настроить модуль тактового генератора.
Работают оба варианта: ipg_clk и ipg_clk_highfreq.

Код
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

//-------------------------------------------------------------

#define IMX_CLK_REG 0x53fd4000 /* CLK registers */
#define IMX_IOMUXC 0x53fa8000 /* IOMUXC registers */
#define IMX_PWM1 0x53fb4000 /* PWM 1 registers */

#define PWM_PWMCR 0x00 /* Control register */
#define PWM_PWMSR 0x04 /* Status register */
#define PWM_PWMIR 0x08 /* Interrupt register */
#define PWM_PWMSAR 0x0c /* Sample register */
#define PWM_PWMPR 0x10 /* Period register */
#define PWM_PWMCNR 0x14 /* Counter register */

//-------------------------------------------------------------

#define MAP_BASE_PWM1 (IMX_PWM1)
#define MAP_BASE_IOMUXC (IMX_IOMUXC)
#define MAP_BASE_CLK (IMX_CLK_REG)
#define MAP_SIZE 4096Ul
#define MAP_MASK (MAP_SIZE - 1)

#define IOMUXC_SW_MUX_CTL_PAD_GPIO9 0x31C

#define CCM_CCGR2 0x70

void *mapped_base_clk;
void *mapped_base_pwm1;
void *mapped_base_iomuxc;

//-----------------------------------------------------------------------

int main(void)
{
unsigned int i;

int fd;

// try open /dev/mem ===============================================

if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
printf("Cannot open /dev/mem.\n");
exit(EXIT_FAILURE);
}

printf("/dev/mem opened.\n");

// try mapped memory CLK =============================================

mapped_base_clk = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE_CLK & ~MAP_MASK);
if (mapped_base_clk == (void *) -1)
{
printf("Memory mapping error.\n");
exit(EXIT_FAILURE);
}

printf("CCM memory block mapped at address %p.\n", mapped_base_clk);
mapped_base_clk+=(MAP_BASE_CLK & MAP_MASK);
printf("Target address mapped 0x%08x-->0x%08x\n",(int) MAP_BASE_CLK,(int)mapped_base_clk);

//==================================================================

printf("Initing CLK Module\n");

*(int*)(mapped_base_clk+CCM_CCGR2) |= 0xC00; // ipg_clk

// try mapped memory IOMUXC =============================================

/* mapped_base_iomuxc = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE_IOMUXC & ~MAP_MASK);
if (mapped_base_iomuxc == (void *) -1)
{
printf("Memory mapping error.\n");
exit(EXIT_FAILURE);
}

printf("IOMUXC memory block mapped at address %p.\n", mapped_base_iomuxc);
mapped_base_iomuxc+=(MAP_BASE_IOMUXC & MAP_MASK);
printf("Target address mapped 0x%08x-->0x%08x\n",(int) MAP_BASE_IOMUXC,(int)mapped_base_iomuxc);
*/
//==================================================================
/*
printf("Initing IOMUX Module\n");

*(int*)(mapped_base_iomuxc+IOMUXC_SW_MUX_CTL_PAD_GPIO9) = 4; // GPIO9 -> PWM
*/
// try mapped memory PWM1 =============================================

mapped_base_pwm1 = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE_PWM1 & ~MAP_MASK);
if (mapped_base_pwm1 == (void *) -1)
{
printf("Memory mapping error.\n");
exit(EXIT_FAILURE);
}

printf("PWM1 memory block mapped at address %p.\n", mapped_base_pwm1);
mapped_base_pwm1+=(MAP_BASE_PWM1 & MAP_MASK);
printf("Target address mapped 0x%08x-->0x%08x\n",(int) MAP_BASE_PWM1,(int)mapped_base_pwm1);


//==================================================================

printf("Initing PWM 1 Module\n");

*(int*)(mapped_base_pwm1+PWM_PWMCR) = 0; // Disable PWM
*(int*)(mapped_base_pwm1+PWM_PWMCR) = 0x3C10000;
*(int*)(mapped_base_pwm1+PWM_PWMSR) = 0;
*(int*)(mapped_base_pwm1+PWM_PWMIR) = 0;
*(int*)(mapped_base_pwm1+PWM_PWMSAR) = 300;
*(int*)(mapped_base_pwm1+PWM_PWMPR) = 600;

*(int*)(mapped_base_pwm1+PWM_PWMCR) |= 1; // Enable PWM

printf("PWM 1 Module - Enabled\n");

while(1)
{
// printf("Counter status 0x%08x\n",(*(int*)(mapped_base_pwm1+PWM_PWMCNR)));
// for (i=0;i<10000;i++);
}

close(fd);
printf("Bye!\n");
return 0;
}


Настройку IOMUX сначала сделал в программе. Когда ШИМ заработал настроил ядро - в файле ядра(/arch/arm/mach-mx5/mx53_loco.c) дописал в массив определения пинов строку: MX53_PAD_GPIO_9__PWM1_PWM0. Пересобрал ядро и залил на плату, программа работает. Задействован выход 38 разъем Х2.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 26.12.2013 15:55 Сообщение: 10
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
ну вот - результат положительный..
теперь в файле борды оформить в структурку с нужными параметрами, зарегать свой pwm и юзать через sysfs, не залезая в железо..

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Отладочные платы » SK-iMX53