Pisca-led avancado (acima de 20 MHz) com OMAP3530

Um amigo esta tentando usar um clone confiavel (EBV) da BeagleBoard para leitura de um sensor. Ele precisa gerar um clock para o AD (objetivo de 100 MHz, mas qualquer coisa acima de 20 MHz ja esta de bom sinal) e armazenar os 1000 dados (16 bits word), que chegam de forma paralela, atraves de DMA para a memoria, para processamento posterior.
Tentei ajudar ele mas o maximo que a gente consegue piscar o led eh 1,1 MHz, mesmo com o ARM trabalhando teoricamente a 720 MHz.
Sera que tem como melhorar isso? Pedi para ele compilar deixando o assembly para ver se nao tem vai-e-vems que atrasam a geracao do clock. Sera que tem como ter acesso mais rapido a um endereco de memoria especifico pelo linux sem ser atraves da forma que nos fizemos (tipo, assembly direto)? O Linux permite isso (Ubuntu)?
O fonte ta anexado.
Tentei ajudar ele mas o maximo que a gente consegue piscar o led eh 1,1 MHz, mesmo com o ARM trabalhando teoricamente a 720 MHz.
Sera que tem como melhorar isso? Pedi para ele compilar deixando o assembly para ver se nao tem vai-e-vems que atrasam a geracao do clock. Sera que tem como ter acesso mais rapido a um endereco de memoria especifico pelo linux sem ser atraves da forma que nos fizemos (tipo, assembly direto)? O Linux permite isso (Ubuntu)?
O fonte ta anexado.
- Código: Selecionar todos
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
int main()
{
int fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) {
printf("Could not open memory.\n");
return(1);
}
// Device Identification according to page 179 of spruf98f.pdf OMAP3530's Manual
volatile ulong *deviceid;
deviceid = (ulong*) mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x4830A000);
if (deviceid == MAP_FAILED) {
printf("DeviceID Mapping failed.\n");
close(fd);
return(2);
}
printf("0x4830 A204: 0x%08lx \n0x4830 A218: 0x%08lx \n ", deviceid[0x204/4], deviceid[0x218/4]);
printf("0x4830 A20C: 0x%08lx.\n\n====================================\n", deviceid[0x20C/4]);
// Pad configuration
volatile ulong *pinconf;
pinconf = (ulong*) mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x48000000);
if (pinconf == MAP_FAILED) {
printf("Pinconf Mapping failed.\n");
close(fd);
return(2);
}
// Configure Expansion header pins as input/output.
pinconf[0x2158/4] = 0x011C011C;
pinconf[0x215C/4] = 0x011C011C;
pinconf[0x2160/4] = 0x011C011C;
pinconf[0x2164/4] = 0x011C011C;
pinconf[0x2168/4] = 0x011C011C;
pinconf[0x216C/4] = 0x011C011C;
pinconf[0x2170/4] = 0x011C011C;
pinconf[0x2174/4] = 0x011C011C;
pinconf[0x2178/4] = 0x011C011C;
pinconf[0x218C/4] = 0x011C011C;
pinconf[0x2190/4] = 0x011C011C;
pinconf[0x2194/4] = 0x011C011C;
pinconf[0x2198/4] = 0x011C011C;
close(fd);
printf("0x4800 244C: 0x%08lx.\n", pinconf[0x244C/4]);
fd = open("/dev/mem", O_RDWR | O_SYNC);
// GPIO Configuration
volatile ulong *gpio;
gpio = (ulong*) mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x49050000);
if (gpio == MAP_FAILED) {
printf("GPIO Mapping failed.\n");
close(fd);
return(3);
}
// Configure all GPIO pins on bank 5 but gpio_157 as input.
// gpio[0x6034/4] = 0xFFFFFFFF;
gpio[0x6034/4] = 0xDFFFFFFF;
printf("GPIO5_OE: 0x%08lx. \t\t\t GPIO6_OE: 0x%08lx.\n", gpio[0x6034/4], gpio[8034/4]);
int c=0;
/*
// Print the state of GPIO5 and GPIO6
for(c=0;c<40000;c++) {
printf("%5d) gpio5: 0x%08lx. \t\t gpio6: 0x%08lx.\n", c, gpio[0x6038/4], gpio[0x8038/4]);
sleep(1);
}
*/
// Switch on and off gpio_157 indefinitely
for(;;) {
gpio[0x603C/4] = gpio[0x6038/4] | 0x20000000;
gpio[0x603C/4] = gpio[0x6038/4] & 0xDFFFFFFF;
}
}