SK-AT91SAM9G45 + GPIO вход + АЦП
alexmfivt
Пункты: 3237
Регистрация: 07.11.2010
Пол: Мужчина
Из: Красноярск
собственно нужно получить информацию с пинов, есть ли уровень или нет. также нужно считать с аналоговых входов напряжение.
пока что вывожу GPIO через "mapped_base = mmap(...)"
sasamy
Пункты: 83542
Регистрация: 14.08.2009
alexmfivt
Пункты: 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
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата как настроить чтение?
настроить чтение чего?
Цитата и как через такой же mmap к АЦП получить доступ?
очевидно, что по образу и подобию, почитав даташит и поменяв циферки примерно тут:
Код #define AT91_PIOA 0xfffff200
#define AT91_PIOB 0xfffff400
#define AT91_PIOC 0xfffff600
одно не могу понять, а где там АЦП? если то, что используется в корке тачскрина, дак оно вроде сильно специализированно..
На любой вопрос есть любой ответ.
alexmfivt
Пункты: 3237
Регистрация: 07.11.2010
Пол: Мужчина
Из: Красноярск
Цитата
одно не могу понять, а где там АЦП? если то, что используется в корке тачскрина, дак оно вроде сильно специализированно..
там 8 каналов, из которых 4 тачевые. мне нужно достучаться до обычного АЦП. (до GPAD4 и GPAD5).
Jury093
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата там 8 каналов, из которых 4 тачевые. мне нужно достучаться до обычного АЦП. (до GPAD4 и GPAD5).
хм.. и действительно, есть там такой узел..
тогда ключевые слова
memories mapping TSADCC
На любой вопрос есть любой ответ.
alexmfivt
Пункты: 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 единиц АЦП)