home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / dev / src / SerialClass1_0.lha / SerialClass.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-11  |  9.1 KB  |  414 lines

  1. #include "SerialClass.h"
  2. #ifndef DEBUG
  3. #define DEBUG
  4. #endif
  5.  
  6. //    Paul Cimino 1995
  7. //    C++ Class to make basic Amiga serial port access a little easier
  8. //    This code is being released into the public domain
  9. //    feel free to improve upon it, however I ask that you :
  10. //        1) Redistribute the improved code
  11. //        2) Fully document changes to the code :
  12. //            A) Why the changes were made
  13. //            B) Document where your code is added
  14. //            C) Don't remove my code, rather comment it out
  15. //        3) Send me a copy (cimino@mdso.vf.ge.com or if that
  16. //            mail id goes away, 73677,1761@compuserve.com )
  17. //
  18. //     It would be great if someone familiar with Asynchronous
  19. //    Transfer Mode (ATM) and other useful protocals could
  20. //     expand this into a truly useful Class
  21. //
  22. //    Thanks go to J. Edward Hanway for his OptMouse ver 1.2 code
  23. //
  24. //
  25. //
  26. SerialClass::SerialClass(char *device, char *portN, int unit, int Baud, int Bits,
  27.     int Stop, Parity Par, HandShake Hand, int HighSpeed, int Share)
  28. {
  29.         // set OPEN status
  30.         isOpen = 0;
  31.         
  32.     // assign the device name
  33.     deviceName = new char [strlen(device)+1];
  34.     strcpy(deviceName, device);
  35.  
  36.     // Default Unit number
  37.     unitNum = unit;
  38.  
  39.     // assign the port name
  40.     if (portN == 0) {
  41.         portName = new char [strlen(deviceName)+5];// just in case the unit 
  42.             // number is ridiculously huge
  43.         sprintf(portName, "%s%d\0", deviceName, unitNum);
  44.     } else {
  45.         portName = new char [strlen(portN)+1];
  46.         strcpy(portName, portN);
  47.     }
  48.  
  49.     // Open the port
  50.     if (!open()) 
  51.     {
  52.         cerr << "Sorry, problem openning the port" << endl;
  53.         cerr << "Port in use ? " << endl;
  54.         cerr << "Here's a good place in the code to add throws\n";
  55.         cerr << "and catches for exception handling !" << endl;
  56.         exit(0);
  57.     } else {
  58. #ifdef DEBUG
  59.         cout << "Default port successfully opened as : ";
  60.         cout << deviceName << " Unit : " << unitNum << endl;
  61. #endif
  62.     }
  63.         
  64.     // set the parameters after openning the port
  65.     setBaud(Baud);
  66.     setBits(Bits);
  67.     setStop(Stop);
  68.     setParity(Par);
  69.     setHand(Hand);
  70.     setHighSpeed(HighSpeed);
  71.     setShare(Share);
  72.  
  73.  
  74. }
  75.  
  76. SerialClass::~SerialClass()
  77. {
  78.     // close the device
  79.     if (isOpen) close();
  80.  
  81.     // Reclaim the device name memory
  82.     if (deviceName) delete [] deviceName;
  83.         
  84.         if (portName) delete [] portName;
  85.     if (deviceName) delete [] deviceName;
  86.     if (port) delete port;
  87.     if (iob) delete iob;
  88.         
  89. }
  90.  
  91.  
  92. int
  93. SerialClass::open(void)
  94.     port = CreatePort(portName, 0);
  95.     if (port) {
  96.         iob = CreateExtIO(port, sizeof(struct IOExtSer));
  97.         if (iob) {
  98.             isOpen = !OpenDevice((unsigned char *)deviceName, 
  99.                                 (unsigned long)unitNum, 
  100.                                 iob, 
  101.                                 (unsigned long)0L);
  102.         }
  103.         
  104.     }
  105.         
  106.     iob_ser = (struct IOExtSer *)iob;
  107.  
  108.     return isOpen;
  109. }
  110.     
  111. void
  112. SerialClass::close(void)
  113. {
  114.         if(isOpen == TRUE) {
  115.         AbortIO(iob);
  116.         CloseDevice(iob);
  117.         isOpen = FALSE;
  118.     }
  119.     if(iob) {
  120.         DeleteExtIO(iob);
  121.         iob = NULL;
  122.     }
  123.     if(port) {
  124.         DeletePort(port);
  125.         port = NULL;
  126.     }   
  127. }
  128.  
  129. void
  130. SerialClass::mDoIO(struct IORequest *iob) 
  131. {
  132. // took this function from "OptMouse", because I don't 
  133. // yet understand IO stuff or pragma calls
  134.  
  135.     register LONGBITS signals, sigbit;
  136.     
  137. #pragma libcalliob->io_Device BeginIO 1e 901
  138.     
  139.     if (isOpen) {
  140.       iob->io_Flags |= IOF_QUICK;
  141.       BeginIO(iob);
  142.       if(!(iob->io_Flags & IOF_QUICK)) {
  143.           sigbit = 1L << iob->io_Message.mn_ReplyPort->mp_SigBit;
  144.           signals = Wait(sigbit | SIGBREAKF_CTRL_C);
  145.         
  146.           if(signals & sigbit) {
  147.                   GetMsg(iob->io_Message.mn_ReplyPort);
  148.           }
  149.         
  150.           if (signals & SIGBREAKF_CTRL_C) {
  151.               close();
  152.               cerr << "Problem in mDoIO, SIGBREAKF_CTRL_C encountered";
  153.               cerr << "\nClosing port" << endl;
  154.           }
  155.       }
  156.    }  
  157. }
  158.     
  159.  
  160. int
  161. SerialClass::setBaud(int BAUD) 
  162. {
  163.     IOB_SER->io_Baud = BAUD;
  164.         setParams();
  165.         
  166.     return BAUD;
  167. }
  168.  
  169. int
  170. SerialClass::setBits(int BITS) 
  171. {
  172.     IOB_SER->io_ReadLen = (unsigned char)BITS;
  173.         IOB_SER->io_WriteLen = (unsigned char)BITS;
  174.         setParams();
  175.         
  176.     return BITS;
  177. }
  178.  
  179. int
  180. SerialClass::setStop(int BITS) 
  181. {
  182.     IOB_SER->io_StopBits = (unsigned char)BITS;
  183.         setParams();
  184.         
  185.     return BITS;
  186. }
  187.  
  188. Parity
  189. SerialClass::setParity(Parity par) 
  190. {
  191.  
  192.     // first, clear the affected bits
  193.     IOB_SER->io_SerFlags &= ~(SERF_PARTY_ON|SERF_PARTY_ODD);
  194.     IOB_SER->io_ExtFlags &= ~(SEXTF_MSPON|SEXTF_MARK);
  195.  
  196.     switch (par) {
  197.                 case NONE : // do nothing;
  198.                         break;
  199.         case EVEN : IOB_SER->io_SerFlags |= SERF_PARTY_ON;
  200.             break;
  201.         case ODD : IOB_SER->io_SerFlags |= SERF_PARTY_ON|SERF_PARTY_ODD;
  202.             break;
  203.         case MARK : IOB_SER->io_SerFlags |= SERF_PARTY_ON;
  204.                         IOB_SER->io_ExtFlags |= SEXTF_MSPON|SEXTF_MARK;
  205.             break;
  206.                 case SPACE : IOB_SER->io_SerFlags |= SERF_PARTY_ON;
  207.                         IOB_SER->io_ExtFlags |= SEXTF_MSPON;
  208.                         break;
  209.         default :
  210.             cerr << "Invalid Parity, should be 0, 1, 2, 3, 4" << endl;
  211.             cerr << "For NONE, EVEN, ODD, MARK, SPACE" << endl;
  212.                         cerr << " YOU used : " << (int) par << endl;
  213.     }
  214.  
  215.         setParams();
  216.         
  217.     return par;
  218. }
  219.  
  220. HandShake
  221. SerialClass::setHand(HandShake hand) 
  222. {
  223.  
  224.     // first, clear the affected bits
  225.     IOB_SER->io_SerFlags &= ~(SERF_7WIRE);
  226.  
  227.     switch (hand) {
  228.                 case NONE : // do nothing;
  229.                         break;
  230.         case RTSCTS : IOB_SER->io_SerFlags |= SERF_7WIRE;
  231.             break;
  232.         default :
  233.             cerr << "Invalid Handshaking, should be 0, 1" << endl;
  234.             cerr << "For NONE, RTSCTS" << endl;
  235.                         cerr << " YOU used : " << (int) hand << endl;
  236.     }
  237.  
  238.         setParams();
  239.         
  240.     return hand;
  241. }
  242.  
  243. int
  244. SerialClass::setHighSpeed(int FLAG) 
  245. {
  246.  
  247.     // first, clear the affected bits
  248.     IOB_SER->io_SerFlags &= ~(SERF_RAD_BOOGIE);
  249.  
  250.     switch (FLAG) {
  251.                 case FALSE : // do nothing;
  252.                         break;
  253.         case TRUE : IOB_SER->io_SerFlags |= SERF_RAD_BOOGIE;
  254.             break;
  255.         default :
  256.             cerr << "Invalid High Speed Flag, should be 0, 1" << endl;
  257.             cerr << "For FALSE, TRUE" << endl;
  258.                         cerr << " YOU used : " << FLAG << endl;
  259.     }
  260.  
  261.         setParams();
  262.     return FLAG;
  263. }
  264.  
  265. int
  266. SerialClass::setShare(int FLAG) 
  267. {
  268.  
  269.     // first, clear the affected bits
  270.     IOB_SER->io_SerFlags &= ~(SERF_SHARED);
  271.  
  272.     switch (FLAG) {
  273.                 case FALSE : // do nothing;
  274.                         break;
  275.         case TRUE : IOB_SER->io_SerFlags |= SERF_SHARED;
  276.             break;
  277.         default :
  278.             cerr << "Invalid Share Flag, should be 0, 1" << endl;
  279.             cerr << "For FALSE, TRUE" << endl;
  280.                         cerr << " YOU used : " << FLAG << endl;
  281.     }
  282.  
  283.         setParams();
  284.           return FLAG;
  285. }
  286.  
  287. void 
  288. SerialClass::setParams(void)
  289. {
  290.         // set the serial port parameters
  291.         IOB_SER->IOSer.io_Command = SDCMD_SETPARAMS;
  292.         mDoIO(iob);
  293. }
  294.  
  295. UBYTE
  296. SerialClass::readByte(void)
  297. {
  298.     UBYTE    ch = 0;
  299.  
  300.     IOB_SER->IOSer.io_Command = CMD_READ;
  301.     IOB_SER->IOSer.io_Length = 1;
  302.     IOB_SER->IOSer.io_Data = (APTR) &ch;
  303.  
  304.     // (Maybe use BeginIO ?)
  305.         // BeginIO(iob);
  306.     mDoIO(iob);
  307.         
  308.     return ch;
  309. }
  310.  
  311. UBYTE *
  312. SerialClass::read(int numBytes)
  313. {
  314.     UBYTE    *chPtr = new UBYTE[numBytes];
  315.  
  316.     IOB_SER->IOSer.io_Command = CMD_READ;
  317.     IOB_SER->IOSer.io_Length = numBytes;
  318.     IOB_SER->IOSer.io_Data = (APTR) chPtr;
  319.  
  320.     // (Maybe use BeginIO ?)
  321.     mDoIO(iob);
  322.         
  323.     return chPtr;
  324. }
  325.  
  326. // Reads text from the serial port until NULL or the termination character
  327. // is received
  328. UBYTE *
  329. SerialClass::read(char termination)
  330. {
  331.     UBYTE    ch, *newPtr, *tmpPtr;
  332.     int    i, size = 1;
  333.  
  334.     newPtr = new UBYTE [size];
  335.  
  336.     IOB_SER->IOSer.io_Command = CMD_READ;
  337.     IOB_SER->IOSer.io_Length = 1;
  338.     IOB_SER->IOSer.io_Data = (APTR) &ch;
  339.  
  340.     do {
  341.         // (Maybe use BeginIO ?)
  342.         mDoIO(iob);
  343.  
  344.         newPtr[size - 1] = ch; // save the character to the end of a string
  345.         tmpPtr = new UBYTE [size]; // allocate room to save the string
  346.         tmpPtr = newPtr;
  347.         newPtr = 0; // remove the new string
  348.         newPtr = new UBYTE [size+1]; // reallocate string with more room
  349.         for (i = 0; i < size; i++) newPtr[i] = tmpPtr[i]; // move string back
  350.         delete [] tmpPtr; // reclaim memory
  351.         size++; // increment size
  352. cout << ch << "Size is " << size << endl;    
  353.     } while (ch != termination);
  354.         
  355.     // terminate the string
  356.     newPtr[size - 1] = 0;
  357.  
  358.     return newPtr;
  359. }
  360.  
  361.  
  362. UBYTE
  363. SerialClass::writeByte(UBYTE ch)
  364. {
  365.     IOB_SER->IOSer.io_Command = CMD_WRITE;
  366.     IOB_SER->IOSer.io_Length = 1;
  367.     IOB_SER->IOSer.io_Data = (APTR) &ch;
  368.        
  369. #ifdef DEBUG
  370.         cout << "Ready to send a character" << endl;
  371. #endif
  372.     // (Maybe use BeginIO ?)
  373.     mDoIO(iob);
  374. //        cout << "Trying SendIO first " << endl;
  375. //        SendIO(iob);
  376. //        cout << "Now trying DoIO" << endl;
  377. //        DoIO(iob);
  378.         
  379. #ifdef DEBUG
  380.         cout << "Character sent" << endl;
  381. #endif
  382.     return ch;
  383. }
  384.  
  385. UBYTE *
  386. SerialClass::writeData(UBYTE *data, int size)
  387. {
  388.     int i;
  389.         
  390. #ifdef DEBUG
  391.         cout << "Data is " << (char *)data << " size is " << size << endl;
  392. #endif    
  393.         for (i = 0; i < size; i++) writeByte(data[i]);
  394.  
  395.     return data;
  396. }
  397.  
  398. char *
  399. SerialClass::write(char *data, char terminationChar)
  400. {
  401.     int i = 0;
  402.         
  403.         while (data[i] != terminationChar) writeByte(data[i++]);
  404.  
  405.     return data;
  406. }
  407.  
  408. void 
  409. SerialClass::setParameters(void) { 
  410.         IOB_SER->IOSer.io_Command = SDCMD_SETPARAMS; // get ready to set serial port parameters
  411.     mDoIO(iob); // DO IT !
  412. }
  413.