Port-hpcsh archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Few Jornada 690 questions



17.08.06 uwe%ptc.spbu.ru@localhost 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 ]
#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);
}
#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);
}


Home | Main Index | Thread Index | Old Index