Re: Few Jornada 690 questions
Adam Wysocki via ArcaBit <[email protected]> Mon, 21 Aug 2006 21:23:04 +0200 (CEST)
| Newsgroups | gmane.os.netbsd.ports.hpcsh |
|---|---|
| Message-ID | <[email protected]> |
17.08.06 [email protected] wrote: > There's no sound *card* in sh3 jornadas. There's an on-chip 8-bit DAC > and one of its channels is hooked to the speaker. You need to feed > the DAC directly from the CPU. This means that you need to have 8K > interrupts per second to play even crappy lo-fi 8KHz 8bit audio. I tried to do it in userspace (I'm new to NetBSD so writing a custom driver could be kind of challenge for now) and even managed to output some sound (and learned the hard way that securelevel greater than 0 prevents readwrite /dev/mem accesses), but it seems that there's no easy way to get the userspace code executed at 8000 Hz. NetBSD doesn't seem to have a realtime scheduler (seems strange, so maybe I'm wrong) and setitimer() and usleep() on this CPU just doesn't work at this frequency even when reniced to -20. Maximum archieved frequency, both using setitimer() and usleep(), was 32 Hz. [gophi@hpcsh ~/src]$ make test && sudo nice -n -20 ./test cc -O -o test test.c us=3122254 (should be 1000000), freq=32 (should be 100) [gophi@hpcsh ~/src]$ make test2 && sudo nice -n -20 ./test2 cc -O -o test2 test2.c us=3119995 (should be 1000000), freq=32 (should be 100) (test.c and test2.c attached) > There is on-chip DMAC that can do timed transfers using internal > counter-timer, but attempts to use it wedge the machine ~immediately. Seems promising. Have you tried it with a lower frequency than 8 kHz? Maybe it just didn't worked because of too high frequency. Do you have some details on this controller? -- [ Adam Wysocki, www.chmurka.net, GSM: +48 514 710 213 ] [ Software Development Department, ArcaBit Sp. z o.o. ] [ Ul. Fortuny 9 :: 01-339 Warszawa :: www.arcabit.com ]
test.c
(text/x-csrc, 878 B)
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <sys/time.h>
#define FREQ 100
#define NUM FREQ
volatile int i = 0;
void sighnd(int signo)
{
i++;
}
main()
{
struct itimerval it;
struct sigaction sa;
struct timeval tv[2];
unsigned long us;
it.it_value.tv_sec = 0;
it.it_value.tv_usec = 1000000L / FREQ;
memcpy(&it.it_interval, &it.it_value, sizeof(it.it_interval));
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sighnd;
sigaction(SIGALRM, &sa, NULL);
gettimeofday(&tv[0], NULL);
setitimer(ITIMER_REAL, &it, NULL);
while(i < NUM)
pause();
gettimeofday(&tv[1], NULL);
us = (tv[1].tv_sec - tv[0].tv_sec) * 1000000L + (tv[1].tv_usec - tv[0].tv_usec);
printf("us=%lu (should be %lu), freq=%lu (should be %lu)\n",
us, NUM * 1000000L / FREQ, 1000000L * NUM / us, FREQ);
}
test2.c
(text/x-csrc, 505 B)
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#define FREQ 100
#define NUM FREQ
main()
{
struct timeval tv[2];
int i = 0;
unsigned long us;
gettimeofday(&tv[0], NULL);
while(i++ < NUM)
usleep(1000000L / (FREQ * NUM));
gettimeofday(&tv[1], NULL);
us = (tv[1].tv_sec - tv[0].tv_sec) * 1000000L + (tv[1].tv_usec - tv[0].tv_usec);
printf("us=%lu (should be %lu), freq=%lu (should be %lu)\n",
us, NUM * 1000000L / FREQ, 1000000L * NUM / us, FREQ);
}