Ник:
Пароль:

Контакты

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 » Embedded Linux
SK-AT91SAM9G45 + GPIO вход + АЦП
alexmfivt
Добавлено 03.05.2012 05:21 Редактировалось 03.05.2012 05:31
0
Сообщение: 1
alexmfivt
0

Пункты: 3237
Регистрация: 07.11.2010
Пол: Мужчина
Из: Красноярск
собственно нужно получить информацию с пинов, есть ли уровень или нет. также нужно считать с аналоговых входов напряжение.
пока что вывожу GPIO через "mapped_base = mmap(...)"
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 03.05.2012 09:36 Сообщение: 2
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Для gpio примеры тут можно посмотреть
http://www.avrfreaks.net/wiki/index.php/Documentation:Linux/GPIO
для ацп - не знаю есть ли рабочий драйвер, по форуму можно поискать, была тема и вроде что-то работало.
Спуститься к концу Подняться к началу
Персональная информация
alexmfivt
Добавлено 03.05.2012 10:21 Редактировалось 03.05.2012 10:22 Сообщение: 3
alexmfivt
0

Пункты: 3237
Регистрация: 07.11.2010
Пол: Мужчина
Из: Красноярск
спасибо. но у мня нет /sys/class/gpio
у меня вывод щас такой:


#define AT91_PIOA 0xfffff200
#define AT91_PIOB 0xfffff400
#define AT91_PIOC 0xfffff600

#define PIO_PER 0x00 /* Enable Register */
#define PIO_PDR 0x04 /* Disable Register */
#define PIO_PSR 0x08 /* Status Register */
#define PIO_OER 0x10 /* Output Enable Register */
#define PIO_ODR 0x14 /* Output Disable Register */
#define PIO_OSR 0x18 /* Output Status Register */
#define PIO_IFER 0x20 /* Glitch Input Filter Enable */
#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */
#define PIO_IFSR 0x28 /* Glitch Input Filter Status */
#define PIO_SODR 0x30 /* Set Output Data Register */
#define PIO_CODR 0x34 /* Clear Output Data Register */
#define PIO_ODSR 0x38 /* Output Data Status Register */
#define PIO_PDSR 0x3c /* Pin Data Status Register */
#define PIO_IER 0x40 /* Interrupt Enable Register */
#define PIO_IDR 0x44 /* Interrupt Disable Register */
#define PIO_IMR 0x48 /* Interrupt Mask Register */
#define PIO_ISR 0x4c /* Interrupt Status Register */
#define PIO_MDER 0x50 /* Multi-driver Enable Register */
#define PIO_MDDR 0x54 /* Multi-driver Disable Register */
#define PIO_MDSR 0x58 /* Multi-driver Status Register */
#define PIO_PUDR 0x60 /* Pull-up Disable Register */
#define PIO_PUER 0x64 /* Pull-up Enable Register */
#define PIO_PUSR 0x68 /* Pull-up Status Register */
#define PIO_ASR 0x70 /* Peripheral A Select Register */
#define PIO_BSR 0x74 /* Peripheral B Select Register */
#define PIO_ABSR 0x78 /* AB Status Register */
#define PIO_OWER 0xa0 /* Output Write Enable Register */
#define PIO_OWDR 0xa4 /* Output Write Disable Register */
#define PIO_OWSR 0xa8 /* Output Write Status Register */
//-------------------------------------------------------------

#define PIN_MASK (1<<20)//(1<<20=0x100000)
//0b00000000000000000000000001000000//
// 01234567890123456789012345678901
// 10987654321098765432109876543210
#define MAP_BASE (AT91_PIOC)


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


int main(void)
{
int fd;
void *mapped_base;

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

fprintf(stderr, "/dev/mem opened.\n");

mapped_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE & ~MAP_MASK);

if (mapped_base == (void *) -1)
{
fprintf(stderr, "Memory mapping error.\n");
exit(EXIT_FAILURE);
}

fprintf(stderr, "Memory block mapped at address %p.\n", mapped_base);
mapped_base+=(MAP_BASE & MAP_MASK);
fprintf(stderr, "Target address mapped 0x%08x-->0x%08x\n",(int) MAP_BASE,(int)mapped_base);

*(int*)(mapped_base+PIO_PER) = PIN_MASK;
*(int*)(mapped_base+PIO_IDR) = PIN_MASK;
*(int*)(mapped_base+PIO_MDDR) = PIN_MASK;
*(int*)(mapped_base+PIO_PUDR) = PIN_MASK;
*(int*)(mapped_base+PIO_OWDR) = PIN_MASK;
*(int*)(mapped_base+PIO_OER) = PIN_MASK;

int val=0;
while (1)
{
if (val=!val)
*(int*)(mapped_base+PIO_SODR) = PIN_MASK;
else
*(int*)(mapped_base+PIO_CODR) = PIN_MASK;
printf("0x%08x\n",(int)(mapped_base+PIO_ODSR));
printf("0x%x\n",*(int*)(mapped_base+PIO_ODSR));
printf("%u\n",val);
usleep (5000000);
}

return 0;
}


как настроить чтение?

и как через такой же mmap к АЦП получить доступ?
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 03.05.2012 13:52 Сообщение: 4
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
как настроить чтение?

настроить чтение чего?

Цитата
и как через такой же mmap к АЦП получить доступ?

очевидно, что по образу и подобию, почитав даташит и поменяв циферки примерно тут:

Код
#define AT91_PIOA 0xfffff200
#define AT91_PIOB 0xfffff400
#define AT91_PIOC 0xfffff600


одно не могу понять, а где там АЦП? если то, что используется в корке тачскрина, дак оно вроде сильно специализированно..

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
alexmfivt
Добавлено 04.05.2012 04:13 Сообщение: 5
alexmfivt
0

Пункты: 3237
Регистрация: 07.11.2010
Пол: Мужчина
Из: Красноярск
Цитата

одно не могу понять, а где там АЦП? если то, что используется в корке тачскрина, дак оно вроде сильно специализированно..


там 8 каналов, из которых 4 тачевые. мне нужно достучаться до обычного АЦП. (до GPAD4 и GPAD5).
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 04.05.2012 10:44 Сообщение: 6
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
там 8 каналов, из которых 4 тачевые. мне нужно достучаться до обычного АЦП. (до GPAD4 и GPAD5).

хм.. и действительно, есть там такой узел..
тогда ключевые слова memories mapping TSADCC

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
alexmfivt
Добавлено 04.05.2012 11:46 Редактировалось 04.05.2012 11:48 Сообщение: 7
alexmfivt
0

Пункты: 3237
Регистрация: 07.11.2010
Пол: Мужчина
Из: Красноярск
победил! только не догоняю как физически работает АЦП, если настроено считывание на несколько каналов.
Код
#define AT91_TAADCC 0xfffb0000
#define MAP_BASE AT91_TAADCC

#define MAP_SIZE 131072Ul
#define MAP_MASK (MAP_SIZE - 1)

#define MAP_BASE_PMC 0xfffffc00

#define MAP_SIZE_PMC 4096Ul
#define MAP_MASK_PMC (MAP_SIZE_PMC - 1)

int QAdc::getADC(int channel)
{
int fd;
void *mapped_base;

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

fprintf(stderr, "/dev/mem opened. ADC\n");

mapped_base = mmap(0, MAP_SIZE_PMC, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE_PMC & ~MAP_MASK_PMC);

if (mapped_base == (void *) -1)
{
fprintf(stderr, "Memory mapping error. PMC\n");
exit(EXIT_FAILURE);
}

fprintf(stderr, "Memory block mapped at address %p. PMC\n", mapped_base);
mapped_base = (char*)mapped_base + (MAP_BASE_PMC & MAP_MASK_PMC);
fprintf(stderr, "Target address mapped 0x%08x-->0x%08x PMC\n",(int) MAP_BASE_PMC,(int)mapped_base);

*(int*)((char*)mapped_base + 0x10) = AT91_ADC_CH(20);

printf("0x%08x\n",(int)((char*)mapped_base+0x18));
printf("0x%x\n",*(int*)((char*)mapped_base+0x18));

mapped_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE & ~MAP_MASK);

if (mapped_base == (void *) -1)
{
fprintf(stderr, "Memory mapping error. ADC\n");
exit(EXIT_FAILURE);
}

fprintf(stderr, "Memory block mapped at address %p. ADC\n", mapped_base);
mapped_base = (char*)mapped_base + (MAP_BASE & MAP_MASK);
fprintf(stderr, "Target address mapped 0x%08x-->0x%08x ADC\n",(int) MAP_BASE,(int)mapped_base);

/*printf("0x%08x\n",(int)((char*)mapped_base+AT91_ADC_CHSR));
printf("0x%x\n",*(int*)((char*)mapped_base+AT91_ADC_CHSR));*/

/*usleep(10000);
*(int*)((char*)mapped_base + AT91_ADC_CR) = 0x1;
usleep(10000);
*(int*)((char*)mapped_base + AT91_ADC_CR) = 0x0;

usleep(10000);*/
*(int*)((char*)mapped_base + AT91_ADC_MR) = 0x0f1f0f00;

//usleep(10000);
*(int*)((char*)mapped_base + AT91_ADC_CHER) = AT91_ADC_CH(4);

//usleep(10000);

/*printf("0x%08x\n",(int)((char*) mapped_base+AT91_ADC_CHSR));
printf("0x%x\n",*(int*)((char*)mapped_base+AT91_ADC_CHSR));*/
int sum = 0;
for(int i = 0; i < 32; i++)
{
*(int*)((char*)mapped_base + AT91_ADC_CR) = AT91_ADC_START;
while(!((*(int*)((char*)mapped_base + AT91_ADC_SR)) & AT91_ADC_EOC(4)))
printf("0");
sum += *(int*)((char*)mapped_base+AT91_ADC_CHR(4));
}



//AT91_ADC_CHR(n) //регистр данных канала АЦП
//printf("0x%08x\n",(int)((char*)mapped_base+AT91_ADC_CHR(4)));
//printf("data from ADC=0x%x\n",*(int*)((char*)mapped_base+AT91_ADC_CHR(4)));
printf("data from ADC=0x%x\nVoltage %.2fV\n",sum/32, sum*10.0/32.0/235.0);

close(fd);
}


причем довольно точно считывает с усреднением на 32 прохода.
за 1 раз разбег измерений может отличаться от 0xea до 0xff (порядка 20 единиц АЦП)
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux