Advertisement
Guest User

bstamp_run.cpp

a guest
Mar 5th, 2013
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.96 KB | None | 0 0
  1. /* Basic Stamp communication */
  2.  
  3. #define _GNU_SOURCE
  4.  
  5. enum {
  6.   MODEL_BS2,
  7.   MODEL_BS2e,
  8.   MODEL_BS2sx,
  9.   MODEL_BS2p24,
  10.   MODEL_BS2p40,
  11.   MODEL_BS2pe24,
  12.   MODEL_BS2pe40,
  13.   MODEL_UNKNOWN
  14. };
  15.  
  16. char * model_names[MODEL_UNKNOWN + 1] = {
  17.   "Basic Stamp 2",
  18.   "Basic Stamp 2e",
  19.   "Basic Stamp 2sx",
  20.   "Basic Stamp 2p24",
  21.   "Basic Stamp 2p40",
  22.   "Basic Stamp 2pe24",
  23.   "Basic Stamp 2pe40",
  24.   "UNKNOWN"
  25. };
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <signal.h>
  31. #include <termios.h>
  32. #include <unistd.h>
  33. #include <fcntl.h>
  34. //#include <sys/types.h>
  35. //#include <sys/stat.h>
  36. #include <sys/ioctl.h>
  37. #include <errno.h>
  38.  
  39. /*#define DEBUG          1*/
  40.  
  41. //#define TRUE           1
  42. #define FALSE          0
  43. #define STATE_CRITICAL -13
  44.  
  45. //#define OK             0
  46. //#define ERROR          -1
  47.  
  48. #define DEFAULT_TIMEOUT 10
  49.  
  50. #define BUFFER_SIZE    1024
  51.  
  52. extern int errno;
  53.  
  54. //int show_usage=FALSE;
  55.  
  56. char *device="/dev/bstamp";
  57. //int probe_number=1;
  58. //int battery_ok=FALSE;
  59. int timeout=DEFAULT_TIMEOUT;
  60. //int invert_test=FALSE;
  61. //int use_celsius=FALSE;
  62.  
  63. int model, firmware_version;
  64.  
  65. char sendbuf[BUFFER_SIZE];
  66. char recvbuf[BUFFER_SIZE];
  67. char *tmpbuf;
  68. int fd;
  69. struct termios oldtios;
  70. struct termios newtios;
  71. int debug_loop_done;
  72.  
  73. void BS2_comm_init(void);
  74. void BS2_comm_halt(void);
  75. void BS2_reset(void);
  76. int BS2_id(void);
  77. // void BS2_write(char * str);
  78. void BS2_read(char * str, int count);
  79. void BS2_sendfile(void);
  80. void BS2_sendfile(char * fname);
  81. void *timeout_handler(int sig);
  82. void *control_c_handler(int sig);
  83.  
  84. int main(int argc, char **argv)
  85. {
  86.     int ready_for_debug=0;
  87.     char recvchar;
  88.  
  89.     if (argc == 2)
  90.     {
  91.     if (strlen(argv[1])>4) // use the filename (like infile.tok) to program the Stamp
  92.     {
  93.         BS2_comm_init();
  94.         if (BS2_id())
  95.         {
  96.             if (model!=MODEL_BS2)
  97.             {
  98.                 unsigned char program_slot=0;
  99.                 write(fd, &program_slot, 1); // send program slot
  100.                 tcflush(fd,TCIFLUSH);
  101.                 usleep(500000);
  102.             }
  103.             fprintf(stderr, "Basic Stamp detected!");
  104.             fprintf(stderr, "Model: %s\n", model_names[model]);
  105.             fprintf(stderr, "Firmware version in BCD = %d\n", firmware_version);
  106.             BS2_sendfile(argv[1]);
  107.             ready_for_debug=1; // now we know the stamp is programmed and debugging
  108.         }
  109.         else
  110.         {
  111.             fprintf(stderr, "Error: No BASIC Stamp identified!\n");
  112.             fprintf(stderr, "Probably the stamp isn't connected, perhaps your stamp version isn't supported?\n");
  113.             fprintf(stderr, "Try looking at the help, try '");
  114.             fprintf(stderr, argv[0]);
  115.             fprintf(stderr, " -h' for more information.\n");
  116.             exit(1);
  117.         }
  118.     }
  119.     else if (argv[1][0]=='-')
  120.     {
  121.         if (argv[1][1]=='h'|argv[1][1]=='?')
  122.         {
  123.             fprintf(stderr, "\nBasic Stamp Linux Programmer / Debugger\n\n");
  124.             fprintf(stderr, "This program is used to program and run a basic stamp.\n");
  125.             fprintf(stderr, "Before it can be used, some simple setup must be done (see below).\n");
  126.             fprintf(stderr, "For more information about the Basic Stamp, see http://www.parallax.com\n\n");
  127.             fprintf(stderr, "This is a modified version of bstamp available at http://bstamp.sourceforge.net\n");
  128.             fprintf(stderr, "Options:\n");
  129.             fprintf(stderr, "\t-h or -? : this help listing\n");
  130.             fprintf(stderr, "\t-v : the program version\n");
  131.             fprintf(stderr, "\t-a : about the program (brief history)\n");
  132.             fprintf(stderr, "\t-s : use stdin instead of INFILE.TOK\n");
  133.             fprintf(stderr, "\talternately, to use stdin do not include any other arguments.\n\n");
  134.             fprintf(stderr, "The basic stamp must be plugged into a local serial (COM) port.\n");
  135.             fprintf(stderr, "Examples here use /dev/ttyS0 as the serial port,.\n");
  136.             fprintf(stderr, " but you may need to use something else (like /dev/ttyS1).\n");
  137.             fprintf(stderr, "A symlink named 'bstamp' in /dev must point to the com port you wish to use.\n");
  138.             fprintf(stderr, "This can be done with 'ln -s /dev/ttyS0 /dev/bstamp'.\n");
  139.             fprintf(stderr, "If the serial port doesn't work, you might try 'MAKEDEV /dev/ttyS0'\n");
  140.             fprintf(stderr, "You may need to be root to accomplish this, try 'su' to become root.\n");
  141.             fprintf(stderr, "When done with MAKEDEV and creating the symlink, type exit.\n\n");
  142.             fprintf(stderr, "You must include a tokenized program when calling this program.\n");
  143.             fprintf(stderr, "First run 'bstamp_tokenize INFILE.TXT OUTFILE.TOK' to make the tokenized program.\n");
  144.             fprintf(stderr, "Next run 'cat INFILE.TOK | bstamp_run'\n\n");
  145.             fprintf(stderr, "Standard Usage: bstamp_run INFILE.TOK\n");
  146.             fprintf(stderr, " Or:\n cat INFILE.TOK | bstamp_run\n Or:\n cat INFILE.BS2 | bstamp_tokenizer | bstamp_run\n");
  147.             exit(0);
  148.         }
  149.         else if (argv[1][1]=='v')
  150.         {
  151.             fprintf(stderr, "bstamp_run version 2004-05-12\n current filename: ");
  152.             fprintf(stderr, argv[0]);
  153.             fprintf(stderr, "\n");
  154.             exit(0);
  155.         }
  156.         else if (argv[1][1]=='a')
  157.         {
  158.             fprintf(stderr, "Modified by Francis Esmonde-White [[email protected]] 2004-05-12\n");
  159.             fprintf(stderr, "notes: added support for BS2p, BS2pe\n");
  160.             fprintf(stderr, "\talso rearranged the code so that future stamps can be more easily added\n");
  161.             fprintf(stderr, "\trenamed internal functions to start with BS2_\n");
  162.             fprintf(stderr, "\tnow using STDIN as the .TOK file location if no arguments are given\n");
  163.             fprintf(stderr, "Stamps recognized by this version:\n");
  164.             fprintf(stderr, "\tBS2\n");
  165.             fprintf(stderr, "\tBS2e\n");
  166.             fprintf(stderr, "\tBS2sx\n");
  167.             fprintf(stderr, "\tBS2p (BS2p24 and BS2p40)\n");
  168.             fprintf(stderr, "\tBS2pe (BS2pe24 and BS2pe40)\n");
  169.             fprintf(stderr, "Known bug: Outputs an unexpected letter after receiving CTRL-C for shutdown.\n");
  170.             fprintf(stderr, "TODO: implement program slot selection in programming phase, currently programming slot 0.\n");
  171.             exit(0);
  172.         }
  173.         else if (argv[1][1]=='s') // use the standard input to program the stamp
  174.         {
  175.             BS2_comm_init();
  176.             if (BS2_id())
  177.             {
  178.                 fprintf(stderr, "Basic Stamp detected!");
  179.                 fprintf(stderr, "Model: %s\n", model_names[model]);
  180.                 fprintf(stderr, "Firmware version in BCD = %d\n", firmware_version);
  181.                 BS2_sendfile();
  182.                 ready_for_debug=1; // now we know the stamp is programmed and debugging
  183.             }
  184.             else
  185.             {
  186.                 fprintf(stderr, "Error: No BASIC Stamp identified!\n");
  187.                 fprintf(stderr, "Probably the stamp isn't connected, perhaps your stamp version isn't supported?\n");
  188.                 fprintf(stderr, "Try looking at the help, try '");
  189.                 fprintf(stderr, argv[0]);
  190.                 fprintf(stderr, " -h' for more information.\n");
  191.                 exit(1);
  192.             }
  193.         }
  194.         else
  195.         {
  196.             fprintf(stderr, argv[0]);
  197.             fprintf(stderr, ": -- invalid call\n");
  198.             fprintf(stderr, "Try looking at the help, try '");
  199.             fprintf(stderr, argv[0]);
  200.             fprintf(stderr, " -h' for more information.\n");
  201.             exit(0);
  202.         }
  203.     }
  204.     else
  205.     {
  206.         fprintf(stderr, argv[0]);
  207.         fprintf(stderr, ": -- invalid call\n");
  208.         fprintf(stderr, "Try looking at the help, try '");
  209.         fprintf(stderr, argv[0]);
  210.         fprintf(stderr, " -h' for more information.\n");
  211.         exit(0);
  212.     }
  213.     }
  214.     else if (argc==1) // use the standard input to program the stamp
  215.     {
  216.         BS2_comm_init();
  217.         if (BS2_id())
  218.         {
  219.             if (model!=MODEL_BS2)
  220.             {
  221.                 unsigned char program_slot=0;
  222.                 write(fd, &program_slot, 1); // send program slot
  223.                 tcflush(fd,TCIFLUSH);
  224.                 usleep(500000);
  225.             }
  226.             fprintf(stderr, "Basic Stamp detected!");
  227.             fprintf(stderr, "Model: %s\n", model_names[model]);
  228.             fprintf(stderr, "Firmware version in BCD = %d\n", firmware_version);
  229.  
  230.             //int test_read=-2;
  231.             //test_read = read(fd, recvbuf, 18);
  232.             //fprintf(stderr, "Data read: %d bytes\n",test_read);
  233.             //fprintf(stderr, "String: %s", recvbuf);
  234.  
  235.             BS2_sendfile();
  236.             ready_for_debug=1; // now we know the stamp is programmed and debugging
  237.         }
  238.         else
  239.         {
  240.             fprintf(stderr, "Error: No BASIC Stamp identified!\n");
  241.             fprintf(stderr, "Probably the stamp isn't connected, perhaps your stamp version isn't supported?\n");
  242.             fprintf(stderr, "Try looking at the help, try '");
  243.             fprintf(stderr, argv[0]);
  244.             fprintf(stderr, " -h' for more information.\n");
  245.             exit(1);
  246.         }
  247.     }
  248.     else
  249.     {
  250.         fprintf(stderr, argv[0]);
  251.         fprintf(stderr, ": -- invalid call\n");
  252.         fprintf(stderr, "Try looking at the help, try '");
  253.         fprintf(stderr, argv[0]);
  254.         fprintf(stderr, " -h' for more information.\n");
  255.         exit(0);
  256.     }
  257.  
  258.  
  259.   if (ready_for_debug)
  260.   {
  261.     int num_read=0;
  262.  
  263.     fprintf(stderr, "DEBUG OUTPUT:     (Press [Control]-[C] to complete sequence)\n");
  264.     fprintf(stderr, "_____________________________________________________________________\n");
  265.     fflush(stderr);
  266.  
  267.     signal(SIGINT,(sighandler_t)control_c_handler);
  268.     alarm(0);
  269.     debug_loop_done = 0;
  270.         do
  271.     {
  272.       if (read(fd, &recvchar, 1))
  273.       {
  274.         printf("%c", recvchar);
  275.  
  276.         /* Take into account DOS EOL: */
  277.         if (recvchar == '\r')
  278.           printf("\n");
  279.  
  280.         fflush(stdout);
  281.       }
  282.  
  283.       /*
  284.       // TODO !!!
  285.       // ADD THE ABILITY TO COMBINE STDIN FROM THE KEYBOARD TO THE DEBUGGER
  286.       //    TO HAVE COMMAND-LINE DEBUGGER STAMP INTERACTION
  287.       // THIS CODE IS CURRENTLY NON-FUNCTIONAL. THE IDEA WAS TO USE IT AS FOLLOWS:
  288.       //    cat hw.bs2 | ./bstamp_tokenize | ./bstamp_run <&0
  289.       // TO APPEND THE STDIN TO THE bstamp_runu command.
  290.  
  291.       if (num_read=fread(sendbuf, 1, BUFFER_SIZE, stdin)) // COMMUNICATE BACK TO STAMP
  292.       {
  293.             write(fd, sendbuf, num_read);
  294.             tcflush(fd,TCIFLUSH);
  295.             usleep(500000);
  296.             //BS2_read(recvbuf, 18); // read echo
  297.       }
  298.       */
  299.     }
  300.         while (!debug_loop_done);
  301.  
  302.     /* Complete sequence: */
  303.  
  304.     write(fd, "\0", 1);
  305.  
  306.     BS2_comm_halt();
  307.     return 0;
  308.   }
  309.   else
  310.   {
  311.     return 1;
  312.   }
  313. }
  314.  
  315. void BS2_comm_init() {
  316.   /*
  317.     setup timeout handlers,
  318.     save com port settings,
  319.     set com port settings
  320.   */
  321.  
  322.     /* catch timeouts */
  323.     signal(SIGALRM,(sighandler_t)timeout_handler);
  324.     alarm(0);
  325.  
  326.     /* open COM port */
  327.     fd=open(device,O_RDWR | O_NOCTTY);
  328.     if(fd<0){
  329.         fprintf(stderr, "Error: Could not open %s for reading/writing!\n",device);
  330.         exit(STATE_CRITICAL);
  331.             }
  332.  
  333.     /* save current COM port settings */
  334.     tcgetattr(fd,&oldtios);
  335.  
  336.     /* set new COM port settings */
  337.     newtios.c_cflag=B9600 | CS8 | CLOCAL | CREAD;
  338.     newtios.c_iflag=IGNPAR;
  339.     newtios.c_oflag=0;
  340.     newtios.c_lflag=0;
  341.     newtios.c_line=0;
  342.     newtios.c_cc[VMIN]=0;
  343.     newtios.c_cc[VTIME]=5;
  344.     tcsetattr(fd,TCSANOW,&newtios);
  345.  
  346. }
  347.  
  348. void BS2_comm_halt(void)
  349. {
  350.  
  351.     fprintf(stderr, "\nShutting down communication!\n");
  352.  
  353.     /* restore original COM port settings and close it */
  354.     tcsetattr(fd,TCSANOW,&oldtios);
  355.     close(fd);
  356.  
  357.     /* reset alarm */
  358.     alarm(0);
  359. }
  360.  
  361. void BS2_reset()
  362. {
  363.   /*
  364.     DTR & Tx High for 2ms,
  365.     DTR Low & Tx High for 36 ms,
  366.     DTR & Tx Low for 20 ms,
  367.     Flush buffer
  368.   */
  369.  
  370.     int dtr_flag;
  371.  
  372.     /* From BASIC Stamp Programming Protocol, page 5: */
  373.  
  374.     /* 1. set DTR high */
  375.     dtr_flag = TIOCM_DTR;
  376.     ioctl(fd, TIOCMBIS, &dtr_flag);
  377.  
  378.     /* 2. Set break condition on TX */
  379.     ioctl(fd, TIOCSBRK, 4);
  380.  
  381.     /* 3. Pause for at least 2 ms: */
  382.     usleep(2000);
  383.  
  384.     /* 4. Set DTR low: */
  385.     dtr_flag = TIOCM_DTR;
  386.     ioctl(fd, TIOCMBIC, &dtr_flag);
  387.  
  388.     /* 5. Pause for at least 36 ms: */
  389.     usleep(36000);
  390.  
  391.     /* 6. Clear break condition on TX */
  392.     ioctl(fd, TIOCCBRK, 4);
  393.  
  394.     /* 7. Pause for approximately 20 ms */
  395.     usleep(20000);
  396.  
  397.     /* ... and flush receive buffer: */
  398.     tcflush(fd,TCIFLUSH);
  399. }
  400.  
  401. int BS2_id()
  402. {
  403.   /*
  404.     reset the stamp,
  405.     try the various stamp recognition sequences,
  406.     set the type and version,
  407.     return 1 if good, 0 otherwise
  408.   */
  409.  
  410.     char snd;
  411.     model = MODEL_UNKNOWN;
  412.     firmware_version = -1;
  413.  
  414.   /* check for BS2 */
  415.     BS2_reset();
  416.  
  417.     snd='B';
  418.     /* Send the identification request character */
  419.     if (write(fd,&snd,1))
  420.     {
  421.     #ifdef DEBUG
  422.             fprintf(stderr, "Write succeeded (%d = %c)\n", snd, snd);
  423.     #endif
  424.     }
  425.  
  426.     /* Enable timeout alarm: */
  427.     alarm(timeout);
  428.  
  429.     /* Receive and discard echo: */
  430.     BS2_read(recvbuf, 1);
  431.     BS2_read(recvbuf, 1);
  432.  
  433.     /* Disable timeout alarm: */
  434.     alarm(0);
  435.     if (recvbuf[0]==char(190))
  436.     {
  437.         snd='S';
  438.         /* Send the identification request character */
  439.         if (write(fd,&snd,1))
  440.         {
  441.         #ifdef DEBUG
  442.             fprintf(stderr, "Write succeeded (%d = %c)\n", snd, snd);
  443.         #endif
  444.         }
  445.  
  446.         /* Enable timeout alarm: */
  447.         alarm(timeout);
  448.  
  449.         /* Receive and discard echo: */
  450.         BS2_read(recvbuf, 1);
  451.         BS2_read(recvbuf, 1);
  452.  
  453.         /* Disable timeout alarm: */
  454.         alarm(0);
  455.         if (recvbuf[0]==char(173))
  456.         {
  457.             snd='2';
  458.             /* Send the identification request character */
  459.             if (write(fd,&snd,1))
  460.             {
  461.             #ifdef DEBUG
  462.                 fprintf(stderr, "Write succeeded (%d = %c)\n", snd, snd);
  463.             #endif
  464.             }
  465.  
  466.             /* Enable timeout alarm: */
  467.             alarm(timeout);
  468.  
  469.             /* Receive and discard echo: */
  470.             BS2_read(recvbuf, 1);
  471.             BS2_read(recvbuf, 1);
  472.  
  473.             /* Disable timeout alarm: */
  474.             alarm(0);
  475.             if (recvbuf[0]==char(206))
  476.             {
  477.                 snd=0;
  478.                 /* Send the identification request character */
  479.                 if (write(fd,&snd,1))
  480.                 {
  481.                 #ifdef DEBUG
  482.                     fprintf(stderr, "Write succeeded (%d = %c)\n", snd, snd);
  483.                 #endif
  484.                 }
  485.  
  486.                 /* Enable timeout alarm: */
  487.                 alarm(timeout);
  488.  
  489.                 /* Receive and discard echo: */
  490.                 BS2_read(recvbuf, 1);
  491.                 BS2_read(recvbuf, 1);
  492.  
  493.                 /* Disable timeout alarm: */
  494.                 alarm(0);
  495.                 firmware_version = recvbuf[0];
  496.                 model = MODEL_BS2;
  497.             }
  498.         }
  499.     }
  500.  
  501.   /* end BS2 check */
  502.  
  503.   /* check for BS2e */
  504.   if (model==MODEL_UNKNOWN)
  505.   {
  506.     BS2_reset();
  507.  
  508.     snd='e';
  509.     /* Send the identification request character */
  510.     if (write(fd,&snd,1))
  511.     {
  512.     #ifdef DEBUG
  513.             fprintf(stderr, "Write succeeded (%d = %c)\n", snd, snd);
  514.     #endif
  515.     }
  516.  
  517.     /* Enable timeout alarm: */
  518.     alarm(timeout);
  519.  
  520.     /* Receive and discard echo: */
  521.     BS2_read(recvbuf, 1);
  522.     BS2_read(recvbuf, 1);
  523.  
  524.     /* Disable timeout alarm: */
  525.     alarm(0);
  526.     if (recvbuf[0]=='e')
  527.     {
  528.         firmware_version = 10;
  529.         model = MODEL_BS2e;
  530.     }
  531.   }
  532.   /* end BS2e check */
  533.  
  534.   /* check for BS2sx */
  535.   if (model==MODEL_UNKNOWN)
  536.   {
  537.     BS2_reset();
  538.  
  539.     snd='X';
  540.     /* Send the identification request character */
  541.     if (write(fd,&snd,1))
  542.     {
  543.     #ifdef DEBUG
  544.             fprintf(stderr, "Write succeeded (%d = %c)\n", snd, snd);
  545.     #endif
  546.     }
  547.  
  548.     /* Enable timeout alarm: */
  549.     alarm(timeout);
  550.  
  551.     /* Receive and discard echo: */
  552.     BS2_read(recvbuf, 1);
  553.     BS2_read(recvbuf, 1);
  554.  
  555.     /* Disable timeout alarm: */
  556.     alarm(0);
  557.     if (recvbuf[0]=='X')
  558.     {
  559.         firmware_version = 10;
  560.         model = MODEL_BS2sx;
  561.     }
  562.     else if (recvbuf[0]=='Y')
  563.     {
  564.         firmware_version = 11;
  565.         model = MODEL_BS2sx;
  566.     }
  567.     else if (recvbuf[0]=='Z')
  568.     {
  569.         firmware_version = 12;
  570.         model = MODEL_BS2sx;
  571.     }
  572.   }
  573.   /* end BS2sx check */
  574.  
  575.   /* check for BS2p */
  576.   if (model==MODEL_UNKNOWN)
  577.   {
  578.     BS2_reset();
  579.  
  580.     snd='P';
  581.     /* Send the identification request character */
  582.     if (write(fd,&snd,1))
  583.     {
  584.     #ifdef DEBUG
  585.             fprintf(stderr, "Write succeeded (%d = %c)\n", snd, snd);
  586.     #endif
  587.     }
  588.  
  589.     /* Enable timeout alarm: */
  590.     alarm(timeout);
  591.  
  592.     /* Receive and discard echo: */
  593.     BS2_read(recvbuf, 1);
  594.     BS2_read(recvbuf, 1);
  595.  
  596.     /* Disable timeout alarm: */
  597.     alarm(0);
  598.     if (recvbuf[0]=='p')
  599.     {
  600.         firmware_version = 10;
  601.         model = MODEL_BS2p24;
  602.     }
  603.     else if (recvbuf[0]=='q')
  604.     {
  605.         firmware_version = 11;
  606.         model = MODEL_BS2p24;
  607.     }
  608.     else if (recvbuf[0]=='r')
  609.     {
  610.         firmware_version = 12;
  611.         model = MODEL_BS2p24;
  612.     }
  613.     else if (recvbuf[0]=='s')
  614.     {
  615.         firmware_version = 13;
  616.         model = MODEL_BS2p24;
  617.     }
  618.     else if (recvbuf[0]=='P')
  619.     {
  620.         firmware_version = 10;
  621.         model = MODEL_BS2p40;
  622.     }
  623.     else if (recvbuf[0]=='Q')
  624.     {
  625.         firmware_version = 11;
  626.         model = MODEL_BS2p40;
  627.     }
  628.     else if (recvbuf[0]=='R')
  629.     {
  630.         firmware_version = 12;
  631.         model = MODEL_BS2p40;
  632.     }
  633.     else if (recvbuf[0]=='S')
  634.     {
  635.         firmware_version = 13;
  636.         model = MODEL_BS2p40;
  637.     }
  638.   }
  639.   /* end BS2p check */
  640.  
  641.   /* check for BS2pe */
  642.   if (model==MODEL_UNKNOWN)
  643.   {
  644.     BS2_reset();
  645.  
  646.     snd='I';
  647.     /* Send the identification request character */
  648.     if (write(fd,&snd,1))
  649.     {
  650.     #ifdef DEBUG
  651.             fprintf(stderr, "Write succeeded (%d = %c)\n", snd, snd);
  652.     #endif
  653.     }
  654.  
  655.     /* Enable timeout alarm: */
  656.     alarm(timeout);
  657.  
  658.     /* Receive and discard echo: */
  659.     BS2_read(recvbuf, 1);
  660.     BS2_read(recvbuf, 1);
  661.  
  662.     /* Disable timeout alarm: */
  663.     alarm(0);
  664.     if (recvbuf[0]=='i')
  665.     {
  666.         firmware_version = 10;
  667.         model = MODEL_BS2pe24;
  668.     }
  669.     else if (recvbuf[0]=='j')
  670.     {
  671.         firmware_version = 11;
  672.         model = MODEL_BS2pe24;
  673.     }
  674.     else if (recvbuf[0]=='k')
  675.     {
  676.         firmware_version = 12;
  677.         model = MODEL_BS2pe24;
  678.     }
  679.     else if (recvbuf[0]=='I')
  680.     {
  681.         firmware_version = 10;
  682.         model = MODEL_BS2pe40;
  683.     }
  684.     else if (recvbuf[0]=='J')
  685.     {
  686.         firmware_version = 11;
  687.         model = MODEL_BS2pe40;
  688.     }
  689.     else if (recvbuf[0]=='K')
  690.     {
  691.         firmware_version = 12;
  692.         model = MODEL_BS2pe40;
  693.     }
  694.   }
  695.   /* end BS2pe check */
  696.   if (model==MODEL_UNKNOWN) return 0;
  697.   else return 1;
  698. }
  699.  
  700. /*
  701. void BS2_write(char * str)
  702. {
  703.   if (write(fd,str,strlen(str)) )
  704.   {
  705.     #ifdef DEBUG
  706.         fprintf(stderr, "Write succeeded [ %s ]\n", str);
  707.     #endif
  708.   }
  709.   usleep(20000);
  710. }
  711. */
  712.  
  713. void BS2_read(char * str, int count)
  714. {
  715.   int i, num_got;
  716.   char chr;
  717.  
  718.   num_got = 0;
  719.  
  720.   for (i = 0; i < count; i++)
  721.   {
  722.     if (!read(fd,&chr,1))
  723.     {
  724.       str[i] = '\0';
  725.     }
  726.     else
  727.     {
  728.       str[i] = chr;
  729.       num_got++;
  730.     }
  731.   }
  732.  
  733.   str[i] = '\0';
  734.  
  735.   #ifdef DEBUG
  736.     fprintf(stderr, "RECEIVED %d BYTES:  %s\n", num_got, str);
  737.     for (i = 0; i < num_got; i++)
  738.     {
  739.       fprintf(stderr, "%4d = %d\n", i, (unsigned char) str[i]);
  740.     }
  741.     fprintf(stderr, "\n");
  742.   #endif
  743. }
  744.  
  745. void BS2_sendfile()
  746. {
  747.   int num_read;
  748.   char buf[18];
  749.   char recvbuf[18];
  750.   char recvchar;
  751.  
  752. if (model = MODEL_BS2)
  753. {
  754.     do
  755.     {
  756.         num_read = fread(buf, 1, 18, stdin);
  757.         #ifdef DEBUG
  758.         fprintf(stderr, "Assuming .TOK file on stdin\n", num_read);
  759.         fprintf(stderr, "Read %d bytes from file...\n", num_read);
  760.         #endif
  761.  
  762.         if (num_read > 0)
  763.         {
  764.             write(fd, buf, num_read);
  765.             tcflush(fd,TCIFLUSH);
  766.             usleep(500000);
  767.             BS2_read(recvbuf, 18); // read echo
  768.             BS2_read(&recvchar, 1); // ack
  769.             fprintf(stderr, "Ack = %d\n", recvchar);
  770.         }
  771.     }
  772.     while (num_read > 0);
  773. }
  774. else if(model!=MODEL_UNKNOWN) // BS2e, BS2sx, BS2p, BS2pe
  775. {
  776.     fcntl(fd,F_SETFD,O_FSYNC);
  777.     do
  778.     {
  779.         num_read = fread(buf, 1, 18, stdin);
  780.         #ifdef DEBUG
  781.         fprintf(stderr, "Assuming .TOK file on stdin\n");
  782.         fprintf(stderr, "Read %d bytes from .TOK file...\n", num_read);
  783.         #endif
  784.  
  785.         if (num_read > 0)
  786.         {
  787.  
  788.             fprintf(stderr, "%d characters transmitted\n", TEMP_FAILURE_RETRY (write(fd, buf, num_read)));  // send 18-byte packet
  789.  
  790.             tcflush(fd,TCIFLUSH);
  791.             usleep(500000);
  792.  
  793.  
  794.             int read_sz=read(fd, recvbuf, num_read); // read and discard 18-byte packet
  795.  
  796.             fprintf(stderr, "%d characters echoed\n",read_sz);
  797.             read_sz=read(fd, &recvchar, 1); // read ack byte
  798.  
  799.  
  800.             if (recvchar==1) // handle Communication error
  801.             {
  802.                 fprintf(stderr, "Ack = %d\n", recvchar); // print ack byte
  803.                 fprintf(stderr, "Error: Communication error while programming stamp, try again\n");
  804.                 exit(1);
  805.             }
  806.             else if (recvchar==2) // handle EEPROM error
  807.             {
  808.                 fprintf(stderr, "Ack = %d\n", recvchar); // print ack byte
  809.                 fprintf(stderr, "Error: EEPROM error.\n");
  810.                 fprintf(stderr, "If this happens consistently, there may be a problem with your stamp.\n");
  811.                 exit(1);
  812.             }
  813.             else if (recvchar!=0)
  814.             {
  815.                 fprintf(stderr, "Ack = %d\n", recvchar); // print ack byte
  816.                 fprintf(stderr, "Error: Unknown error while programming stamp!\n");
  817.                 exit(1);
  818.             }
  819.         }
  820.     }
  821.     while (num_read > 0);
  822. }
  823. else
  824. {
  825.     fprintf(stderr, "Error: Basic Stamp model not recognized when trying to upload\n");
  826.     exit(1);
  827. }
  828.  
  829. }
  830.  
  831. void BS2_sendfile(char * fname)
  832. {
  833.   int in_fd, num_read;
  834.   unsigned char buf[18];
  835.   unsigned char recvbuf[18];
  836.   unsigned char recvchar;
  837.  
  838. if (model = MODEL_BS2)
  839. {
  840.     in_fd = open(fname, O_RDONLY);
  841.     if (in_fd == -1)
  842.     {
  843.         fprintf(stderr, "Error loading %s!\n", fname);
  844.         exit(1);
  845.     }
  846.  
  847.     do
  848.     {
  849.         num_read = read(in_fd, buf, 18);
  850.         #ifdef BUG
  851.         fprintf(stderr, "Read %d bytes from file...\n", num_read);
  852.         #endif
  853.  
  854.         if (num_read > 0)
  855.         {
  856.             write(fd, buf, num_read);
  857.             tcflush(fd,TCIFLUSH);
  858.             usleep(500000);
  859.             read(fd, recvbuf, 18); // num_read);
  860.             read(fd, &recvchar, 1);
  861.             fprintf(stderr, "Ack = %d\n", recvchar);
  862.         }
  863.     }
  864.     while (num_read > 0);
  865.  
  866.     close(in_fd);
  867. }
  868. else if(model!=MODEL_UNKNOWN) // BS2e, BS2sx, BS2p, BS2pe
  869. {
  870.     in_fd = open(fname, O_RDONLY);
  871.     if (in_fd == -1)
  872.     {
  873.         fprintf(stderr, "Error loading %s!\n", fname);
  874.         exit(1);
  875.     }
  876.  
  877.     do
  878.     {
  879.         num_read = read(in_fd, buf, 18);
  880.         #ifdef BUG
  881.         fprintf(stderr, "Read %d bytes from file...\n", num_read);
  882.         #endif
  883.  
  884.         if (num_read > 0)
  885.         {
  886.  
  887.             fprintf(stderr, "%d characters transmitted\n", TEMP_FAILURE_RETRY (write(fd, buf, num_read)));  // send 18-byte packet
  888.  
  889.             tcflush(fd,TCIFLUSH);
  890.             usleep(500000);
  891.  
  892.             int read_sz=read(fd, recvbuf, num_read); // read and discard 18-byte packet
  893.  
  894.             fprintf(stderr, "%d characters echoed\n",read_sz);
  895.             read_sz=read(fd, &recvchar, 1); // read ack byte
  896.  
  897.  
  898.             if (recvchar==1) // handle Communication error
  899.             {
  900.                 fprintf(stderr, "Ack = %d\n", recvchar); // print ack byte
  901.                 fprintf(stderr, "Error: Communication error while programming stamp, try again\n");
  902.                 exit(1);
  903.             }
  904.             else if (recvchar==2) // handle EEPROM error
  905.             {
  906.                 fprintf(stderr, "Ack = %d\n", recvchar); // print ack byte
  907.                 fprintf(stderr, "Error: EEPROM error.\n");
  908.                 fprintf(stderr, "If this happens consistently, there may be a problem with your stamp.\n");
  909.                 exit(1);
  910.             }
  911.             else if (recvchar!=0)
  912.             {
  913.                 fprintf(stderr, "Ack = %d\n", recvchar); // print ack byte
  914.                 fprintf(stderr, "Error: Unknown error while programming stamp!\n");
  915.                 exit(1);
  916.             }
  917.         }
  918.     }
  919.     while (num_read > 0);
  920.  
  921.     close(in_fd);
  922. }
  923. else
  924. {
  925.     fprintf(stderr, "Error: Basic Stamp model not recognized when trying to upload\n");
  926.     exit(1);
  927. }
  928.  
  929. }
  930.  
  931. /* handle timeouts */
  932. void *timeout_handler(int sig){
  933.  
  934.   fprintf(stderr, "ERROR: Timed out waiting for data from %s\n", device);
  935.  
  936.   //tcsetattr(fd,TCSANOW,&oldtios);
  937.   //close(fd);
  938.  
  939.   //exit(STATE_CRITICAL);
  940.  
  941.   return NULL;
  942. }
  943.  
  944. /* handle control c */
  945. void *control_c_handler(int sig)
  946. {
  947.  
  948.     fflush(stdout);
  949.     fflush(stderr);
  950.  
  951.     fprintf(stderr, "\n_____________________________________________________________________\n");
  952.     fprintf(stderr, "\nReceived [Control]-[C]!\n");
  953.     fflush(stderr);
  954.  
  955.     debug_loop_done = 1;
  956.     return NULL;
  957. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement