Announcement

Collapse
No announcement yet.

Non standard Comm bit rate

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Non standard Comm bit rate

    Help says "Common baud rates range from 110 to 256000. There are equates defined in the WIN32API.INC file, prefixed with %CBR_ to assist you with specifying a common baud rate, but you are not restricted to a limited set of rates." bold added

    I need a rate of 40000, but program ignores
    COMM SET nComm, BAUD = 40000
    and stays at whatever the last standard bit rate setting was.
    Code:
    #compile exe
    #dim all
    
    function pbmain () as long
      local nComm as dword
      
      nComm = freefile
      open "COM1" as #nComm
      comm set #nComm, baud = 9600
      msgbox str$(comm(#nComm, baud))
      comm set #nComm, baud = 40000
      msgbox str$(comm(#nComm, baud))
      comm set #nComm, baud = 56000
      msgbox str$(comm(#nComm, baud))
    end function
    Results in 9600, 9600, 56000

    PB Win 8.04 on XP.

    Thanks,

    added: Strange other nonstandard values work, like 4123.

    added 2: I vaguely remember being able to set the 16X clock divider value via API under Win 98, and getting within 1 or 2% of desired bit rate. Can't find that now in PSDK.
    Last edited by Dale Yarker; 20 Sep 2008, 05:03 AM. Reason: added
    Dale

  • #2
    Maybe should read ..not restricted to a limited set of rates. Legal values will depend on the serial driver being used. ?

    Asking for a BaudRate of 40000 results in "Error! 5 Illegal function call"

    Using the API (CreateFile etc) also fails when a BaudRate of 40000 is requested (SetCommState error 87 "The parameter is incorrect").

    Both PB and API work OK (at 40000) with virtual ports created by GpsGate though..
    Last edited by Dave Biggs; 20 Sep 2008, 06:32 AM.
    Rgds, Dave

    Comment


    • #3
      What bit rate does GPSGate use? My GPS unit uses a very standard 9600.

      I've been searching MSDN and google between posts ... doesn't look good.
      Dale

      Comment


      • #4
        GpsGate creates virtual ports that can be set to any Baud rate by the application that connects to them.

        You can find the program here http://franson.com It's pretty usefull for all sorts of things - not just distributing GPS signals to multiple client programs (which was it's original purpose).
        Rgds, Dave

        Comment


        • #5
          >Asking for a BaudRate of 40000 results in "Error! 5 Illegal function call"

          Amazing what you can learn when you (properly!) check the system ERR variable, huh?
          Michael Mattias
          Tal Systems Inc. (retired)
          Racine WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Serial Port Devices

            Seeing how I work with Multiple Serial Port Devices (anything from Motor controllers, to Digital Read Outs to other devices) and they each have shall we say "Their Quirks" to enhance their operation, and avoid conflicts with others it can be confusing.

            What most (if not ALL) seem to adhere to is common "Baud Rates" (or as Dale more correctly referred to as "Bits" and not BAUD ), is usually some multiple of 9600

            Since my interest in Serial ports, and debugging hard to find problems, I threw my RunTime Debugger - Find that elusive bug in the source code forums against it as a test, and sure enough I came up with
            Trace Begins...
            TRACEPRINT(<0D><0A><09>Unhandled PbError # 5 - Illegal function call<0D><0A><09> Function = PBMAIN at line: 25)
            SETGETDEBUGTRACERUNNING(-1,0,-1)
            SETGETDEBUGTRACERUNNING Exit

            Unhandled PbError # 5 - Illegal function call
            Function = PBMAIN at line: 25

            TRACEPRINT Exit
            TRACELASTERROR Exit
            Tests without it, came up the same as Dale's (9600, 9600,5600)

            Could be an oversight, but the docs do read as
            Common baud rates range from 110 to 256000. There are equates defined in the WIN32API.INC file, prefixed with %CBR_ to assist you with specifying a common baud rate, but you are not restricted to a limited set of rates.
            To me that would read that I could pick any viable "BaudRate" I wish as long as the Hardware was matched I wont get into
            added 2: I vaguely remember being able to set the 16X clock divider value via API under Win 98, and getting within 1 or 2% of desired bit rate. Can't find that now in PSDK.
            because you are right...but that is a nit-pick scenario and probably does not apply

            Dave's comment of
            Legal values will depend on the serial driver being used. ?
            Rung more of a bell because the 'Unhandled PbError # 5 - Illegal function call" could actually be because the test you are performing. (I have not looked into what the built in Serial driver will allow, but lets say its all multiples of 9600 then it would not surprise me that error 5 is correct. If it were a "Virtual COM" (like most USBtoRS232 devices it still would not surprise me)

            The catch you have to look for is the typical problem of the "Rosetta Stone"

            Hardware must match software must match your application in order for all 3 to talk to each other correctly

            Engineer's Motto: If it aint broke take it apart and fix it

            "If at 1st you don't succeed... call it version 1.0"

            "Half of Programming is coding"....."The other 90% is DEBUGGING"

            "Document my code????" .... "WHYYY??? do you think they call it CODE? "

            Comment


            • #7
              Forgot Code

              Sorry Guys, I forgot to post the code to show my tests
              (Only slightly modified from Source Code Forum)

              ErrorHandling.inc
              Code:
              '*** ErrorHandling.inc
              '***      Written by: Cliff Nichols - 08-28-2008
              '***      Modified by: Cliff Nichols - 09-18-2008
              '***      Compiler: 8.04/9.0
              '***      Should work on: 7/8/9
              '***      Tested on: XP-Pro SP3, Vista-Ultimate
              '***      Should work on: 95/98/ME/NT/2K/XP/Vista
              '***      Purpose - Beefed up Error Handling Routines to attempt to "Bullet-Proof" apps
              '*** Usage:
              '***      StartTrace - Create a Trace log file
              '***      TraceVariables - Common Variables for each function
              '***
              '***      TraceUnhandled - Steps for anything that you did not think of when writing and testing your code
              '--------------------------------------------------------------------------------
              '*** Now for the FUN Stuff
              '***      PB has 'On Error' for handling errors on the DDT side
              '***           PB can raise an error just by ERR = some number
              '***      Windows has 'GetLastError' to check any errors via SDK
              '***           Windows has to check for errors and handle them (errors are not raised)
              '***      Windows has "Exceptions" (You've seen them...the default usually shows the typical "*.exe has encountered a problem and needs to close" message)
              '***           Windows "Exceptions" can be raised, but default handler is typically fatal, but you can override that fatality
              '*** I REALLLLLLY want to know how to do the below without visibly inserting numbers but.....
              '***      PB Line numbers (if inserted) can assist in locating where an error occured (larger projects its smarter to contain line numbers to their functions)
              '***      PB FUNCNAME$ in conjunction with the line numbers can nail down what line the error occured on
              '***           Conjunction, junction, whats your function??? :-)
              '*** What makes it all work????
              '*** MACRO's baby, yeah baby yeah...(Finally got this one when larger code all had the same multiple commands and got tedious to type or copy/paste)
              '*** Globals.....Real Men don't need no stinkin Globals :-) (Finally got this one working deep with Windows API...See "Parameter as Reply" discussion)
              '--------------------------------------------------------------------------------
              
              '*** If not already declared in your code, then declare this INC
              #IF NOT %DEF(%ERRORHANDLING)
                   %ERRORHANDLING = 1
              '*** Globals
              '***      NONE
              '***           - Use SetGetDebugTraceRunning to keep value in replacement for a global DebugTraceRunning
              '***           - Use SetGetLastFunction to keep value in replacement for a global LastFunction
              '*** Constants
                   %UNKNOWN_VALUE = -1
              '*** Constants not found in Win32Api.Inc
                   %EXCEPTION_ILLEGAL_INSTRUCTION  = &HC000001D
                   %EXCEPTION_STACK_OVERFLOW       = &HC00000FD
              '*************************************************************************************************************
              '*** Macro's - When Compiled, replace the name of the macro with all the functions and processes in the macro
              '***           As if you had done it yourself in each and every SUB/FUNCTION it was called
              '***           Do not add line numbers to Macro's unless you want to renumber functions that use the macros
              '*************************************************************************************************************
              '*** TraceUnhandled
              '***      Macro to replace code at the end of each function being being debugged
              '***           Code will jump to end ON ERROR or if told to jump to end
              '***           Code relies on TraceVariables to compile
              '*************************************************************************************************************
                   MACRO TraceUnhandled
              12        EXIT FUNCTION                                               'Exit to not Execute Function code again
              13   ErrHandler:
              14        ErrFunc = GetLastError                                      'Get API Last Error
              15        TraceLastError FUNCNAME$, ErrFunc, ERR, ERL
              16        SetUnhandledExceptionFilter %NULL
                   END MACRO
              '*************************************************************************************************************
              '*** TraceVariables
              '***      Macro to replace code at the begginning of each function being being debugged
              '***           Code sets up variables to jump to end ON ERROR or if told to jump to end
              '***           Code relies on TraceUnhandled to compile
              '*************************************************************************************************************
                   MACRO TraceVariables
              '*** Would be Line Numbers 11 to 16 but Macro Expansion will not allow for this
              '*** Even though at the end of functions, Start Line Numbers at 20 or above, since no telling how many lines per function
                        ON ERROR GOTO ErrHandler                                    'Avoid using error numbers higher than 240, as they are reserved for use in critical error situations which can never be trapped with ON ERROR.
                        LOCAL DebugTraceRunning AS LONG                             'Variable for if debugging
                        LOCAL LastErrorValue AS LONG                                'Variable for GetLastError
                        LOCAL PbErrorValue AS LONG                                  'Variable for PB ERR
                        LOCAL ErrorLineNumber AS LONG                               'Variable for line number where the error occured (or the last checked line)
                        LOCAL ErrFunc AS LONG                                       'Variable for if there was an error in the function
                        LOCAL ErrorBuff AS ASCIIZ * %MAX_PATH                       'Variable for Win32Api Error Description
                        LOCAL WhatToTrace AS STRING                                 'Variable for what to log for an error
                        SetLastError(0)                                             'Ensure the last Windows error is cleared
                        ERRCLEAR                                                    'Ensure the last PB error is cleared
              '          SetUnhandledExceptionFilter %EXCEPTION_EXECUTE_HANDLER      '<--- Use this exception handler if wanting to use windows default (the typical "*.exe has encountered a problem and needs to close" message)
                        SetUnhandledExceptionFilter CODEPTR (TraceExceptionHandler) '<--- Use this exception handler if wanting to make a better crash-proof program
                   END MACRO
              '*************************************************************************************************************
              '*** TraceOn
              '***      Macro to replace code that would be blindly TRACE ON
              '***           Code only turns the trace on if debugging
              '***           Leaving a function will turn TRACE OFF by default (although I like to purposely call it to clean up after myself)
              '*************************************************************************************************************
                   MACRO TraceOn
                        ErrFunc = SetGetDebugTraceRunning(%UNKNOWN_VALUE, DebugTraceRunning, %UNKNOWN_VALUE)      '<---Find out if debugging or not
                        SELECT CASE DebugTraceRunning
                             CASE 0                                                 'Not running a trace
                             CASE ELSE
                                  TRACE ON                                          'Turn on trace if debugging
                        END SELECT
                   END MACRO
              '*************************************************************************************************************
              '*** TraceOff
              '***      Macro to replace code that would be default TRACE OFF
              '***           Code only turns the trace off if debugging
              '***           Leaving a function will turn TRACE OFF by default (although I like to purposely call it to clean up after myself)
              '*************************************************************************************************************
                   MACRO TraceOff                                                   '<--- Not needed if exiting function but I am a stickler
                        ErrFunc = SetGetDebugTraceRunning(%UNKNOWN_VALUE, DebugTraceRunning, %UNKNOWN_VALUE)
                        SELECT CASE DebugTraceRunning
                             CASE 0                                                 'Not running a trace
                             CASE ELSE
                                  TRACE OFF                                         'Turn off trace if debugging
                        END SELECT
                   END MACRO
              '*************************************************************************************************************
              '*** LastErrorCheck
              '***      Macro to replace code that would be multiple lines for Win32Api GetLastError
              '***           Code only traces if debugging
              '***           TraceLastError will decide if a Windows or a PB Error and log accordingly
              '*************************************************************************************************************
                   MACRO LastErrorCheck
                        ErrFunc = GetLastError                                      'Get API Last Error
                        TraceLastError FUNCNAME$, ErrFunc, ERR, ERL                 'Pass all known info to the function for logging
                   END MACRO
              '*************************************************************************************************************
              '*** NOW FOR THE STANDARD INC SETUP
              '*************************************************************************************************************
              '*** Declares:
                   DECLARE FUNCTION SetGetDebugTraceRunning(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
                   DECLARE FUNCTION SetGetLastFunction(ValueToSet AS STRING, ValueResults AS STRING, ResetValue AS LONG) AS LONG
                   DECLARE FUNCTION SetGetOverRideError(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
                   DECLARE FUNCTION StartTrace() AS LONG
                   DECLARE FUNCTION EndTrace() AS LONG
                   DECLARE FUNCTION TraceProgramName(ParentAppName AS ASCIIZ * %MAX_PATH) AS LONG
                   DECLARE FUNCTION TraceLastError(FunctionName AS STRING, LastErrorValue AS LONG, PbErrorValue AS LONG, ErrorLineNumber AS LONG) AS LONG
                   DECLARE FUNCTION TracePrint(WhatToTrace AS STRING) AS LONG
                   DECLARE FUNCTION TraceExceptionHandler(BYREF lpEP AS EXCEPTION_POINTERS) AS LONG
              '*** Dependant Inc Files:
              '***      None
              '*** Functions:
              '***      SetGetDebugTraceRunning Replaces the need for global variables so that local variables in other functions are easier to read
                   FUNCTION SetGetDebugTraceRunning(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
              '*** Would be lines 1 to 11 but Macro expansion will not allow for this
                        TraceVariables                                              'Macro for Declaring variables for error checking
                        STATIC FunctionValue AS LONG                                'Static to hold current value
                        SELECT CASE ResetValue                                      'Decide whether to Set or to Get the current value
                             CASE %False, %UNKNOWN_VALUE                            'If set to False, or -1 Then Get Current Value
                                  ValueResults = FunctionValue                      'Return Results as a parameter
                             CASE = %TRUE                                           'If set to True then Reset the Current Value
                                  FunctionValue = ValueToSet                        'Reset the value
                                  ValueResults = FunctionValue                      'Return Results as a parameter
                        END SELECT
                        FUNCTION = %False                                           'Return if Function Failed
                        TraceUnhandled                                              'Exit Function or handle unhandled errors
                   END FUNCTION
              '*** SetGetLastFunction Replaces the need for global variables so that local variables in other functions are easier to read
                   FUNCTION SetGetLastFunction(ValueToSet AS STRING, ValueResults AS STRING, ResetValue AS LONG) AS LONG
              1         TraceVariables                                              'Macro for Declaring variables for error checking
              2         STATIC FunctionValue AS STRING                              'Static to hold current value
              3         SELECT CASE ResetValue                                      'Decide whether to Set or to Get the current value
              4              CASE %False, %UNKNOWN_VALUE                            'If set to False, or -1 Then Get Current Value
              5                   ValueResults = FunctionValue                      'Return Results as a parameter
              6              CASE = %TRUE                                           'If set to True then Reset the Current Value
              7                   FunctionValue = ValueToSet                        'Reset the value
              8                   ValueResults = FunctionValue                      'Return Results as a parameter
              9         END SELECT
              10        FUNCTION = %False                                           'Return if Function Failed
              11        TraceUnhandled                                              'Exit Function or handle unhandled errors
                   END FUNCTION
              '*** SetGetOverRideError Replaces the need for global variables so that local variables in other functions are easier to read
                   FUNCTION SetGetOverRideError(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
              1         TraceVariables                                              'Macro for Declaring variables for error checking
              2         STATIC FunctionValue AS LONG                              'Static to hold current value
              3         SELECT CASE ResetValue                                      'Decide whether to Set or to Get the current value
              4              CASE %False, %UNKNOWN_VALUE                            'If set to False, or -1 Then Get Current Value
              5                   ValueResults = FunctionValue                      'Return Results as a parameter
              6              CASE = %TRUE                                           'If set to True then Reset the Current Value
              7                   FunctionValue = ValueToSet                        'Reset the value
              8                   ValueResults = FunctionValue                      'Return Results as a parameter
              9         END SELECT
              10        FUNCTION = %False                                           'Return if Function Failed
              11        TraceUnhandled                                              'Exit Function or handle unhandled errors
                   END FUNCTION
              '*** Start Tracing
                   FUNCTION StartTrace() AS LONG
              1         TraceVariables                                              'Macro for Declaring variables for error checking
              2         LOCAL TraceLogName AS ASCIIZ * %MAX_PATH
              3         ErrFunc = TraceProgramName(TraceLogName)                    'Get a trace log name
              4         SELECT CASE ErrFunc                                         'If no error creating the log
              5              CASE %FALSE
              6                   DebugTraceRunning = %TRUE                         'Set variable for if tracing
              7                   TRACE NEW TraceLogName                            'Create the log
              8              CASE ELSE                                              'Some Error Occurred
              9         END SELECT
              10        ErrFunc = SetGetDebugTraceRunning(%TRUE, DebugTraceRunning, %TRUE)    'Set the flag that we are tracing
              11        TraceUnHandled                                              'Macro for Local Variables and Unhandled Errors
                   END FUNCTION
              '*** End Tracing
                   FUNCTION EndTrace() AS LONG
              1          TraceVariables                                             'Macro for common variables
              2          LOCAL TraceLogName AS ASCIIZ * %MAX_PATH
              3          ErrFunc = TraceProgramName(TraceLogName)                   'Get a trace log name
              4          SELECT CASE ErrFunc                                        'If the trace log name exists (no error) then
              5               CASE %FALSE
              6                    DebugTraceRunning = %FALSE
              7                    TRACE CLOSE                                      'Close Trace File
              8               CASE ELSE                                             'Some Error Occurred
              9          END SELECT
              10          ErrFunc = SetGetDebugTraceRunning(%FALSE, DebugTraceRunning, %TRUE)      'Set the flag for we are no longer tracing
              11          TraceUnHandled                                            'Macro for Local Variables and Unhandled Errors
                   END FUNCTION
              '*** Set up a log file name
                   FUNCTION TraceProgramName(ParentAppName AS ASCIIZ * %MAX_PATH) AS LONG
              1          LOCAL ErrFunc AS LONG
              2          ErrFunc = GetModuleFileName(GetModuleHandle(BYVAL %NULL), ParentAppName, %MAX_PATH)       'Returns current path to owning parent
              3          ParentAppName = MID$(ParentAppName, 1, INSTR(ParentAppName, ".exe") - 1)  'Strip all but the parent '.exe' part
              4          ParentAppName = ParentAppName + " - Error Log.log"          'Append string to show an error log
              5          SELECT CASE ErrFunc
              6               CASE 0                                                 'Function Failed
              7                    FUNCTION = ErrFunc
              8               CASE ELSE                                              'Function Passed
              9                    FUNCTION = %False
              10          END SELECT
                   END FUNCTION
              '*** Trace Last Error (if any)
                   FUNCTION TraceLastError(FunctionName AS STRING, LastErrorValue AS LONG, PbErrorValue AS LONG, ErrorLineNumber AS LONG) AS LONG
                        LOCAL LastError AS LONG
                        LOCAL WhatToTrace AS STRING
                        LOCAL ErrFunc AS LONG
                        LOCAL DebugTraceRunning AS LONG
                        LOCAL ErrorBuff AS ASCIIZ * %MAX_PATH
              
                        ERR = PbErrorValue                                          'PB Clears ERR at the end of functions so to preserve it I reset it
                        SELECT CASE ERR                                             'Is it a PB Error?
                             CASE 0                                                 'Not a PB Error
                                  FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, LastErrorValue, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL     'Format the message
                                  WhatToTrace = $TAB + "Unhandled WindowsError - " + STR$(LastErrorValue) + " - " + ErrorBuff + $CRLF + $TAB + " Function = " + FunctionName + " at line: " + STR$(ErrorLineNumber)
                             CASE ELSE                                              'PB Error
                                  LastError = ERR
                                  WhatToTrace = WhatToTrace + $CRLF + $TAB + "Unhandled PbError # " + STR$(ERR) + " - " + ERROR$ + $CRLF + $TAB + " Function = " + FunctionName + " at line: " + STR$(ErrorLineNumber)    '<--- ERL not quite working at this time
                                  SELECT CASE LastError
                                       CASE 0, %ERR_NOERROR                         'No Error
                                       CASE 5, %ERR_ILLEGALFUNCTIONCALL             'Illegal function call
                                       CASE 6, %ERR_OVERFLOW                        'Overflow                '<---This error is not currently supported.
                                       CASE 7, %ERR_OUTOFMEMORY                     'Out of Memory
                                       CASE 9, %ERR_SUBSCRIPTPOINTEROUTOFRANGE      'Subscript / Pointer out of range
                                       CASE 11, %ERR_DIVISIONBYZERO                 'Division by zero         '<---This error is not currently supported.
                                       CASE 24, %ERR_DEVICETIMEOUT                  'Device TimeOut for UDP or TCP communications
                                       CASE 51, %ERR_INTERNALERROR                  'Internal Error
                                       CASE 52, %ERR_BADFILENAMEORNUMBER            'Bad File Name or Number '<--- Also used for Serial Port Errors
                                       CASE 53, %ERR_FILENOTFOUND                   'File not found
                                       CASE 54, %ERR_BADFILEMODE                    'Bad File Mode
                                       CASE 55, %ERR_FILEISOPEN                     'File is already open    '<--- Also used for Serial Port Errors
                                       CASE 57, %ERR_DEVICEIOERROR                  'Device I/O Error        'Serial Port, TCP, UDP
                                       CASE 58, %ERR_FILEALREADYEXISTS              'File already exists
                                       CASE 61, %ERR_DISKFULL                       'Disk full
                                       CASE 62, %ERR_INPUTPASTEND                   'Input past end
                                       CASE 63, %ERR_BADRECORDNUMBER                'Bad record number
                                       CASE 64, %ERR_BADFILENAME                    'Bad file name
                                       CASE 67, %ERR_TOOMANYFILES                   'Too many files
                                       CASE 68, %ERR_DEVICEUNAVAILABLE              'Device unavailable
                                       CASE 69, %ERR_COMMERROR                      'COMM Error         '<---Serial Port Error
                                       CASE 70, %ERR_PERMISSIONDENIED               'Permission Denied
                                       CASE 71, %ERR_DISKNOTREADY                   'Disk not ready
                                       CASE 72, %ERR_DISKMEDIAERROR                 'Disk media error
                                       CASE 74, %ERR_RENAMEACROSSDISKS              'Rename across disks
                                       CASE 75, %ERR_PATHFILEACCESSERROR            'Path/File access error
                                       CASE 76, %ERR_PATHNOTFOUND                   'Path not found
                                       CASE 99, %ERR_OBJECTERROR                    'Object error
                                       CASE 241, %ERR_GLOBALMEMORYCORRUPT           'Global Memory Corrupt
                                       CASE 242, %ERR_STRINGSPACECORRUPT            'String space corrupt
                                       CASE ELSE                                    'Either a 'Compile-Time' error (handled by PB) or Unknown what to do so just exit the function
                                  END SELECT
                        END SELECT
                        TraceOn                                                     'If debugging then trace
                        TracePrint WhatToTrace                                      'If debugging then trace what?
                   END FUNCTION
              '*** Print to trace file if debugging
                   FUNCTION TracePrint(WhatToPrint AS STRING) AS LONG
              1         TraceVariables                                              'Macro for common variables
              2         ErrFunc = SetGetDebugTraceRunning(%UNKNOWN_VALUE, DebugTraceRunning, %UNKNOWN_VALUE)      'Check if Debugging
              3         SELECT CASE DebugTraceRunning
              4              CASE 0                                                 'Not running a trace
              5                   FUNCTION = DebugTraceRunning
              6              CASE ELSE
                                  TRACE ON
              7                   TRACE PRINT WhatToPrint + $CRLF                   '<--- Chose string since I do not know what is to be printed + $CRLF for log file
              8                   FUNCTION = %FALSE
              9         END SELECT
              10        TraceUnHandled                                              'Macro for Local Variables and Unhandled Errors
                   END FUNCTION
              '--------------------------------------------------------------------------------
              '*** Now for the DOOZYYYYyyyy....Handling GPF's and other major fatal errors
              '*** Commented fields are ones that I have no value for (yet) but MSDN say they exist
              '--------------------------------------------------------------------------------
                   FUNCTION TraceExceptionHandler(BYREF lpEP AS EXCEPTION_POINTERS) AS LONG
                        STATIC TerminateInProcess AS LONG
                        LOCAL ErrorRecord AS EXCEPTION_RECORD POINTER
                        LOCAL ErrorCode AS LONG POINTER
                        LOCAL WhatToTrace AS STRING
                        LOCAL i AS LONG                                                  'For homing in on where the exception occurred
                        LOCAL CallStackFunctions AS STRING                               'For homing in on where the exception occurred
                        SELECT CASE TerminateInProcess                              'If Unloading due to error let the OS handle it.
                             CASE %TRUE
                                  SetUnhandledExceptionFilter %EXCEPTION_EXECUTE_HANDLER 'Reactivate default Error Handler
                                  RaiseException %NULL, %NULL, %NULL, %NULL              'Force normal Error Handler
              '*** Exit the thread (and application if this is the only thread)
                                  ExitThread 0
                             CASE %FALSE
                                  TerminateInProcess = %TRUE
                                  ErrorRecord = lpEP.pExceptionRecord                    'Detect the actual exception record
                                  DO UNTIL @ErrorRecord.pExceptionRecord = 0             'Gather the exception record(s)
                                       CALL MoveMemory(@ErrorRecord, @ErrorRecord.pExceptionRecord, SIZEOF(ErrorRecord))
                                  LOOP
                                  ErrorCode   = @ErrorRecord.ExceptionCode
              '*** Now we have in ErrorCode the ExceptionCode, that raised the crash, log the info
                                  SELECT CASE ErrorCode
                                       CASE %EXCEPTION_ACCESS_VIOLATION
                                            WhatToTrace =   "ACCESS VIOLATION" + " <---> " + "The thread tried to read from or write to a virtual address for which it does not have the appropriate access"
                                       CASE %EXCEPTION_ARRAY_BOUNDS_EXCEEDED
                                            WhatToTrace =   "ARRAY BOUNDS EXCEEDED" + " <---> " + "The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking."
                                       CASE %EXCEPTION_BREAKPOINT
                                            WhatToTrace = "BREAKPOINT" + " <---> " + "A breakpoint was encountered."
                                       CASE %EXCEPTION_DATATYPE_MISALIGNMENT
                                            WhatToTrace =   "DATATYPE MISALIGNMENT" + " <---> " + "The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries"
                                       CASE %EXCEPTION_FLT_DENORMAL_OPERAND
                                            WhatToTrace =  "FLOAT DENORMAL OPERAND" + " <---> " + "One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value."
                                       CASE %EXCEPTION_FLT_DIVIDE_BY_ZERO
                                            WhatToTrace =  "FLOAT DIVISION BY ZERO" + " <---> " + "The thread tried to divide a floating-point value by a floating-point divisor of zero."
                                       CASE %EXCEPTION_FLT_INEXACT_RESULT
                                            WhatToTrace =  "FLOAT INEXACT RESULT" + " <---> " + "The result of a floating-point operation cannot be represented exactly as a decimal fraction."
                                       CASE %EXCEPTION_FLT_INVALID_OPERATION
                                            WhatToTrace =  "FLOAT INVALID OPERATION" + " <---> " + "This exception represents any floating-point exception not included in this list."
                                       CASE %EXCEPTION_FLT_OVERFLOW
                                            WhatToTrace =  "FLOAT OVERFLOW" + " <---> " + "The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type."
                                       CASE %EXCEPTION_FLT_STACK_CHECK
                                            WhatToTrace =  "FLOAT STACK CHECK" + " <---> " + "The stack overflowed or underflowed as the result of a floating-point operation."
                                       CASE %EXCEPTION_FLT_UNDERFLOW
                                            WhatToTrace =  "FLOAT UNDERFLOW" + " <---> " + "The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type."
                                       CASE %EXCEPTION_ILLEGAL_INSTRUCTION
                                            WhatToTrace =  "ILLEGAL INSTRUCTION" + " <---> " + "The thread tried to execute an invalid instruction."
                                       CASE %EXCEPTION_IN_PAGE_ERROR
                                            WhatToTrace = "IN PAGE ERROR" + " <---> "
                                            WhatToTrace = WhatToTrace + "The thread tried to access a page that was not present, and the system was unable to load the page."
                                            WhatToTrace = WhatToTrace + "For example, this exception might occur if a network connection is lost while running a program over "
                                            WhatToTrace = WhatToTrace + "the network."
                                       CASE %EXCEPTION_INT_DIVIDE_BY_ZERO
                                            WhatToTrace =   "INTEGER DIVISION BY ZERO" + " <---> " + "The thread tried to divide an integer value by an integer divisor of zero."
                                       CASE %EXCEPTION_INT_OVERFLOW
                                            WhatToTrace =   "INTEGER OVERFLOW" + " <---> " + "The result of an integer operation caused a carry out of the most significant bit of the result."
              '                         CASE %EXCEPTION_INVALID_DISPOSITION
              '                              WhatToTrace =   "INVALID DISPOSITION" + " <---> " + "An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception."
              '                         CASE %EXCEPTION_NONCONTINUABLE_EXCEPTION
              '                              WhatToTrace =   "NONCONTINUABLE EXCEPTION" + " <---> " + "The thread tried to continue execution after a noncontinuable exception occurred."
                                       CASE %EXCEPTION_PRIV_INSTRUCTION
                                            WhatToTrace =   "PRIVATE INSTRUCTION" + " <---> " + "The thread tried to execute an instruction whose operation is not allowed in the current machine mode."
                                       CASE %EXCEPTION_SINGLE_STEP
                                            WhatToTrace =   "SINGLE STEP" + " <---> " + "A trace trap or other single-instruction mechanism signaled that one instruction has been executed."
                                       CASE %EXCEPTION_STACK_OVERFLOW
                                            WhatToTrace =  "STACK OVERFLOW" + " <---> " + "The thread used up its stack."
                                       CASE ELSE
                                            WhatToTrace =  CHR$(0)
                                  END SELECT
                                  FOR i = CALLSTKCOUNT TO CALLSTKCOUNT - 1 STEP -1
              '                    CallStackFunctions = CallStackFunctions + CALLSTK$(i)
                                       CallStackFunctions = CALLSTK$(i)
                                  NEXT i
              '*** Code for writing a crash-log, save opened documents etc...
                                  WhatToTrace = $TAB + "Unhandled WindowsException - " + STR$(@ErrorRecord.ExceptionCode) + " - " + WhatToTrace + $CRLF + $TAB + " Function = " + CallStackFunctions + " at line: " + STR$(ERL)
                                  TracePrint WhatToTrace
              '*** Exit the thread (and application if this is the only thread)
                                  ExitThread 0                  'This will stop the typical "*.exe has encountered a problem and needs to close" error message to send a report to M$
                        END SELECT
                   END FUNCTION
              #ENDIF
              DaleYarkerNonStandardBitRate.bas
              Code:
              #COMPILE EXE
              #DIM ALL
              #DEBUG ERROR OFF                                                      'Force all errors to be logged (including crashes)
              #TOOLS ON                                                             'Keep all Integrated tools turned on
              #INCLUDE "WIN32API.INC"                                               'Added for allowing Windows functions
              #INCLUDE ".\ErrorHandling.inc"                                        'Added for Debugging
              
              FUNCTION PBMAIN () AS LONG
                   TraceVariables                                                   'Add To whatever function you want to debug (Line Numbers 1 - 11)
                   StartTrace                                                       'Start Tracing Errors
              20   LOCAL nComm AS DWORD                                             'Start at Line Numbers 20 or higher
              21   nComm = FREEFILE
              22   OPEN "COM1" AS #nComm                                            'Really should be COMM OPEN "COM1" AS #nComm
              23   COMM SET #nComm, BAUD = 9600
              24   MSGBOX STR$(COMM(#nComm, BAUD))
              25   COMM SET #nComm, BAUD = 40000
              26   MSGBOX STR$(COMM(#nComm, BAUD))
              27   COMM SET #nComm, BAUD = 56000
              28   MSGBOX STR$(COMM(#nComm, BAUD))
                   EndTrace                                                         'A little misleading, but will be jumped over if a problem so it will be logged
                   TraceUnHandled                                                   'Macro for Local Variables and Unhandled Errors (Line Numbers 12 - 16)
              END FUNCTION
              Engineer's Motto: If it aint broke take it apart and fix it

              "If at 1st you don't succeed... call it version 1.0"

              "Half of Programming is coding"....."The other 90% is DEBUGGING"

              "Document my code????" .... "WHYYY??? do you think they call it CODE? "

              Comment


              • #8
                Thanks Dave and Cliff.

                After looking a lot of Google links, for 40K it would need a divider of 2.6. Rounding to integer of 2 or 3 would not have been a close enough bit rate. So it is a case of PB and/or Windows protecting me from myself. The cause is that the clock feeding the X16 counter in the UART is about 1.8MHz (unverified info from pages found via google).

                Learned: For odd bit rates below around 4K you can put in almost number you want because rounding exact divider to integer gives a bit rate that is close enough to work (bit 8 sampled within bit 8's duration, not during bit 7 or stop bit). Makes sense now. The project I did during Win 98 era was communicating with electro-mechanical TTYs, 5, 7, or 8 data bits, between 47.5 and 150 bps; and had no problems. When I started this project it didn't occur to me that I couldn't use whatever whatever rate I wanted as long as it was below 115200.

                Luckily the guy doing the other end of the serial link (on a PIC) said it would be easy to change from 25uS bit width (40Kbps) to 26uS (38461.5bps). That is only 0.16% off from standard 38400bps, and will work well. A happy outcome.

                Thanks again,
                Dale

                Comment

                Working...
                X