Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
COMM ports

 
Post new topic   Reply to topic    Forum Index -> ZBasic IDE
Author Message
DH*
Guest





Posted: 07 January 2006, 15:11 PM    Post subject: COMM ports Reply with quote

The machine I use for development has 11 serial ports.

The IDE presents an empty combo box for selecting a serial port.
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 07 January 2006, 17:45 PM    Post subject: Reply with quote

We use a process called "comm port enumeration" where we look at entries in the registry to see what devices are available. The actual code used is:

Code:
//
// Enumerate the existing comm ports, invoking a caller-supplied function
// for each port.
//
void CommPort::
EnumCommPorts(EnumCommPortProc func, void *arg)
{
   HKEY hkCommMap;
   if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0,
         KEY_QUERY_VALUE, &hkCommMap) != ERROR_SUCCESS)
      return;

   char *nameBuf = 0;
   char *valBuf = 0;
   DWORD cnt, maxNameLen, maxValLen;
   if (::RegQueryInfoKey(hkCommMap, NULL, NULL, NULL, NULL, NULL, NULL,
         &cnt, &maxNameLen, &maxValLen, NULL, NULL) == ERROR_SUCCESS)
   {
      // The max value name size is returned in TCHARs not including
      // the terminating null character.
      nameBuf = new char[++maxNameLen * sizeof(char)];

      // The max value size is returned in bytes needed to hold the UNICODE
      // strings including terminating null character regardless of the
      // function type (ANSI or UNICODE).
      maxValLen = (maxValLen / 2) * sizeof(char);
      valBuf = new char[maxValLen];

      if (nameBuf && valBuf)
      {
         for (DWORD idx = 0; idx < cnt; ++idx)
         {
            DWORD nameLen = maxNameLen;
            DWORD valLen = maxValLen;
            DWORD type;
            LONG nRes = ::RegEnumValue(hkCommMap, idx, reinterpret_cast<LPTSTR>(nameBuf),
                  &nameLen, NULL, &type, reinterpret_cast<LPBYTE>(valBuf), &valLen);

            unsigned port = GetPort(valBuf);
            if ((nRes == ERROR_SUCCESS) && (type == REG_SZ) && !func(valBuf, port, arg))
               break;
         }
      }
   }
   delete[] valBuf;
   delete[] nameBuf;
   ::RegCloseKey(hkCommMap);
}

//
// Extract the comm port number from a string in the form COMnnn.
// Return zero for an invalid string or other error.
//
unsigned CommPort::
GetPort(const char *str)
{
   unsigned port = 0;
   if (str != NULL)
   {
      while (isspace(*str))
         str++;
      if (memicmp(str, "COM", 3) == 0)
      {
         str += 3;
         while (isdigit(*str))
            port = port * 10 + (*str++ - '0');
      }
   }
   return(port);
}



Another user has reported that this does not work on Win98SE. So far, there have been no reports of it not working on Win2K or later.

As a workaround, you can set the comm port and related parameters by adding/editing lines in the User Options file. The lines have the following form:
Code:
debug.comport=2
debug.speed=19200
debug.capture=1
debug.reset=1
download.verify=1
download.clear=1
download.quiet=0


The first two lines set the port and speed (other than for downloading). These should be all that you need. The remaining entries correspond to checkboxes on the Device Options dialog.
Back to top
DH*
Guest





Posted: 07 January 2006, 18:31 PM    Post subject: Reply with quote

This is a 98SE machine but all of the ports are listed in the registry where you're looking.

I'll try the workaround.
Back to top
pjc30943



Joined: 02 Dec 2005
Posts: 220

Posted: 08 January 2006, 1:43 AM    Post subject: Reply with quote

dhouston wrote:
This is a 98SE machine but all of the ports are listed in the registry where you're looking.

I'll try the workaround.


That happened to me as well: in the registry, but not the box. The workaround has functioned perfectly, including using the zload instead of the default F5 (see one of Don's previous emails).
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 08 January 2006, 3:21 AM    Post subject: Reply with quote

The downloader may not function correctly on Win98SE. See http://www.zbasic.net/forum/viewtopic.php?t=74 for a way to work around the problem using ZLoad.
Back to top
DH*
Guest





Posted: 08 January 2006, 11:35 AM    Post subject: Reply with quote

The registry location you are looking to is not accurate. It's possible for a user to edit the registry adding ports or modifying those listed. In my case port numbers 40, 50, and 99 were still listed from where I had renamed some ports (a few years back) in order to test some VB code on ports higher than those usually seen.

REALbasic was also failing to correctly enumerate ports if more than nine were present. They found a function in a MS setup DLL that fixed this. If I saved the email exchange I'll send you the details. Device Manager appears to always list the ports correctly.

While I have an XP machine (also with extra serial ports) I still use an old laptop that's not capable of running XP. My preferred development machine has an older motherboard with ISA slots in order to use an oscilloscope card that needs ISA. 98SE is about its limit as well.

Everything I do is freeware and I like to avoid support problems whenever possible.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZBasic IDE Time synchro. with the server - Timezone/DST with your computer
Page 1 of 1

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group