hhopen.c

Go to the documentation of this file.
00001 
00048 #include <dev/board.h>
00049 
00050 #include <sys/heap.h>
00051 #include <sys/thread.h>
00052 #include <sys/timer.h>
00053 #include <sys/version.h>
00054 
00055 #include <stdlib.h>
00056 #include <stdio.h>
00057 #include <string.h>
00058 #include <io.h>
00059 #include <fcntl.h>
00060 
00061 #define HHOPENVERSION "1.0.0"
00062 
00063 #define BUFFERSIZE  128
00064 
00065 #define DEV_DXM             DEV_UART0
00066 #define DEV_DXM_NAME        DEV_UART0_NAME
00067 #define DEV_DXM_SPEED_LOW   9600
00068 #define DEV_DXM_SPEED       250000
00069 
00070 #define DEV_USB             DEV_UART1
00071 #define DEV_USB_NAME        DEV_UART1_NAME
00072 #define DEV_USB_SPEED       125000
00073 
00074 typedef struct {
00075     FILE * devusb;
00076     FILE * devdxm;
00077     char connected;
00078 } CHANNEL_t;
00079 
00080 const char str_start[] PROGMEM = "starting %S";
00081 const char str_fail[] PROGMEM = "FAIL\r\n";
00082 const char str_ok[]   PROGMEM = "OK\r\n";
00083 
00084 /*
00085  * Transfer data from input stream to output stream.
00086  */
00087 void StreamCopy(FILE * ostream, FILE * istream, char *cop)
00088 {
00089     int cnt;
00090     char *buff;
00091 
00092     buff = malloc(BUFFERSIZE);
00093     while (*cop) {
00094         if ((cnt = fread(buff, 1, BUFFERSIZE, istream)) <= 0)
00095             break;
00096         if (*cop && (cnt = fwrite(buff, 1, cnt, ostream)) <= 0)
00097             break;
00098         if (*cop && fflush(ostream))
00099             break;
00100     }
00101     *cop = 0;
00102     free(buff);
00103 }
00104 
00105 /*
00106  * From DXM to USB.
00107  */
00108 THREAD(dxm2usb, arg)
00109 {
00110     CHANNEL_t *cdp = arg;
00111 //  int got;
00112 //  char *buff;
00113 
00114 //  buff = malloc(BUFFERSIZE);
00115 
00116     for(;;)
00117     {
00118         if( cdp->connected) {
00119             NutThreadSetPriority(64);
00120             /*
00121             *buff = fgetc( cdp->devdxm);
00122             fputc( *buff, cdp->devusb);
00123             */
00124             /*
00125              * copy data from DXM to USB
00126             got = _read(_fileno(cdp->devdxm), buff, BUFFERSIZE);
00127             _write(_fileno(cdp->devusb), buff, got);
00128              */
00129             StreamCopy(cdp->devusb, cdp->devdxm, &cdp->connected);
00130             NutThreadSetPriority(128);
00131         }
00132         NutThreadYield();
00133     }
00134 }
00135 
00136 /*
00137  * From USB to DXM
00138  */
00139 THREAD(usb2dxm, arg)
00140 {
00141     CHANNEL_t *cdp = arg;
00142 //  int got;
00143 //  char *buff;
00144 
00145 //    buff = malloc(BUFFERSIZE);
00146 
00147     for(;;)
00148     {
00149         if( cdp->connected) {
00150             NutThreadSetPriority(64);
00151             /*
00152             *buff = fgetc( cdp->devusb);
00153             fputc( *buff, cdp->devusb);
00154 
00155             fputc( *buff, cdp->devdxm);
00156             */
00157             //got = _read(_fileno(cdp->devusb), buff, BUFFERSIZE);
00158             /* local echo
00159              * disabled as DXM has echo itself
00160             _write(_fileno(cdp->devusb), buff, got);
00161             */
00162             // _write(_fileno(cdp->devdxm), buff, got);
00163 
00164             StreamCopy(cdp->devdxm, cdp->devusb, &cdp->connected);
00165             NutThreadSetPriority(128);
00166         }
00167         NutThreadYield();
00168     }
00169 }
00170 
00171 
00172 /*
00173  * ALIFE thread just toggling PORTF7
00174  *
00175  */
00176 THREAD(ALife, arg)
00177 {
00178     NutThreadSetPriority(64);
00179     for(;;) {
00180         PORTF ^= (1<<PF7);
00181         NutSleep( 500);
00182     }
00183 }
00184 
00185 /*
00186  * DXM control functions
00187  *
00188  */
00189 #define HHBACKL_PORT    PORTB
00190 #define HHBACKL_DDR     DDRB        /* Port init done in nutinit.c */
00191 #define HHBACKL_RED     (1<<PB6)
00192 #define HHBACKL_GREEN   (1<<PB5)
00193 #define HHBACKL_BLUE    (1<<PB7)
00194 
00195 #define HHDXM_PORT      PORTE
00196 #define HHDXM_DDR       DDRE
00197 #define HHDXM_RESET     (1<<PE7)
00198 #define hhdxm_reset_h() HHDXM_PORT |= HHDXM_RESET
00199 #define hhdxm_reset_l() HHDXM_PORT &= ~HHDXM_RESET
00200 #define HHDXM_CTS       (1<<PE3)
00201 #define HHDXM_RTS       (1<<PE2)
00202 #define hhdxm_cts_ena() HHDXM_PORT &= ~HHDXM_CTS
00203 #define hhdxm_cts_dis() HHDXM_PORT |= HHDXM_CTS
00204 #define HHDXM_BOOT0     (1<<PE6)
00205 #define hhdxm_boot0_h() HHDXM_PORT |= HHDXM_BOOT0
00206 #define hhdxm_boot0_l() HHDXM_PORT &= ~HHDXM_BOOT0
00207 
00208 void DXM_Reset( void)
00209 {
00210     hhdxm_reset_l();    /* Set DXM to RESET */
00211     hhdxm_boot0_l();    /* Prevent from starting bootloader */
00212     NutSleep( 200);     /* Sleep for 100ms) */
00213     hhdxm_reset_h();    /* Release RESET from DXM */
00214 }
00215 
00216 void DXM_Init( void)
00217 {
00218     HHDXM_DDR |= HHDXM_CTS|HHDXM_RESET|HHDXM_BOOT0; /* Set DXM control line as output */
00219     HHDXM_DDR &= ~HHDXM_RTS;                        /* Set DXM status lines as input */
00220     hhdxm_boot0_h();
00221     hhdxm_reset_l();
00222 }
00223 
00224 const char dxmstr_atz[]  PROGMEM = "ATZ\r\n";
00225 const char dxmstr_dxm1[] PROGMEM = "DIAMEX";
00226 const char dxmstr_atsb[] PROGMEM = "ATSB6\r\n";
00227 
00228 int DMX_Reconfigure( FILE * dev, FILE * debug)
00229 {
00230     char *buff;
00231     char trigger, l;
00232     u_long baud = 250000UL;
00233 
00234     buff = malloc(BUFFERSIZE);
00235 
00236     /* set baudrate 250kbaud */
00237     fputs_P(dxmstr_atsb, dev);
00238     fflush( dev);
00239     while( fgetc(dev) != '6');
00240 
00241     while( fgetc( dev) != '>');
00242     //fputs_P(PSTR("."), debug);
00243 
00244     /* restart with new baudrate */
00245     fputs_P(dxmstr_atz, dev);
00246     fflush( dev);
00247     _ioctl( _fileno(dev), UART_SETSPEED, &baud);
00248 
00249     /* wait for DIAMEX string */
00250     trigger = 1;
00251     do {
00252         fgets( buff, BUFFERSIZE, dev);
00253         fprintf_P( debug, PSTR("%s\r\n"), buff);
00254         l = strlen(buff);
00255         if( strncmp_P( buff, dxmstr_dxm1, l)==0) trigger = 0;
00256     } while( trigger);
00257     fputs(PSTR("250000\r\n"), debug);
00258 
00259     free(buff);
00260     return 0;
00261 }
00262 
00263 /*
00264  * LCD backlight control functions
00265  *
00266  */
00267 void Backlight_Init( void)
00268 {
00269     /* Set Backlight to yellow */
00270     HHBACKL_PORT |= HHBACKL_BLUE|HHBACKL_GREEN;
00271 }
00272 
00273 void Backlight_Color( int r, int g, int b)
00274 {
00275 }
00276 
00277 /*
00278  * Main application routine.
00279  *
00280  * Nut/OS automatically calls this entry after initialization.
00281  */
00282 int main(void)
00283 {
00284     CHANNEL_t cd;
00285     u_long baud = DEV_DXM_SPEED;
00286     u_long bufsz = BUFFERSIZE;
00287     char * buff = NULL;
00288     int state;
00289 #ifdef DEBUG_ISM
00290     int os = 0xff;
00291 #endif
00292 
00293     /* Init backlight of LCD */
00294     Backlight_Init();
00295     /* Initalize DXM hardware interconnection */
00296     DXM_Init();
00297 
00298     /*
00299      * Register our devices.
00300      */
00301     NutRegisterDevice(&DEV_USB, 0, 0);  /* USART for communication to USB chip */
00302     NutRegisterDevice(&DEV_DXM, 0, 0);  /* USART fpr communication to DXM module */
00303 
00304     /*
00305      * Setup the uart1 device for USB0 access.
00306      */
00307     cd.devusb = fopen(DEV_USB_NAME, "r+b");
00308     baud = DEV_USB_SPEED;
00309     _ioctl(_fileno(cd.devusb), UART_SETSPEED, &baud);
00310     _ioctl(_fileno(cd.devusb), UART_SETRXBUFSIZ, &bufsz);
00311     _ioctl(_fileno(cd.devusb), UART_SETTXBUFSIZ, &bufsz);
00312 
00313     fprintf_P(cd.devusb, PSTR("\r\nNutO/S version %s"), NutVersionString());
00314     fputs_P( PSTR("\r\nHHopen DXM USB Bridge version "HHOPENVERSION"\r\n"), cd.devusb);
00315 
00316     /*
00317      * Setup the uart0 device for DXM access.
00318      */
00319     baud = DEV_DXM_SPEED_LOW;
00320     cd.devdxm = fopen(DEV_DXM_NAME, "r+b");
00321     _ioctl(_fileno(cd.devdxm), UART_SETSPEED, &baud);
00322     _ioctl(_fileno(cd.devdxm), UART_SETRXBUFSIZ, &bufsz);
00323     _ioctl(_fileno(cd.devdxm), UART_SETTXBUFSIZ, &bufsz);
00324 
00325     /*
00326      * Start simple life-check thread toggling port F7.
00327      */
00328     NutThreadCreate("alife", ALife, NULL, 64);
00329 
00330     /*
00331      * Release DXM from RESET
00332      */
00333     DXM_Reset();
00334     hhdxm_cts_ena();
00335 
00336     /*
00337      * Talk to DXM and reconfigure it to 250000baud
00338      */
00339 //  DMX_Reconfigure( cd.devdxm, cd.devusb);
00340 
00341     /*
00342      * Start a RS232 receiver thread.
00343      */
00344     fputs_P( PSTR("start dxm2usb "), cd.devusb);
00345     if( NutThreadCreate("dxm2usb", dxm2usb, &cd, 128) == NULL)
00346         fputs_P( str_fail, cd.devusb);
00347     else
00348         fputs_P( str_ok, cd.devusb);
00349 
00350     /*
00351      * Start a RS232 sender thread.
00352      */
00353     fputs_P( PSTR("start dxm2usb "), cd.devusb);
00354     if( NutThreadCreate("usb2dxm", usb2dxm, &cd, 128) == NULL)
00355         fputs_P( str_fail, cd.devusb);
00356     else
00357         fputs_P( str_ok, cd.devusb);
00358 
00359     /*
00360      * Now loop endless for connections.
00361      */
00362     cd.connected = 0;
00363     state = 0;
00364     for (;;) {
00365         if( cd.connected == 0) {
00366 
00367 #ifdef DEBUG_ISM
00368             if( os != state) {
00369                 fprintf_P( cd.devusb, PSTR("ISM %d\r\n"), state);
00370                 os = state;
00371             }
00372 #endif
00373             switch( state)
00374             {
00375                 case 0:
00376                     buff = malloc(BUFFERSIZE);
00377                     state = 1;
00378                     break;
00379                 case 1:
00380                     fgets( buff, BUFFERSIZE, cd.devdxm);
00381                     fputs( buff, cd.devusb);
00382                     if( strlen(buff)==0)
00383                         break;
00384 
00385                     if( strncmp_P( buff, dxmstr_dxm1, strlen_P(dxmstr_dxm1))==0)
00386                         state = 2;
00387                     break;
00388                 case 2:
00389                     *buff = fgetc( cd.devdxm);
00390                     fputc( *buff, cd.devusb);
00391                     if( *buff == '>')
00392                         state = 3;
00393                     break;
00394                 case 3:
00395                     fputs_P( dxmstr_atsb, cd.devdxm);
00396                     fflush(cd.devdxm);
00397                     state = 4;
00398                     break;
00399                 case 4:
00400                     *buff = fgetc( cd.devdxm);
00401                     fputc( *buff, cd.devusb);
00402                     if( *buff == '>')
00403                         state = 5;
00404                     break;
00405                 case 5:
00406                     fputs_P( dxmstr_atz, cd.devdxm);
00407                     fflush(cd.devdxm);
00408                     baud = DEV_DXM_SPEED;
00409                     _ioctl( _fileno(cd.devdxm), UART_SETSPEED, &baud);
00410                     state = 6;
00411                     break;
00412                 case 6:
00413                     fgets( buff, BUFFERSIZE, cd.devdxm);
00414                     fputs( buff, cd.devusb);
00415                     if( strlen(buff)==0)
00416                         break;
00417 
00418                     if( strncmp_P( buff, dxmstr_dxm1, strlen_P(dxmstr_dxm1))==0)
00419                         state = 7;
00420                     break;
00421                 case 7:
00422                     *buff = fgetc( cd.devdxm);
00423                     fputc( *buff, cd.devusb);
00424                     if( *buff == '>') {
00425                         cd.connected = 1;
00426                         free(buff);
00427                     }
00428                     break;
00429                 default:
00430                     fputs_P(PSTR("ERROR ISM\r\n"), cd.devusb);
00431                     break;
00432             }
00433             NutSleep( 1);
00434         }
00435         else {
00436             NutSleep(1000);
00437         }
00438     }
00439     return 0;
00440 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/