From 7be3db60a0efba40a0c10a4476490a05fa62a1bc Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Thu, 17 May 2012 18:41:13 +0000 Subject: Ajout des premiers bouts de code pour les tests : test1 = prise de son via pulse audio (à l'arache avec le modèle "simple") test2 = premières illuminations avec le projo LED test3 = fade R/G/B et jeu avec les problématiques de timing test4 = à faire : Appli GTK pour assembler les tests précédents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2012-violon-leds/trunk@2 6be1fa4d-33ac-4c33-becc-79fcb3794bb6 --- tests/test1/compil.sh | 3 + tests/test1/test1.c | 121 ++++++++++++++++++++++++++++++++ tests/test2/compil.sh | 1 + tests/test2/notes.txt | 78 +++++++++++++++++++++ tests/test2/test2.c | 151 +++++++++++++++++++++++++++++++++++++++ tests/test3/compil.sh | 1 + tests/test3/test3.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/test4/test4.c | 11 +++ 8 files changed, 557 insertions(+) create mode 100755 tests/test1/compil.sh create mode 100644 tests/test1/test1.c create mode 100755 tests/test2/compil.sh create mode 100644 tests/test2/notes.txt create mode 100644 tests/test2/test2.c create mode 100755 tests/test3/compil.sh create mode 100644 tests/test3/test3.c create mode 100644 tests/test4/test4.c diff --git a/tests/test1/compil.sh b/tests/test1/compil.sh new file mode 100755 index 0000000..b54d0be --- /dev/null +++ b/tests/test1/compil.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +gcc -o test1 test1.c -lpulse-simple diff --git a/tests/test1/test1.c b/tests/test1/test1.c new file mode 100644 index 0000000..e99d2ff --- /dev/null +++ b/tests/test1/test1.c @@ -0,0 +1,121 @@ +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. + ***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include +#include + +#define BUFSIZE 1024 + +/* A simple routine calling UNIX write() in a loop */ +static ssize_t loop_write(int fd, const void*data, size_t size) { + ssize_t ret = 0; + + while (size > 0) { + ssize_t r; + + if ((r = write(fd, data, size)) < 0) + return r; + + if (r == 0) + break; + + ret += r; + data = (const uint8_t*) data + r; + size -= (size_t) r; + } + + return ret; +} + +int main(int argc, char*argv[]) { + + + /* The sample type to use */ + static const pa_sample_spec ss = { + .format = PA_SAMPLE_S16LE, + .rate = 44100, + .channels = 2 + }; + pa_simple *s = NULL; + int ret = 1; + int error; + int i,j; + float sum; + + /* Create the recording stream */ + if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) { + fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); + goto finish; + } + + j=0; + for (;;) { + uint8_t buf[BUFSIZE]; + + /* Record some data ... */ + if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) { + fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); + goto finish; + } + +//printf("DEBUG : BUFSIZE==%i\n", BUFSIZE); + sum=0; + for (i=0;i 2000 || sum < -2000) { + printf("!"); + } else { + printf("."); + } + fflush(stdout); + + //printf("%i\t%f\n", j++, sum); +/* if (printf("%f\n", sum)) { + fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno)); + goto finish; + } +*/ + /* And write it to STDOUT + if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) { + fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno)); + goto finish; + }*/ + } + + ret = 0; + +finish: + + if (s) + pa_simple_free(s); + + return ret; +} diff --git a/tests/test2/compil.sh b/tests/test2/compil.sh new file mode 100755 index 0000000..023d012 --- /dev/null +++ b/tests/test2/compil.sh @@ -0,0 +1 @@ +gcc -g -o test2 test2.c -lftdi -lrt diff --git a/tests/test2/notes.txt b/tests/test2/notes.txt new file mode 100644 index 0000000..96a702e --- /dev/null +++ b/tests/test2/notes.txt @@ -0,0 +1,78 @@ + + +ENTTEC OPEN DMX USB + +lsusb | grep FT232 +Bus 004 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC + + +On peut communiquer avec ce périphérique Série via la libftdi + +i libftdi1 - Library to control and program the FTDI USB controller + + +Dans l'ordre : + +#include + +static const int VID = 0x0403; //! FTDI Vendor ID +static const int PID = 0x6001; //! FTDI Product ID + +// One "official" DMX frame can take (1s/44Hz) = 22727272ns +#define DMX_FRAMETIME 22727272 +#define DMX_BREAK 110000 +#define DMX_MAB 16000 +#define DMX_CHANNELS 512 + +inline void ts_diffadd(struct timespec *res, struct timespec *a, struct timespec *b, struct timespec *c) { + time_t rem; + + res.tv_nsec=a.tv_nsec-b.tv_nsec+c.tv_nsec; + rem=res.tv_nsec/1e9 + res.tv_nsec=res.tv_nsec%1e9; + res.tv_sec=a.tv_sec-b.tv_sec+c.tv_sec+rem; + + if (res.tv_nsec<0 && res.tv_sec>0) res.tv_sec--; res.tv_nsec+=1e9; + if (res.tv_nsec>0 && res.tv_sec<0) res.tv_nsec-=1e9; res.tv_sec++; +} + + +ftdi_usb_find_all(&ftdi, &list, QLCFTDI::VID, QLCFTDI::PID); + +ftdi_usb_open_desc(&m_handle, QLCFTDI::VID, QLCFTDI::PID, name().toAscii(), serial().toAscii()) +ftdi_usb_reset(&m_handle) +ftdi_set_baudrate(&m_handle, 250000) +ftdi_set_line_property(&m_handle, BITS_8, STOP_BIT_2, NONE) +ftdi_setflowctrl(&m_handle, SIO_DISABLE_FLOW_CTRL) +ftdi_usb_purge_buffers(&m_handle) +ftdi_setrts(&m_handle, 0) + +frame_time.tv_sec=0; +frame_time.tv_nsec=DMX_FRAMETIME; + +// Attente initiale (juste après ouverture periph) +to_sleep.tv_sec=0; +to_sleep.tv_nsec=1e6; +nanosleep(to_sleep,NULL); + + +clock_gettime(CLOCK_MONOTONIC, now); + +ts_diffadd(to_sleep,frame_time,now,trame_begin); +nanosleep(to_sleep); + +clock_gettime(CLOCK_MONOTONIC, trame_begin); +ftdi_set_line_property2(&m_handle, BITS_8, STOP_BIT_2, NONE, BREAK_ON) +usleep(DMX_BREAK); +ftdi_set_line_property2(&m_handle, BITS_8, STOP_BIT_2, NONE, BREAK_OFF) +usleep(DMX_MAB); +m_ftdi->write(m_universe) +ftdi_write_data(&m_handle, m_universe, sizeof(m_universe)) + + + +ftdi_usb_close(&m_handle) + + + +rq : si résultat <0, affichage erreur avec ftdi_get_error_string(&m_handle) diff --git a/tests/test2/test2.c b/tests/test2/test2.c new file mode 100644 index 0000000..3b20afd --- /dev/null +++ b/tests/test2/test2.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include + +// FTDI Vendor ID +#define VID 0x0403 +// FTDI Product ID +#define PID 0x6001 + +#define DMX_CHANNELS 512 +// One "official" DMX frame can take (1s/44Hz) = 22727272ns +#define DMX_FRAMETIME 22727272 +#define DMX_BREAK 110000 +#define DMX_MAB 16000 + +#define MAX_STR 64 + +inline void ts_diffadd(struct timespec *res, struct timespec *a, struct timespec *b, struct timespec *c) { + time_t rem; + + res->tv_nsec=a->tv_nsec-b->tv_nsec+c->tv_nsec; + rem=res->tv_nsec/1000000000; + res->tv_nsec=res->tv_nsec%1000000000; + res->tv_sec=a->tv_sec-b->tv_sec+c->tv_sec+rem; + + if (res->tv_nsec<0 && res->tv_sec>0) res->tv_sec--; res->tv_nsec+=1000000000; + if (res->tv_nsec>0 && res->tv_sec<0) res->tv_nsec-=1000000000; res->tv_sec++; +} + +void e(int res, const char *funcname, struct ftdi_context *ftdi, int exit_val) { + char *reason; + + if ( res < 0 ) { + reason=ftdi_get_error_string(ftdi); + fprintf(stderr, "Error in %s : %s\n", funcname, reason); + exit(exit_val); + } + +} + +/* +struct ftdi_device_list +{ + // pointer to next entry + struct ftdi_device_list *next; + // pointer to libusb's usb_device + struct usb_device *dev; +} +*/ + +int main() { + int res; + + char *manufacturer, *description, *serial; + char universe[DMX_CHANNELS+1]; + + struct ftdi_context ftdi; + struct ftdi_device_list *devlist=NULL; + struct usb_device *dev=NULL; + + struct timespec ts_frame_time, ts_dmx_break, ts_dmx_mab, ts_to_sleep, ts_trame_begin, ts_now; + + ts_frame_time.tv_sec=0; + ts_frame_time.tv_nsec=DMX_FRAMETIME; + ts_dmx_break.tv_sec=0; + ts_dmx_break.tv_nsec=DMX_BREAK; + ts_dmx_mab.tv_sec=0; + ts_dmx_mab.tv_nsec=DMX_MAB; + + (void) memset(universe, 0, DMX_CHANNELS); + (void) memset(&ftdi, 0, sizeof(ftdi)); + universe[DMX_CHANNELS]=0; + + manufacturer=malloc(MAX_STR); + description=malloc(MAX_STR); + serial=malloc(MAX_STR); + + e(ftdi_init(&ftdi),"ftdi_init",&ftdi,10); + e(ftdi_usb_find_all(&ftdi, &devlist, VID, PID),"ftdi_usb_find_all",&ftdi,11); + + //Always take the first device + if (devlist==NULL || devlist->dev==NULL) { + fprintf(stderr, "No usb device detected (looking for 0x%04X:0x%04X)\n", VID, PID); + exit(2); + } + dev=devlist->dev; + +// fprintf(stderr, "DEBUG : next==%p\n", devlist->next); + + e(ftdi_usb_get_strings(&ftdi, dev, manufacturer, MAX_STR, description, MAX_STR, serial, MAX_STR),"ftdi_usb_get_strings",&ftdi,12); + fprintf(stderr, "Connecting to USB device ('%s','%s','%s')\n", manufacturer, description, serial); + e(ftdi_usb_open_dev(&ftdi,dev),"ftdi_usb_open_dev",&ftdi,13); + fprintf(stderr, "Connected\n"); + + //Init the device + e(ftdi_usb_reset(&ftdi),"ftdi_usb_reset",&ftdi,15); + e(ftdi_set_baudrate(&ftdi, 250000),"ftdi_set_baudrate",&ftdi,16); + e(ftdi_set_line_property(&ftdi, BITS_8, STOP_BIT_2, NONE),"ftdi_set_line_property",&ftdi,17); + e(ftdi_setflowctrl(&ftdi, SIO_DISABLE_FLOW_CTRL),"ftdi_setflowctrl",&ftdi,18); + e(ftdi_usb_purge_buffers(&ftdi),"ftdi_usb_purge_buffers",&ftdi,19); + e(ftdi_setrts(&ftdi, 0),"ftdi_setrts",&ftdi,20); + + // 1ms pause for initialization completion + ts_to_sleep.tv_sec=0; + ts_to_sleep.tv_nsec=1000000; + nanosleep(&ts_to_sleep,NULL); + + ts_trame_begin.tv_sec=0; + ts_trame_begin.tv_nsec=0; + + // Wait the end of the previous timeslot + clock_gettime(CLOCK_MONOTONIC, &ts_now); + ts_diffadd(&ts_to_sleep,&ts_frame_time,&ts_now,&ts_trame_begin); + nanosleep(&ts_to_sleep,NULL); + + clock_gettime(CLOCK_MONOTONIC, &ts_trame_begin); + + e(ftdi_set_line_property2(&ftdi, BITS_8, STOP_BIT_2, NONE, BREAK_ON),"ftdi_set_line_property2",&ftdi,30); + nanosleep(&ts_dmx_break,NULL); + e(ftdi_set_line_property2(&ftdi, BITS_8, STOP_BIT_2, NONE, BREAK_OFF),"ftdi_set_line_property2",&ftdi,31); + nanosleep(&ts_dmx_mab,NULL); + + + + // Tests + universe[2]=120; + universe[3]=120; + universe[4]=120; + + + //e(ftdi_write_data(&ftdi, universe, DMX_CHANNELS),"ftdi_write_data",&ftdi,32); + res=ftdi_write_data(&ftdi, universe, DMX_CHANNELS); + + //fprintf(stderr, "DEBUG : to_sleep=={%li,%li}\n", ts_to_sleep.tv_sec, ts_to_sleep.tv_nsec); + fprintf(stderr, "DEBUG : res==%i\n", res); +// fprintf(stderr, "DEBUG : universe==%s\n", universe); + + e(ftdi_usb_close(&ftdi),"ftdi_usb_close",&ftdi,50); + ftdi_list_free(&devlist); + ftdi_deinit(&ftdi); + + + free(manufacturer); + free(description); + free(serial); + + exit(0); +} + diff --git a/tests/test3/compil.sh b/tests/test3/compil.sh new file mode 100755 index 0000000..023d012 --- /dev/null +++ b/tests/test3/compil.sh @@ -0,0 +1 @@ +gcc -g -o test2 test2.c -lftdi -lrt diff --git a/tests/test3/test3.c b/tests/test3/test3.c new file mode 100644 index 0000000..301ea49 --- /dev/null +++ b/tests/test3/test3.c @@ -0,0 +1,191 @@ +#include +#include +#include +#include +#include + +// FTDI Vendor ID +#define VID 0x0403 +// FTDI Product ID +#define PID 0x6001 + +#define DMX_CHANNELS 6 +//#define DMX_CHANNELS 512 +//#define DMX_FRAMETIME 24000000 +#define DMX_FRAMETIME 0 +#define DMX_BREAK 110000 +#define DMX_MAB 16000 + +#define MAX_STR 64 + +inline void ts_diffadd(struct timespec *res, struct timespec *a, struct timespec *b, struct timespec *c) { + time_t rem; + + res->tv_nsec=a->tv_nsec-b->tv_nsec+c->tv_nsec; + rem=res->tv_nsec/1000000000; + res->tv_nsec=res->tv_nsec%1000000000; + res->tv_sec=a->tv_sec-b->tv_sec+c->tv_sec+rem; + + if (res->tv_nsec<0 && res->tv_sec>0) { res->tv_sec--; res->tv_nsec+=1000000000; } + if (res->tv_nsec>0 && res->tv_sec<0) { res->tv_nsec-=1000000000; res->tv_sec++; } +} + +void e(int res, const char *funcname, struct ftdi_context *ftdi, int exit_val) { + char *reason; + + if ( res < 0 ) { + reason=ftdi_get_error_string(ftdi); + fprintf(stderr, "Error in %s : %s\n", funcname, reason); + exit(exit_val); + } + +} + +/* +struct ftdi_device_list +{ + // pointer to next entry + struct ftdi_device_list *next; + // pointer to libusb's usb_device + struct usb_device *dev; +} +*/ + +int dmx_universe_write(struct ftdi_context *ftdi, char *universe, int uni_len) { + static struct timespec ts_frame_time={0,DMX_FRAMETIME},ts_dmx_break={0,DMX_BREAK}, ts_dmx_mab={0,DMX_MAB}, ts_trame_begin={0,0}; + struct timespec ts_to_sleep, ts_now; + + // http://www.opendmx.net/index.php/DMX512-A#Timings + // http://www.erwinrol.com/?s=dmx + // symbo_perdiod is 4us (250kHz) + // Full packet minimal timing : DMX_BREAK+DMX_MAB+(1+8+2)*513*symbol_period=22698us + + ftdi_async_complete(ftdi,0); + // Wait the end of the previous timeslot +/* + clock_gettime(CLOCK_MONOTONIC, &ts_now); + ts_diffadd(&ts_to_sleep,&ts_frame_time,&ts_now,&ts_trame_begin); + + //fprintf(stderr, "DEBUG : ts_to_sleep==%li.%09li\n", ts_to_sleep.tv_sec, ts_to_sleep.tv_nsec); +// ts_to_sleep.tv_sec=0; +// ts_to_sleep.tv_nsec=23000000; + nanosleep(&ts_to_sleep,NULL); + + clock_gettime(CLOCK_MONOTONIC, &ts_trame_begin); +*/ + e(ftdi_set_line_property2(ftdi, BITS_8, STOP_BIT_2, NONE, BREAK_ON),"ftdi_set_line_property2",ftdi,30); + nanosleep(&ts_dmx_break,NULL); + e(ftdi_set_line_property2(ftdi, BITS_8, STOP_BIT_2, NONE, BREAK_OFF),"ftdi_set_line_property2",ftdi,31); + nanosleep(&ts_dmx_mab,NULL); + + + //return ftdi_write_data(ftdi, universe, uni_len); + return ftdi_write_data_async(ftdi, universe, uni_len); +} + +int main() { + int i,res; + + char *manufacturer, *description, *serial; + char universe[DMX_CHANNELS+1]; + + struct ftdi_context ftdi; + struct ftdi_device_list *devlist=NULL; + struct usb_device *dev=NULL; + + struct timespec ts_to_sleep; + + (void) memset(universe, 0, sizeof(universe)); + (void) memset(&ftdi, 0, sizeof(ftdi)); + + manufacturer=malloc(MAX_STR); + description=malloc(MAX_STR); + serial=malloc(MAX_STR); + + e(ftdi_init(&ftdi),"ftdi_init",&ftdi,10); + e(ftdi_usb_find_all(&ftdi, &devlist, VID, PID),"ftdi_usb_find_all",&ftdi,11); + + //Always take the first device + if (devlist==NULL || devlist->dev==NULL) { + fprintf(stderr, "No usb device detected (looking for USB ID 0x%04X:0x%04X)\n", VID, PID); + exit(2); + } + dev=devlist->dev; + +// fprintf(stderr, "DEBUG : next==%p\n", devlist->next); + + e(ftdi_usb_get_strings(&ftdi, dev, manufacturer, MAX_STR, description, MAX_STR, serial, MAX_STR),"ftdi_usb_get_strings",&ftdi,12); + fprintf(stderr, "Connecting to USB device ('%s','%s','%s')\n", manufacturer, description, serial); + e(ftdi_usb_open_dev(&ftdi,dev),"ftdi_usb_open_dev",&ftdi,13); + fprintf(stderr, "Connected\n"); + + //Init the device + e(ftdi_usb_reset(&ftdi),"ftdi_usb_reset",&ftdi,15); + e(ftdi_set_baudrate(&ftdi, 250000),"ftdi_set_baudrate",&ftdi,16); + e(ftdi_set_line_property(&ftdi, BITS_8, STOP_BIT_2, NONE),"ftdi_set_line_property",&ftdi,17); + e(ftdi_setflowctrl(&ftdi, SIO_DISABLE_FLOW_CTRL),"ftdi_setflowctrl",&ftdi,18); + e(ftdi_usb_purge_buffers(&ftdi),"ftdi_usb_purge_buffers",&ftdi,19); + e(ftdi_setrts(&ftdi, 0),"ftdi_setrts",&ftdi,20); + + // 1ms pause for initialization completion + ts_to_sleep.tv_sec=0; + ts_to_sleep.tv_nsec=1000000; + nanosleep(&ts_to_sleep,NULL); + +// fprintf(stderr, "DEBUG : res==%i\n", res); +// fprintf(stderr, "DEBUG : universe==%s\n", universe); + //for(i=1;i<=256;i=i<<1) { + for(i=1;i<=256;i++) { + universe[2]=i-1; + universe[3]=0; + universe[4]=0; + res=dmx_universe_write(&ftdi, universe, DMX_CHANNELS); + } + //for(i=1;i<=256;i=i<<1) { + for(i=1;i<=256;i++) { + universe[2]=256-i; + universe[3]=0; + universe[4]=0; + res=dmx_universe_write(&ftdi, universe, DMX_CHANNELS); + } + //for(i=1;i<=256;i=i<<1) { + for(i=1;i<=256;i++) { + universe[2]=0; + universe[3]=i-1; + universe[4]=0; + res=dmx_universe_write(&ftdi, universe, DMX_CHANNELS); + } + //for(i=1;i<=256;i=i<<1) { + for(i=1;i<=256;i++) { + universe[2]=0; + universe[3]=256-i; + universe[4]=0; + res=dmx_universe_write(&ftdi, universe, DMX_CHANNELS); + } + //for(i=1;i<=256;i=i<<1) { + for(i=1;i<=256;i++) { + universe[2]=0; + universe[3]=0; + universe[4]=i-1; + res=dmx_universe_write(&ftdi, universe, DMX_CHANNELS); + } + //for(i=1;i<=256;i=i<<1) { + for(i=1;i<=256;i++) { + universe[2]=0; + universe[3]=0; + universe[4]=256-i; + res=dmx_universe_write(&ftdi, universe, DMX_CHANNELS); + } + + e(ftdi_usb_close(&ftdi),"ftdi_usb_close",&ftdi,50); + ftdi_list_free(&devlist); + ftdi_deinit(&ftdi); + + + free(manufacturer); + free(description); + free(serial); + + exit(0); +} + diff --git a/tests/test4/test4.c b/tests/test4/test4.c new file mode 100644 index 0000000..4d7f1c5 --- /dev/null +++ b/tests/test4/test4.c @@ -0,0 +1,11 @@ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + -- cgit v1.2.3