/******************************************************************************!
* \file sinus.c
* \author Sebastien Beaugrand
* \sa http://beaugrand.chez.com/
* \copyright CeCILL 2.1 Free Software license
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <errno.h>
#include "wiring.h"
#include "common.h"
void analogSetFrequencies(int argc, char* argv[]);
extern char** gArgv;
extern double gVPeak;
struct timespec gTimeval;
struct timespec gOffset;
int gCount;
int16_t buff[N];
void sigalarm_handler(int s) {
s = s;
}
/******************************************************************************!
* \fn sampleRate
******************************************************************************/
int sampleRate()
{
double t = gTimeval.tv_sec - gOffset.tv_sec +
(gTimeval.tv_nsec - gOffset.tv_nsec) / 1000000000L;
return (gCount << M) / t;
}
/******************************************************************************!
* \fn quit
******************************************************************************/
void quit(int status)
{
if (status == EXIT_SUCCESS) {
fprintf(stderr, "Sample rate = %d Hz\n", sampleRate());
}
exit(status);
}
/******************************************************************************!
* \fn sigpipe
******************************************************************************/
void sigpipe(int sig)
{
if (sig == SIGPIPE) {
quit(EXIT_SUCCESS);
}
}
/******************************************************************************!
* \fn main
******************************************************************************/
int main(int argc, char* argv[])
{
char freqStr[16];
int freq = atoi(argv[2]);
analogSetFrequencies(argc, argv);
analogInit();
gVPeak = 51.0;
if (signal(SIGPIPE, sigpipe) == SIG_ERR) {
perror("signal");
exit(EXIT_FAILURE);
}
struct sigaction sa;
sa.sa_handler = sigalarm_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGALRM, &sa, NULL) != 0) {
perror("sigaction");
exit(EXIT_FAILURE);
}
struct itimerval it = { { 0, 1000000 / RATE }, { 0, 1000000 / RATE } };
if (setitimer(ITIMER_REAL, &it, 0) != 0) {
perror("setitimer");
exit(EXIT_FAILURE);
}
if (clock_gettime(CLOCK_REALTIME, &gTimeval) < 0) {
perror("clock_gettime");
exit(EXIT_FAILURE);
}
gOffset.tv_sec = gTimeval.tv_sec;
gOffset.tv_nsec = gTimeval.tv_nsec;
for (gCount = 0; gCount < 5000; ++gCount) {
for (int i = 0; i < N; ++i) {
if (clock_gettime(CLOCK_REALTIME, &gTimeval) < 0) {
perror("clock_gettime");
quit(EXIT_FAILURE);
}
buff[i] = analogRead(0);
if (select(0, 0, 0, 0, 0) >= 0 || errno != EINTR) {
perror("select");
quit(EXIT_FAILURE);
}
}
if (write(STDOUT_FILENO, buff, N << 1) < 0) {
perror("write");
quit(EXIT_FAILURE);
}
if (gCount < 599) {
switch (gCount) {
case 75:
gArgv[1] = "3500";
break;
case 150: // 150 = 9615 / 64 = RATE / N
gArgv[1] = "200";
break;
case 225:
gArgv[1] = "3500";
break;
case 300:
gArgv[1] = "200";
break;
case 375:
gArgv[1] = "3500";
break;
case 450:
gArgv[1] = "200";
break;
case 525:
freq = 2000;
sprintf(freqStr, "%d", freq);
gArgv[1] = freqStr;
break;
}
} else if (gCount % 100 == 99) {
freq += 100;
sprintf(freqStr, "%d", freq);
gArgv[1] = freqStr;
}
}
quit(EXIT_SUCCESS);
}