SELF-CONTAINED TRANSPORTABLE LIFE SUPPORT SYSTEM

Abstract: A self-contained transportable life support system, (10) for resuscitation, stabilization, and transport of a patient has an environmentally controlled housing (22, 26) for receiving and supporting a patient, and a plurality of medical services disposed within the housing (22, 26). A control circuit (46) attached to the housing (22, 26) has at least a portion thereof extending to an external surface of the housing (22, 26) for regulating operation of the medical devices, and environmental conditions of within the housing in response to monitored life support conditions of the patient.

Description: SELF-CONTAINED TRANSPORTABLE LIFE SUPPORT SYSTEM Field of the Invention The present invention relates generally to medical devices utilized to treat intensive care patients and more particularly to a self-contained transportable life support system which is utilized in the resuscitation, stabilization, and transport of medical patients such as heart attack victims, stroke victims, accident victims and battlefield casualties. Background of the Invention The need to transport medical patients and persons suffering from various medical emergency conditions such as heart attacks, strokes, etc. is well-known. Nedical personnel speak of a "golden hour" within which such a medical patient must be transported to a medical facility so that proper medical care can be provided therefor. The survival rate for such medical patients is greatly enhanced if they are transported to the medical facility within the golden hour. However, as those skilled in the art will appreciate, it is often difficult to transport a patient to a remotely located medical facility in a timely manner, particularly within the golden hour. Frequently accidents occur at remote locations and thus require a substantial amount of time to transport the medical patient to a distant hospital. Also, in battlefield situations, it is frequently impossible to transport a casualty immediately. In either instance, a hospital may be located hundreds, if not thousands, of miles from a hospital, thus necessitating several hours of transport time. As such, it is frequently beneficial to perform various emergency medical procedures at the site of the medical problem, and then to attempt to provide ongoing medical care during transport. By providing such early emergency medical care and by continuing medical treatment during transport to a remote hospital, the mortality rate of such transported medical patients is substantially reduced. It is well-known to use various different medical devices in the field, i.e., at locations remote from a medical facility, so as to enhance a medical patient's chance of survival. For example, it is well-known to use an ECG and a defibrillator upon heart attack victims, so as to monitor the condition thereof and so as to provide medical treatment therefor in the field. Typically, the medical patient is placed upon a stretcher and then various different medical devices are used thereupon, as necessary. During transport the medical devices may either be temporarily disconnected from the patient or, alternatively, may be hand carried along therewith by additional personnel. However, disconnection of the medical devices from the patient results in the undesirable disruption of medical monitoring or treatment therefor. Hand carrying the medical devices along with the patient requires extra personnel, which may not be available, or for which there may not be adequate room within the transport vehicle. As such, it is desirable to provide a system for transporting a medical patient wherein the medical devices are carried along with the stretcher. In an attempt to provide such a system for transporting a medical patient while facilitating the continuous use of medical devices thereupon, the Mobile Intensive Care Rescue Facility (MIRF) was developed by the Royal Australian Army Medical Corp. The MIRF is intended to provide sufficient medical equipment to have the capabilities of an intensive care hospital ward. The MIRF is designed so as to facilitate the removal and replacement of the various pieces of medical equipment therefrom for maintenance. The MIRF is specifically designed to accommodate two major roles: the transfer of critically ill people from one point to another, such as from a ward to an x-ray room or from one hospital to another; and the bringing of life support systems quickly to the scene of an accident or other medical emergency. The MIRF can be configured to include a blood pressure cuff, an invasive blood pressure monitor, a body temperature sensor, a heart rate sensor (finger clip sensor), an oxygen saturation sensor, an exhaled air carbon dioxide sensor, and an electrocardiograph, so as to facilitate medical monitoring of a patient. Further, the MIRF can include a ventilation system, a volumetric infusion pump, a syringe pump, a suction unit, and a defibrillator so at to facilitate medical treatment. However, since the various medical devices of the MIRF are not integrated with the housing thereof, the inclusion of all of the medical devices results in a system having substantial weight. Further, since the various medical devices of the MIRF are not integrated with the housing thereof, the volume occupied thereby and the electrical power consumption of the medical devices thereof are not optimal . As such, it would be desirable to provide an integrated system which utilizes a single power supply and which eliminates redundant components, so as to achieve a substantial reduction in weight, volume, and power consumption. Another contemporary system is the MOBI described in United States Letters Patent No. 4,957,121, issued to Icenogle et al . on September 18, 1990. The MOBI is similar to the MIRF in concept. That is, like the MIRF, the MOBI utilizes off-the-shelf medical devices which are contained attached to housing thereof, so as to be transportable therewith, thus eliminating disruptions in the medical care provided thereby during transport. However, also like the MIRF, the MOBI is not an integrated system and thus possesses substantially greater weight, volume, and power consumption than desirable. Further examples of such contemporary life support systems include those disclosed in U.S. Patent Nos. 4,584,989; 4,352,991; 4,691,397; 3,304,116; and 3,341,246. U.S. Patent No. 4,584,989 discloses a life support stretcher bed adapted to accommodate patients in intensive or cardiac care units in hospitals. The life support stretcher bed is broadly adapted for electrical medical devices, medical supplies and features an under carriage including a support structural, wheels, a patient housing with a mattress, an electrical power source and supports for mounting the medical equipment. U.S. Patent No. 4,352,991 teaches a life support system adapted for field use in a vehicle with available power and includes electrically operable life support units, means for supporting the life support units, a patient stretcher, and a dc power source adapted for battery or remote power source. U.S. Patent No. 4,691,397 teaches a device for carrying the life supporting devices of a bedridden patient including a table like means for supporting the devices, an IV holder, wheeled transport means and a hospital bed footboard securing means. U.S. Patent No. 3,304,116 teaches a multiple purpose wheeled carriage capable of supporting a stretcher carrying a patient, adapted with four castered wheels, a fifth wheel, a rectangular frame, a fluid pressure actuated means for vertical adjustment, operating and control means and patient support means. U.S. Patent No. 3,341,246 teaches a hospital stretcher adapted broadly with a litter structure having telescopic post elements and other means for manipulating the patient to various positions. It is frequently desirable to isolate a medical patient from the environment during transport thereof to a medical facility. It is also frequently desirable to isolate the medical patient from care givers and other personnel. Isolating the medical patient from care givers and other personnel may be desirable when the medical patient has a suppressed immune system, open wound, or when the presence of a contagion is suspected among the care givers and/or other personnel. It is desirable to isolate the patient from the environment when the environment contains substances which may be detrimental to the medical patient. For example, if the patient has suffered severe blood loss or is experiencing difficulty breathing, then it is desirable to prevent the patient from breathing dust, engine exhaust, smoke, etc. It is also desirable to isolate the medical patient from the environment when bacteriological, chemical and/or radiological hazards are present, as may occur during battlefield conditions. It may be desirable to isolate the care givers from the medical patient in instances where the medical patient is suspected of having a contagious disease, or has been exposed to bacteriological, chemical or radiological contamination. As such, it is desirable to provide a means for isolating the patient from the environment and care givers, as well as isolating the care givers from the patient. As discussed above, increased transit times make the initial preparation of the medical patient substantially more crucial. This may include resuscitation, and in any event must be sufficient to avoid causing further injury to the medical patient during transport. It is generally also necessary to provide continuous care, i.e., stabilization, for the patient during transit. Proper care during transit frequently includes ventilation, suction, fluid infusion and possibly defibrillation. Further, it is highly desirable to monitor blood pressure, temperature and respiration. It may also be desirable to monitor ventilation gases for p0 2 and pC0 2 , and also to monitor 0 2 saturation, cardiac output and local blood flow. By providing such care and monitoring, the probability of survival for the medical patient is greatly enhanced. Variations in the monitored parameters may signal the need for an immediate change in the medical care being provided. Further, such longer transit times make environmental protection for the medical patient even more desirable. For example, increased transit time makes loss of body heat a much greater concern. Thus, protection from cold and rain is desirable. Although, as discussed above, various different mobile intensive care systems have been proposed, such contemporary mobile intensive care systems are not suitable for transport via military vehicles having standard NATO stretcher holders. Such military vehicles require that the stretcher or other housing upon which the medical patient rests, along with the medical patient, fit within a well defined and rigid envelope so as not to interfere with adjacent vehicle structures and/or other patients and stretchers. No contemporary mobile intensive care system is known which fits with this envelope. Thus, such prior art mobile intensive care systems cannot be efficiently carried via such military vehicles. This means that fewer such battlefield casualties can be transported via a particular military vehicle when such contemporary mobile intensive care systems are utilized, thus inherently causing undesirable delays in transport and also undesirably increasing the risk of mortality. The UH-60 Blackhawk helicopter, the UH-1 Huey helicopter, the Hu Vee ambulance, the C-130 Fixed Wing aircraft, and the C-141 Fixed Wing aircraft all utilize standard NATO stretcher holders such that a plurality of such NATO stretchers, having battlefield casualties laying thereupon, can be efficiently carried thereby. For example, in the UH-60 Blackhawk helicopter, such stretchers are mounted to a vertical bulkhead carousel in a stacked configuration, such that the number of battlefield casualties so carried is maximized. In order to facilitate evacuation of a medical patient from the battlefield to a remote hospital, a number of such military vehicles are commonly used. For example, a HumVee may be utilized to transport the medical patient to a helipad where the medical patient is then transported via a UH-60 Blackhawk or UH-1 Huey helicopter to an airfield. From the airfield the medical patient is then transported, typically, via C-130 or C- 141 fixed wing aircraft to an airport near the remote hospital. As mentioned above, all of these military vehicles presently have stretcher holders which are specifically configured to hold the NATO standard stretcher. In order to be carried via such military vehicles, a life support system must fit within the standard stretcher holders of such vehicles and still leave enough room for the medical patient resting thereon. Of course, the support system must not interfere with adjacent, e.g., stacked, medical patients and/or life support systems. However, to date, no such life support systems are known which are specifically configured to be compatible with such standard stretcher holders. Since contemporary mobile intensive care systems are not configured for transport via military vehicles utilizing standard NATO stretcher mounts, it is frequently necessary to remove the medical patient therefrom, so as to facilitate such transport. Such removal of the medical patient from a contemporary mobile intensive care system may require disconnection from or disruption of desirable medical treatment, thus increasing the risk of mortality. Further, as those skilled in the art will appreciate, removing a medical patient from a mobile intensive care system, such that the medical patient can be placed upon a stretcher for transport aboard a military vehicle utilizing standard NATO stretcher mounts, tends to exacerbate existing injuries and thus tends to further increase the rate of mortality for such battlefield casualties. As such, it is desirable to provide a single mobile intensive care system upon which the medical patient is placed at the battlefield and upon which the medical patient remains throughout the entire trip to the remote hospital. Further, such contemporary mobile intensive care systems require skilled operators having extensive training to assure that proper care is provided to the medical patient. Although mobile intensive care systems requiring such extensive training are generally suitable for use in civilian applications, it is highly desirable to minimize the amount of skill and training required for use in battlefield situations. This allows medics or medical care givers to be trained in a minimum amount of time. It also facilitates use of the life support system when trained personnel are not available (as is often the case in battlefield situations). Thus, it is desirable to provide a mobile intensive care system which requires minimal skill and training for such battlefield applications. Further, since the individual medical devices of contemporary mobile intensive care systems are not integrated with one another, the medical care provided thereby is not optimized. This lack of integration further enhances the requirement for trained personnel. Additionally, such lack of integration necessitates constant monitoring of the medical patient during transport. Constant monitoring of the medical patient is often either difficult or impossible, since skilled medical personnel are generally either not available or are highly taxed during such evacuation procedures. As such, it is desirable to provide means for preparing a medical patient for a lengthy transport, i.e., stabilizing the medical patient, and for providing the necessary medical care during such transport. It is also desirable to provide medical devices which are integrated so as to mitigate the skill and training required for the proper operation thereof, and so as to facilitate automated operation thereof such that minimal attention of a care giver is required during transport. It is also desirable to provide a mobile intensive care system wherein the medical devices thereof cooperate with one another so as to optimize medical care provided thereby. Further, it is desirable to provide a mobile intensive care system which protects the medical patient from the environment, so as to mitigate the detrimental effects thereof. Summary of the Invention The present invention specifically addresses and alleviates the above-mentioned deficiencies associated with the prior art. More particularly, the present invention comprises a self-contained transportable life support system for resuscitation, stabilization, and transport of a patient. As used herein, the terms medical patient and patient are defined to include patients and/or victims of any accident and/or medical condition resulting in the need for emergency medical care. Thus, the term medical patient includes victims of heart attacks and strokes, as well as victims of accidents and wartime casualties. The system comprises an environmentally controlled housing for receiving and supporting a patient, and a plurality of medical devices disposed within the housing. A control circuit is attached to the housing such that at least a portion of the control circuit extends to an external surface of the housing. The control circuit regulates operation of the medical devices and environmental conditions within the housing in response to monitored life support conditions of the patient. The control circuit is programmably controllable to regulate operation of the medical devices and life support conditions of the patient independent of operator intervention. The control circuit preferably comprises a closed-loop control system. The medical devices preferably comprise a ventilator, suction device, fluid infuser, defibrillator, oxygen enricher/generator, electrocardiograph, electroencephalograph blood pressure monitor, temperature sensor, respiration volume and rate monitor, ventilator gas monitor, 0 2 saturation monitor, and a cardiac rate and cardiac output and local blood flow monitor, and a device for performing blood chemistry analysis. A heater is preferably disposed within the housing and in electrical communication with the control circuit, for heating an interior portion of the housing so as to maintain the interior portion above a predetermined minimum temperature. Similarly, a cooler is preferably disposed within the housing and in electrical communication with the control circuit, for cooling an interior portion of the housing so as to maintain the interior portion below a predetermined maximum temperature. An air filtration system is preferably disposed within the housing and in electrical communication with the control circuit, for filtering air within the housing. The medical devices comprise at least one medical monitoring device for monitoring at least one life support condition of the patient and at least one medical treatment device for providing medical treatment to the patient. The medical devices providing treatment are regulatable by the control circuit in response to signals from the medical monitoring devices. A communication circuit attached to the housing provides communications between the control circuit and a remote location. The communication circuit preferably comprises a transmitter for transmitting information representative of patient life support conditions and patient physiological status and a receiver for receiving externally generated remote control signals. The control circuit is responsive to the remote control signals, such that patient life support conditions are regulatable in response to the remote control signals. The control circuit preferably comprises a general purpose microprocessor. The housing has an interior portion which is configured to receive and engage a stretcher. An exterior portion is configured to engage vehicular mounted stretcher supports. The housing preferably comprises four stretcher retention members disposed within the housing for receiving and engaging a stretcher within the housing. Each of the stretcher retention members comprises a stretcher engagement mechanism operative to provide locking engagement to the stretcher solely in response to placement of the stretcher upon the stretcher engagement mechanism. The control circuit preferably comprises first and second battery sections. A charging circuit selectively charges either one of the first and second battery sections or both sections simultaneously. The control circuit is operative to alternately charge the first battery section from an external power source while maintaining the second battery section ready to power the medical devices during an interruption of external power. Then the charging control circuit is operative to charge the second battery section from the external power source while maintaining the first battery section ready to power the medical devices during an interruption of external power. Thus, while each battery section is being charged, the other battery section is in a stand-by mode, such that it serves as a backup power source and takes over operation of the medical devices in the event that the external power source which is providing electrical power to the medical devices fails. The medical devices preferably comprises a temperature monitoring system connectable to a patient for monitoring a body temperature of the patient and a temperature control system connectable to the patient for controlling the body temperature of the patient. The temperature control system alternatively comprises an extracorporeal blood temperature controller for regulating the blood temperature of the patient in response to the temperature monitoring system. Alternatively, the temperature control system comprises a temperature controlled water jacket. The temperature monitoring system preferably comprises either an indwelling rectal temperature probe, an infrared eardrum temperature sensor, an axillary temperature sensor, or an intraesophageal temperature sensor. Two invasive pressure sensors are preferably provided, so as to facilitate simultaneous measurement of blood pressure and intracranial pressure, for example. According to one preferred configuration of the present invention, the temperature control system directs temperature controlled air about the patient in response to the temperature monitoring system, so as to maintain the temperature of the patient within a desired range. The housing is preferably sealable so as to isolate the patient therein from chemical, biological and radiological conditions existing external to the housing. A pressure regulating mechanism disposed within the housing and in electrical communication within the control circuit regulates pressure within the housing so as to facilitate such isolation. The control circuit preferably comprises an audio/visual device disposed external to the housing and in electrical communication with the control circuit, for displaying patient life support conditions. The audio/visual device preferably displays treatment instructions in response to patient life support conditions. The control circuit preferably comprises a power regulator for regulating application of electrical power to the medical devices in accordance with an assigned priority status of the medical devices. The controller is preferably operative to modify the assigned priority status of medical devices in response to the patient support conditions in order to preserve the limited battery resource. The control circuit is preferably operative to simulate a plurality of life support conditions, to monitor an operator's utilization of the medical devices in response to the simulated life support conditions, and to evaluate the effectiveness of the operator's utilization of the medical devices. The housing preferably comprises a hyperbaric chamber and a hypobaric chamber, preferably formed of a lightweight, durable polymer or composite material. The control circuit preferably comprises a medical data reader for receiving medical data from a medical data storage device. The control circuit is operative to regulate operation of the medical devices in response to the received medical data. The medical devices preferably comprise a "dog tag" having medical data stored therein, an identification card having medical data stored therein, or a data storage device implanted beneath a patient's skin. These, as well as other advantages of the present invention will be more apparent from the following description and drawings. It is understood that changes in the specific structure shown and described may be made within the scope of the claims without departing from the spirit of the invention. Brief Description of the Drawings Figure 1 is a perspective view showing two self- contained transportable life support systems of the present invention containing battlefield casualties, ready for transport upon a helicopter; Figure 2 is a perspective view of the self-contained transportable life support system of Figure 1 showing the upper housing section and the medical patient exploded away from the housing thereof; Figure 3 is a schematic view of a patient disposed upon the lower housing section of the present invention and having a plurality of medical devices attached thereto; Figure 4 is a perspective view of one preferred configuration of the head end of the self-contained transportable life support system of the present invention; Figure 5 is a perspective view of the head end of the self-contained transportable life support system of Figure 4 showing the infusion device thereof deployed for use; Figure 6 is a perspective view of the open lower housing section of the present invention, showing the medical devices and system components contained therein; Figure 7 is a top plan view of the open lower housing section of Figure 6; Figure 8 is an exploded view of the lower housing section; Figure 9 is a block diagram of the communications, controls, and displays graphical interface; Figure 10 is a schematic representation of the communication, controls, and displays hardware architecture; Figure 11 is a block diagram of the communications, controls, and displays interface; Figure 12 is a sample algorithm for the controls and displays; Figure 13 is a symbol utilized to indicate that the defibrillator is off; Figure 14 is a symbol utilized to indicate that the defibrillator is on and charging; Figure 15 is a functional block diagram of the power management system; Figure 16 is a block diagram showing the power management system in the autonomous mode; Figure 17 is a block diagram showing the power management system in the recharge mode; Figure 18 is a block diagram showing the power management system in the auxiliary power mode; Figure 19 is a block diagram showing the power management system in the auxiliary power with recharge mode; Figure 20 is a block diagram showing the power management system in further detail; Figure 21 is a perspective view of the battery pack system; Figure 22 is a schematic illustration of the battery segment; Figure 23 is a full system schematic diagram of the environmental control system; Figure 24 is a functional block diagram of the environmental control system; Figure 25 is a block diagram of the environmental control system equipment cooling subsystem; Figure 26 is a block diagram of the environmental control system patient cooling subsystem; Figure 27 is a block diagram of the environmental control system pneumatic subsystem; Figure 28 is a schematic representation of the heat load interactions; Figure 29 is a block diagram of the ventilator; Figure 30 is a block diagram of the ventilator and onboard oxygen generator system; Figure 31 is a block diagram of the communication system and external interfaces; Figure 32 is a perspective view of a stretcher retention member; Figure 33 is an electrical schematic of the present invention; Figure 34 is a flow diagram showing different display presentations; Figure 35 is a functional diagram showing the software architecture of the present invention; Figure 36 is a sample screen display showing blood pressure; Figure 37 is a sample display showing a plurality of controls; Figure 38 is a sample screen display showing graphs of breathing rate and title volume; Figure 39 is a sample screen display showing patient status; Figure 40 is a sample screen display showing the results of performing the built in test (BIT), wherein passing a subsystem passing the built in test is represented a green line interconnecting the system BIT symbol and the subsystem symbol and a subsystem failing the test is represented by a red line interconnecting the system BIT symbol and the subsystem symbol; Figure 41 is a simplified block diagram illustrating operation of the control circuit; and Figure 42 is a detailed block diagram illustrating the control circuit in further detail. Detailed Description of the Preferred Embodiment The description set forth below in connection with the appended drawings is intended as a description of the presently preferred embodiment of the invention, and is not intended to represent the only form in which the present invention may be constructed or utilized. The description sets forth the functions and the sequence of steps for constructing and operating the invention in connection with the illustrated embodiment. It is to be understood, however, that the same or equivalent functions may be accomplished by different embodiments that are also intended to be encompassed within the spirit and scope of the invention. Although discussed and illustrated herein as having particular application in battlefield situations, those skilled in the art will appreciate that the transportable life support system of the present invention may be utilized in various different civilian applications, such as emergency rescue and medical evacuation. As such, description and illustration of the present invention for battlefield applications is by way of illustration only, and not by way of limitation. The transportable life support system of the present invention is illustrated in Figures 1-42 which depict a presently preferred embodiment thereof. Referring now to Figure 1, two self-contained transportable life support systems 10 of the present invention contain battlefield casualties,i.e. , or medical patients 12, who have been readied for transport upon an evacuation vehicle, i.e., helicopter 14. A soldier 16 views a hand held monitoring device 18 via which the medical condition of the medical patients 12 is monitored. The monitoring device 18 provides an indication of the status of each patient 12 contained within a self-contained transportable life support system 10. Optionally, the monitoring device 18 prioritizes patients according to the severity of their medical condition, so as to provide an indication of which medical patients 12 should be evacuated first. Additionally, the monitoring device 18 performs a data logging function, so as to provide a record containing the identification of the medical patient 12, the medical condition thereof, the time of evacuation, and the destination to which the medical patient 12 is to be transported. Each of the medical patients 12 has a plurality of medical devices in use thereupon, so as to enhance the survivability thereof. The medical devices provide medical monitoring and medical treatment which is intended to extend the golden hour sufficiently to allow transport thereof from the battlefield to a remotely located hospital. Integrated controls and displays 24 minimize the effort required by a medic or other minimally trained personnel in order to provide adequate medical care for the patient. The self-contained transportable life support system of the present invention is specifically configured to facilitate attachment of a standard NATO stretcher (Stanag) thereto via drop-in attachment wherein stretcher retention members receive and engage the handles of the standard NATO stretcher solely in response to placement of the stretcher thereupon. Thus, in use, the stretcher is merely laid upon the self-contained transportable life support system to facilitate automatic attachment thereto. Once the stretcher is so attached, the desired medical monitoring devices and medical treatment devices are utilized to provide the desired medical care for the medical patient. Referring now to Figure 2, the medical patient 12 is disposed upon a standard NATO stretcher 20. The stretcher attaches to the lower housing section 22 of the self-contained transportable life support system via four stretcher retention members 24 which automatically attach the stretcher 20 thereto when the stretcher is placed upon the lower housing section 22. An optional upper housing section 26 forms a canopy over the medical patient 12, and cooperates with the lower housing section 22 so as to define a housing which provides isolation for the medical patient 12. A transparent window 27 is preferably provided to facilitate viewing of the medical patient 12. The upper housing section 26 is optionally pressurizable so as to enhance such isolation. Positive pressurization, i.e., pressure above ambient, of the upper housing section 26 is provided to isolate the medical patient 12 from care givers and/or the environment. Such positive pressurization of the upper housing section 26 causes air to leak therefrom. Thus, air is prevented from leaking into the upper housing section 26. Thus, biological, chemical, and radiological isolation may be provided for the medical patient 12 by filtering air prior to pressurizing the upper housing section 26 with it. The upper housing section 26 may also be provided with a negative pressure, i.e., a pressure below ambient, such that air leaks from the environment into the container, so as to provide for isolation of the care givers from the medical patient. In this instance, air drawn into the upper housing section is filtered prior to being exhausted therefrom. The upper housing section 26 is preferably formed of a lightweight, rigid, polymer or composite material. Alternatively, the upper housing section 26 may be comprised of a fabric, having support straps or hoops for maintaining the desired shape thereof. In any event, the upper housing section 26 is preferably configured so as to provide a substantially air tight seal to the lower housing section 22, so as to minimize air leakage either there into or therefrom, thus improving the isolation capability. However, it would be recognized that an absolutely air tight seal is not necessary since the upper housing section 26 can be pressurized as discussed above, so as to provide the desired isolation. The medical devices are preferably integrated into the lower housing section 22 in a manner which minimizes the weight and volume thereof. Weight is minimized by eliminating components common to a plurality of the medical devices, such as the power supplies therefor. Volume is minimized by such elimination of common components and also by packaging the medical devices more economically than is possible with off-the-shelf devices. Further, such integration of the medical devices provides for more efficient power consumption since the devices are powered from a common source and are under common control, so as to facilitate more efficient operation thereof. According to the preferred embodiment of the present invention, a fluid infuser 28, which is stored within a storage compartment of the lower housing section 22 prior to use, may be laid upon the stretcher to provide fluid infusion for the medical patient 12. The stretcher 20 comprises two poles 30, each pole having two handles 32, one handle being formed upon either end thereof. Canvas 34 stretchers between the two poles 30. Two feet 31 depend downwardly from each pole 30. The lower housing section 22 is configured to receive the feet 31 within channels 39 formed within the lower housing section 22, so as to prevent longitudinal movement of the stretcher 20 with respect to the lower housing section 22. The stretcher retention members 24 prevent lateral, as well as vertical, movement of the stretcher 20 relative to the lower housing section 22. Referring now to Figure 3, the medical monitoring devices and medical treatment devices provided to a patient disposed upon the self-contained transportable life support system of the present invention are shown schematically. Either medical grade air, i.e., oxygen enriched air 70 or oxygen 72, is provided via the ventilator 50 to the patient 12. Such oxygen enriched air or oxygen may be provided to the ventilator either via the onboard oxygen generator system, pressurized oxygen bottles, or via an external source thereof. The suction unit 44 may be used to provide suction to maintain a clear airway or, alternatively, may be utilized to provide suction to wounds, as desired. Physiological monitors 74 monitor such medical parameters as blood pressure, heart rate, ECG, etc. Defibrillator 76 may be used when fibrillation is indicated by the physiological monitor 74 or by the defibrillator's automated assessment of patient status. A blood chemistry assessor 78 provides blood chemistry assessment. Data logging facilitates review of the patient's monitored medical parameters and treatment. It is important to remember that the medical devices shown in Figure 3 are actually integrated into the lower housing section 22 of the present invention, and are not off-the-shelf, separate discreet units, as shown. The medical devices are illustrated as separate, discreet, off-the-shelf units for clarity only, and so as to give a general indication of the types of medical devices integrated into the present invention. Referring now to Figures 4 and 5, one preferred configuration of the head end of the lower housing section 22 is shown. According to this preferred configuration, the head end 26 of the lower housing section 22 comprises a visual display 84 for displaying information regarding operation of the ventilator. Controls 86 for controlling operation of the ventilator allow a care giver to vary the respiration rate and tidal volume. Physiological monitoring is facilitated via monitor 88 which facilitates display of blood pressure, temperature, ECG, etc. and also provides for the control of the medical monitoring devices which monitor blood pressure, temperature, ECG, etc. The controls of the physiological monitor 88 also allow the care giver to preset alarm limits for physiological parameters such as blood pressure, temperature, ECG, etc. When such an alarm is exceeded, an audible alarm sounds. Intravenous drug administration is facilitated via infusion pump 90, which may comprise a high volume infusion pump. According to the preferred embodiment of the present invention, three separate fluid inputs are accepted by the infusion pump 90 and three separate metered outputs are provided thereby. The three outputs can be joined together into a single output, in any combination desired. Suction reservoir 92 facilitates the collection of fluids collected by one or more suction device(s). Referring now to Figure 6 and 7, according to the preferred embodiment of the present invention, the lower housing section 22 contains the medical monitoring devices and medical treatment devices necessary to prolong the golden hour sufficiently to enhance a patient's survivability during extended transport to a remote medical facility. The lower housing section 22 preferably comprises a lightweight polymer or composite structure configured to contain the medical monitoring devices and medical treatment devices. The medical devices are integrated with the lower housing section 22 in a manner which reduces the volume thereof. Such integration also facilitates construction of the present invention in a manner which allows it to be used in military vehicles having standard NATO stretcher mounts, wherein the size of equipment received within the standard NATO stretcher mounts is strictly constrained in order to avoid interference with nearby stretchers and/or other mounted objects, i.e., battlefield casualties on NATO stretchers. A monitor or touch screen display 25 is formed at the head end 26 of the lower housing section 22. The touch screen display 26 preferably comprises a closable cover 29 to provide protection thereto. A second monitor and/or touch screen may be formed upon the inner surface of the cover 29, if desired. An environmental control system fan assembly 30 is provided at the foot end 32 of the lower housing section 22 and comprises at least one fan for drawing air into the upper housing section 26 and filters for filtering the air. In a similar manner, equipment fan assembly 34 contains at least one fan for drawing air into the equipment compartment 36 of the lower housing section 22 and filters for filtering the air drawn into. According to the preferred embodiment of the present invention, the filters of the system fan assembly 34 provide chemical, biological, and radiological filtering, so as to provide isolation of the medical patient 12 disposed within the upper housing section 26. The filters of the fan assembly 34 provide particulate filtering, so as to inhibit contamination of the medical devices contained within the lower housing section 22. The air path of the upper housing section 26 and the lower housing section 22 are separate and isolated from one another, such that the air in each path is not commingled. When the self-contained transportable life support system of the present invention is first powered up, the equipment fans run for a short period of time prior to the application of electrical power to the medical devices, such that any oxygen and/or hydrogen which is built up in the lower housing section 22 is exhausted prior to fully powering the system up, so as to mitigate any explosion or fire hazard which could be caused thereby. Power supply circuitry 36 receives electrical power from battery packs 38 or power converters 44 to provide electrical power to the medical devices. The battery packs 38 define first and second battery sections which cooperate to provide electrical power to the various medical devices of the self-contained transportable life support system. Preferably, a controller is configured to facilitate charging of one of the battery sections while the other of the battery sections is providing power to the self-contained transportable life support system, and then the roles of the two battery sections switch such that the second battery section provides electrical power to the self-contained transportable life support system while the first battery section is charging. A suction pump 40 may be utilized to provide suction to maintain clearance of the airway, as well as to remove blood and/or other body fluids from wounds, etc. Fluids removed by the suction pump 40 may either be dumped overboard or deposited within suction bottle 42 for later analysis. Power converters 44 convert electrical power from a building, transport vehicle, etc. into power which is usable for running the medical devices of the self- contained transportable life support system, as well as power for charging the batteries 38 thereof. Control circuitry 46 facilitates control of the medical devices of the present invention such that the medical treatment devices thereof are responsive to the medical monitoring devices thereof and such that the medical treatment devices cooperate to provide beneficial medical treatment to the patient. The control circuitry 46 is responsive to operator input via the touch screen display 26, a separate hand-held monitoring device, as well as remote control instructions from medical personnel at a remote medical facility. Ventilator pneumatic controller 48 controls the ventilator compressor 50 so as to provide ventilation for the medical patient. The closed-loop ventilator accepts oxygen from either an external source or from the onboard oxygen generator/pressurized oxygen bottle/enrichment system. The ventilator can also be utilized to administer anesthesia. Oxygen generator 52 provides oxygen or oxygen enriched air which may be provided to the patient through the ventilator. Channels 39 are configured to receive the feet 31 of the stretcher 20, so as to prevent longitudinal and lateral movement of the stretcher relative to the lower housing section 22. Stretcher retention members 24 facilitate drop-in attachment of the stretcher to the lower housing section 22 such that the handles 30 of the stretcher need merely be placed upon the stretcher retention members 24, which then open in response to the weight of the stretcher and automatically close about the handles thereof so as to provide secure attachment of the stretcher to the lower housing section 22. Alternatively, the stretcher retention members 24 may be opened manually and then closed in response to lowering of the stretcher handles 30 thereupon. The stretcher retention members 24 prevent lateral and vertical movement of the stretcher relative to the lower housing section 22. Oxygen reservoirs 56 temporarily store oxygen generated by the oxygen generator 52. The use of an onboard oxygen generator 52 eliminates the need to carry heavy and bulky bottled or liquid oxygen. The onboard oxygen generator preferably utilizes facilitative transport membrane to provide oxygen or oxygen enriched air to the medical patient. Heat exchangers 58 facilitate temperature control of the patient by providing temperature controlled air or water thereto. An environmental control system preferably comprises a vapor compression cooler and a heater and an air temperature controller. According to the preferred embodiment of the present invention, the air temperature controller can both heat and cool air which is provided to the upper housing section 26 for breathing. Additionally, the environmental control system comprises an air filter system for filtering breathing air supply to the upper housing section. The breathing air is filtered so as to remove biological, chemical, and radiological contamination in a manner similar to that of a contemporary gas mask. Referring now to Figure 8, the lower housing section 22 generally comprises a sled 100, padding 102 is disposed upon the sled 100 such that the patient is supported thereby when placed upon the lower housing section 22. The lower housing section 22 is configured such that the canvas 34 of the stretcher 20 rests upon the pads 102, such that the pads 102 receive the full weight of the patient. The filter housing 104 houses the fan and filter assemblies which provide cooling into the medical devices, as discussed above. Access door support stiffeners 106 provide structural rigidity to the access doors. Forward access door 108 provides access to the head compartment 11 of the lower housing section 22, center access door 110 provides access to the center compartment 13 of the lower housing section 22 and, aft access door 112 provides access to the foot compartment of the lower housing section 22. Center access door stiffeners attach to the center access door 113 to provide structural rigidity thereto. Environmental control system equipment exhaust housing 30 contains the environmental control system fans and filters for providing filtered air to the upper housing section 26, as described above. Referring now to Figure 9, the display 24 is controlled via system management algorithms 202 which cooperate with low level digital and analog input/output channels 204. The low level digital and analog input/output channels cooperate with patient care management algorithms 206, the status of which are displayed upon display 24. Device communications and interfaces 208 cooperate with patient care management algorithms 206 and system management algorithms 202. Referring now to Figure 10, the display 25 is preferably under the control of a CPU 302 having at least 8 megabytes of RAM 304 and at least 100 megabytes of hard disk or equivalent non-volatile storage 305. According to the preferred embodiment of the present invention, 48 channels of digital input/output 306 are provided. The input/output channels provide information regarding device status, i.e., on/off, charge configuration, relay on/off, and digital sensors. The digital input/output 306 also facilitates control of the defibrillator. Thirty-two channels of analog input/output 308 provide pressure sensing, temperature sensing, velocity sensing, gas sensing, etc. Six serial input/output channels provide external communications, data storage device communications, physiological sensors, ventilator, and touch screen. Referring now to Figure 11, the control circuitry 46 of the central controller controls the operation of the onboard oxygen generator system 52, the ventilator controller 48, the environmental control system 49, the power distribution system 51, the suction unit 40, the display 25, the defibrillator 29, the infusion pump 28, the physiological monitor and IV pump controller 55, the patient sensors 57, and the communications unit 88. Referring now to Figure 12, a sample controls and displays algorithm is shown. According to the sample algorithm, when a high C0 2 level is sensed, then stale air is dumped from the upper housing section 26 by starting the fan 154, if it is not already running. The exhaust valve is opened, with a time delay, if desired. Air movement is preferably verified. Trend analysis is then initiated upon the patient to verify that C0 2 is being properly exhausted. When the housing C0 2 level is at an acceptable level, then the system returns to the normal operation state. If the C0 2 cannot be cleared, then an alarm is sounded to alert the care giver. Figure 13 shows the preferred symbol utilized to indicate that the defibrillator is off and Figure 14 shows the preferred symbol used to indicate that the defibrillator is being charged. Flashing of the symbol of Figure 14 indicates that the defibrillator is ready to discharge. Pressing the flashing symbol of Figure 14 on the touch screen 25 causes the defibrillator to discharge. Referring now to Figure 15, power converters 44 are configured to accept electrical power from the Blackhawk Medevac helicopter 350, the HumVee 352, as well as STD CONUS POWER 354. Power conditioner 61 assures that the power is compatible with the main bus 63 of the self- contained transportable life support system of the present invention. The batteries 38 receive power from the main bus 63 to facilitate charging thereof and provide power to the main bus 63 when being utilized for the operation of the self-contained transportable life support system. Non-noise sensitive lodes 81 receive power directly from the bus 63 while sensitive lodes 83 receive power via precision power supplies 85. Referring now to Figures 15-19, the operational modes of the power management system are illustrated. ith particular reference to Figure 16, in the autonomous mode of operation, the batteries 38 provide electrical power to the environmental control system 49, the onboard oxygen generator system 52, the ventilator and compressor units 48, the suction unit 40, the controls and displays unit 25, the communication unit 88, the defibrillator 29, the data storage device 55 (data storage device for maintaining a log of medical parameters and medical treatment provided), and the infusion pump 53. With particular reference to Figure 17, in the recharge mode, the power converters 44 provide electrical power to the battery groups 38. With particular reference to Figure 18, in the auxiliary power mode, electrical power is provided by an outside source. Such electrical power may comprise 400 hertz 500, 120 VAC 502 and/or 25 VDC 504. The power converter 44 receives, the 400 hertz 500 and/or the 120 VAC 502 and provides an output at 21.2 amps maximum, 534 watts maximum to the ECS system 49, onboard oxygen generator system 52, ventilator and compressor unit 48, suction unit 40, control and display unit 25, communications unit 88, defibrillator 29, data storage device 55, and infusion pump 53. With particular reference to Figure 19, during the auxiliary power with recharge mode, the battery power groups 38 are charged while providing operation similar to that in the auxiliary power mode of Figure 18. Referring now to Figure 20, an overall schematic representation of the power management system is provided. This schematic representation shows the various relationships of the power sources, i.e., the 400 hertz 500, 120 VAC 502 and the 25 VDC 504. The battery power group 38 may be charged, as shown in Figure 19. Powers provided to the various loads as shown in Figures 16, 18 and 19. Referring now to Figure 21, each battery section is preferably comprised of a plurality of battery packs 600, each battery pack comprising a plurality of individual batteries 602 which are connectable to the electrical system of the self-contained transportable life support system via negative bus bar support 604 and positive bus bar support 606. Thus, the negative bus bar support 604 and the positive bus bar support 606 provide for both the electrical connection of the battery pack, as well as the mechanical mounting thereof. Negative relay control 608 and positive relay control 610 facilitate selective reconfiguration of a particular battery pack from the remaining packs in the event of failure thereof protection diodes 612 isolate reconfigured battery cells and prevent overcharging of the battery 602. Thus, in the event that a particular cell fails to operate properly, the battery pack containing that cell is automatically disconnected from the remaining battery packs, so as to facilitate the maintenance of desired power to the medical devices. Each battery pack preferably comprises 42 individual cells. Referring now to Figure 22, a plurality of battery packs such as those shown in Figure 21 are configured so as to provide approximately 25.2 volts DC to the power bus. With particular reference to Figure 23, wherein the full system schematic of the environmental control system is provided, a nuclear/biological/chemical (NBC) filter 150 and a fan 152 are disposed within the upper housing section fan assembly 30. The fan 152 provides filtered air to cooling fan 154 which directs the filtered air onto the patient 12. A portion of the air brought into the upper housing section via blower 152 is exhausted therefrom as leakage 156. Another portion of the air brought into the upper housing section 26 via blower 152 is provided to the suction unit 40. Another portion 158, the remainder 160 of the air brought into the upper housing section via the blower 152 is re-circulated within the upper housing section, preferably passing through air/water heat exchanger 162. The heat exchanger preferably provides 1 gallon per minute of temperature controlled water at approximately 20 psid from the cooling unit 164. The cooling unit 164 preferably comprises a motor driver 166 for driving a compressor pump unit 168 so as to circulate refrigerant through an evaporator 170 and a condenser 172 according to well- known refrigeration principles. A check valve 174 prevent back flow of air into the suction unit. Similarly, a check valve 176 prevents back flow into the ventilator/compressor 50. The outputs of the ventilator/compressor 50 and suction unit 40 may either be dumped overboard or dumped into a container, as desired. With particular reference to Figure 24, a functional block diagram of the environmental control system is provided. According to the preferred embodiment of the present invention, both a clean air path 400 and an open- loop cooling system 402 are provided. Ambient air 404 is NBC filtered 406. Optionally, a pressurization unit 408 pressurizes a patient compartment 410 of the upper housing section in a desired fashion. The patient compartment 410 of the upper housing section may be pressurized to a level slightly above ambient to isolate the patient from the environment and care giver. Alternatively, the patient compartment 410 of the upper housing section 26 may be pressurized to a level slightly less than ambient to isolate the care giver from the patient. Closed-loop cooling system 412 facilitates desirable temperature control of the patient compartment 410. When the patient compartment is pressurized slightly above ambient pressure, then leakage overboard 414 occurs. Exhalant dump 416 is also exhausted from the patient compartment. The suction unit 40 provides a dump 418 overboard. In the open-loop cooling system 402, ambient air 404 is subjected to particulate filtration 420. The particulate filtered air is then provided to the oxygen generating system 422, the medical electronics 424, the control electronics 426, and the mechanical/electrical equipment 428, all of which receive electrical power from the battery groups 430. The battery groups 430 provide electrical power to the various air movers 432 which then exhaust hot air 434 out of the system. The hot exhaust receives its heat from the closed-loop cooling system heat rejection unit 436. Referring now to Figure 25, the particulate filter 17 provides particulate filtered air to the head compartment 11, center compartment 13, and foot compartment 15, in that order. Within the head compartment 11, sensor boards, precision power supplies, defibrillator board and battery, and the suction pump are cooled by the particulate filtered air. Within the center compartment 13, the power converters 44, central controller 46, ventilator compressor 50, ventilator pneumatic controller 48, onboard oxygen generation system 52, compressor 51 as well as any other electrical devices disposed therein are cooled by the particulate filtered air. In the foot compartment, the battery packs 78 and gear pumps 4 are filtered by the particulate filtered air. Referring now to Figure 26, the patient cooling subsystem comprises a generally re-circulating air system wherein fan 154 provides the patient 12 within the patient compartment 410 defined by the upper housing section with temperature controlled air, preferably at 100 cubic ft. per minute at 0.20 inches water column. The air is provided to the patient at approximately 72°F (22"C). Approximately 379 watts of heat must be removed from the patient compartment 410 in order to maintain the exhaust temperature therein at approximately 84°F (29'C). The re-circulating air is exhausted from the patient compartment 410 and provided to an air/water heat exchanger 162 which preferably circulates water at approximately 1 gallon per minute at 20 psid therefrom to the cooling unit 164. Water preferably exits the cooling unit 164 and enters the air/water heat exchanger 162 at a temperature approximately 65°F and is pumped by two redundant gear pumps 180 and 182. After leaving the air/water heat exchanger 162, the water is at approximately 69°F and is cooled by the evaporator 170 of the cooling unit 164 back to approximately 65°F. With particular reference to Figure 27, the pneumatic subsystem is shown. The onboard oxygen generator 52 provides oxygen or oxygen enriched air 53, preferably at a rate of approximately 0.7 cubic ft. per minute average, 2.1 cubic ft. per minute peak, to the ventilator/compressor 50. Exhaust air 55 from the ventilator/compressor passes to the patient 12 through check valve 176 and is preferably dumped overboard. Alternatively, the exhausted air may be filtered for later analysis. The NBC filter 150 preferably provides 3.5 cubic ft. per minute max, 1.7 cubic ft. per minute average, and 1 cubic ft. per minute minimum, at approximately 1.2 inch water column minimum. Air from the NBC filter 150 and blower 152 provides air to both the ventilator/compressor 150 and the patient 12. Referring now to Figure 28, a heat load interaction diagram is provided. The upper housing section 26 receives heat load from the solar source (i.e., the sun), ambient air 502, the sky 504, and surrounding structures 506. The controlled environment 508 receives heat loading from the solar source 500, the upper housing section 26, circulation fans and pressurization blowers 510, the insertion of powered objects 512, such as the IV and the data storage device, and the patient 12. Additionally, onboard heat generators 518 include the batteries, electronics, power converter, environmental control system hot side equipment, ventilator, and suction unit. The lower housing section is subject to heating and/or cooling via ground contact 520, the effects of surrounding structures 522, ground layer ambient air 524, and ground reflective solar radiation 526. The controlled environment is also subject to pressurization air leakage 514, and onboard air consumption 516. Referring now to Figure 29, a schematic depicting operation of the ventilator is provided. Ambient air is drawn through the NBC filter 150 by fan 152. Air compressor 700 driven by motor 702 provides air through water separation filter 704 to air reservoir 706. Wall air is provided through connectors 710 to the regulator 712. The output of the regulator 712 is provided to the air reservoir 706. Ambient air is also provided to the onboard oxygen generator system 52, the output of which is low pressure oxygen or oxygen enriched air which is provided to optional buffer reservoir 714. From the optional buffer reservoir, oxygen flows through oxygen compressor 716 to oxygen reservoir 718 where it is stored at approximately 20 to 30 psi. Oxygen may also be provided to the oxygen reservoir 718 from a wall outlet via connector 720 and regulator 722. Oxygen from the oxygen reservoir 718 is blended with air from the air reservoir 706 via blender 724 having a high pressure (20-30 psi) output. Ventilator controls 726 then facilitate the administration of oxygen or oxygen enriched air to the patient 12. Referring now to Figure 30, the integration of the ventilator and onboard oxygen generator system and the interfaces thereof are shown. Suction is provided via suction tube 800 so as to facilitate air way clearance. Fluids drawn through suction tube 800 are collected in suction reservoir 802. Preferably, suction between 0 and 200 mmHg. is provided. Ventilation is facilitated via ventilation tube 804 which extends into the patient's trachea and is connected to pC0 2 capnograph sensor 808. Exhaust from the ventilation tube 804 is facilitated via expiration tube 806 from pC0 2 capnograph sensor 808. pC0 2 capnograph signal data is transmitted via capnograph electronics to the system control circuit. Optional vaporizing assembly 810 facilitates the vaporization of anesthetic gases. The vaporization assembly 810 can be by-passed, as desired. The ventilator performs gas mixing at a high pressure of between 20 and 50 psi. Air way pressure and tidal volume are controllable, either manually or via the system control circuit. Timing may also be either manually controlled or controlled via the system control circuit. Referring now to Figure 31, the data communication and associated external interfaces are shown. The enclosure, upper housing section 21 houses the patient 12. The physiological monitor and IV pump controller 55 stores the output of sensors attached to the patient 12 and control pump 28. The local control module 762 is a standalone device which may be carried by medical personnel to monitor the status of the patient contained within the self-contained transportable life support system of the present invention as shown in Figure 1. Thus, a single local control module 762 can be utilized to monitor a plurality of different self-contained transportable life support systems to verify the proper operation thereof and the condition medical patient contained therein. The personal status monitor 18 monitors the status of the patient and may control the infusion pumps 763 and also communicate with the physiological monitor. The pump 763 may be a portable infusion external to the self- contained transportable life support system. Such communications preferably are facilitated via the radio 754 of the self-contained transportable life support system, or an equivalent external radio. The data storage device 90 is in communication with a radio 750 so as to facilitate communications with remote medical personnel . Communications are optional and facilitated with administrative personnel to facilitate logistics regarding injured personnel at a ground station 752. Communications with external devices may be either via an RS-232 link, or preferably, an Ethernet link. Referring now to Figure 32, a stretcher retention member 34 according to the present invention is shown. The structure retention member is preferably configured such that attachment of the lower housing section to a stretcher is facilitated by merely dropping or lowering the stretcher upon the stretcher retention members 54 such that the handles 32 of the stretcher 20 contact the stretcher retention members 54 and are captured thereby. Optionally, the stretcher member 34 may be configured such that manual opening thereof is required prior to placing the stretcher 20 thereupon. Once the stretcher 20 is then placed the stretcher retention member 34, the stretcher retention member 34 closes and locks about the handles 32 of the stretcher 20. According to one preferred configuration of the retention member 34, a lower coupling 122 is formed upon a base 120. The base 120 facilitates attachment of the stretcher retention member 34 to the lower housing section 22 of the present invention. An upper coupling 124 is pivotally attached to the lower coupling 122 and is disposable in open and close positions. In the open position, as shown in Figure 32, an activation bar 126 extends approximately perpendicularly from the upper coupling 124 such that when a stretcher 20 is laid upon the lower housing section 22, one handle 32 thereof engages the activation bar 126 and pushes the activation bar downwardly, thus rotating the upper coupling 124 into the closed position thereof. When the upper coupling 124 is rotated into the closed position thereof, the upper coupling 124 locks in place, such that it must be manually unlocked in order to remove the stretcher 20 from the lower housing section 22. Referring now to Figure 33, a schematic of the present invention is provided. According to the present invention, a variety of different power inputs may be utilized to operate the medical devices thereof and/or simultaneously charge the batteries thereof. According to the preferred embodiment of the present invention, such external power may comprise 115/200 VAC, 400 Hz; 120 VAC, 60 Hz; 25 VDC. This power is provided to power converters 44 which provide nominal 25.2 volts DC to facilitate operation of the medical devices and/or charging of the batteries 38. Control circuit 46 facilitates cooperation of the different medical monitoring and medical treatment devices, so as to provide proper medical care for the patient, depending upon the particular medical problems thereof. Referring now to Figure 34, the touch screen monitor 24 displays various medical parameters 790, 791, 792, 793 and 794, as well as displaying controls 795 for facilitating desired operation of the medical devices. The medical monitoring devices and medical treatment devices of the present invention are preferably under the control of a control circuit 46, preferably a general purpose microprocessor, which runs an algorithm program to facilitate desired monitoring and control of the medical devices. As shown in Figure 35, the software architecture comprises system input/output 900, communication 902 and a graphical user interface 904. According to the preferred embodiment of the present invention, system management functions 906, as well as patient care functions 908 comprise applications which run under any suitable operating system. The system input/output includes device input/output, data storage device, ventilator, touch screen, defibrillator, radio frequency communications, infusion pump and physiological sensors. The screen input/output for the environmental control system, power, gas monitoring, contaminants, defibrillator, and equipment bay is also provided. System input/output also includes power management, environmental control system management, i.e., patient compartment, as well as the equipment bay. Preferably, built-in test functions are provided. The graphical user interface includes ventilator management, onboard oxygen generator system management, defibrillator management, suction unit control, patient temperature management, and sensor monitoring. The graphical user interface also facilitates a medic interface, physician interface, alarm notification, system diagnostics, and system maintenance. Referring now to Figure 36, a sample display of a screen for indicating blood pressure is provided. Systolic blood pressure is indicated by the upper most curve 940 and diastolic blood pressure is indicated by the lower most curve 942. Referring now to Figure 37, a sample display indicating the status of the medical devices, i.e., defibrillator and ventilator, as well as patient medical parameters is provided. Since a touch screen monitor is utilized, the medical devices of the self-contained transportable life support system of the present invention can be both monitored and controlled from the touch screen monitor 25. For example, a defibrillator can be turned off, activated so as to initiate charging, and caused to discharge by pressing the heart shaped symbol 750. Referring now to Figure 38, a sample screen further illustrating medical device status and patient medical parameters is provided. Control of the medical devices is provided via a touch screen interface. For example, by pressing the up arrow 950 associated with breathing rate, the breathing rate provided by the ventilator can be increased. Likewise, oxygen concentration and tidal volume can easily be varied, as desired. Referring now to Figure 39, a sample screen showing patient status is provided. As shown, the heart rate 960 is 80 beats per minute, the blood pressure 926 is 120/80, and the patient's temperature 964 is 98°F. The sample screen shows that the defibrillator is off and suction is on and that the ventilator is providing ventilation at a rate of 20 breaths per minute with a tidal volume of 780 ccs. and oxygen saturation of 97%. Referring now to Figure 40, the screen display resulting from a system self test is shown. The symbol in the center 980 is representative of the system built- in- test (BIT). From the system BIT 980 symbol extends lines to a ventilator symbol 981, and ECS symbol 982, a suction unit symbol 983, an onboard oxygen generator system symbol 984, a defibrillator symbol 985, a communications unit symbol 986, a display symbol 987, and a power symbol 988. When the system built-in-test is successful for a particular subsystem and its communications channel, then the line from the system BIT symbol 980 to that subsystem and the subsystem symbol will be green in color. A subsystem failure is indicated by displaying a green line from the system built-in-test symbol 980 to the appropriate subsystem and the subsystem symbol will be red in color. A failure of the communications channel from the system to the subsystem will be indicated by displaying a red line from the system built-in-test symbol 980 to that subsystem symbol and the subsystem symbol will be red in color because its status cannot be verified. For example, if the communications unit 986 failed the system built-in-test, then the line joining the system built-in-test symbol 980 to the communications unit symbol 986 would be green and the communications unit symbol would be red instead of green. Additionally, if the communications channel to the ventilator 981 failed the system built-in-test, then the line joining the system built-in-test symbol 980 to the ventilator symbol 981 would be red instead of green and the ventilator symbol 981 would be red instead of green because its status cannot be verified. As described in more detail below, the self- contained transportable life support system incorporates a control circuit that functions to monitor, control, prioritize and regulate power to the functional devices and circuits of the life support system. As will be recognized by those skilled in the art, the particular manner in which the control circuit performs those functions may be varied substantially without departing from the broader aspects of the present invention. Implementation of the control circuit functions will vary in accordance with the operating characteristics of the particular devices and other circuits cooperating with the control circuit, as well as the desired level of sophistication to be implemented. In one embodiment, the control circuit functions via a single redundant data bus to communicate information to and from the functional devices and circuits via one or more electrical busses, to which the medical devices and other circuits are operatively connected. In such a case, information to and from the control circuit may be formatted in digital packets whereby each functional device and circuit may be separately addressed to communicate control and data signals. In another implementation, the control circuit may be implemented in a construction whereby the control circuit is separately connected to the other functional devices and circuits via substantially dedicated circuit paths. In either case, the control circuit provides adaptive control of the functional devices and circuits in order to maintain desired life support conditions of the patient. Programming instructions suitable to implement the functions of the control circuit are submitted with this application. However, those instructions are intended to be exemplary and may be supplemented, modified or rearranged without departing from the broader aspects of the adaptive control implemented by the control circuit. That adaptive control allows the life support system to function independent of operator intervention, as may be required during periods of patient transport, or when other patient requirements limit the immediate attention that can be provided by appropriate medical personnel. Once the patient is placed in the housing, and the housing is sealed, the control circuit may be placed in an automatic mode whereby monitoring and treatment functions can be selectively implemented, modified, sequenced and terminated by the control circuit, without need for operator intervention. The control circuit is also operable in a manual, or partially manual mode, whereby some or all of the functions of the control circuit may be manually regulated by an operator, overriding control circuit programming. In other embodiments, the control circuit may function to facilitate manual operation of only select functions of a medical monitoring device, medical treatment device or environmental control device. Moreover, such manual operation may be effected by medical personnel at a remote station, in radio communication with the life support system, whereby the patient life support conditions and environmental conditions within the housing may be remotely monitored and regulated. The particular delegation of which functions may be manually controlled, and the response of the control circuit to such manual control are matters which may be varied in accordance with the desired sophistication of the control system, without departing from the broader aspects of the present invention. Figure 41 is a simplified block diagram illustrating operation of the control circuit to provide adaptive control of the interconnected functional devices and circuits. As illustrated therein, control circuit 46 is in bi-directional communication with the medical device 803, which includes medical monitoring devices 805 and medical treatment devices 807, the control circuit is thereby operative to receive information from the medical monitoring devices 805, and to regulate operation of medical treatment devices 807, in response to that information. For example, a medical monitoring device may be implemented as an electrocardiograph and the medical treatment devices 807 may be implemented as defibrillator. For example, information from the medical monitoring devices 805 may thereby provide information respecting cardiac condition of the patient. In accordance with preset threshold conditions, the control circuit is operative to implement programming to activate the medical treatment device, as necessary to bring the monitored life support condition to acceptable parameters. The control circuit 46 is operative to provide adaptive control of the medical treatment devices, based upon not simply one condition in isolation, but rather upon an evaluation of multiple life support conditions, and the inter-relationship thereof. As a result of such evaluation, the control circuit 46 may regulate the operation of the medical monitoring devices 805, the medical treatment devices 807 and the environmental control devices 809. The control circuit 46 can monitor, implement, modify, sequence and/or terminate the monitoring functions of medical devices 805, and/or the treatment functions of one or more medical treatment devices 807, in response to adaptive program control. Environmental control devices 809 may be implemented as monitoring devices and/or regulating devices operative to sense and/or regulate environmental conditions within the housing. Such conditions may include temperature, sound, light, pressure, humidity patient inclination and other environmental conditions. Thus, for example, environmental control devices 809 may be operative to sense chemical or bacterial conditions within the housing, and to implement air filtration functions to deplete any chemical, biological, or radiological contaminants. In the presently preferred embodiment, such air filtration functions are normally implemented on a continuous basis in order to assure that the environmental conditions within the housing remain isolated from environmental conditions external to the housing. Input device 811 and audio/video device 813 are preferably connected to an exterior surface of the housing to allow access to the control circuit without the need to sacrifice environmental isolation of the patient within the housing. Input device 811 is operative to input instructions or requests for information to control circuit 46. In response to such instructions or request for information, the control circuit 46 is operative to regulate the operation of the functional devices and circuits in accordance with proper control. Audio/video device 813 permits an operator to view information communicated to the control circuit 46, and monitor the operation thereof. In one implementation, the audio/video device 813 allows for audio communication with the patient within the chamber, and/or an operator located at a remote station 815. The remote station 815 may be located at a hospital or other medical service facility where trained medical personnel may monitor and regulate the operation of the life support system, via a radio frequency link to communication circuit 817. The communication circuit 817 is provided with a transmit circuit 819 and a receive circuit 821. Transmit circuit 819 and receive circuit 821 are collectively operative to communicate information and instructions between remote station 815 and the control circuit 46. Remote control signals communicated from remote station 815 may be interpreted by control circuit 46 to regulate the operation of medical monitoring devices 805, medical treatment devices 807 and/or environmental control devices 809. A microphone and speaker disposed within the housing facilitates audio communication between the patient and/or local care giver and an operator remote station 815. The patient may thereby verbally communicate his condition and treatment request to the remote station 815, which may in turn access patient life support condition information from medical monitoring devices 805, via control circuit 46. The operator at remote station 815 may further regulate the medical monitoring devices 805 to obtain further information as may be considered useful by the operator. Upon evaluation of such information, the operator at remote station 815 may thereupon direct the control circuit 46 to regulate the operation of medical treatment devices 807 in accordance with a desired treatment plan. The effectiveness of that plan can be constantly monitored by accessing information from the medical monitoring devices 805 and by direct verbal communication with the patient via a microphone and speaker or monitor disposed within the housing. The life support system may further be provided with a reader 823 operative to read information disposed on a medical storage device 825, and to communicate such information to control circuit 46. Reader 823 may, for example, operate to input information concerning a patient's medical history to the control circuit 46. The control circuit 46 is thereupon operative to regulate operation of the medical monitoring devices 805, medical treatment devices 807 and environmental control devices 809, in response to such information. As noted above, the control circuit 46 is preferably also operative to simulate a plurality of life support conditions to an operator, to monitor an operator's utilization of the medical devices in response to such simulated life support conditions, and to evaluate the effectiveness of the operator's utilization of the medical devices. The control circuit 46 thereby may operate in a training or simulation mode without any patient present within the housing. As illustrated in connection with Figure 42, the control circuit 46 may also function as a power regulator to regulate the application and distribution of electrical power to the medical devices. As shown therein, the control circuit 46 further comprises power regulating circuit 827, charging circuit 829 and first and second battery sections 831, 833. In this embodiment, the power regulating circuit 827 operates to regulate the operation of charging circuit 829 to alternately charge one of first battery section 831 and second battery section 833, while power is drawn from the other battery section. External power provided to charging circuit 829 may thereby be directed to charge first battery section 831, while second battery section 833 provides output power to medical devices 803 and other functional components of the life support system. In accordance with predetermined parameters, power regulation circuit 827 may thereupon regulate the operation of charging circuit 829 such that external power is applied to charge second battery section 833, while power from first battery section 831 is applied to medical devices 803. The control circuit 46 may further be operative to regulate the distribution of power from the first and second battery sections 831, 833, in accordance with a preset priority status assigned to the medical devices, environmental control devices and other circuits within the life support system. In that embodiment, the power regulation circuit 837 is operative to monitor the available power from the first and second battery sections 831, 833. The control circuit 46 is operative to monitor the power requirements of the medical devices, environmental control devices and other circuits within the life support system, and to distribute available power to those devices and circuits in accordance with an assigned priority status attributable to those devices and circuits. Moreover, control circuit 46 is further operative to modify the assigned priority status of individual medical devices, environmental control devices and other circuits within the life support system, in response to monitored conditions of the life support system, or in response to manual control. Various other scenarios may be implemented whereby the control circuit regulates power distribution to the individual medical devices, environmental control devices and other circuits in accordance with urgent medical conditions as may arise within the life support system. As will be recognized by one of ordinary skill, the description of the control circuit 46 may be modified, simplified or enhanced, in accordance with a particular application, without departing from the broader aspects of the present invention. The transportable life support system of the present invention provides individual, personalized, medical intensive care for military casualties, medical patients, chemical/biologically contaminated patients requiring isolation, and any other personnel who require rapid transport to a medical care facility or sustained ICU care in any care setting. Additionally, the transportable life support system of the present invention provides means for quickly and easily re-configuring austere facilities into resuscitative, operative, and post-operative medical care facilities. Thus, various non-medical field environments such as those of a ship, aircraft, school, office, home, clinic, etc. may be quickly transformed into an intensive care environment with the use of the transportable life support system of the present invention. The transportable life support system provides the medical monitoring and care devices required for such intensive care applications. Further, the transportable life support system of the present invention can be utilized as a sterile environment for surgical procedures if necessary. Continuity of care is of paramount importance in the transport of a medical patient from the austere environment of a battlefield or accident site to a location having better medical care facilities, e.g., typically a traditional hospital located remotely from the accident site or battlefield. The transportable life support system of the present invention comprises medical equipment commonly utilized in intensive care situations, which is specifically configured as a lower housing section which can be hand carried by two people and is configured to mount to standard military evacuation vehicles and can be adapted to mount to civilian emergency medical care vehicles or for use in a hospital. Use of the transportable life support system of the present invention minimizes the number of care givers required during resuscitation and transport and also minimizes the amount of skill required to be possessed by such care givers. According to the preferred embodiment of the present invention, intelligence is provided in the transportable life support system so as to facilitate standalone operations utilizing closed-loop controls. On-board sensors provide inputs for physiological parameter processing which supports intelligent decision making for operation of the various incorporated intensive care medical devices. The physiological parameter processing also facilitates treatment administration by providing instructions to trained or untrained personnel regarding the patient's medical needs. Both patient and life support system status reporting and management is also facilitated. By providing such closed-loop automation of the transportable life support system of the present invention, it is possible to maximize the time during which a stabilized medical patient may be left unattended or under the care of only the on-board monitoring and control system. This is particularly useful in facilitating the transfer of battlefield or civilian casualties from a hostile environment to a remote hospital wherein care givers are simply not available to facilitate desired constant monitoring. Additionally, according to one configuration of the present invention, a remote care giver monitors the on¬ board sensors and provides instructions to the transportable life support system, so as to provide enhanced care for the medical patient. Telecommunications capability supports such remote reporting, query, and command/control operations. Thus, the transportable life support system of the present invention provides an integrated medical device or intensive care unit (ICU) having standalone capability. According to the preferred embodiment of the present invention, multiple levels of operational and communication capability are provided. The transportable life support system may be configured to operate in a standalone, local, interfaced, or remote mode of operation. The standalone mode of operation provides the most sophisticated autonomous control of the medical devices utilizing sensor inputs from the medical patient. The interface mode of operation allows for electrical, oxygen, and data interface to the transportable life support systems operating environment, e.g., an evacuation vehicle, auxiliary support system, etc., so as to minimize taxing of the transportable life support systems' own resources, thereby enhancing their lifetime. In the remote mode of operation, data communication is provided to a remote site, typically a medical professional, who monitors and evaluates data from the transportable life support system and provides trauma treatment inputs to the life support medical devices. Because of the provision for data storage and communication according to the transportable life support systems of the present invention, the present invention can easily be integrated into various battlefield, civilian emergency logistics, and resource allocation systems. For examples, information regarding battlefield casualties and their medical conditions can be readily compiled and evaluated at a central location. Such logistic considerations may also be useful in civilian applications particularly during catastrophes such as earthquakes, floods, hurricanes, etc. In order to accommodate transport aboard standard military evacuation vehicles such as the UH-60 Blackhawk helicopter, the UH-1 Huey helicopter, the HumVee, the C- 130 winged aircraft, and/or the C-141 fixed wing aircraft, the medical equipment of the transportable life support system of the present invention has been configured to fit within a lower housing section having a height of approximately 6 inches. Such con iguration is compatible with standard NATO litter mounts such that transportable life support system of the present invention may simply be carried aboard such military evacuation vehicles in the same manner that a standard NATO structure having a battlefield casualty disposed thereupon is carried. More particularly, the transportable life support system of the present invention is specifically configured so as to facilitate transport upon standard military evacuation vehicles. In order to accommodate such transportation, the physical envelope of the transportable life support system is constrained to 20 inches of height, 22.75 inches of width, and 85.5 inches of length. The lower housing section upon which the medical patient is placed and within which the medical devices reside is constrained to a height of 6 inches. Such construction assures that the transportable life support system of the present invention attaches such standard military vehicles via the stretcher handles of the standard NATO stretcher to which the transportable life support system is attached. All of the controls and monitoring devices of the present invention are fully operable during transport of the medical patient. The environmental control system also facilitates patient comfort management, by maintaining a comfortable temperature. The lower housing section provides a physical bed upon which the stretcher and medical patient are placed and also facilitates tie-down thereof, so as to avoid upset during transportation. The environmental container (chamber) provides isolation from adverse chemical/biological environments and also facilitates reverse isolation that may be necessary when the medical patient is contaminated with a chemical or biological agent. The transportable life support system of the present invention is fully autonomous, utilizing standalone utility capabilities such as internal power, environmental control onboard oxygen generation enhancement, and autonomous communications. The communications capability of the present invention includes reporting of the status of the patient, as well as the transportable life support system itself. Both local and remotely communicated alarms provide an alert that medical or system parameters have exceeded desirable limits. Recorded information regarding the status of the patient is maintained on board the transportable life support system and may be communicated to another site. The communication of this information is particularly useful when advance preparation is necessary to assure adequate medical treatment for the medical patient. For example, medical personnel may be alerted in advance to the medical patient's arrival and the particular problems and needs of the medical patient such that the appropriate equipment and personnel are on-hand upon the medical patient's arrival. In addition, recording of treatment data, patient data and system data is valuable in medical research. According to the preferred embodiment of the present invention, the communication system includes location sensing and communicating equipment for providing the location of the transportable life support system to a remote location. It is preferably implemented utilizing the Global Positioning System (GPS). Additionally, the maintenance requirements for the transportable life support system are preferably automated and integrated into the system such that notification of a particular requirement is provided upon the display thereof, as well as instructions for performing such maintenance, if desired. Onboard repair advice and maintenance procedures may optionally also be provided. By providing the geographic location of battlefield or civilian disaster casualties carried upon the transportable life support system of the present invention, the dispatch of medical personnel, medical equipment, supplies, medicines, etc. to treat the battlefield or civilian casualty is facilitated, as desired. Local mentoring is provided so as to minimize the training and skill required in order to properly prepare a medical patient for transport, i.e., stabilize the medical patient. Such local mentoring is provided via either autonomous operation of the life support system utilizing onboard sensors and diagnostic software, or, alternatively, via remote teleconsulting utilizing the onboard telecommunications capability. According to the preferred embodiment of the invention, a training mode is available which allows a user to simulate various different types of trauma casualties, and thus allows care givers to attain proficiency in the proper use of the transportable life support system of the present invention. The use of the transportable life support system of the present invention facilitates mobile, agile, war fighting, since the requirement for treating battlefield casualties within the theater of operations is substantially mitigated thereby. Thus, according to the emerging doctrine whereby battlefield casualties are immediately transported to a remote hospital, evacuation of such casualties and replacement thereof with new personnel, e.g., soldiers, is readily facilitated. Further, it is well established that the availability of adequate medical support substantially influences a soldier's willingness to engage the enemy. Thus, the present invention not only enhances the medical treatment of such battlefield casualties and logistics associated with evacuating and replacing such casualties, but also enhances the soldier's ability to fight. The present invention is capable of providing trauma care within minutes. Because of its lightweight and compact structure, it may readily be deployed to the battlefield front civilian disaster areas where casualties commonly occur or pre-positioned in potential disaster areas. Also, because of its rugged, integrated structure, the present invention may be air-dropped to remote, inaccessible locations and is also configured for air retrieval. Such configuration additionally makes the present invention desirable for use in rescue activities in a remote and inaccessible location, such as a steep, rugged terrain, shipboard and small watercraft, and arctic conditions. The present invention may find particular applicability in cold weather environments, wherein the ability of the environmental chamber to isolate the medical patient from such cold is beneficial. Such logistic information regarding the geographic origin and present location of battlefield casualties further facilitates practical command decision making regarding real-time modifications to battle plans. For example, an excessive number of battlefield casualties originating from a common battlefront location would tend to be indicative of the need for reinforcements at that location. The transportable life support system of the present invention is preferably configured to accept computerized medical records, such as those which are anticipated to be carried by individual soldiers. As those skilled in the art will appreciate, attempts are presently being undertaken to incorporate military medical records into dog tags, ID cards, etc. so as to facilitate the automatic retrieval of such data. Thus, the medical history of an individual soldier is quickly transferred to the control system of the transportable life support system such that pertinent information contained therein may be utilized for the diagnosis and treatment of the battlefield casualty. It is further contemplated that the environmental chamber of the present invention may be utilized in controlled pressure or hyperbaric applications, so as to provide desired medical treatment for the battlefield casualty. For example, in order to treat decompression sickness it may be desirable to increase the pressure within the environmental chamber to a value substantially above ambient air pressure and then to provide a controlled decrease of pressure over time. Additionally, a pressurization suit may be utilized to control blood flow to portions of a battlefield casualty's body, so as to reduce the likelihood and/or severity of shock and also so as to mitigate bleeding therefrom. For example, repressurizable pants may be utilized to limit blood flow to the lower extremities, so as to mitigate bleeding therefrom and also so as to mitigate the undesirable effects of shock. Training is facilitated by specifically accommodating well-known training dummies, such as ResusiAnnie (which is commonly used to train for cardiopulmonary resuscitation), and Harvey, a well-known cardiovascular resuscitation dummy. Three modes of training are provided. In the first mode, a human subject is placed within the transportable life support system of the present invention and a desired physical problem is specified, via a care giver input. The system then simulates sensor inputs from the patient and instructs the care giver to take specific action. In the second mode of training, a training dummy is utilized in place of a human being. In the third training mode, the transportable life support system of the present invention is utilized in a standalone mode, i.e., wherein no personnel or dummy is utilized to simulate a battlefield or civilian casualty. A type of injury is specified or randomly selected by the training system and the care giver is instructed as to how to provide care therefor. A cardiac assist may be provided. The cardiac assist comprises either a mechanical chest compression device, an intra-aorta balloon pump, or an extracorporeal pump. An extracorporeal pump, oxygenator, and warmer/cooler may be provided so as to facilitate cardiac assist, blood oxygenation, and control of body core temperature. The extracorporeal chiller may be utilized to induce hypothermia, so as to decrease mortality by mitigating the undesirable effects of shock, decreasing blood flow, and consequent bleeding, and decreasing the body's requirement for oxygen. The transportable life support system of the present invention also provides a portable operating lower housing section which may be utilized in various different non-sterile environments for the performance of emergency medical operative procedures. The upper housing section 26 and filter system provides isolation from external contaminants/contagions. Optional isolation gloves provide access to the battlefield casualty while maintaining a sterile environment therefor. Configuring the environmental chamber for hyperbaric applications also facilitates its use in the treatment of various typical conditions wherein increased oxygen delivery is indicated. Use as a hyperbaric chamber is also preferably facilitated. According to one preferred configuration of the transportable life support system of the present invention, the medical devices are integrated with the transportable lower housing section so as to provide modular construction. Such modular construction facilitates easy removal and replacement of each medical device, so as to facilitate maintenance thereof. Such modularity also facilitates the configuration of a transportable life support system which is specifically configured for a particular application. For applications wherein a particular type of medical condition is anticipated, only those medical devices required for the treatment of that medical condition are included. This reduces the weight of the transportable life support system, as well as the cost associated therewith. For example, if the present invention were to be utilized at a non-contact sporting event, such as a marathon, then those medical devices for monitoring and supporting cardiac function would be necessary since heart attacks are common during such events. However, those medical devices commonly associated with the treatment of trauma, such as the ventilator, may not be required. Such modular construction also facilitates quick reconfiguration of the transportable life support system for use in various different applications. Since such modular construction allows for the quick removal and/or replacement of the various medical devices thereof, a transportable life support system can be sent to a central location wherein a variety of such medical devices are stored and can there be quickly reconfigured for a particular use, as desired. Medical treatment devices of the present invention are responsive to the medical monitoring devices thereof. However, such interactions are based upon the particular medical condition of the medical patient being treated thereby. Thus, rather than a particular medical treatment device being solely responsive to a particular medical monitoring device, each medical treatment device is responsive to those particular medical monitoring devices which are indicative of the medical patient's condition. Thus, according to the preferred embodiment of the present invention, a computer monitors the status of all of the medical monitoring devices and then, based upon a control algorithm, actuates those medical treatment devices which are necessary for the proper treatment of the medical patient. As such, the various complex interactions of the medical monitoring devices and medical treatment devices are possible. The prioritization schedule utilized to shut down the various systems and/or medical devices of the present invention as battery power diminishes is preferably a dynamic schedule based upon the particular condition of the medical patient. Thus, those medical devices which are most necessary for the proper medical care of the medical patient remain activated the longest. For example, for a medical patient having trouble breathing, the ventilator would be given highest priority and would be the last medical device to be deactivated. In this manner, the time required to transport the medical patient to a hospital is extended and the medical patient's probability of surviving such transport are enhanced. According to the preferred embodiment of the present invention, an estimated time to reach the destination is entered. Based upon the estimated time of transport and the medical patient's medical condition, a prioritization schedule is generated which assures that those medical devices required for the proper medical treatment of the medical patient remain energized for the duration of the transport. Thus, as the medical patient requires ventilation and the estimated time of transport is two hours, then power is managed in a manner which assures that the ventilator remains activated for two hours. Approximately one half inch of padding is formed upon the upper surface of the transportable lower housing section such that, when a stretcher is disposed thereupon, the padding cushions the medical patient. In this manner, it is not necessary to support the stretcher its full height above the lower housing section. Rather, the stretcher may be positioned lower, i.e., closer to the lower housing section, thereby reducing the overall height of the life support system. Thus, the medical patient does not rely upon the stretcher to provide a comfortable and resilient surface upon which to lie, but rather is cushioned by the padding of the lower housing section itself. The handles may optionally be deployable from a stowed position, such that they are out of the way when not being utilized. The use of such padding also facilitates the transport of a medical patient upon the lower housing section without the use of a stretcher. In this instance, the medical patient lies directly upon the padding of the transportable lower housing section. Optionally, handles are formed directly to the lower housing section to facilitate carrying thereof without an attached stretcher. Thus, the padding formed upon the lower housing section defines a bed for the medical patient. Tie downs, belts, and/or buckles are optionally provided so as to secure the medical patient to the lower housing section, to prevent undesirable movement thereof during transport and/or treatment. The transportable life support system of the present invention is preferably configured to be airworthy. Thus the transportable life support system does not radiate excessive levels of electro-magnetic radiation. Further, the transportable life support system is configured so as not to be substantially susceptible to environmental electro-magnetic radiation, such as that generated by an aircraft or vehicle. The transportable life support system is configured so as to be compatible with utilities commonly found upon military vehicles and in medical environments such as power, oxygen, etc. According to the preferred embodiment of the present invention, brushless exhaust fans commence operation before power is applied to any other electrical circuit of the present invention. The exhaust fans purge air from within the lower housing section, thereby likewise purging any oxygen which potentially leaks from the oxygen reservoir and/or lines and/or pressurized oxygen bottles, as well as any hydrogen which may potentially leak from batteries. Thus, actuating the brushless exhaust fans first mitigates any explosion or fire hazard associated with the presence of such gases within the lower housing section. According to the preferred embodiment of the present invention, the equipment and patient air paths are completely separate from one another. Preferably, the air path of the equipment bay within the lower housing section is such that air is drawn over the equipment contained therein, from one end of the lower housing section to the other end thereof. Preferably, the air within the upper housing section 26, as well as the air provided to the ventilator, is pre-filtered through a nuclear, biological, and chemical (NBC) personal filter, such as those commonly used in military gas masks. A hot air blanket may be utilized to distribute hot air to a medical patient through a porous side thereof. Thus, hot air flow is primarily directed from the blanket to the medical patient. Optionally, a pair of hot air blankets may be utilized such that the medical patient lies upon one and is covered by another. The hot air may be collected under the upper housing section and then recirculated, so as to further enhance rewarming. Alternatively, a water blanket may be utilized to distribute hot water to a bladder-type blanket. Again, a water blanket may be utilized both under and on top of the medical patient. The water is recirculated and reheated, as necessary. Dry blankets may utilize either the medical patient's own body heat or an electrical or chemical heating pad. Again, dry blankets may be placed both beneath and on top of the medical patient. Either the hot air blanket, water blanket, or dry blanket may be formed in a modular fashion so as to facilitate localized heating of the medical patient as desired. Upper housing section heating can be utilized to warm the air within the upper housing section in order to facilitate rewarming. Rewarming of the medical patient is preferably performed with the upper housing section 26 in place, so as to provide protection from environmental elements. Body heating may additionally be accomplished via extra-corporeal warming of the medical patient's blood. Rewarming of the medical patient may occur either gradually or at a maximum rate. Gradual rewarming is preferably performed at approximately 1° F per hour. The standard approach for rewarming a hypothermic medical patient is total body immersion in a fluid bath, generally not exceeding 110° F. The objective is to rewarm the medical patient's body as rapidly as possible, but also to limit the temperature applied to the skin to less than 110° F in order to avoid skin and/or tissue damage. Such fast rewarming may be indicated by severely depressed cardiac function or circulation. It is generally necessary to bring the core temperature to above 90° F before adequate cardiac contractility can be resumed in order to facilitate sustained circulation. Defibrillation may also be necessary to restore cardiac rhythm if fibrillation occurs after the cold arrest. The defibrillator of the present invention is preferably configured so as to be inoperative when the medical patient is under hypothermic conditions, since use thereof would not be beneficial to a hypothermic medical patient. The hot air blanket preferably comprises a Bair- Hugger type of blanket. When hot air is blown through a blanket having an aluminized plastic layer on one side thereof and a very porous material on the other side thereof so as to facilitate desired hot air distribution. In this manner hot air can be provided to a hypothermic medical patient over a very large area thereof. Clinical reports claim the hot air blanket to be as effective as water blanket for the rewarming of hypothermic medical patient using only top-side coverage thereof. Optionally, the padding formed upon the lower housing section is either porous or has air channels formed therethrough so as to facilitate hot air distribution over the lower surface of the medical patient. The lower housing section 22 preferably exhausts approximately 100° F air at approximately 50 ft per minute in order to dissipate approximately 933 watts of thermal heat flow therefrom. The temperature of the exhausted air may reach a maximum of approximately 161° F if the inlet air is at a temperature of approximately 95° F. Inlet air for the equipment bay is filtered for particulates, but is not nuclear/biological/ chemical (NBC) filtered. Exhaust air from the equipment bay may be utilized for air blanket rewarming of a hypothermic medical patient. If equipment bay exhaust air is utilized for rewarming of a hypothermic medical patient, then it is recommended that the upper housing section be removed or substantially opened, so as to limit undesirable breathing of the equipment bay exhaust air. Optionally, the equipment bay air, after being warmed by the equipment bay, is NBC filtered before being applied to the hot air blanket. In this case, the upper housing section may remain in place and fully closed, so as to provide desirable NBC protection. A water blanket may optionally be provided above and/or below the patient in order to facilitate hypothermic rewarming. Preferably, a recirculating water/anti-freeze medium is utilized to facilitate heat transfer from a STEPO micro-cooling system to heat exchanges which cool the air being circulated in the patient compartment. Optionally, a heating and cooling circuit can be provided so as to facilitate direction of the water path into a circulating water blanket which is then applied to the patient. A heater would then heat the water/anti-freeze mixture, if desired, prior to mixture flowing into the water blanket. Optionally, a second such blanket may be provided beneath the medical patient, so as to enhance heat transfer. The padding formed upon the upper surface of the lower housing section optionally comprises heating or temperature controlled pads. Preferably, either circulating water or electrical heating elements are utilized to control the temperature of the pads. By insulating the outer surface of any blankets utilized to control the temperature of the medical patient, heat loss is mitigated, thereby increasing the efficiency and effectiveness thereof. When the upper housing section 26 is utilized, then such heat loss generally serves to heat the surrounding air, thereby enhancing the efficiency of the temperature control system. Alternatively, temperature control may be provided via heating with a dry blanket, which itself is preferably either electrically or chemically heated, and which has a wet towel in laminar juxtaposition thereto. The wet towel functions to increase thermal conduction between the dry blanket and the medical patient and also facilitates more even distribution of the heat from the dry blanket. Optionally, heating modules are utilized to provide for the selective heating of local areas, typically the more densely vascularized regions of the neck, arm pits, groin, behind the knees, etc. At these locations, blood veins are disposed close to the body's surface, thereby facilitating heat transfer to the medical patient without requiring extensive heating of the surrounding tissue. Such undesirably excessive heating increases oxygen demand before the ventilation and circulation supporting medical devices can accommodate such increased demand. Additionally, the use of such modules to facilitate localized heating allow the localized heating to continue while other treatments are performed which require better access to the medical patient than is possible with continuous blanket coverage. That is, while a blanket would have to be removed in order to facilitate the performance of such treatments, thereby at least temporarily terminating heat control of the medical patient, such modules may generally remain in place and effective throughout such medical procedures. When the upper housing section 26 is in place, then electrical heaters are preferably utilized to heat a circulating fluid so as to provide warmth therein. As those skilled in the art will appreciate, various alternative heating methodologies may likewise be utilized. For example, electrical heating elements may be utilized directly within the upper housing section. It may be beneficial to provide a transportable life support system according to the present invention at various locations where such is likely to find utility. For example, places where a large number of people are present, e.g., office buildings, industrial plants, sporting events, etc. are likely to the site of an injury, accident, or illness resulting in the need for immediate transportation of the victim to a hospital, while utilizing life support devices. As such, it may be beneficial to store transportable life support systems at various locations throughout a municipality, in the anticipation of such likely use. Thus, the transportable life support system of the present invention provides a means for transporting an individual medical patient from the site of the injury or the occurrence of a medical problem to a remote hospital. In battlefield applications intensive care is provided for casualties while maintaining chemical and/or biological isolation of the medical patient. Isolation from the environment and/or care givers is also facilitated. Additionally, the transportable life support system of the present invention provides means to reconfigure austere facilities into resuscitative, operative, and post-operative medical care facilities. Thus, various field environments such as shipboard, aircraft, school, home, office, hospital, battlefield, etc. may be effectively converted into medical care facilities because of the autonomous nature of the transportable life support system of the present invention. The transportable life support system of the present invention provides continuity of care during transport of a medical patient from a site of injury to a hospital or other location where medical care may be provided. Its lightweight facilitate hand carrying and its configuration facilitates interface with various different military evacuation vehicles. Built-in communications and intelligence provide a head count of injuries and logistics reporting, so as to facilitate enhanced battlefield and civilian emergency management. Intelligent and closed-loop controls automate the medical treatment process, so as to reduce the skill and training required of a resident care giver. Medical monitoring devices and physiological parameter processing facilitates intelligent automated decision making for controlling the operation of medical treatment devices, as well as treatment administration via the care giver. Medical patient and system status are automatically reported via the telecommunications to enhance medical care provided and also further facilitate battlefield and civilian emergency management. The use of such closed-loop automation and automated intelligent decision making autonomous operation, wherein the care giver may leave the medical patient within the transportable life support system unattended for extended amounts of time. Audible and/or visible alarms notify the care giver in the instance that a condition arises which requires the care giver's immediate attention. Thus, advance levels of intensive care may be provided with minimally trained on-site personnel. The telecommunications capability of the present invention allow remote medical personnel to monitor the medical patient and to control the medical treatment devices providing care thereto. Such telecommunications may either be automatic, i.e., self-activated in response to the monitoring of medical parameters of the medical patient, or may be initiated by the local care giver. Such telecommunications facilitate reporting of the condition of the medical patient, queries by the local care giver and responses to such queries from remote medical personnel, and control of the medical treatment devices by such remote medical personnel. It is understood the exemplary transportable life support system described herein and shown in the drawings represents only a presently preferred embodiment of the invention. Indeed, various modifications and additions may be made to such embodiment without departing from the spirit and scope of the invention. For example, various different configurations of the present invention are contemplated. It is contemplated that a housing may be configured so as to accommodate more than one medical patient. Additional medical devices may then be provided, or advantage of the capability of existing medical devices to service more than one person may be taken. Additionally, the upper housing section 26 may be configured so as to be disposable, in the fashion of the roof of a convertible automobile. Additionally, as those skilled in the art will appreciate, various other medical monitoring and/or medical treatment devices may be integrated into the present invention. Thus, these and other modifications and additions may be obvious to those skilled in the art and may be implemented to adapt the present invention for use in a variety of different applications. The program listing for controlling the microprocessor of the control circuit 46 such that the medical treatment devices are responsive to the medical monitoring devices and such that the medical treatment devices cooperate with one another to provide medical care for the patient is incorporated as follows. PROGRAM LISTING COMNUNIT.PAS unit Comnunit; interface type TScreenControl - class (TObjβct) procedure TurnOnMedicsScreen; end; implementation uses Repair, Ventdet, Main, Dispspac, Diagvent; procedure TScreenControl.TurnOnMedicsScreen; begin MedicsGUI.Visible :- True; if suctionOnToggle » True then MedicsGUI . lblSuctionlndicator.Caption := 'ON' else MedicsGUI .lblSuctionlndicator.Caption :» 'OFF'; if ventOnToggle = True then MedicsGUI. entPowerBtn.Caption :- 'SHUT OFF' else MedicsGUI.ventPowerBtn.Caption :- 'TURN ON'; end; end. { HOW TO USE ONE OF THESE MEMBER FUNCTIONS > give access to the unit that contains the class (in the implementation's "uses".) > then declare an object of that type in the implementation's var. > Then in each procedure of the unit that needs the object, create the object by using... objectName :•■ TheClassName.create; > And finally call it using the . as in: objecName. urnOnMedicsScreen; } PROGRAM LISTING DIAGVENT.PAS unit Diagvent ; interface uses SyβUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrlβ, StdCtrls; type Tdiag_vent - class(TForm) Imagel: TImage; Shape1: TShape; Label1: TLabel; Shape2: TShape; testLabe1: TLabe1; Label2: TLabel; procedure ShapelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ShapelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ImagelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Shape2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure alaππQbtnClic (Sender: TObject); procedure readinspireTbtnClick(Sender: TObject); procedure readBPMbtnClick(Sender: TObject); procedure manualBtnClick(Sender: TObject) ; procedure setInBpireTClick(Sender: TObject); procedure setBPMClick(Sender: TObject); procedure ResetVentBtnClick(Sender: TObject); procedure patientPressBtnClick(Sender: TObject) ; procedure alarmResetBtnClick(Sender: TObject) ? private { Private declarations } public { Public declarations } end; var diag_vent: Tdiag_vent; const ALQ - 2, const ALR - 3; const MAC - 4, const MB » 5; const MI = 6; const MIMV - 7 ; const MO - 8; -70- const MSC - 9; const PMAX - 10; const PMIN - 11; const PP » 12; const RBR «■ 13; const RIT - 14 const RST - 15; const SBR - 16; const SIT - 17; implementation {$R *.DFM} function ventControl(ventDevice, OnOff : integer) : integer; far; external 'GUIIF'; procedure Tdiag_vent.ShapelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Labell -Caption :- 'Resevoir Picture'; , end; procedure Tdiag_vent.ShapeIMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Labell .Caption end; procedure Tdiag_vent.ImagelMouseDown(Sender: TObject; Button: TMouseButton; t Shift: TShiftState; X, Y: Integer); begin diag_vent.Visible :«■ False; end; procedure Tdiag_vent.Shape2MouseDowτι(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Labell .Caption := 'Motor'; end; procedure Tdiag_vent.alarmQbtnClick(Sender: TObject); begin ventControl(ALQ, 1) ; end; procedure Tdiag_vent.readinspireTbtnClick(Sender: TObject); begin ventControl(RIT, 1) ; end; procedure Tdiag_vent.readBPMbtnClick(Sender: TObject); begin ventControl (RBR, 1) ; end; procedure Tdiag_vent.manualBtnClick(Sender: TObject); begin ventControl(MB, 1) ; end; procedure Tdiag_vent. setInspireTClick(Sender: TObject); begin ventControl(SIT, 1) ; end; procedure Tdiag_vent. setBPMClick(Sender: TObject); begin ventControl (SBR, 1) ; end; procedure Tdiag_vent.ResetVentBtnClick(Sende : TObject); begin ventControl (RST, 1) ; end; procedure Tdiag_vent.patientPressBtnClick(Sender: TObject); begin ventControl(PP, 1) ; end; procedure Tdiag_vent.alarmResetBtnClick(Sender: TObject); begin ventControl (ALR, 1) ; end; end. PROGRAM LISTING LSTATδ.DPR progrαm Lstatβ; uses Forms, Main in 'MAIN.PAS' {MedicsGui} , Repair in 'REPAIR.PAS' {SyβtemGUI} , Ventdet in 'VENTDET.PAS ' {VENTDETAIL}, Dispspac in 'DISPSPAC.PAS' {DisplaySpace} , Comnunit in 'COMNUNIT.PAS' , Diagvent in 'DIAGVENT.PAS' {diag_vent}, Neuro in 'NEURO.PAS' {neuroSurg}; var dummy: integer; {I dunno why, but I can't declare a Bool here. Go to Main.} {$R *.RES} function startEtC02 : integer; far; external 'GUIIF'; function startFlow : integer; far; external 'GUIIF'; function ventControl(ventDevice, onOff : integer) : integer; far; external 'GUIIF'; function f nControl(fanDevice, onOff : integer) : integer; far; external 'GUIIF'; function defibControl(de ibDevice, onOff : integer) : integer; far; external 'GUIIF'; function initControl : integer; far; external 'GUIIF'; begin Application.CreateForm(TMedicsGui, MedicsGui) ; Application.CreateForm(TSystemGUI, SystemGUI) ; Application.CreateForm(TVENTDETAIL, VENTDETAIL) ; Application.CreateForm(TDisplaySpace, DisplaySpace) ; Application.CreateFoπn( diag_vent, diag_vent) ; Application.CreateForm(TneuroSurg, neuroSurg) ; SystemGUI.Left := 1; MedicsGUI.Left :- 1; VENTDETAIL.Left :- 1; DisplaySpace.Left :- 1; diag__vent.Left :»• 1; neuroSurg.Left :«» 168; SystemGUI.Top :- 1; MedicsGUI. op :- 1; VENTDETAIL.Top :- 1; DisplaySpace.Top :»• 1; diag_vent.Top : β 1; neuroSurg.Top :» 1; SystemGUI.Height :» 608; MedicsGUI.Height := 608; VENTDETAIL.Height :- 608; DisplaySpace.Height := 608; 1 diag_vent.Height :- 608; neuroSurg.Height :- 608; SystemGUI.Width :- 808; MedicsGUI.Width :« 808; VENTDETAIL.Width :- 808; DisplaySpace. idth :- 808; diag_vent.Width : » 808; neuroSurg. idth :- 640; VENTDETAIL.selfTestPnl. op :- 80; {80} VENTDETAIL.self eβtPnl.Left :- 232; VENTDETAIL.selfTeβtPnl. idth :- 353; VENTDETAIL.selfTestPnl.Height :- 369; {257} VENTDETAIL.ventWarnPnl. op :- 57; VENTDETAIL.ventWarnPnl.Left := 0; VENTDETAIL.ventWarnPnl.Width :- 257; VENTDETAIL.ventWarnPnl.Height :- 392; {328} MedicsGUI.recordMenuPanel.left :- 136; MedicsGUI .recordMenuPanel.top :*=• 56; MedicsGUI .recordMenuPanel.Height := 321; MedicsGUI .recordMenuPanel.width : « 417; MedicsGui.setBPpanel.left := 112; MedicsGui.setBPpanel.top :» 120; MedicsGui.setBPpanel.height :» 201; MedicsGui. setBPpanel.width :- 377; MedicsGui.BPhistoryPnl.left := 104; MedicsGui.BPhistoryPnl.top :*• 96; MedicsGui.BPhistoryPnl.height :- 305; MedicsGui.BPhistoryPnl.width := 393; NovaSamplerWriteCntr := 0; ventSamplerCntr :=■ 0; condFanOnToggle := True; {TURN THIS BACK ON FOR GENE 111 II 11 II I I I I 11 II ) modeOnToggle := False; ventOnToggle :» False; defibOnToggle :• False; suctionOnToggle :- False; {These variables are declared in the Main Unit's first var.) {This is another way to initialize a digital control. When main screen comes on, it notices this toggle and responds by calling sucControl( ) ... I think. But I can't explain it really. } spo2BoardEnabled :« False; capnoBoardEnabled :*» False; flowBoardEnabled :- False; anyRecOn :»■ False; allBoardsEnabled := False; { Can't use a windows call here.} BPMDesired := 16; setPresMinVar :«=■ 15; setPresMaxVar := 65; setBreathRateVar := 15; setlnspirVar := 1.5; ventControl(POWER,0) ; defibControl(FIRE, 0) ; fanControl(COND, 1); {TURN THIS ON FOR GENE///////////////////////} ventSamplerCounter := 0; NovaSamplerCounter :- 0; diagLabelVisibleState :- False; toggleTheDiagnosticLabels (diagLabelVisibleState) ; {False turns them off and in the project source, it is. } startEtC02; { init Commands for John's boards; } startFlow; Application.Run; end. { INTERFACE WITH JOHN'S DLL > To use one of John's functions, declare the function's name in the unit your are calling it from. function fanControl(FanNum, OnOff: integer) : integer; far; external 'GUIIF'; where this is the name of the •dll Λ and the fanNum const variables are in the implementation's var section. like this: const CIRC = 3; <-note that it's not := 3 > To cut down on the number of function nsLmes in the .dll the function will take a parameter to indicate which fan or which thermocouple, int fanControl(3, 1) ; I Λ — 0,1, for off or on Λ — which fan: > COND " ■ 1 condensor fans > CIRC D 3 circulation fans > PRES = 4 pressurization fans > John's functions return an error code; zero for OK > One of John's controls should be called anytime a button indication changes. NORMAL BUTTON if xxxBtn.Caption - 'OFF' then begin yyyControl (unit2,1); xxxBtn.Caption := 'ON'; end else begin yyyControl(unit2,0) ; xxxBtn.Caption := 'OFF'; end; MORE THAN ONE PLACE BUTTON AND JOHN'S CONTROLS > Where more than one button controls the same thing, call the .dll function whenever I change the state of the toggleVariable. That iβ, search for this... suctionOnToggle :=» ' ...instead of a caption change In otherwords, I don't have to turn on the fan everytime a screen has it's fan indicator turn on. DLL INTERFACE CONTROL DOCUMENT (all CAPS are const, global to Delphi) DIGITAL OUTPUT (TO LSTAT) > anControl(int,int) ; fanNumber-toDLL, on/off-toDLL anNumber COND = 1 condensor fans CIRC = 2 circulation fans PRES - 3 pressurization fans > ventControl (int,int) ; ventDevice-toDLL, on/off-toDLL ventDevice = POWER = 1 ventilator whole thing power on > sucControl(int,int) ; ventDevice-toDLL, on/off-toDLL sucDevice = POWER = 1 suction unit whole thing power on > defibControl (int,int) ; defibDevice-toDLL, on/off-toDLL defibDevice = POWER = 1 defibrilator whole thing power on RESUME = 2 reset button, also momentary FIRE = 3 discharge action execute button, momentary > ecsControl(int,int) ; ECSDevice-toDLL, on/off-toDLL ECSDevice = POWER = 1 compressor relay and 2 pumps > powerControl (int,int) ; powerDevice-toDLL, on/off-toDLL powerDevice = CHARGE = 1 turn on charge > obogsControl(int,int) ; OBOGSDevice-toDLL, on/off-toDLL ECSDevice - POWER - 1 OBOGS whole thing power on DIGITAL INPUTS (from LSTAT) > anSenseD(int,int) ; fanNumber-toDLL, on/off-fromDLL fanNumber « COND β 1 condensor fans CIRC - 3 circulation fans PRES « 4 pressurization fans > ventSenseD(int,int) ; ventDevice-toDLL, on/off-fromDLL ventDevice « POWER β 1 whole thing power on confirm > sucSenseD(int,int) ; ventDevice-toDLL, on/off- romDLL sucDevice « POWER «=■ 1 whole thing power on confirm > defibSenseD(int,int) ; defibDevice-toDLL, on/off-fromDLL defibDevice = POWER = 1 whole thing power on confirm READYLITE - 2 discharge action ready light (this signal comes to us on .5 sec, off .5 sec) REUSMELITE = 3 LED under the RESUME button > ECSSenseD(int,out: int); ecsDevice-toDLL, on/off- romDLL ecBDevice = POWER = » 1 compressor relay and 2 pumps confirm on > powerSenseD(int,int) ; powerDevice-toDLL, on/off-fromDLL powerDevice = BANK1 = 1 battery voltage > 12 volts bank 1 BANK2 ~ 2 battery voltage > 12 volts bank 2 > obogsSenseD(in ,int) ; OBOGSDevice-toDLL, on/off-fromDLL OBOGSDevice = POWER ■= 1 OBOGS whole thing power on confirm ANALOG INPUTS (calibration and units conversion done on the .dll side) > ECSPresSenseA(int,int) ; airConUnit-toDLL, press-fromDLL (0-255) nun Hg airConUnit = EVAP = 1 evaporator coil COND = 2 condensor coil BLOW «= 3 blower fan pressure CANO = 4 canopy fan pressure > sucSenseA(int,int) ; sucPump-toDLL, press-fromDLL (0-255) mm Hg sucPump = ■ PUMP = » 1 pump intake side PUKE » 2 puke tank side > OBOGSSenseA(int,int) ; OBOGSDevice-toDLL, on/off-fromDLL (0-255) mm Hg OBOGSDevice = TANK1 = 1 OBOGS 02 tank number 1 TANK2 » 2 OBOGS 02 tank number 2 > tempSenseA(int,int) ; thL ^vice-toDLL, temp-fromDLL (float) degrees C thDevicel = BATCOMPl = 11 Battery compartment 1 BATC0MP2 = 12 Battery compartment 2 BATC0MP3 = 13 Battery compartment 3 5 CONDBOT - 22 Condensor hot side CONDCOOL - 23 Condensor less-hot side EVAPICOLD - 31 Evaporator 1 cold side EVAP2COLD - 32 Evaporator 2 cold side EVAP1WARM - 34 Evaporator 1 less-cold side EVAP2WARM - 35 Evaporator 2 less-cold side EQPTXST •* 4 Equipment exhaust temperature AMBIENT - 5 Entire system supply temp PATSUP - 6 Air temp at head of patient PATRETRN = 7 Air temp at foot of patient DISPLAY - 8 Diβplay box CPU = 9 On the CPU chip of the computer > voltSenseA(int,int) ; vDevice-toDLL, voltage-fromDLL (float) volts or amps vDevice - 1 BATCHRG - 1 Battery recharge current (1 volt per amp) BATLOAD - 2 Battery load current ( 1 BATVOLT ** 3 Battery voltage DCSUPV = 4 DC Supply voltage ACSUPV - 5 AC Supply voltage HYBRID INPUTS (These are digital to John's side but analog to Delphi. ) > fanTachSenseHA(int,int) ; fanNumber-toDLL, flow-fro DLL (0-255) cuft/min fanNumber «■ COND *» 1 condensor fans CIRC >■ 2 circulation fans PRES => 3 canopy pressurization fans HOW TO CHECK IF DLL IS IMPLIMENTED if tempSenseA(EQPTXST,eqpTe p) > 0 then messageDlg( 'The .dll hasn''t implemented this yet.' ,mtlnformation, [ bOK], 0); CONTROLS, MORE THAN ONE PLACE > In some global place declare suctionOnToggle as Bool then in any place where there's a control use this: if suctionOnToggle = True then begin suctionOnToggle := False; Labell.Caption :» 'OFF'; BitBtnlO.Glyph.LoadFromFile{ 'suction2.bmp' ) ; callHardware (1,1); fi end else bla bla opposite of the above Then in Project Source place initialize the toggle... suctionOnToggle :- True; And whenever a screen (which containβ that control) is turned on, that is, when XXXX.Visible :«■ True, do the following: if suctionOnToggle « True then lblSuctionlndicator.Caption :■ 'ON' THERE'S NO NEED TO TURN EQUIPMENT ON AGAIN O O P In some unit (usually one not associated with a form) find the "type" area of the interface and "declare" a class. Unlike C++, when you declare a class you must at the same time, inherit from one just like it. Then you list the member variables and member procedures. For example: interface type TScreenControl = class (TObject) procedure TurnOnMedicsScreen; procedure doAnyThingProcedure; constructor initProcessTypeName; end; Notes: > the (TObject) iβ what's being inherited. That space can be blank. > if you use public and private they mean the same as if you placed their forwards in either the "interface" or "implementation" areas. In the implementation area write some code to define a member procedure. Like this: procedure TMyScreenControl.TurnOnMedicsScreen; begin blaBlairBla :>= ■ True; if blaBla =■ True then blaBlaEtcEtc; else blaEtcBlaBla; 7 end . A constructor is a procedure where the word "procedure" is replaced with "constructor" (that is where the thing is defined and declared). > Then enable the scope of the class/procedure to other units: In the implementation's "uses" section of the unit that contains the call to the member procedure, add the name of the unit that contains the class procedure definition, as in . . . uses DisplaySpace, Comnunit; > instance the class 1) in the implementation's var section of the unit that contains the call, declare the object... a_ScreenHappening: TScreenControl; 2) in the declaration area of the procedure definition that contains the call, "create" the object as in... a_ScreenHappening : « TScreenControl.Create; where .Create is a procedure inherited from TObject. 3) or do the anObj.Create thing in the "OnCreate" method of the form it's in. > call the function a_ScreenHappening.TurnOnMedicsScreen; > destroy the object when you are done. If the Create was called as a part of Form coming into exiβtance, then use the "OnDestroy" method to free up some RAM. Example: a_ScreenHappening.Free HOW TO MAKE A NEW BUILD > In File Manager create a new directory. > Save-As Project with new name in that new directory > Use the Select-from-form-list-icon calling up each form, clicking on Save-File-As for each one. (Usually you use the same name; the name offered. ) > Save Project (or run it) to record all new files in project. > Although bit maps become part of the .dfm file, there may be some that are needed in run time. So move all b p's as well. - auctionl.bmp - suction2.bmp - vent.bmp - venteet.bmp - hartzap0.bmp - hartzapl.bmp - hartzap2.bmp > If you want a floppy backup, drop to DOS and go to either the new or old directory and do a pkzip A:\whatever.zip *.* DIAGNOSTIC MESSAGE msg, liteState : integer; sg :- 'liteState is: ' + intToStr(liteState) ; messageDlg (msg, mtlnformation, [ bOK], 0); meβsageBeep(1) ; These are slow. They take a whold second. messageBeep(MB_ICONASTERISK) ; messageBeep(MB_ICONEXCLAMATION) ; These constants make different messageBeep(MB_ICONHAND) ; sounds under the control of messageBeep(MB_ICONQUESTION) ; sound delee, in Control icon. messageBeep(MB_OK) ; TIMERS Ventilator form: One: ventDataSamplerTimer (every 7.5 seconds) calls John's ventCtrlWait(ALQ, 0) then my getAlarm(ventVal) calls John's ventCtrlWait(PP, 0) then my patientPres(ventVal) calls John's ventCtrlWait(RBR, 10) —back up resp rate then my drawBreathCurve(bpm) calls John's getPulseox(avg02, avgHR, StatusCode) then label.caption then three labels for avgHR, and two for avy02 calls John's getCapnostat(entC02 , rr) then label.caption then one label for entC02 and three places for rr calls John's getFlow(tidalVol, expVol, pPress) then label.caption then Two: initDelayTimer (every 1.0 seconds) calls systemControl(VENTINIT,ctrlState) DisplaySpace form: One: EKGTimer (3 seconds) calls drawEKG inside of which is a tight loop which callβ John's ekgSenseA Two: curveCyclerTimer (1 second) calla drawCurvβ inside of which. . . 1. it uses rand() to create the data 2 . stores it and 3. draws the curves (five curves are drawn, but only heart rate is needed) pulβeOx(HRATB,0) Main form: One: defibFlaβhCheckTijner (.9 se --timing important to catch blinking. ) calls John's defJbSenseD(READYLITE, readylndicatorState ) then it makes the appropriate labels appear, disappear. Repair form: (20 seconds) One: hrdwrHlthMonCyclβrTimer calls many of John's tempSenβeA(EQPTXST,eqpTemp) then label.caption { STORING DATA Save this as an example of the Windows way to file I/O. } { DisplaySpace . tempDataMβπ>rθ . ines . Strings [ lineβDown ] : ■ ' ' + intToStr ( count ) + ' ' + floatToStrF( (yTempDat[count] / 10.0) ,ffFixed, , 1) ; DisplaySpace.heartRatβDataMemo.Lines.Strings[ linesDown] :- ' ' + intToStr(count) + ' ' + floatToStrF( (YRateDatfcount] / 10.0 ) , ffFixed, , 1) ; if count mod 10 - 0 then begin linesDown :- linesDown + 1; DisplaySpace. tempDataMeπo. ines . Strings [ linesDown) : - intToStr(count) + ' minutes in'; DisplaySpace.heartRateDataMemo.Lines.Stringβ[ linesDown) :- intToStr(count) + ' minutes in'; DisplaySpace.tempDataMemo.Lines.SaveToPile( 'CORTEMP.DAT' ) ; DisplaySpace.heartRateDataMemo.Lines.SaveToFile{ 'HRTRATE.DAT' ) ; end; } {Where heartRateDataMemo is a Tnemo control with pre-written header.} { THE TROUBLE WITH THIS WAY IS YOU HAVE TO OPEN THE WINDOW AND PUT A BUNCH OF CRβ IN. } {CUSTOMIZING THE CURVE POSITION AND ERASE COLOR} 10 PROGRAM LISTING NEURO.PAS unit Neuro; interface uses SysUtils, WinTypeβ, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Buttons; type TneuroSurg ■ class (TForm) Image2: TImage; Image3: TImage; procedure FormDeβtroy(Sender: TObject); procedure exitBtnClick(Sender: TObject); procedure FormClic (Sender: TObject); private { Private declarations } public { Public declarations } end; var neuroSurg: TneuroSurg; implementation uses Main, Dispspac, Repair, Comnunit, Ventdet; {$R *.DFM} var theScreen: TScreenControl; procedure TneuroSurg.FormDestroy(Sender: TObject) ; begin theScreen.Free end; procedure TneuroSurg.exitBtnClick(Sender: TObject); begin close; end; procedure TneuroSurg.FormClick(Sender: TObject); begin neuroSurg.Visible :■ False; VENTDETAIL.Visible :- True; if suctionOnToggle » True then begin VENTDETAIL.Labell.Caption :- 'ON'; VENTDETAIL.BitBtnlO.Glyph.LoadFromFile ( 'suctionl.bmp' ) ; end end; end. PROGRAM LISTING AIO.H /* aio.h Author : J. Brayton, T223/GB History : 9/01/95 Description I Classes for AIO board. Contents: */ // ■ // fifndef _AIO_DOT_H ♦define _AIO_DOT_H linclude "aiocon.h" linclude <conio.h> linclude <stdlib.h> linclude <iostream.h> linclude <stdio.h> class aio { public: aio( ) ; //-aio() {}; int readChannel(unsigned char); }; /* aio: :aio Description : Constructor Returns : N/A */ // ■ // aio: :aio( ) { > /* aio: :readChannel(cmdbyte) Description : For initial prototype, this function will read the value of channel. Returns : '/ // ■ // ιnt aio: :readChannel(unsigned char cmdbyte) { unsigned char lobyte, hibytβ; int decval; outp(BASEADDRAIO,cmdbyte) ; //Poll for conversion complete Boolean ready - TRUE; clock_t timel » clock(); while ( ( (inp(BASEADDRAI0+4) & (1 « 7)) — 1) && //wait for conversion comlete ( (clock( )-timel)/CLOCKS_PER_SEC<-AD_TIME0UT ? TRUE : (ready-FALSE) ) ) ; if ( 1ready) { //Write to βtatus record, //cout « BELL; te - inp(BASEADDRAIO) ; te - inp(BASEADDRAIO--l) ; al - (hibyte«8) | lobyte; } > lendif UI048 DOT H PROGRAM LISTING AIOCON.H aiocon.h Author : J. Brayton, T223/GB History : 9/05/95 Description : Analog 10 communcation 10 module constants Contents: Constants for AIO board. II lifndef _AI0C0N_DOT_H ♦define AIOCON DOT H linclude "iotypes.h" //Base address defined in ioconfig.h const AD_TIMEOUT - 1; //One second timeout lendif COMM CON DOT H PROGRAM LISTING COMM4CON.H /* comm4con.h Author : J. Brayton, T223/GB History : 9/05/95 Description : Serial communcation 10 module constants Contents: Constants for COM4 boards. */ II lifndef COMM CON_DOT_H ♦define " C0MM4C0N DOT H linclude "iotypes.h" //Base addresses defined in ioconfig.h const char ST0P_BIT - (1«2) const char PARITY_ENABLE - (1«3) const char EVEN_PARITY - (1«4) const char SET_PARITY » (1«5) const char SET_BREAK - (1«6) const int VENT_XMT_ IME0UT - 1; //Seconds before timeout on vent commands. const int VENT_RCV_TIMEOUT - 1; //Seconds before timeout on vent response. const int XMT_TIMEOUT - 5; // 5 sec timeout on transmit const int RCV_TIME0UT - 1; 11 1 sec timeout on receive //dandy.astoud - I have changed the vent timeout to a large //number to allow for testing without timing out. Change //back to 5 when done testing. const int VENT_INIT_TIME0UT - 30; // Timeout on ventilator self-test const int VENT_RSP_TIMEOUT - 5; // Timeout on ventilator response const int BP_RSP_TIMEOUT " 5; // Timeout on blood pressure board /* const char A - 65; const char B =» 66; const char C - 67; const char D = 68; //Ventilator Commands, const char *VCMD ALQ ' "ALQ\r"; const char *VCMD_ALR "ALR\r"; char *VCMD_MAC "MAC-nn\r"; const char *VCMD MB "MB\r"; const char *VCMD_MI "Ml\r"; const char *VCMD_MIMV "MIMV\r"; const char *VCMD_HO "MO\r"; const char *VCMD_MSC "MSC\r"; char *VCMD_PMAX "PMAXnnXr"; char *VCMD_PMIN "PMINnn\r"; const char *VCMD_PP "PP\r"; const char *VCMD_RBR "RBR\r"; const char *VCMD_RIT "RIT\r"; const char *VCMD RST "RST\r"; char *VCMD_SBR "SBRnn\r"; char *VCMD SIT "SITn.n\r"; //Pulse Ox constants // const int SP02SPECDATALNGTH //Number of bytes affected by special data. //These are not really constant, but are set once and never //touched again, (sounds like a constant to me) //Commands for the EtC02 board // // //Cont Waveform Mode (3.3.1) const C02C0NTLNGTH - 3; unsigned char C02cont[C02CONTLNGTH] ; // //Data Request Mode (no waveform) (3.3.3) const C02DRNWFLNGTH - 3; unsigned char C02dataReqNWF[C02DRNWFLNGTH] ; // //Set ETC02 Time Period (3.3.4) const C02SETTIMEPERLNGTH - 4; unsigned char C02setTimePer[C02SETTIMEPERLNGTH] ; // //Get ETC02 Time Period (3.3.5) const C02GETTIMEPERLNGTH » 2; unsigned char C02getTimePe [C02GETTIMEPERLNGTH] ; // //Set Respiration Rate Editor (3.3.6) const C02SETRREDIT0RLNGTH = 3; unsigned char C02setRReditor[C02SETRREDIT0RLNGTH] ; // //Get Respriation Rate Editor (3.3.7) const C02GETRREDITORLNGTH - 2; unsigned char C02getRReditor[C02GETRREDITORLNGTH] ; // //Set Compensation Values (3.3.8) const C02SETC0MPVALLNGTH = 6; unsigned char C02setCompVal[C02SETCOMPVALLNGTH] ; // //Get Compensation Values (3.3.9) const C02GETC0MPVALLNGTH - 2; unsigned char C02getCompVal[C02GETCOMPVALLNGTH] ; // //Stop Continuous Mode (3.3.10) const C02STOPLNGTH - 2; unsigned char C02Btop[C02STOPLNGTH] ; //0x8f <chksm> // //Get Complete Status (3.3.11) const C02GETSTATUS - 2; unsigned char C02getStatus[C02GETSTATUS] ; // //Rest Monitor Parameters to Factory Defaults (3.3.12) const C02RESETLNGTH - 2; unsigned char C02reset[C02RESETLNGTH] ; // //Get Sensor Serial Number (3.3.13) const C02SENSERIALLNGTH => 2; unsigned char C02senSerial[C02SENSERIALLNGTH] ; 3 // //Get SW Rev. (3.3.1 ) const C02SWREVLNGTH « 2; unsigned char CO2swrev[C02SWREVLNGTH] ; // //Get Self Test Results (3.3.15) const C02TESTLNGTH - 2; unsigned char C02test[C02TESTLNGTH] ; // //Set No Respiration Timer (3.3.16) const C02SETN0RESTMRLNGTH - 3; unsigned char C02setNoResTmr[C02SETNORESTMRLNGTH] ; // //Get No Respiration Timer (3.3.17) const C02GETN0RESTMRLNGTH ° 2; unsigned char C02getNoResTm [CO2GETN0RESTMRLNGTH] ; // //Start Cell Zero (3.3.18) const CO2STRTCELL0LNGTH » 2; unsigned char CO2strtCell0[CO2STRTCELL0LNGTH] ; // //Start Adapter Zero (3.3.19) const CO2STRTADPTR0LNGTH = ■ 2; unsigned char C02strtAdptrO[CO2STRTADPTR0LNGTH] ; // //Stop Current Zero Command (3.3.20) const CO2STOP0LNGTH - 2; unsigned char CO2stop0[CO2STOP0LNGTH] ; // //Set Sampling Pump Status (3.3.21) const C02SETΞMPLPUMPLNGTH =■ 3; unsigned char C02setSmplPump[C02SETSMPLPUMPLNGTH] ; // //Get Sampling Pump Status (3.3.22) const C02GETSMPLPUMPLNGTH =■ 2; unsigned char C02getSmplPump[C02GETSMPLPUMPLNGTH] ; //ETC02 response packet lengths const int C02SWREVrespLNGTH = 37; const int C02TESTrespLNGTH - 3; const int CO2ADPTR0respLNGTH » 3; const int MAXC02DATA - 10; const int C02DATAC0UNT - 3; const enum C02DATACMDBYTES {ETC02 = 0X81, RR = 0X82, INSPC02 = 0X83}; const int C02DATAPOS[MAXC02DATA] = {ETC02, RR, INSPC02, 0,0,0,0,0,0,0}; const int C02DATALENGTH[MAXC02DATA] = {2, //bytes 4 2, //byteβ 1, //bytes 0,0,0,0,0,0,0}; const int C02DATAOFFSET[MAXC02DATA] - {4, //EtC02 is I bytes beyond command 4, //RR is I bytes beyond command 4, //Inspired C02 is ♦ bytes beyond cmd 0,0,0,0,0,0,0}; //Note: GUIIF.CPP/getCapnoESB uses a hardcodβd value for C02PACKETSIZE. // Should this array change in anyway, mod to this routine may be required. // The following constant is used in the routine. It must be changed // if the position of the parameter changes in the lookup table. const int C02ESBOFFSET - 4; //Extended Status Byte offset into packet. const int C02PACKETSIZE[MAXC02DATA] - {7, //EtC02 packet length 7, //RR packet length 6, //Insp C02 packet length 0,0,0,0,0,0,0}; //Packet sizes for all the command bytes for capnostat. conat int CO2X80PSIZE - 5; const int C02X81PSIZE = 7; const int C02X82PSIZE •* 7; const int C02X83PSIZE « 6; const int C02X84PSIZE - 8; //Commands for the flow board // //Get Software Revision const FLOWSWREVLNGTH - 4; unsigned char FLOWswrev[FLOWSWREVLNGTH] ; //OxCA-NBF-RF-CKS //Number of patient parameters requested from flow. const int FLOWDPICOUNT - 6; //Number of flow waveforms requested. const int FLOWWFCOUNT - 3; //Up to MAXWF //Start Waveform/Data Mode (Command D2h) const FLOWWFDATALNGTH = FLOWDPICOUNT + 4; unsigned char FLOWwfdata[FLOWWFDATALNGTH] ; //Stop Flow Continuous Mode (Command C9h) const FLOWWFSTOPLNGTH = 3; unsigned char FLOWwfstop[FLOWWFSTOPLNGTH] ; // //Array of DPI masks const MAXWF = 6; const MAXDPIs = ■ 16; // 5 const enum WAVEFORMS {FLOW*0X01, PRESSURE-0X02, CO2-0X04, VOLUME-0X08, PRESSURE2-0X10, AUX-0X20}; const int REQWAVEFORMS[MAXWF] - {FLOW,PRESSURE,VOLUME, 0, 0, 0} ; //These are the parameter DPIs (can not exceed 16) const enum DPIS {TIDVOL-22, EXPVOL-24, PKPRESS-30, AVGPRESS-31, FREQ-34, IE-35}; //This array will give us the bit position of each DPI in the DPI mask. const int DPIPOS[MAXDPIs] - {TIDVOL, EXPVOL, PKPRESS, AVGPRESS, FREQ, IE, 0,0,0,0,0,0,0,0,0,0}; //Blood Pressure Commands // const unsigned char *BPCMDS[] {"\200 "\201 "\202 "\203 "\204 "\205 "\206 "\207 "\208 "\209 "\210 "\211 "\212 "\213 "\214 "\215 "\216 "\217 "\218 "\219 "\220 "\221 "\222 223;;DB\3", • \224;;DC\3", • \225;;DD\3", P \226;;DE\3", '\227;;DF\3"}; ♦endif COMM4CON DOT H PROGRAM LISTING DEBUG.H / * debug . h Author : J. Brayton, T223/GB History : 8/12/95 Description : Debug constants. Contents : Constants used to selectively include debug statements. I */ //«« — // //♦define DEBUGl //Print Constructor and destructor calls //♦define DEBUG2 //Print function calls //♦define DEBUG3 //other information //♦define DEBUG4 //other information //♦define TEST //Include test code exclude hardware specific code PROGRAM LISTING FILEIO.H / * fileio . h Author : J. Brayton History : 2/01/96 Description : Prototype header file to collect in one place constants, variables, etc. required for logging data. Contents: */ // m „„« „„-.« ™™™™ _ // const unsigned BLOCKSIZB - 7; //Number of bytes in a block static int nextToRead; static int handle; enum FileOP {OPEN-0, CL SE-1}; const char starttime - Oxff; PROGRAM LISTING GUIFF.DEF - 104 - GUIIF.DEF (module definition file) LIBRARY GUIIF DESCRIPTION 'GUI Interface DLL used to interface with Delphi' EXETYPE WINDOWS CODE PRELOAD MOVBABLB DISCARDABLE DATA PRELOAD MOVBABLB SINGLE HBAPSIZE 2048 EXPORTS initControl fanControl ventControl ventCtrlWait pumpControl defibControl ecsControl powerControl defibSenseD te pSenβeA ekgSenseA getrs232 systemControl getPulsox getPulsoxWF getPulsoxWFs getEtC02swrev getEtC02selfTest startEtC02 stopEtC02 getCapnostat getCapnoESB getCapnoWFsβb capnoAdptrO getAHCapno getFlowSWrev βtartFlow stopFlow getFlow getAllFlow wfPulβox bpControl logwf logWaveFor statuβlog readChannel dummy reset518 readBoardTemp getDHVeraion iodrvr4 iodrvrδ iodrvrδ iodrvr7 iodrvr9 iodrvrlO iodrvrll target iodrvrl2 iodrvrl3 iodrvrl4 iodrvrlδ iodrvrlδ iodrvrl7 iodrvrlβ iodrvrl9 iodrvr20 iodrvr21 iodrvr22 iodrvr23 iodrvr24 iodrvr25 iodrvr26 iodrvr27 writeval readval PROGRAM LISTING GUIFF.H /* guiif.h Author : J. Brayton, T223/GB History : 9/15/95 Description : Prototypes for exported functions of GUI interface DLL. Contents: (to be determined) • / / /- // lifndef _GUIIF_DOT_H ♦define _GUIIF_DOT_H linclude "guiifcon.h * ♦include < indows.h> extern "C" { int FAR PASCAL _export initControl(const int); int FAR PASCAL _export nControl(fanCode fanNo, unsigned int onOff) ; int FAR PASCAL _export ventControl(ventCode ventCmd,unsigned int value, int &state) ; int FAR PASCAL _export ventCtrlWait(ventCode ventCmd, unsigned int value); int FAR PASCAL _export pumpControl(pumpCode event, unsigned int onOff) ; int FAR PASCAL _export defibControl (defibCode action, unsigned int onOff) ; int FAR PASCAL _export ecsControl(int event, unsigned int onOff) ; int FAR PASCAL _export powerControl (int notUsed, unsigned int onOff) ; int FAR PASCAL _export defibSenseD(defibCode event, int &state); int FAR PASCAL _export tempSenseA(tempCode location, unsigned int far Stemp) ; int FAR PASCAL _export ekgSenseA(); ChnlBfr * FAR PASCAL _export getrs232(int board, int chnl, int &sob, int &eob); int FAR PASCAL __export systemControl (int βysEvent, int SctrlState) ; int FAR PASCAL _export getPulsox(int &avg02, int &avgHR, int istatuβCode) ; int FAR PASCAL _export getPulsoxWF(int &o2satWF) ; 1 int FAR PASCAL _export gβtPulβoxWFβ (int * fco2satWFs, int isize); int FAR PASCAL _export getAllPulβox(int *-io2Data, int * &o2satWFβ, int fcsize, int tstart); int FAR PASCAL _export getEtC02swrev(unsigned char far * &swrev,int fclength) ; int FAR PASCAL _export getBtC02βelfTest(int fcβtatus); int FAR PASCAL _export βtartBtC02 ( ) ; int FAR PASCAL _export stopEtC02(); int FAR PASCAL _export getCapnostat(int far * tcapnoPara s, int Seize) ; int FAR PASCAL _export getCapnoBSB(int fcESBl, int J.ESB2, int &ESB3) ; int FAR PASCAL _export getCapnoWFssb(int ϋwavβform, int issb) ; int FAR PASCAL _βxport capnoAdptrO(int icsb) ; int FAR PASCAL _export getAllCapno(int far * iwf, int iwfsize, int &start, int far * fipatData, int Spatdsize, int &ssb, int far * &esb, int Sesbsize); int FAR PASCAL _export getFlowSWrev( ) ; int FAR PASCAL _export βtartFlow(); int FAR PASCAL _export stopFlow(); int FAR PASCAL _export getFlow(int * &flowParams, int Seize); int FAR PASCAL _export getAllFlow (int ** fiflowwfs, int * ifwfsize, xnt * &fwfstart, int * &dpis, int * ϋdpivalue, int irdpisize, int fcestatusl, int &estatus2, int -«estatus3) ; int FAR PASCAL _export wfPulsox(unsigned char far * &flowWF, int -.size) ; int FAR PASCAL _export bpControl(conβt bpCode bpCmd, int 4,ctrlState, unsigned char far * ibpResp, int &size) ; int FAR PASCAL _export logwf(int waveform); int FAR PASCAL __export logWaveForm(int waveform, int command); int FAR PASCAL _export βtatuslog(char * msg); int FAR PASCAL _export readChannel(int channel); int FAR PASCAL __export du my(int &inout); int FAR PASCAL ~«xport reβet518(int) ; int FAR PASCAL _export readBoardTemp(int) ; const char * FAR PASCAL _export gβtDllVersion( ) ; 2 void FAR PASCAL _export iodrvr4 ( ) void FAR PASCAL _export iodrvr5( ) void FAR PASCAL _export iodrvrδ( ) void FAR PASCAL _export iodrvr7{ ) void FAR PASCAL _export iodrvr9() void FAR PASCAL _export iodrvrlO( void FAR PASCAL _βxport iodrvrll{;, void FAR PASCAL _export target(int Sβob, int teob, int ibfrlndx, ChnlBfr far ϋcbufr) ; void FAR PASCAL _export iodrvrl2 void FAR PASCAL _export iodrvrl3 void FAR PASCAL _export iodrvrl4 void FAR PASCAL _export iodrvrl5 void FAR PASCAL _export iodrvrl6 void FAR PASCAL _export iodrvrl7 void FAR PASCAL _export iodrvrlβ void FAR PASCAL _export iodrvrl9 nt event) void FAR PASCAL _export iodrvr20 void FAR PASCAL _export iodrvr21 void FAR PASCAL _export iodrvr22 void FAR PASCAL _export iodrvr23 void FAR PASCAL _export iodrvr24 void FAR PASCAL _export iodrvr25 void FAR PASCAL _export iodrvr26 void FAR PASCAL _export iodrvr27 void FAR PASCAL export writeval val) unsigned int FAR PASCAL _export readval( ) ; } ♦endif GUIIF DOT H PROGRAM LISTING GUIFFCON.H ♦ifndef _GUIIFCON_D T_H ♦define _GUIIFCON_DOT H //........ /* guiifcon.h Author i J. Brayton History : Created 6/1/95 Deβcription : Constants for GUIIF. Contents: */ // ■ ♦include "iotypes.h" SIT 17}; enum ventCode enum pumpCode {SUCPOWER - 1, VEN POWER - 2}; nel assignments const PC2_CURNT_M0N - 0; const PC2_VLT_MON - 1; const PC2 VLT CNTRL - 2; //System control constants (used with βystemControl entry) //Ventilator initialize event //Ventilator wait ofr RDY state //Ventilator wait for ON state : //Ventilator wait for IMV state //Ventilator in IHV mode state //bpControl constants const BPWAIT - 0; //Requests bpControl to look for end notice message. const BPNOWAIT - 1; //Requests bpControl to return response immediately. const BPWAITING - 2; //Indicates bpControl is looking for end notice message. const BPREADY - 3; //Indicates bpControl has seen end notice message. //conβt BPWΛIT4STATUS - 0; //Blood pressure waiting for end notice message. //const BPSTATUSAVAIL - 1; //Blood pressure status report available const CAPTUREFLOW - 1; //Novametrix capture flow event //Used in system const CAPTUREETC02 « 2; //Novametrix capture EtC02 event //control to conβt CAPTURESP02 - 3; //Novametrix capture SP02 event //identify events, const CAPTUREVENT - 4; const CAPTUREC2B1 » 5; //These two values are used for testing const CAPTUREC4B2 - 6; //purposes at the moment. const SP02SDLEN - 7; //Special data block is 7 bytes long. const ETC02ETLEN - 7; //End tidal C02 length incl checksum. const ETC02RRLEN - 7; //Reβp Rate length incl checksum. //Ventilator states const COMMAND - 0 //Ventilator ready to accept command const WAIT4RESP0NSE - 1 //Ventilator waiting for response const RESPONSERCVD - 2 //Ventilator received expected response const CMDNOTACCEPTED - 3 //Ventilator could not perform command const VENTTIMEOUT 5; //Ventilator timed out waiting for response //Ventilator retry option const VENTRETRY 3; //Number of times to try to send ventilator //when timeout occurs. //Blood Pressure Cuff retry option const BPRETRY - 3; //Number of times to send command to Blood Pressure Brd //Ventilator return codes const int NORESP - -1; const int INVALIDVENTCMD - -2; const int INVALIDVENTSTATE - -2 const int VALUEOUTOFRANGE - -3 const int VENTSBRTIMEOUT - -4 const int VENTALQTIMEOUT - -5 const int VENTALRTIMEOUT - -6 const int VENTPMAXTIMEOUT - -7 const int VENTPMINTIMEOUT - -8 const int VENTPPTIMEOUT - -9 const int VENTSITTIMEOUT - -10 const int VENTRSTTIMEOUT » -11 const int VENTMOTIMEOUT - -12 const int VENTMIMVTIMEOUT = -13 const int VENTMACTIMEOUT - -14; //Ventilator response packet lengths //Alarm query response //Alarm reset response 3; //Intermittent Mandatory Ventilaor //Mode ON response //Pressure and Set Breath Rate responses //Patient pressure response //Reset ventilator response //Set Inspriatory Time response const AslashCdashnne 7; //MAC response //Misc const INITIALIZE » 1; //Ventilator response strings (old way) dandy.astound const char lpszRDY[ ] = "RDY\r"; const char IpszON [] = "ON\r ; const char lpszIMVf ] - "IMV\r"; const char lpszALQf] = "ALQ-"; const char IpszALRf] - "ALR\r"; const char lpszCM[] « "cm\r"; const char lpszHUH[] » "?\r"; //Ventilator response strings (new way) // response alternate response // char *ventResponse[ 16] [2 ] { {"ALQ-n\r", NULL}, //Alarm Query {"ALR\r", NULL}, //Alarm Reset {"A/C-nn\r" , NULL} , //Mode: Assist Control {"MBC\r", NULL} , //Manual Breath {"A/C-nn\r", "IMV\r" }, //Mode Inquire {"IMV", NULL} , //Mode: IMV {"0N\r", NULL}, //Mode: On {"SC\r", NULL} , //Mode: Standby/Charge {"nn\r" , NULL}, //Pressure Maximum {"nn\r" , NULL}, //Pressure Minimum {"nnncna\r", '-nnncm\r"}, //Patient Pressure <"nn.n\r", "nnn.\r"}, //Read Breath Rate { "n.nβ\r", NULL}, //Read Inβptiration Time {"RDY\r", NULL}, //Reset Ventilator {"nn\r" , NULL}, //Set Breath Rate {"n.ns\r", NULL} }; //Set Inspiratory Time //Constants for GetAllPulsox const int SP02WFDATAMAX - 20; //Returns up to this number of waveform values. const int SP02SPECDATAMAX - 3; //Heart Rate, 02 Sat, Status Code. //Constants for GetAllCapno const int TEMPBFRSIZE - 50; const CAPNOWFSIZE - 20; //Maximum waveform values passed back const CAPNODATASIZE - 3; //EtC02, Resp. Rate, inspired C02 const CAPNOESBSIZE - 3; //Number of extended status bytes passed back. //Position of data in array passed back, const ETC02P0S - 0; const RRPOS - 1; const INSPC02P0S - 2; c nst SSSPOS - 3; //Constants for GetAllFlow const int FLOWBFRSIZB - 100; const FLOWWFMAX - 3; //Flow, Pressure, and Volume waveform (in that order) const FLOWWFSIZE - 20; //Maximum number of waveform values passed back const FLOWAVGSIZE - 2; //Number of pointB to average. const MAXDPIS 10; //Constants for data logging commands const int STARTLOG - 1; const int CONTLOG - 2; const int STOPLOG - 3; //These numbers represent the number of bytes left in the current buffer //at which point the logging routine will not start recording due to //posBibility of current buffer filling and overwriting buffer being //logged. // pulsox, capno, flow const int FLOWWF - 1; const int CAPNOWF « 2; const int PULSOXWF - 3; const int PULSOXBFRZONB - 50; const int CAPNOBFRZONE - 50; const int FLOWBFRZONB - 100; const int BFRZO;iE[] - {PULSOXBFRZONB ,CAPNOBFRZONE,FLOWBFRZONE}; //Blood Pressure return codes const int BPRES1TIME0UT - -1? const int INVALIDBPCMD - -2; const int INVALIDBPCTRLSTATE - -3; ♦endif GUIIFCON DOT H PROGRAM LISTING GUIFTST.H // . ..... .. ..... . /* guiiftst.h Author : J. Brayton History : 02/05/95 Description : This header file contains the guiif test and status record. Contents: Test and Status record (along with some conditional compilation switches) . */ / /nvnαιcπnna-αnB-r-iMnwκHK-ssiBisi --.κHBKS a->κκ-iι // //»»»>»»>>»Conditional compilation options: //Displays system configuration (conditional compilation flags) ♦define DISPLAY FLAGS IN LIBMAIN ♦define ENABLE_TEST_MODE //Includes code to simulate hardware when not present. //Looks for 518 board to determine if H/W is present. //NOTE: ENABLE_TEST_MODE takes precedence over // ENABLE_JOHNS_TEST_MODE //Idefine FORCE_TEST_MODE //Forces Test Mode even if hardware is present. //Test mode muβt be enabled, //♦define ENABLE_JOHNS_TEST_MODE //Will call getAllinit to initialize internal //internal data structure with real data from //logged data. Idefine ENABLE_AUDIBLE_ERROR //KEEP THIS ENABLED - OTHERWISE COMPILATION ERRORS //♦define STATUS_LOG_ENABLED //♦define VALIDATE_CHECKSUM_LOG_ENABLED //♦define CALC_CHECKSUM_LOG_ENABLED //♦define ENABLE_INVALID_CHKSM_NOTIFY //File 10 is all done on the fly in logWaveFor s. //The above statement is not true since there is a problem with opening //a binary file and appending the data. //♦define DISABLE_FILE_IO //Disables file 10 in InitControl and IODRVR16 //♦define DISABLE_FILB_IO_IN_LIBHAIN //Disables Open in LIBMAIN Idefine DISABLE_FILE_IO_IN_WEP //Disables fclose in WEP (causes system crash) Idefine ENABLE_FATAL_ERROR_MSGS //♦define ENABLE_DATA_LOSS_MSGS //Display when we can not send all waveform points ♦define ENABLE_STATUS_LOG_IN_LIBMAIN ♦define ENABLE_STATUS_L G_IN_START_WF ♦define ENABLE_STATUS_LOG_IN_STOP_WF Idefine ENABLE_LOGGING_ERR0RS //♦define ENABLE_CALLING_STATUS //Message given when function is called. ♦define ENABLE_LOGGING_STATUS //Display when buffers are logged. ♦define ENABLE_AVG_GET_ALL_FLOW //Compiles the new averaging routine. ♦define ENABLE_VENT_CMD_ERRORS //Displays commands not able to be sent to vent. Idefine ENABLE_SENDCMDTOVENT_DISPLAY //Displays commands sent to ventilator. Idefine DISABLE_INTERRUPTS //Prevents modification of interrupt vector table. //This prevents system crashes on dev workstations. const NUMBEROFBOARDS - 2; const NUMBEROFCHANNELS - 4; typedef struct BrdandChnl { int board; int channel; }; typedef int Comm4Channels[NUMBEROFBOARDS] [NUMBEROFCHANNELS] ; struct commStatus { int RS232_TEMP_BFR_NOT_NULL; //Means we potentially lost data. Comm4Channelβ RS232_dataLoβs; int TIHEOUT_ON_XMT_RS232; //Very unlikely and indicates a real problem. Comm4Channels RS232timeout; >? PROGRAM LISTING IOCONFIG.H / /...., ....... ...— / * ioconf ig . h Author : J. Brayton, T223/GB History : 7/09/95 Description : This file collects together in on location all the parameters, constants, etc. of all the LSTAT 10 modules. Instead of having several files for each 10 board, this one file should make it easy to make configuration changes while quickly viewing overall system configuration to spot potential address, channel, and IRQ conflicts. I While this offers the advantage of giving an overall I system view, it does have the disadvantage of forcing I a complete build even when only one parameter is changed I for a local 10 module. At the time this decision was made, however, a complete rebuild did not take long, Eventually, these parameters may be read in from a file I which would avoid rebuilding the software when changes are made. Making system configuration changes, however, should be a rare event. Contents: System con iguration parameters for all LSTAT 10 boards. */ mαanan Bαn // lifndef _I0C0NFIG_D0T_H Idefine _I0C0NFIG_D0T_H (.include "guiiftst.h" / /πaβ--itιπ«a«aaBSia iϊi aaar«ilβ« α B usas-KS-S-SBBiπB nt // Base Addresses / IRQs 1 // The Sensoray Model 518 PC104 Sensor Coprocessor // .=_».. ..... ...... ........... //Currently both boards do not have IRQs assigned. //However, it is planned that IRQ 1 will be used //in the future for board 1. The current system //configuration does not allow board 2 any //IRQ assignment. This is subject to change //based on system configuration changes. / / Bna βB-s-scEa-3αr(-3aBKjiB-3Msj--i xi-c as nffzx-9 // BASE_ADDRESS DEFINED (board 1) / / naassaiaBSsascπnaavs nBsiKBiiMBBai VB nπaK const unsigned int BASEADDR518N01 =* 0x2B0; // BASE_ADDRESS DEFINED (board 2) const unsigned int BASEADDR518N02 = 0x3B0; //Number of 518 boards in system, const NUMOF518BRDS - 2; // The PCM-UI048 Digital 10 / /==-=====3===-===aαϊiC-i--aaB3πBt-.aα : =sa-3-issα=nnc:3ii-fsaι //Currently this board does not have an IRQ //assigned to it. The current system configuration //does not allow any IRQ assignment. It is not //clear whether an IRQ for this board will be //needed in the future. -SS-3.S- // BASE_ADDRESS DEFINED const unsigned int BASEADDRUI048 - 0x300; / /-=-=c.-:^s--:-= 3 -=--}-===;- r tα- XB nc-aBS-3-==ιaaa-3- = // The PCM-C0M4 Serial 10 //.._.., ....... ..... .—.........._. typedef unsigned int Chnladdr[4]; //Channel maps const Chnladdr C0M4B1CHNLS - {0x3E8,0x2E8,0x3A8,0x2A8} ; const Chnladdr COM4B2CHNLS - {0x100,0x108,0x110,0x118}? //Interrupt ID register addresses const unsigned int C0M4INTIDS[] - {0X220, 0X240}; //Board 1 - IRQ 5, Board 2 - IRQ 7 const int COM4B1IRQ - 5; //These constants are currently not const int COM4B2IRQ - 7; //used to set IRQs. (see LIBMAIN) //Define number of COM4 boards in system, const NUMOFCOM4BRDS - 2; //Define where boards are connected. const VENTBRD - 1; //The ventilator is talking to COM4 board 1 const VENTCHNL - 1; //Ventilator on channel 1 const VSTATCHNL - 2; //Status port on board with ventilator. const NOVABRD - 2; //The novametrix boards are talking to COM4 board 2. const FLOWCHNL - 1; //Novametrix flow module on channel 1 const ETC02CHNL - 2; //Novametrix capnostat module on channel 2 const SP02CHNL - 3; //Novametrix pulseoximter module on channel 3 const NSTATCHNL » 4; //Alternate status port on board with Novametrix const BPBRD ■ 2; const BPCHNL 5; const STATBRD VENTBRD; //Board used for writing status/diagnostics. const STATCHNL VSTATCHNL; //Channel used for writing status/diagnostics. Description Ventilator Status Port Unavailable Unavailable NovaMetrix Flow Novametrix EtC02 Novametrix SP02 Alternate Status Port */ //Define baud rate divisor fdefine DIV50 2304 Idefine DIV4800 24 ♦define DIV9600 12 Idefine DIV19200 6 //Define LCR mask bits ♦define NO_PARITY 0 ♦define ONE_STOP 0 ♦define EIGHT_DATA 3 //Channel configuration typedef struct ChnlConfig { unsigned int baud; unsigned int parity; unsigned int data; unsigned int stop; }; conβt ChnlConfig C0M4BRD1C0NFIG[ ] - { {DIV9600,NO_PARIT ,EIGHT_DATA,ONE_STOP} , //Ventilator {DIV19200,NO_PARITY,EIGHT_DATA,ONE_STOP} , //Status port {DIV9600,NO_PARITY,EIGHT_DATA,ONE_STOP} , //Unavailable {DIV9600,NO_PARITY,EIGHT_DATA,ONE_STOP} } ; //Unavailable conβt ChnlConfig COM4BRD2CONFIG[ ] - { {DIV19200,NO_PARITY,EIGHT_DATA,1}, //NovaMetrix Flow {DIV9600,NO_PARITY,EIGHT_DATA,ONE_STOP} , //Novametrix EtC02 {DIV4800,NO_PARITY,EIGHT_DATA,ONE_STOP} , //Novametrix SP02 {DIV4800,NO_PARITY,EIGHT_DATA,ONE_STOP}} ; //Blood Pressure Board // -. .................... ... // The PCM-AIO Analog 10 //.. ........... .... ................ //Currently this board does not have an IRQ //assigned to it. The current system configuration //does not allow any additional IRQ assignments. //It is not clear whether an IRQ for this board //will be needed in the future. //»._»=...............----..„.-...--.-.--.-.... // BASE_ADDRESS DEFINED //_. «: ....... .... .... const unsigned int BASEADDRAIO - 0x190; ♦endif IOCONFIG DOT H PROGRAM LISTING IODRVR.CPP //. .. ». .......... /* iodrvr.cpp Author : J. Brayton, T223/GB History : 11/16/95 Description i Universal 10 drvier which can be used to call any entry point in the guiif.dll for testing various 10 modules. Run in debug and set switch variable to appropriate value to call desired driver. Contents: Basically a dummy routine to call actual 10 drivers. */ // ■ II ♦include <conio.h> ♦include "comm4.h" ♦include <windows.h> ♦include <string.h> ♦include <mem.h> ♦include "guiif.h" ♦include "fileio.h" // Note: Only guiif.h should be needed, but the other includeβ // are included to avoid errors. Need to determine why // this is a problem. const I0DRVR4 const I0DRVR5 5; const I0DRV 6 6; const I0DRVR7 7; const I0DRVR9 9; const IODRV 10 ■ 10 const I0DRV 11 ■ 11 const I0DRVR12 • 12 const I0DRVR13 • 13 const I0DRVR14 • 14 const I0DRVR15 ■ 15 const I0DRVR16 ■ 16 const I0DRVR17 ■ 17 const I0DRVR18 - 18 const I0DRVR19 ■ 19 const IODRVR20 ■ 20 const I0DRVR21 ■ 21 const I0DRVR22 > 22 const IODRVR23 ■ 23 const IODRVR24 - 24 const IODRVR25 ' 25 const IODRVR26 - 26; const IODRVR27 - 27; void main( ) { //while (lkbhit()); //Allow for data collection. //Call entry point into guiif.dll to perform test. //Must run in debug to examine results, int defaultcase - IODRVR27; int drvrno - defaultcase; switch (drvrno) { case I0DRVR4 : iodrvr4 ( ) ; break; //Channel buffers manipulation test. case I0DRVR5 : iodrvr5{); break; //Ventilator start-up and SBR test. case IODRVR6 : iodrvrβ( ) ; break; //Ventilator general test (ventControl) case I0DRVR7 i iodrvr7 ( ) ; break; //Novametrix first checkout. case I0DRVR9 : iodrvr9 ( ) ; break; //EtC02 first checkout case IODRVR10: iodrvrl0(); break; //Ventilator general test (ventCtrlWait) case IODRVR11: iodrvrll(); break; //FLOW first checkout case I0DRVR12: iodrvrl2(); break; //double bufferring checkout (general //checkout of internal variables) case IODRVR13: //initControl(OPEN) ; //Opens files (is done in LibMain if commented) iodrvrll(); //Command novametrix boards into continuous mode. while (lkbhitO) iodrvrl3(); //Writes full buffers to diβk using creat/write. break; case I0DRVR14: iodrvrl4{); break; //double bufferring checkout case IODRVR15: initControl(OPEN) ; //Opens files iodrvrl5{); //file io test. initControl(CLOSE) ; break; case I0DRVR16: //Writes full buffers to disk using fopen/fwrite. iodrvrll(); //Command novametrix boards into continuous mode. while (lkbhitO) iodrvrl6(); //Writes full buffers to disk using creat/write. break; case IODRVR17: //Unit test of getCapnostat iodrvrl7 ( ) ; break; case IODRVR18: //Unit test of getFlow iodrvrl8( ) ; break; case I0DRVR19: //Used by GUIIOTST for timing study. iodrvrl9(0); //Stores system time each time it is called. break; case IODRVR20; //More capnostat testing. iodrvr20( break; case IODRVR21 //More testing of pulsox. iodrvr21 ( ) break; case IODRVR22 //Even more testing of pulsox. iodrvr22 ( ) break; case IODRVR23 //Some post BIG MOD testing. iodrvr23 ( ) break; case IODRVR24 //Start ventilator and writes buffer to disk. iodrvr24 ( ) break; case IODRVR25 //Start ventilator and writes buffer to disk. iodrvr25 ( ) break; case IODRVR26 //Test new file logging βcheme. iodrvr26( ) break; case IODRVR27 //Tests new ventFindlnBuffer scheme iodrvr27 ( ) break; default: ; PROGRAM LISTING IODRVR.DEF IODRVR.DEF (module definition file) NAME IODRVR DESCRIPTION 'Stand alone unit test for 10 nodules' EXBTYPE WINDOWS CODE PRELOAD MOVBABLB DISCARDABLE DATA PRELOAD MOVBABLB MULTIPLE HBAPSIZB 1024 STACKSIZE 8192 IMPORTS GUIIF.ventControl GUIIF.pumpControl GUIIF.βyβtemControl GUIIF.iodrvr4 GUIIF.iodrvr5 GUIIF.iodrvr6 GUIIF.iodrvr7 GUIIF.iodxvr9 GUIIF.iodrvr10 GUIIF.iodrvrl2 GUIIF.iodrvr13 GUIIF..iodrvr14 GUIIF.iodrvr15 GUIIF.iolrvr16 GUIIF.iodrvr17 GUIIF.iodrvr18 GUIIF.iodrvrl9 GUIIF.iodrvr20 GUIIF.iodrvr21 GUIIF.iodrvr22 GUIIF.iodrvr23 GUIIF.iodrvr24 GUIIF.iodrvr25 GUIIF.iodrvr26 PROGRAM LISTING IOTYPES.H - 134- / /..., .— -. .... an............ / * iotypes . h Author : J. Brayton, T223/GB History : Was formerly known as s518glbl.h Description : Contains common types, clasβes, etc, for all 10 routines. Contents: Types, classes... */ // • ♦ifndef _IO_TYPES_DOT_H ♦define _IO_TYPES_DOT__H linclude <dos.h> ♦include "ioconfig.h" // Boolean Type typedef enum Boolean { TRUE « 10, FALSE - 0} ; //The following are used as indices into data structures, const COM4BRD1 - 0; const COM4BRD2 = 1; const CHNL1 - 0 const CHNL2 » 1 const CHNL3 - 2 const CHNL4 - 3 const CHNLSPERBRD 4; //Channels per board. //Old stuff / / VVVΛΓVVVVVVVVV ΓVVVVVVVVVVVV ^ wwwv //More constants const CHNLBFRSIZE - 1000; //Size of a channel buffer in byteβ const BOARDBFRSIZE - 4000; //Total size of a board buffer in bytes // ΛΛΛ Λ ΛΛΛΛΛ ΛΛΛA Λ const DOUBLE 2; const BRD1CBNL1BLKSIZB - 1000; //Vβntilator const BRD1CHNL2BLKSIZB - 1000; //DataPak const BRD1CHNL3BLKSIZB - 1; //Not Available const BRD1CHNL4BLKSIZB - 1; //Not Available conβt BRD2CHNL1BLKSIZB ■ 2000; //Flow const BRD2CHNL2BLKSIZB - 2000; //BtC02 const BRD2CHNL3BLKSIZE - 2000; //Sp02 const BRD2CHNL4BLKSIZE - 1; //Not Assigned typedef struct BfrStuff { unsigned char *bfr; int bfrlndx; int laβtread; int βavelndx; dostime_t *timeStamρ; }; typedef struct ChnlBlk { BfrStuff *curBfrInfo; BfrStuff *flushBfrInfo; BfrStuff *tempBfrInfo; char *fileName; int blockSize; >; typedef ChnlBlk ChnlBlks[CHNLSPERBRD] ; / /Old stuf f / / VVVVVVVVVVVVVVVΛΓVVVVVVVVVV ΓV^^ wvwv //Typeβ to be used to define channel and board buffers for RS232 typedef unsigned char ChnlBfr[CHNLBFRSIZB] ; //channel buffer typedef unsigned char BrdBfr[BOARDBFRSIZE]; //board buffers typedef ChnlBfr ChnlBfrsfCHNLSPERBRD] ; // Λ Λ static enum Mode {REAL, TEST} sysMode - REAL; ♦endif 10 TYPES DOT H PROGRAM LISTING IRQMNGR.CPP -137- * irqmngr.cpp Author : J. Brayton, T223/GB History : 10/12/95 Description : Interrupt manager routine. Contents : The two interface routines, ConnectToISQ and DisconnectFromlRQ enables a process to easily βet up the interrupt vector to handle interrupts. This interrupt manager also guards against trying to use an IRQ which is already in use. */ ll- ll ♦include <iostream.h> ♦include <βtdio.h> ♦include <dos.h> ♦include <conio.h> ♦include "irqmngr.h" 11 The following typedef definitition did not work using the DOS system //services to get and βet sege ent/offset for an interrupt. Instead //of using DOS system service calls, I used C library routines to //set up the interrupt vector. The alternate typedef for the 01d_Handler //is required when using the C libarary routines. // //typedef void (_far interrupt *Old_Handler) (void) ; typedef void _far _ " hterrupt (*Old__Handler) ( ... ) ; //Use with getvect/setvect //typedef int (_far interrupt *New_Handler) ( ) ; typedef void _far _xnterrupt (*New__Handler)(...) ; //Use with getvect/setvect //These are the interrupt stub routines which use the irq_data to dispatch //the appropriate interrupt handler. Again, the signature must conform //to what is expected by the C utility routines. Note that isrlb and //isr23 handle ctrl-break and ctrl-c interrupts to prevent the user from //interrupting the interrupt processing which would leave things in an //unknown and precarious state, I I void far interrupt isr2( . void far interrupt isr3 ( . void far interrupt isr4 ( . void far interrupt iβr5 ( . void far interrupt isr7 ( . void far interrupt isrl0{ void far interrupt isrll( void far interrupt isrl5( void far interrupt isrlb( void far interrupt isr23 ( //When any IRQs are hooked by one of the routines, the IRQ //code disables control-break termination by taking over //the two control-break vectors. The saved control-break //state is stored in the following three variables. // static Old_Handler old_intlb; static 01d_Handler old_int23; static unsigned char old_dos_break_state; //A count of the number of handlers currently in use. II static int count - 0; //This structure keeps track of the state of each of the //eight possible IRQ lines the IRQ manager can take over. //This includes the address of the new handler, the old //handler, and most importantly, the data pointer passed //to the new handler when it is invoked. // struct { enum irq_name irq; void *isr data //All of the new ISR handlers are called when the interrupt 2 //occurβ. All they do is call the hooked routine, passing it a //pointer to the data block it asked for in the ConnectToIRQ( ) //routine. When this is done, they take care of issuing the EOI //instruction and then exiting. // void _far _interrupt isr2( ... ) { irq_data[0] .isr_routine{irq_data[0] .isr_data) ; disable( ) ; outp(0x20, 0x20); return; } void _far _interrupt isr3( ... ) { irq_data[ 1] .isr_routine(irq_data[1] .isr_dat ) ; disable( ) ; outp(0x20, 0x20); return; } void _far _interrupt isr4 (...) { irq_data[2] .isr_routine(irq_data[2] .isr_data) ; disable( ) ; outp(0x20, 0x20); return; } void _far _interrupt isr5(...) { irq_data[3] .isr_routine(irq_data[3] .isr_data) ; disable( ) ; outp(0x20, 0x20); return; } void _far _interrupt iβr7(...) { irq_data[4] .isr_routine(irq_data[4] .iBr_data) ; disable( ) ; outp(0x20, 0x20); return; } //These routines have to send an EOI to the second 8250 PIC //as well as the first. void _far _interrupt isrl0(...) { irq_data[5] .isr_routine(irq_data[5] .isr_data) ; disable( ) ; outp(0xa0, 0x20); outp(0x20, 0x2tf); return; } void _far _interrupt isrll(...) { irq_data[6] .iβr_routinβ(irq_data[6] .isr_data) ; disable( ) ; outp(0xa0, 0x20); outp(0x20, 0x20); return; } void _far _intβrrupt isrl5(...) { irq_data[7] .isr_routine(irq_data[7] .isr_data) ; disable( ) ; outp(0xa0, 0x20); outp(0x20, 0x20); return; } 11 The two control-break vectors do nothing, so that Contrl-C //and Contrl-Break both have no effect. // void _far _interrupt intlb(...) { return; } void _far _interrupt int23(...) { return; } Old_Handler HookVector(int interrupt_number, New_Handler new_handler) { //Note: The commented code is an attempt to use DOS system services // to handle setting up the interrupt vector. Found using // C library routines to be easier and, more importantly, // produces the desired reβults. //union REGS r; //βtruct SREGS β - {0, 0, 0, 0}; // es, cβ, BB, ds Old Handler old handler - 0; //Try getvect to get interrupt vector instead of using DOS system service // old_handler - getvect(interrupt_number) ; //dandy.astound // //cout << "interrupt number : " « interrupt_number << " "; //printf("old_handler : %p\n", old_handler) ; //r.h.al - (unsigned char) interrupt_number; //r.h.ah - 0x35; //MS-DOS system service Get Segment and Offset //int86x(0x21, &r, &r, &s); //Assign old_handler the address that was in interrupt vector(int num) //This is where an exception is raised; can't seem to successfully //assign the segment address and offset to old_handler. // //* ( (unsigned _far *) old_handler + 1) - s.es; //* ( (unsigned _far *) old_handler) - r.x.bx; //dandy.astound //cout << "interrupt number : " << interrupt_number << " "; //printf( "new_handler : %p\n", new_handler) ; ββtvect(interrupt_number,new_handler) ; //Now set interrupt vector to point to new ISR. // //s.ds - FP_SEG(new_handler) ; //data segment //r.x.dx - FP_OFF(new_handler) ; //offset //r.h.al - (unsigned char)interrupt number; //r.h.ah ** 0x25; //MS-DOS syβte servcie Set Interrupt Vector. //int86x(0x21,&r, &r, &s); return old_handler; } //HookVector void UnHookVector(int interrupt__number, Old_Handler old_handler) { /* // A R A R R A R A R A R A R A R A R A R A R R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R A R R A R A R A R A R A R A R A R A R A R A R A R //Could use setvect library call do this, but let's try using //the DOS system services for a change. NOTE: System crashes //using this method. Now let's use setvect utility. // union REGS r; struct SREGS s - {0, 0, 0, 0}; s.ds - FP_SBG(old_handlβr) ; r.x.dx - FP_OFF(old_handlβr) ; r.h.al - (unsigned char) interrupt_numb«r; r.h.ah - 0x25; int 86x ( 0x2 1 , i , ir , & s ) ; / / R A R A R A R R R A R R A R A R A R A R A R A R A R Λ R A R R A R A R A R A R A R A R A R R A R A R A R A R R Λ R~R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R Λ R A R Λ R Λ R Λ R Λ R Λ R Λ R Λ R */ setvect(interrupt_number,old_handler) ; } //When we have taken over an interrupt, we don't want keyboard breaks //to cause us to exit without properly restoring vector. This routine //takes over the DOS and BIOS control-break routines, and sets the DOS //BREAK flag to 0. The old state of all these variables is saved off so it //can be restored when the last interrupt routine is restored. void TrapKeyboardBreak( ) { union REGS r; old_intlb - HookVector(Oxlb, intlb); //Control-C old_int23 - HookVector(0x23, int23); //Control-break r.h.ah - 0x33; //MS-DOS system service Get or Set State of Ctrl-break r.h.al - 0x0; //Request state int86(0x21, ir, &r) ; old_doβ_break_βtate - r.h.dl; r.h.ah - 0x33; r.h.al - 1; r.h.dl - 0; int86(0x21, &r, &r) ; } //When the last interrupt is restored, we can βet the //control-break vectors back where they belong, and restore //the old setting of the DOS break flag. // void ReβtoreKeyboardBreak( ) { union REGS r; UnHookVector(Oxlb, old_intlb) ; UnHookVector(0x23, old_int23); r.h.ah - 0x33; r.h.al - 1; r.h.dl - old_dos_brβak_state; int86(0x21,£.r, &r) ; } //When connecting to an IRQ, pass an IRQ number plus a pointer to ets ary int i; int pic_mask; int pic_address; int interrupt_number; int temp; for (i-0; ; i++) { if (irq_data[i] .irq « irq) break; if (irq_data[i] .irq — IRQ15) return RS232_ILLEGAL_IRQ; } if (irq_data[i] .isr_routine 1- 0) return RS232_IRQ_IN_USE; if (count++ « 0) TrapKeyboardBreak( ) ; irq_data[i] .isr_data - isr data; irq_data[i] .isr_routine - Tsr_routine; pic_mask - 1 « (irq%8); if (irq < IRQ8) { pic_address — 0x20; interrupt_number - irq + 8; } else { pic_address ■» OxaO; interrupt_number - irq + 104; } irq_data[i] .old_isr - HookVector(interrupt number, irq_data[T] .handler) ; disable( ) ; temp - inp(pic_address+l) ; irq_data[i] .old_pic_enable_bit - temp & pic_mask; //dandy.astound 7 / /This routine restores an old interrupt vector . int disconnectFromIRQ ( enum irq_name irq ) { nt temp; for (i-0; ;i++) { if (irq_data[i) .irq -- irq) break; if (irq_data[i].irq — IRQ15) return(O); } if (irq_data[i] ,isr_routine -- 0) return(O); irq_data[i] .isr_data - 0; irq_data[i] .isr_routine - 0; pic_mask - 1 << (irq%8); if (irq < IRQ8) { pic_address - 0x20; interrupt number - irq + 8; } else { pic_address - OxaO; interrupt_number - irq + 104; } UnHookVector(interrupt_number, irq_data[i] .old_isr) ; if (--count —■ 0) RestoreKeyboardBreak( ) ; return(1) ; PROGRAM LISTING IRQMNGR.H / / ■ ■B B l / * irqmngr . h Author : J. Brayton, T223/GB History : 10/16/95 Description : Header file for IRQ manager. Contents: Two public functions have their prototypes here. All the code for the IRQ manager is found in irqmngr.cpp. 10 */ Il¬ II lifndef _IRQMNGR_DOT_H l s Idefine _IRQMNGR_DOT_H linclude "rs232con.h" enum irq_name {IRQO-0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15, 0 ILLEGAL_IRQ - -1}; RS232Error connectToIRQ(irq_name irq, void* isr_data block, void (*isr_routrne) (void *isr_data_block) ) ; int disconnectFromIRQ(enum irq_name irq); 5 ♦endif IRQMNGR DOT H 0 5 PROGRAM LISTING PPFLOW.CCP //This ia the post-processing routine for the flow board, ♦include <stdio.h> linclude <stdlib.h> ♦include <string.h> ♦include <iostream.h> ♦include "iotypes.h" linclude "comπ»4con.h" //Quick and dirty Walter Reed poβt-procesaing routine which //will read Novametrix binary log files and generate an ASCII //version of the waveforms contained in the files. //Prototype of processing... (this works) //fread( (void *)fcvalue,1,l,infhandlβ) ; //itoa(value, bfr, 10); //strcat(bfr," "); //fwrite( (void *)bfr,βtrlen(bfr) , 1, outfhandle); //dandy.astound //These are the global variables which were part of flow.cpp. They will //be moved to the appropriate header files when all is working. //Right now, it is easier to include them here. static int βavenbf, findx; static unsigned char flσwbfr[100]; const FLOWWFMAX - 3; //Flow, Pressure, and Volume waveform (in that order) const FLOWWFSIZE - 20; //Maximum number of waveform values passed back const MAXDPIS - 10; int overrun[FLOWWFMA ] ; //Used to indicate data loss per wf int flowWF[FLOWWFSIZE]; int preββWF[FLOWWFSIZE]; int volWFfFLOWWFSIZE]; int *flowWFs[FLOWWFMAX] - {flowWF, pressWF, volWF} ; int flowWFβize[FLOWWFMA ]; int flowWFstart[FLOWWFMA ]; int flowDPIs[MAXDPIS]; int flowDPIvalues[MAXDPIS]; int estatusl, eatatuβ2, estatus3, dpisize; int onewfvalue; int cmdByteSeen - 0; int nbf - 0; 1 int i , j ; const char *flowinfilename "c j \\logWflow. dat" ; const char *flowoutfilename "c : \\] ogWflowwf . dat " ; const char *voloutfilename "c : WlogWvolwf . dat" ; const char *preβsoutfilename "c: WlogWpresewf .dat" ; unsigned char tempbfr[50]; //Temp storage to build our packets char bfr[20]; const char tab - 9; int value; FILE *infhandle; FILE *flowoutfhandle; FILE *voloutfhandle; FILE *pressoutfhandle; //———--π————-—--—————————............... ;. /* validChksm Description : Validates data using checksum. This is used internally at the moment(i.e., not an dll entry point). THIS DOES NOT CALCULATE A CHECKSUM. Returns : Success is non-zero */ II- I I Boolean validChksm(const unsigned char * bfr, const int bfrlen) { unsigned char sum ■ 0; for (int i - 0; i < bfrlen-1; sum +- *(bfr+i++)); if ( ( ( (sum&0x7f) + *(bfr+i) )&0x7f) « 0) //Valid checksum return(TRUE) ; else { cout << "Invalid checksum found..." « endl; return(FALSE) ; } > void main( ) { 2 //Open files. infhandle - fopen(flowinfilename, "rb"); flowoutfhandlβ - fopβn(flowoutfilename, "wt"); voloutfhandle - fopen(voloutfilename, "wt"); presaoutfhandle - fopen(preββoutfilename, "wt"); if ((infhandlβ - fopen(flowinfilename, "rb")) — NULL) { fprintf(stderr, "Cannot open input file.Xn"); return; } if ( (flowoutfhandle - fopen(flowoutfilename, "wt")) « NULL) { fprintf(stderr, "Cannot open flow output file.\n"); return; } if ( (voloutfhandle - fopen(voloutfilename, "wt")) — NULL) { fprintf(stderr, "Cannot open volume output file.Xn"); return; if ( (pressoutfhandle - fopen(pressoutfilename, "wt")) — NULL) fprintf(stderr, "Cannot open pressure output file.Xn"); return; while ( lfeof(infhandle)) { //Get byte from file fread( (void *)fcvalue,1, l,infhandle) ; if (value — OxOOff) { //Time stamp follows. //Get next four bytes and write to all files. for (int i - 0; i < 4; i++) if ( lfeof(infhandle) ) { fread( (void *)ϋvalue, 1, l,infhandle) ; itoa(value, bfr, 10); strcat(bfr,"\n") ; fwrite( (void * )bfr,strlen(bfr) , 1, flowoutfhandle) ; fwrite( (void *)bfr,strlen(bfr) , 1, voloutfhandle) ; fwrite( (void *)bfr,strlen(bfr) , 1 , pressoutfhandle) ; > continue; } if (value — 0xd3){ //Command byte cmdByteSeen - 1; findx - 0; flowbfr[findx++] - value; } else if (cmdByteSeen) { //Get number of bytes nbf - value; flowbfr[findx++3 - nbf; cmdByteSeen - 0; } else if (nbf > 0) if (findx — nbf+1) { //flow buffer is full after we get next byte flowbfr[findx++3 ■ value; βavenbf - nbf; nbf - 0; //Calculate checksum if (validChkβm(flowbfr,findx) ) { //Validate checksum //For each waveform, save in appropriate array. for (j - 0; j < FLOWWFMAX; j++) switch (j) { case 0 : //Flow onewfvalue - (flowbfr[ (j*2)+2)«8) | flowbfr[ (j*2)+3] ; itoa(onewfvalue, bfr, 10); strcat(bfr,"\n") ; fwrite((void *)bfr,strlen(bfr) ,1, flowoutfhandle) ; break; case 1 i //Pressure onewfvalue - (flowbfr[ (j*2)+2]«8) | flowbfr[ (j*2)+3] ; itoa(onewfvalue, bfr, 10); strcat(bfr,"\n"); fwrite((void *)bfr,βtrlen(bfr) , 1, pressoutfhandle) break; case 2 : //Volume onewfvalue - (flowbfr[ (j*2)+2 ]«8) | flowbfr[ (j*2)+3] ; itoa(onewfvalue, bfr, 10); strcat(bfr,"\n"); fwrite((void *)bfr,strlen(bfr) , 1, voloutfhandle) break; 4 - 152- dβfault i //Huh? cout « "Unknown waveform..." « endl ; //Now get DPIs for (j - 0; j < savenbf - FLOWWFMAX*2 - 1; J+-3 ) if (flowbf [FLOWWFMAX*2+2+j] -- 2) { //Special case - extended statue (3 bytes ) βstatuβl - flcwbfr[Fl-rOWWFMAX*2+3+j] ; βstatus2 - flowbfr[FLOWWFMAX*2+4+ ] ; βstatus3 - flowbfr[ LOWWFMAX*2+5+j]; j++; //Add one more for this special 3-byte dpi. > else if (dpisize < MAXDPIS) { flowDPI β [ dpisize ] flowbfr[FLOWWFMAX*2+2+j] ; flowDPIvalues[dpisize++] - (flowbfr[FLOWWFMAX*2+3+j3«8) | flowbfr[FLOWWFMAX*2+4+j] ; } else { //Need to pre-allocate more space. } elβe //Invalid checksum - discard data //Do we really want to discard data? nbf - 0; } elβe //Place data in buffer. flowbfr[findx++] - value; } } /* FROM CAPNOSTAT POST-PROCESSING. int indx - 0; int c dlen - 0; while ( Jfeof(infhandle) ) { //Get byte from file E fread( (void *)ivalue,1, 1,infhandle) ; if ( ( valuetOxOOBO) I- 0) { //Command byte awitch (value) { caβe 0x80 : cmdlen - 5; break; case 0x81 J cmdlen - 7; break; case 0x82 i cmdlen - 7; break; case 0x83 : cmdlen - 6; break; caβe 0x84 : cmdlen - 8; break; default: ; //Unrecognized command byte } indx - 0; tempbfr[indx++] - value; } else if (cmdlen > 0) //We have seen command byte, so we know what to do. if (indx « cmdlen-l){ //Array is full after we read the next byte. tempbfr[indx++] - value; cmdlen - 0; if (validChksm(tempbfr,indx) ) {//Valid checksum? //Calculate wf and place in global area, capnowf - (tempbfr[l] << 8) | tempbfr[2]; itoa(capnowf , bfr, 10); strcat(bfr," "); fwrite( (void * ) bf r , s trlen ( bf r ) outf handle) //Go ahead and capture short status byte, capnosβb - tempbfr[3]; //We really don't care about these values, I think, but //in case we do at a later time, all we need to do is //pipe them to another file, switch (tempbfr[0]) { case 0x80 : break; case 0x81 : //wfhb-wflb-ββb-ethb-etlb-chk //Calculate etC02 capnodata[ETC02P0S] - (tempbfr[4] « 8) tempbfr[5) ; break; case 0x82 : //wfhb-wflb-sab-rrhb-rrlb-chk //Calculate Respiration Rate capnodata[RRPOS] - (tempbfr[4] « 8) tempbfr[5] break; caβe 0x83 : //wbhb-wflb-ssb-inspb-chk //Calculate inspired C02 capnodata[INSPC02P0S] - tempbfr[4}; break; case 0x84 i //wfhb-w Ib-ββb-esbl-ββb2-eβb3-chk //Get Exend d Status bytes capnoβsb[0] - tβmpbfr[4]/ capnoββb[l] » tempbfr[5]; capnoβsb[2] - tβmpbfr[6]/ break; default: ;//Unknown command } > else //Invalid checksum - discard data //Do we really want to discard data??????????????? cmdlen - indx ■ 0; } else //place data in temp buffer tempbfr[indx++] ■ value; > fclose(infhandle) ; fcloβe(outfhandle) ; > /* This is flow processing done on the bufferred data, //From flow prototype - zero out size array, for (int j - 0; j < FLOWWFMAX; j++) flowWFsize[j3 - 0; //Zero out over run array. for (j - 0; j < FLOWWFMAX; j++); overrunfj] - 0; dpisize - 0; Iifdef ENABLE_CALLING_STATUS strcpy(statuβMβg,"Get Flow WFs...\n\r") ; statuslo (statuβMsg) ; ♦endif ENABLE_CALLING_STATUS ♦ifdef ENABLE_TEST_MODB if (sysMode « TEST) { for (i-0; i<FLOWWPSIZE; i++) flowWPfi] - i; for (i-0; i<FLOWWFSIZE; i++) pressWF[i] - i; for (i-0; KFLOWWFSIZE? i++) volWFfi] - i; 7 flowwfs - flowWFs; for (int i - 0; i < FLOWWFMAX; i++) flowWFsize[i] - FLOWWFSIZE; fwfaize - flowWFsize; for (i-0; i<FLOWWFMAX; i++) flowWFstartfi] - i; fwfstart - flowWFstart; i - 0; flowDPIβ[i3 - 22; flowDPIvalues[i++] - 0 flowDPIβ[i3 - 24; flowDPIvalues[i++3 - 1 flowDPIβ[i) - 30; flowDPIvalues[i++] - 2 flowDPIsfi] - 31; flowDPIvalues[i++] - 3 flowDPIs[i] - 34; flowDPIvalues[i++] - 4 flowDPIs[i] - 35; flowDPIvalues[i++] - 5 dpis - flowDPIβ; dpivalue - flowDPIvalueβ; dpisize - 6; estatusl - eetatus2 - estatus3 » 0; return(99) ; } ♦endif ENABLE_TEST_MODE retval - 1; //First select which board the novametrix sensors are on. // if (NOVABRD—1) { IbrdBlks - ibrdlBlks; lbfrSize - blchnlblkβize[FLOWCHNL-l] ; } else { IbrdBlks - &brd2Blks; lbfrSize - b2chnlblksize[FLOWCHNL-l] ; } //Need to get local copies of pointers to hopefully avoid //having the ISR change a pointer on us in mid-stream. //It may be too late even now, but this is the best we //can do for now. lcurBfr - (*lbrdBlks+FLOWCHNL-l)->curBfrlnfo->bfr; lflushBfr - (*lbrdBlks+FLOWCHNL-l)->flushBfrInfo->bfr; //Grab the last read index. llastreadc - (*lbrdBlks+FLOWCHNL-l)->curBfrlnfo->lastread; llastreadf - (*lbrdBlks+FLOWCHNL-l)->flushBfrlnfo->laBtread; //Grab current index lindex - (*lbrdBlks+FLOWCHNL-l)->curBfrInfo->bfrIndx; i - llastreadc; if (llastreadc « -1) { //Must go back to flush buffer first 8 llastreadc - 0; //This prepares us to read current buffer after flush. for (i - llastreadf; i < lbfrSize; i++) if (lflushBfr[i] — 0xd3){ //Command byte cmdByteSeen - 1; findx - 0; flowbfr[findx++] - lfluβhBfr[i] ; } else if (cmdByteSeen) { 11 Get number of bytes nbf - lflushBfr[i]; flowbfr[findx++} - nbf; cmdByteSeen - 0; } else if (nbf > 0) if (findx « nbf+1) { //flow buffer is full after we get next byte flowbfr[findx++] - lflushBfr[i ; savenbf - nbf; nbf - 0; //Calculate checksum if (validChksm(flowbfr,findx) ) { //Validate checksum //For each waveform, save in appropriate array. for (j - 0; j < FLOWWFMAX; j++) { if (flowWFsize[j] >- FLOWWFSIZE) { //Wrap around - data loss ♦i def ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcp ( statusMsg, "Flow Data LossXnXr" ) ; statuslog(statusMsg) ; } ♦ endif ENABLE_DATA_LOSS_MSGS overrun [ j ] - 1 ; retval - - 1 ; / /To indicate data los s f lowWFsize f j ] - 0 ; f l owWF s [ j ] [ f l owWF s i z e [ j ] ] (flowbfr[ ( j*2)+2]«8) | flowbfrf ( j*2)+3]; f lowWFsize [ j ] ++ ; } / /Now get DPIs 9 or (j - 0; j < savcnbf - FLOWWFMAX*2 - 1; j + - 3 ) if ( lowb r[FLOWWFMAX*2+2+j] — 2) { //Special case - extended status (3 byte s ) estatuβl - lowb r[ LOWWFMAX*2+3+j); eβtatus2 - flowbfr[FLOWWFMAX*2+4+j ] ; eβtatus3 - flowbfr[FLOWWFMAX*2+5+j ] ; j++; //Add one more for this special 3 -byte dpi . } else if (dpisizβ < MAXDPIS) { flo DPI s [ dpisize ] f lowbf r [ FLOWWFMAX* 2 + 2 + j ) ; flowDPIvaluββ[dpiβize++} - (flowbfr[FLOWWFMAX*2+3+j ]«8) flowbfr[FLOWWFMAX*2+4+j ) ; > else { //Need to prβ-allocate more space. ♦ifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { βtrcpy(statusMsg, "Allocatemore space for DPIa.XnXr") ; statuslog( statusMsg) ; ) ♦endif ENABLE_DATA_LOSS_MSGS retval - -1; } } else //Invalid checksua - discard data nbf - 0; > else //Place data in buffer. flowbfr[findx++] - lflushBfr[i] ; (*lbrdBlkB+FLOWCHNL-l)->flushBfrInfo->lastread - -1; 10 PROGRAM LISTING PPPC02.CCP //This is the post-processing routine for the capnostat board. ♦include <stdio.h> ♦include <βtdlib.h> ♦include <string.h> ♦include <iostream.h> ♦include "iotypes.h" ♦include "comm4con.h" //Quick and dirty Walter Reed post-processing routine which //will read Novametrix binary log files and generate an ASCII //version of the waveforms contained in the files. //Prototype of processing... (this works) //fread( (void * ) &value, 1, 1,infhandle) ; //itoa(value, bfr, 10); //strcat(bfr," "); //fwrite( (void *)bfr, strlen(bfr) , 1, outfhandle) ; const char *capnoinfilename - "c:\Xlog\Xcapno.dat"; const char *capnooutfilename - "c: \\log\\pco2wf.dat" ; const CAPNODATASIZE - 3; //BtC02, Resp. Rate, inspired C02 const CAPNOESBSIZE - 3; //Number of extended status bytes passed back. //Position of data in array passed back, const ETC02POS - 0; const RRPOS - 1; const INSPC02POS - 2; const SSSPOS - 3; unsigned char tempbfr[50]; //Temp storage to build our packets char bfr[203 ; int capnowf; int capnoβsb; int capnodata[CAPNODATASIZE3 ; int capnoesb[CAPN0ESBSIZE3 ; const char tab - 9; int value; FILE *infhandle; FILE *outfhandle; I * validChksm Description Validates data using checksum. This is used internally at the moment(i.e. , not an dll entry point) THIS DOBS NOT CALCULATE A CHECKSUM. Returns : Success is non-zero '/ ti¬ ll Boolean validChkβm(conβt unsigned char * bfr, const int bfrlen) { unsigned char sum - 0; for (int i - 0; i < bfrlen-1; sum +- *(bfr+i++)); if ( ( ( (βumi0x7f) + *(bfr+i) )i0x7f) — 0) //valid checksum return(TRUB) ; else { cout << "Invalid checksum found..." << endl; return(FALSE) ; } } void main( ) { //Open file. infhandle - fopen(capnoinfilename, "rb"); outfhandle - fopen(capnooutfilename, "wt"); ((infhandle - fopen(capnoinfilename, "rb")) — NULL) { fprintf(stderr, "Cannot open input file.Xn"); return; } if ( (outfhandle - fopen(capnooutfilename, "wt")) -- NULL) { fprintf(stderr, "Cannot open output file.Xn"); return; } int indx - 0; int cmdlen - 0; while ( Ifeof(infhandle) ) { //Get byte from file fread((void *) &valuβ, 1 , 1,infhandle) ; if (value — OxOOff) { //Time stamp follows. 11 Get next four bytes and write to file, for (int i - 0; i < 4; i++) if ( Ifeof(infhandle) ) { outfhandlβ) ; r_ con 5 } if ( (valueiOxOOδO) I- 0) { //Command byte switch (value) { caβe 0x80 t cmdlen " 5; break; caβe 0x81 i cmdlen - 7; break; case 0x82 : cmdlen - 7; break; Q case 0x83 t cmdlen - 6; break; case 0x84 : cmdlen - 8; break; default: ; //Unrecognized command byte > indx - 0; tempbf [indx++3 - value; } else 5 if (cmdlen > 0) //We have seen command byte, BO WΘ know what to do. if (indx — cmdlen-l){ //Array is full after we read the next byte. tempbfr[indx++] - value; cmdlen - 0; if (validChksm(tempbfr,ind ) ) {//Valid checksum? 0 //Calculate wf and place in global area. capnowf - (tempbfr[l] « 8) f tempbfr[2]; itoa(capnowf, bfr, 10); strcat(bfr,"\n"); fwrite( (void *)bfr,strlen(bfr) ,l, outfhandle) ; //Go ahead and capture short status byte, capnosβb - tempbfr[3]; 5 //We really don't care about these values, I think, but //in case we do at a later time, all we need to do is //pipe them to another file, switch (tempbfr[0]) { caβe 0x80 : break; 0 case 0x81 : //wfhb-wflb-ssb-βthb-etlb-chk //Calculate etC02 capnodata[ETC02P0S] - (tempbfr[4] « 8) tempbfr[5] break; case 0x82 : //wfhb-wflb-ssb-rrhb-rrlb-chk //Calculate Respiration Rate 5 capnodatafRRPOS] - (tempbfr[4] << 8) | tempbfr[5] ; break; case 0x83 : //wbhb-w lb-sβb-inspb-chk //Calculate inspired C02 capnodata[INSPC02POS3 - tβmpbfr[ j; break; case0x84 t //wfhb-wfIb-ssb-e»bl-ββb2-esb3-chk //Get Bxended Status bytes capnoββb[0] - tβmpbfr[4]; capnoeβb[lj » tempbf [5J; capnoeβb[2] - tempbfr[6j; break; default: ;//Unknown command } > else //Invalid checksum - discard data //Do we really want to discard data??????????????? cmdlen - indx - 0; > else //place data in temp buffer tempbfr[indx++3 - value; > fcloβe(infhandle) ; fclose(outfhandle) ; /* Thiβ iβ the code used to process data bufferred from capnostat board. if (llastreadc — -1) { //Must go back to flush buffer first llastreadc - 0; //This prepares us to read current buffer after flush. for (i - llastreadf; i < lbfrSize; i++) if ((lflushBfr[ilfc0x80) 1- 0) { //Command byte switch (lfluβhBfr[i]) { case 0x80 : cmdlen - 5; break; case 0x81 : cmdlen - 7; break; case 0x82 : cmdlen - 7; break; case 0x83 : cmdlen - 6; break; case 0x84 : cmdlen ■» 8; break; default: //Unrecognized command byte } indx - 0; tempbfr[indx++3 - lflushBfr[i] ; if (cmdlen > 0) //We have seen command byte, so we know what to do. if (indx — cmdlen-l){ //Array is full after we read the next byte. tempbfr[indx++3 - lflushBfr[i] ; cmdlen - 0; if (validChkβm(tempbfr,indx) ) {//Valid checksum? //Calculate wf and place in global area. if (wfsize >- CAPNOWFSIZB) { //Wrap around - data loss cond. Iifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { βtrcpy(statusMsg, "Capno Data LoseXnXr"); statuslog(statusMsg) ; } ♦endif ENABLE_DATA_LOSS_MSGS retval - -1; //To indicate data loss wfsize - 0; } capnowf[wfBlze++3 - (tempbfr[l] << 8) | tempbfr[2] ; capnoβsb - tempbfr[3] switch (tempbfr[0]) { case 0x80 : break; case 0x81 : //wfhb-wfIb-ssb-ethb-etlb-chk //Calculate etC02 capnodata[ETC02P0S] - (tempbfr[4] « 8) I tempbfr[5] ; break; case 0x82 : //wfhb-wflb-ssb-rrhb-rrlb-chk //Calculate Respiration Rate capnodata[RRPOS] - (tempbfr[4] « 8) | tempbfr[5] ; break; case 0x83 : //wbhb-wflb-sab-inβpb-chk //Calculate inspired C02 capnodata[INSPC02POS] - tempbfr[4]; break; c a s e 0 x 8 4 / /wf hb-wf Ib-ssb-esbl-eβb2-esb3-chk 11 Get Exended Status bytes capnoesb[0] - tempbfr[4]; capnoesbjlj - tempbfr[53; capnoe8b[2] - tempbfr[6]; break; default: ; //Unknown command } } else //Invalid checksum - discard data t; cmdlen - indx - 0; } else //place data in temp buffer tempbfr[indx++] - IfluβhBfr[i] ; ( *lbrdBlk D +B C02CHHL-l)->flushBfrInfo->lastread - -1; > PROGRAM LISTING PPSP02.CCP ♦include <βtdio.h> ♦include <stdlib.h> linclude <string.h> ♦include "iotypes.h" ♦include "comm4con.h" //Quick and dirty Walter Reed post-processing routine which //will read Novametrix binary log files and generate an ASCII //version of the waveforms contained in the files. This routine //will handle pulsox data only. Separate routines will be used for //other waveforms. //Prototype of processing... (this works) //fread( (void *)fcvalue, 1, 1,infhandle) ; //itoa(valuβ, bfr, 10); //βtrcat(bfr," "); //fwrite((void *)bfr,strlen(bfr) , 1, outfhandle); const char *poinfilename - "c:\Xlog\Xpuleox.dat"; const char *pooutfilename - "c:\Xlog\Xspo2wf.dat"; char bfr[20] ; const char tab - 9; - int value; FILE *infhandle; FILE *outfhandle; void main( ) { //Pulsox first. //Open file. infhandle - fopen(poinfilename, "rb"); outfhandle - fopen(pooutfilename, "wt"); if ((infhandle - fopen(poinfilename, "rb")) ~ NULL) { fprintf(βtderr, "Cannot open input file.Xn"); return; } if ((outfhandle - fopen(pooutfilename, "wt")) — NULL) { fprintf(stderr, "Cannot open output file.Xn"); return; } int seenFEcount - 0; Boolean seenFEtoggle - FALSE; while ( Ifeof(infhandle) ) { //Get byte from file 1 frβad( (void *)4value, 1, 1,infhandlβ) ; if (seβnFEcount ~ 0) if (value 1- 0xfe){ //Write waveform value to file (or timestamp) itoa(value, bfr, 10); street(bfr,"\n"); fwrite((void *)bfr,strlen(bfr) ,1, outfhandle); } else { //Start of special data. sβenFEcount - SP02SPBCDATALNGTH-1; βeβnFBtoggle - TRUE; //Do not take this value; take next. eenFEtogglβ) { //Waveform value a(value, bfr, 10); strcat(bfr,"Xn"); ' " fwrite((void *)bfr,strlen(bfr) ,1, outfhandle); > else { //Special data value //What are we to do with this value } //Decrement count and toggle flag seenFEtoggle - lβeenFEtoggle; seenFEcount—; > //fread( (void *)Svalue,1, 1,infhandlβ) ; //itoa(value, bfr, 10); //strcatfbfr," "); / Itwrite( (void *)bfr,βtrlen(bfr) ,1, outfhandle); } fclose(infhandle) ; fclθBβ(outfhandle) ; } /* This is the code uβed to handle the data being buffered. while { for (i - llastreadf; i < lbfrSize; i++) if (seenFEcount » 0) if (lflushBfr[i] J- 0xfe){ if (size >- SP02WFDATAMAX) {//Loss of data will occur - not good. Iifdef ENABLE_DATA_LOSS_MSGS • } if (retval — 1) { βtrcpy(statusMsg, "Sp02 Data LoββXnXr") ; βtatuslog(BtatusMsg) ; } ♦endif ENABLE_DATA_LOSS_MSGS retval - -1; //Wrap data around to beginning of buffer, size - 0; pulaeoxWFa[βize++] - lflushB r[iJ ; } puleeoxWFB[eize++] - lflushBfr[i] ; } else {//Start of special data. seenFEcount - SP02SPECDATALNGTH-1; ββenFEtoggle - TRUE; //Do not take this value; take next. } else {// if (seenFBtoggle) { //Waveform value if (size >- SP02WFDATAMAX) {//Loss of data will occur. ♦ifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { atrcpy(statusMsg, "Sp02 Data LoβaXnXr"); statuβlog(βtatusMsg) ; > ♦endif ENABLE_DATA_LOSS_MSGS retval - -1; //Wrap data around to beginning of buffer. size - 0; } pulseoxWFs[size++] - lfluβhBfrfi] ; > else //Special data value //Save special data. pulseoxSpecData[ (5-seenFEcount) 12 ) - lfluβhBfr[i]; //Decrement count and toggle flag seenFEtoggle - 1βeenFEtoggle; seenFEcount—; } */ PROGRAM LISTING QTEST.DEF IODRVR8.DBF (module definition file) NAME QTBST DESCRIPTION 'Quick Test' EXETYPB WINDOWS CODE PRELOAD HOVBABLB DISCARDABLE DATA PRELOAD MOVBABLB MULTIPLE BBAPSIZB 1024 STACKSIZB 8192 IMPORTS GUIIF. βtDllVerβion GUIIF.θkgSβnβeΛ PROGRAM LISTING RS232.H : J. Brayton, T223/GB : 10/16/95 tion : Abstract class for RS232 s: Thiβ header file defines the RS232 base class from from which all other classes are derived including 8250 and 16550. // enum RS232PortName {COMl - 0, COM2, COM3, COM4, C0M5, C0M6, C0M7, C0M8}; class Settings { public: long BaudRate; char Parity; int WordLen th }; enum RS232Error {RS232_SUCCESS 0 , RS232_WARNING warnings*/ - -100 , RS232_FUNCTION_NOT_SUPPORTED , RS232_TIMEOUT, RS232_ILLEGAL_BAUD_RATE, RS232_ILLEGAL_PARITY_SETTING, RS232_ILLEGAL_W0RD_LBNGTH, RS232_ILLEGAL_STOP_BITS, RS232_ILLBGAL_LINE_NUMBBR, RS232_NO_MODBM_RESPONSE, RS232_NO_TBRMINATOR, RS232_DTR_NOT_8UPPORTED, RS232_RTS_NOT_SUPPORTBD, RS232_RTS_CTS_NOT_SUPPORTBD, RS232_DTR_DSR_NOT_SUPPORTED, RS232_XON_XOFF_NOT_SUPPORTED, RS232_NBXT_FREE_WARNING, RS232_ERROR /*FATAL*/ - -200, RS232_IRQ_IN_USB, RS232_PORT_NOT_FOUND, RS232_PORT_IN_USE, RS232_ILLEGAL_IRQ, RS232_MEMORY_ALLOCATION_ERROR, RS232_NEXT_FREE_EROR} ; const int UNCHANGED - -99; conβt int FOREVER - -1; const int DISABLE - 0; const int CLEAR - 0; const int ENABLE - 1; const int SET - 1; const int RESET - 1; const int REMOTE_CONTROL - -1; class RS232 { protected : RS232PortName port_name; Settings saved_Bθttings; Settings settings; RS232Error error_status; int debug_line_count; //Mandatory protected functions virtual int read_buffer(char* buffer, unsigned int count) 0; virtual int write_buffer(char* buffer, unsigned int count -1' o; virtual int read_byte() - 0; virtual int write_byte(int c) - 0; public: unsigned int ByteCount; long ElapsedTime; //Mandatory functions. All derived classeβs must define these. virtual RS232Error Set(long baud_rate - UNCHANGED, int parity - UNCHANGED, int word_length - UNCHANGED, int stop_bits - UNCHANGED) - 0; virtual int TXSpaceFree{ ) - 0; virtual int RXSpaceUsed( ) - 0; virtual int Cd( ) - 0 virtual int Ri( ) - 0 virtual int Ctβ() - 0 virtual int Dsr() « 0 virtual int ParityError(int clear - UNCHANGED) - 0; virtual int BreakDetect(int clear - UNCHANGED) - 0; virtual int FramingError(int clear - UNCHANGED) - 0; virtual int HardwareOverrunError(int clear - UNCHANGED) - 0; //Optional functions. Derived classes are not required to suppor these. virtual -RS232(){} virtual int Break(long milliseconds - 300); virtual int SoftwareOverrunError(int clear - UNCHANGED); virtual int XonXoffHandshaking(int setting - UNCHANGED); virtual int RtsCtsHandshaking(int setting - UNCHANGED); virtual int DtrDsrHandshaking(int setting - UNCHANGED); virtual int Dtr(int setting - UNCHANGED); virtual int Rts (int setting - UNCHANGED); virtual int Peek(void* buffer, unsigned int cout); virtual int RXSpaceFree( ) ; virtual int TXSpace_Used{ ) ; virtual int FlushRXBuffer( ) ; virtual int FlushTXBuffer( ) ; virtual char* ErrorName (int error); virtual int IdleFunction( ) ; virtual int FormatDebugOutput(char* buffer - 0, int line_number - -1); //Non-virtual functions. These work the same for all classes . int Read(void* buffer, unsigned int cout, long milliseconds - 0); int Read(void* buffer, unsigned int count, char* terminator); int Write(void* buffer, unsigned int count - 0, long milliseconds - 0, T char* terminator - 0); int Read(long milliseconds - 0); int Write(int c, long milliseconds - 0); int Peek( ) ; int ReadSettings(Settings fccopy) { copy - settings; return(RS232_SUCCESS) ; } int DebugLineCount( ) {return(debug_line_count) ; } }; long ReadTime(); PROGRAM LISTING RS232CON.H : J. Brayton, T223/GB : 10/16/95 tion : RS232 related types, etc s : // ♦ifndef _RS232_DOT_H Idefine RS232 DOT H enum RS232PortName {COMl - 0, COM2, COM3, COM4, COM5, C0M6, COM7, COM8}; class Settin s }; enum RS232Error {RS232_SUCCESS - 0, RS232_WARNING warnings*/ - -100, RS232_FUNCTI0N_N0T_SUPP0RTED, RS232_TIMEOUT, RS232_ILLEGAL_BAUD_RATE, RS232_ILLEGAL_PARITY_SETTING, RS232_ILLEGAL_W0RD_LENGTH, -178- RS 232_ILLBGAL_STOP_BITS , R≤232_ILLEGAL_LINB_NUMBER, RS232_NO_MODBM_RBSPONSB , RS 232_NO_TBRMI NATOR , RS 232_DTR_NOT_S U POR B D , RS 232_RTS_NOT_SUPPORTBD , RS 232_RTS_CTS_NOT_SUPPORTED , RS232_D R_DSR_ OT_SUPPORTBD, RS 232_XON_XOFF_NOT_SUPP RTBD , RS 232_NBXT_FREB_WARNING , RS232_BRROR /*FATAL*/ - -200, RS232_IRQ_IN_USE, RS 232_PORT_NOT_FOUND , RS 232_PORT_IN_USE , RS232_ILLBGAL_IRQ, RS 232_MBMORY_ALLOCATION_ERROR , RS232_NBXT_FREE_BROR} ; const nt REMOTE_CONTROL - -1; ♦endif _RS232_DOT_H PROGRAM LISTING S518COM.H //. —.......... J. Brayton Created 6/1/95 on : Constants for 518. Sensor Codes, Scale factors, Config file values. Timeouts, Error Codes, Command Codes, and other 518 specific constants. 10 lifndef _S518CON_D T_H ♦define _S518CON_DOT_H //Bases addresses defined in ioconfig.h l s //Sensor Codes ' // const char VOLTAGE 0x15; //sensor code for voltage sensor const char CURRENT_LOOP 0x11; //sensor code for amp sensor const char THERMISTOR - OxlA; //sensor code for thermistor sensor const char THERMOCOUPLE OxlD; //sensor code for thermocouple sensor 0 //Scaled values const float VSCALAR - 0.0002; //500 microvolts const float TSCALAR - 0.15; //degree Celsius //Constantβ that should be read from configuration file. Boolean noChannelCheck - FALSE; 5 //Timeout Constants // const int SEND_TIMEOUT 5; //seconds const int RECV_TIMEOUT 5; //seconds const int RST TIMEOUT 10; //seconds //518 specific constants 0 const int nu OfChans - 8; //Command Codes // const char DECLARE_CHAN 0x10; const char READ BOARD TEMP ' 0x40; 1 5 11 Error Codes I I const int BASE_ERROR_CODB conβt int NO_ERRORS const int COMMAND_NOT_SENT const int SENSOR_C0DE_NOT_SENT const int DATA_NOT_READ const int TIME0UT_0N_SEND const int TIME0UT_0N_READ_LO const int TIMEOUT_ON_RBAD_HI const int READ_CHAN_CMD_NOT_SENT const int TIMEOUT_ON_READ__BYTE const int RESET_FAILED const int DUPLICATE CHNL DECLARE //Error Code description array // const char* erDeβcriptionf ] {"NO_ERRORS", "COMMAND_NOT_SENT" , "SENSOR_CODE_NOT_SENT" , "DATA_NOT_READ" , "TIMEOUT_ON_SEND" , "TIMEOUT_ON_READ_LO" , "TIMEOUT_ON_READ_HI" , "READ_CHAN_CMDJNOT_SENT" , "TIMEOUT_ON_READ_BYTE" , "RESET_FAILED", "DUPLICATE_CHNL_DECLARE"} ; lendif S518C0N DOT H PROGRAM LISTING TI CPP /* ventFindlnBuffer(bfr, length, pattern, altpattβrn, value) - new way ll Boolean ventFindlnBuffe (const char *bfr, const int plength, conβt char *pattern, conβt char ♦ altpattern, int &value) { const int LBFRSIZE - 50; static char lbfr[LBFRSIZE] , *pos, *savepos; static int i, mult; static const char *laltpattern; value - 0; mult - 1; //Return the length of string matched to be used in calling routine //to update buffer index if a match is found, //plength - strlen(bfr); //If altpattern is NULL, then βet local alt pattern to pattern. This //is useful below when checking for both patterns without having to worry //about dereferencing a null pointer. // v And I do mean "-" if { 1 (laltpat.ern-altpattern) ) laltpattern - pattern; //First copy bfr to enable us to modify string. We can not use //strcpy since bfr may not be null terminated, //strcpyflbfr, bfr); //First copy bfr to enable us to modify string. if (plength > LBFRSIZE-1) { //We need to increase the size of our array. ♦ifdef ENABLE_FATAL_BRROR_MSGS strcpy(statusMsg, "Array too small in ventFindlnBuffer. XnXr" ) ; statuslog(statusMsg) ; dif ENABLB_FATAL_ERROR_MSGS elβe { memcpy((void *)lbfr, (void *)bfr, plength); lbfr[plength] - '\0'; //Add null terminated character. } //Replace all digits with 'n'. for (i-'O'; i<-'9'; i++) while (pos-βtrchr(lbfr,i) ) if ( ( 1 strcmp(lbfr,pattern) ) | | ( 1 strcmp{lbfr, laltpattern) ) ) { //We have a match. //cout << "We have a match" << endl; //First copy original string. strcpy(lbfr, bfr); //First replace all '-' with blank starting at position 1. savepos - lbfr; while (pos-strchr( (char *) (lbfr+1 ),'-') ) { *pos - ' '; savepos - pos; } //Remove. ll '.' noting if any '. ' precedes an IT . while (pos-strchr(lbfr, ' . ' ) ) { if (*(pos+l) « '\r') mult - 10; //Remove ' . ' strcpy(pos,pos+1 ) ; } //Convert to integer, value - atoi(savepos) *mult; return(TRUE) ; } else //cout « "We DO NOT have a match." « endl; return(FALSE) ; 10 15 20 30 35 T2.CPP PROGRAM LISTING //: ......... ............ .. /* ventFindlnBuffer(bfr, length, pattern, altpattern, value) - new way ll Boolean ventFindlnBuffer(const char *bfr, const int plength, const char *pattern, const char *altpattern, int lvalue) { const int LBFRSIZE - 50; static char lbfr[LBFRSIZE] , *pos, *savepos; static int i, mult; static const char *laltpattern; value - 0; mult = 1; //Return the length of string matched to be used in calling routine //to update buffer index if a match is found, //plength = strlen(bfr); //If altpattern is NULL, then βet local alt pattern to pattern. This //is useful below when checking for both patterns without having to worry //about dereferencing a null pointer. // v And I do mean "-" if ( ! (laltpattern-altpattern) ) laltpattern - pattern; //First copy bfr to enable us to modify string. We can not use //strcpy since bfr may not be null terminated. //strcpy(lbfr, bfr); //First copy bfr to enable us to modify string, if (plength > LBFRSIZE-1) { //We need to increase the size of our array. Iifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in ventFindlnBuffer. XnXr" ) ; statuslog(statusMβg) ; ♦endif ENABLE_FATAL_ERROR_MSGS } else { memcpy((void *)lbfr, (void *)bfr, plength); lbfr[plength] - '\0'; //Add null terminated character. } //Replace all digits with 'n'. for (i-'O'; i<-'9'; i++) while (pos-strchr(lbfr,i) ) *pos ■» 'n' ; if ( ( 1 strcmp(lbfr,pattern) ) [| ( J strcmp(lbfr,laltpattern) ) ) { //We have a match. //cout << "We have a match" << endl; //First copy original string. strcpy(lbfr, bfr); //First replace all '-' with blank starting at position 1. savepos «=■ lbfr; while (pos=strchr( (char *) (lbfr+1),'-') ) { *pos = ' ' ; savepos — pos; } //Remove all '.' noting if any '.' precedes an /r. while (pos-strchr(lbfr, '.') ) { if (*(ρos+l) « '\r') mult - 10; //Remove ' . ' strcpy(pos,pos+1) ; } //Convert to integer. value - atoi(savepos) *mult; return(TRUE) ; } else //cout « "We DO NOT have a match." « endl; return(FALSE) ; 10 15 20 25 30 35 PROGRAM LISTING TEMP.CPP int FAR PASCAL _export ventCtrlWait(ventCode ventCmd, unsigned int value) { βtatic clock_t timel; static char nn[17]; static char * nnptr; static char temp[20]; static int i, βob, βavesob, bfrβize, br, n, dec, sign; static double dvalue; static unsigned char * bfr; static int diff; int retVal; int timer; //Used to indicate that no response from RS232 serial char bell - 0x07; //link is probably hanging system. static int llastread, lsize, βavesize; static unsigned char tempCmd[50]; ChnlBlk *lbrdBlk; Boolean found - TRUE; //dandy.astound //cout << "ventcontrol / event - " << event « "\n"; switch (ventCmd) { case ALQ: Iifdef ENABLE_TEST_MODE if (sysMode -- TEST) { n = rand()%28; if (n > 7) return(O) ; else return(n) ; } ♦endif ENABLE TEST MODE if (VENTBRD — 1) IbrdBlk - -.brdlBlks [VENTCHNL-l ] ; else //Assume board 2 IbrdBlk - &brd2Blks [VENTCBNL-l ] ; for (i-0; KVENTRETRY; i++) { //Send the command if (VENTBRD — 1) com4boardl.cmdALQ{ ) ; else //asβ-ume board 2 com4board2.cmdALQ( ) ; timel - clock( ) ; timer - 1; //Wait for response. retVal - VENTALQTIMEOUT; while ( (clock( )-timel) /CLOCKS_PER_SEC<VENT_RSP_TIMEOUT) //Beep if having to wait more than usual to indicate //why the system may be hanging. if (( (clock( )-timel)/CLOCKS_PER_SEC) > timer) { cout « bell; timer++; } if (lbrdBlk->curBfrIn o->lastread >= 0 ) { //No wrap-arround //dandy-astoundI //First copy data into channel buffer. //com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; //dandy.astoundl / / b f r - ( c h a r *)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-1 ] ; bfr - lbrdBlk->curBfrInfo->bfr; //dandy. stound1 / / s o b - s a v e s o b com4BfrIndx[ VENTBRD- 1] [VENTCHNL-1] .sob; sob - savesob - lbrdBlk->curBfrlnfo->lastread; sob - findInBuffer(bfr,sob,lpszALQ) ; //Returns negative if //not found. Otherwise, //returnβ updated sob. if (sob < 0) { //Check if ventilator did not understand command t lor that the value was out of range, sob - findlnBuffer(bfr,βaveβob, IpszHUH) ; if (sob >- 0) { //Command not understood; value out of range. //dandy.astound1 //com4BfrIndx[VBN BRD-l][VENTCHNL-l3.βob- sob; lbrdBlk->curBfrInfo->lastread - sob; return(VALUEOUTOFRANGB) ; } else {//sob >- 0 //Then we have seen at least a "ALQ-". //If bfrlndx is 2 position beyond nβ, then assume live have the alarm number followed by return. //dandy. stoundI / / d i f f com Bfrlnd [VENTBRD-13 [VENTCHNL-I3.bfrlndx - βob; diff - lbrdBlk->curBfrInfo->bfrIndx - sob; //dandy.astound1 //if ((diff — NE) j I // ( (CHNLBFRSIZE+diff) — NE)) { if (diff — NE) { //Make the assumption that we have received ALQ-ne //response packet. //dandy.astound1 //Copy NE. //for (i-0; i<NE; i++) / / t e m p [ i ] lbrdBlk->curBfrInfo->bfr [ sob+i ] ; //temp[ i 3 - ' \0 ' ; //Make conversion. n - atoi(bfr+strlen(lp8zALQ) ) ; //dandy.astoundl tin - atoi(temp) ; //dandy . astound ] [VBNTCHNL- l ] . sob - ( sob+NE ) %CHNLBFRSIΣB; lbrdBlk->curBfrInfo->laβtread - βob+NE ; return ( n ) } > else { //Wrap-around situation //Firβt get partial command string in flush buffer. llaβtread - lbrdBlk->flushBfrlnfo->lastread; savβsize - lβize - lbrdBlk->blockSi∑e llastread; if (lsizβ > βizeof(tempCind) ) { //We need to increase the size of our array, ♦ifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in ventCtrlWait.XnXr") ; statuslog(βtatuBMsg) ; ♦endif ENABLE_FATAL_ERROR_MSGS break; } memcpy((void *)tempCmd, &(lbrdBlk->flushBfrlnfo->bfr[llastread] ) , lsize) ; //Now get rest of command in current buffer, if ((lsize + lbrdBlk->curBfrInfo->bfrIndx) > sizeof(tempCmd) ) { //We need to increase the size of our array. Iifdef BNABLE_FATAL_BRROR_MSGS strcpy(statusMsg, " Array too smal l in ventCtrlWait . XnXr" ) ; statuslog ( statusMsg) ; ♦endif ENABLE_FATAL_ERROR_MSGS break; } llastread - 0; lsize - lbrdBlk->curBfrlnfo->bfrIndx; mβmcpy((void *)&tempCmd[savesize] , & (lbrdBlk->curBfrInfo->bfr[llastread] ) ,lsize) ; bfr - tempCmd; sob - findlnBu er(bfr,βob,lpβzALQ) ; //Returns negative if //not found, Otherwise, //returns updated sob, if (sob < 0) { //Check if ventilator did not understand command //or that the value was out of range, sob - findlnBuffer(bfr,βavoβob,lpazHUB) ; if (sob >- 0) { //Command not understood; value out of range. //dandy. stoundI //com4BfrIndx[VENTBRD-l] [VEN CHNL-1] .βob- sob; //Set the flush buffer lastread variable to -1 to indicate //that we are done looking at the buffer. lbrdBlk->fluβhBf Info->laβtread - -1; lbrdBlk->curBfrInfo->la8tread - lsize; return(VALUEOUTOFRANGE) ; } } //Then we have seen at least a "ALQ-" . //If total length of command is equal to the length //we expect for a valid command, then assume we //we have the alarm number followed by return. if ((savesize+ lsize) « (strlen(lpszALQ) + NE >> < //Make the assumption that we have received //response packet. //Copy NE. 5 7/for (i-0; i<NE; i++) // temp[i3 - bfr[strlen(lpszALG;) //temp[i] - '\0'; //Make conversion. n - atoi(bfr+strlβn(lpszALQ) ) ; //dandy.astound //coβ4BfrIndx[VBNTBRD-l] [VBNTCHNL-1) .sob // (sob+NE)%CHNLBFRSIZE; //Set the flush buffer lastread variable to -1 to //indicate that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->laβtread - -1; lbrdBlk->curBfrlnfo->lastread - lsize; return(n) ; } } //Timeout has occurred. //Abort command - Reset sob to end of buffer and //start anew. Thiβ essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . //dandy.aβtound1 //com4BfrIndx[VENTBRD-l3[VENTCHNL-l].sob - // com4BfrIndx[VENTBRD-l3 [VENTCHNL-1].bfrlndx; lbrdBlk->curBf rInf o->lastread lbrdBlk->curBfrInfo->bfrIndx; } return ( retVal ) ; PROGRAM LISTING DI048.B T/US97/10588 -198- /* uio48.h Author : J. Brayton, T223/GB Hiβtory : 9/01/95 Description : Classes for UI048 board. Contents: UI048 sensor classes / II- // ♦ifndef _UI048_DOT_H ♦define _UI048_DOT_H ♦include "uiocon.h" ♦include <conio.h> ♦include <βtdlib.h> ♦include <iostream.h> ♦include <stdio.h> ♦ifdef cpluβpluβ ♦define CPPARGS ♦else ♦define CPPARGS ♦endif //UI048 //void interrupt(*getvect(int interruptno)) ( ... ); class uio48 { public: uio48() ; ~uio48() {}; int resetBoard(int) ; int writeChannel(unsigned int, unsigned int); unsigned int readPort(int) ; int readChannel(int) ; >; II- /* uio48: :uio48 Description : Constructor Returns N/A */ / / ■ iBaHnαaxa // uio48: :uio48( ) { //cout << "constructor called" << endl; //Clear all registers on UI048 //Set all registers to writeable by writing Mask bits outp(BASEADDRUI048+7,OxOO) ; //Clear 10 port 0-5 corresponding to connectors Jl & J2 for (unsigned int port «• 0; port < 6; port++) outp(BASEADDRUI048+port,OxOO) ; //Clear interrupt control registers for (int intrnlAdd - 1; ihtrnlAdd < » 2; intrnlAdd++) { outp(BASEADDRUI048+7, (intrnlAdd«6) ); for (port-0; port < 3; port++) outp(BASEADDRUIO48+port+8,0x00) ; } //Reset internal address IA to zero. outp(BASEADDRUI048+7,OxOO) ; //= /* uio48 : :resetBoard(value) Description For initial prototype, this function will set all 10 registers to value on the UI048 Does not affect interrupt registers. This is primarily a test function since board is reset in constructor and little error processing is being performed in prototype. Returns : ' Success/Failure ti¬ l l int uio48 : :resetBoard(int value) { //Set all registers to writeable by writing Mask bits outp(BASEADDRUI048+7,0x00) ; if (value — 0) //Clear 10 port 0-5 corresponding to connectors Jl & J2 for (unsigned int port - 0; port < 6; port++) outp(BASEADDRUIO48+port,0x00) ; else //Set 10 port 0-5 corresponding to connectors Jl & J2 for (unsigned int port - 0; port < 6; port++) outp(BASEADDRUI048+port,OxFF) ; return(0) ; > /* uio48 : :writeChannel(channel, value) Description : For initial prototype, this function will write the value to channel on connector Returns : Success/Failure */ //====== // int uio48: : riteChannel (unsigned int channel, unsigned int value) { //cout << "writeChannel ( " << channel << " , " << value << "}" << endl << endl; //Used to determine port number and bit to write value div_t portBit = div(channel, 8); //returns quot,rem //cout << "Channel " << channel << " translates to port " << // portBit.quot << " and shift " << portBit.re << endl; //cout << "portBit : " << portBit.quot << " " << portBit.rem << endl << endl; //Read port to get current 10 channel values. unsigned int readback - inp(BASEADDRUI048+portBit.quot) ; //cout « "Readback : " « readback « endl; //cout « "portBit : " << portBit.quot << " " << portBit.rem « endl << endl; unsigned int temp - readback & ~(0x01«portBit.rem) ; //printf( "0x01«portBit.rem %x\n", 0x01« portBit.rem) ; //printf( "-(the previous value) %x\n", ~(0x01«portBit.rem) ) ; //printf ( "temp - readback & -( 0x01«portBit.rem) : %x\n", temp) temp |= (value«portBit.rem) ; //cout << "temp ]= (value<<portBit.rem) : " « temp << endl; //Now write port with new value. outp(BASEADDRUI048+portBit.quot,temp) ; return(0) ; } // ■ /* uio48: :readPort(port) Des( ription : For initial prototype, thiβ function will read the value of port. Thiβ function currently does not change mask bits. Returns Readback value */ ti¬ ll unsigned int uio48: :readPort(int port) { //Read port to get current 10 channel values, return(inp(BASEADDRUI048+port) ) ; } /* uio48: :readChannel(channel) Description : For initial prototype, this function will read the value of channel. This function currently does not change mask bits. Returns Readback value */ li¬ lt int uio48: :readChannel(int channel) { //Used to determine port number and bit. div_t portBit - div(channel, 8); //returns quot,rem //cout « "Channel " « channel « " translates to port " « // portBit.quot « " and shift " « portBit.rem « endl; //Rβad port to get current 10 channel values. unsigned int readback - inp(BASBADDRUI048+portBit.quot) ; //printf("Readback : %x\n", readback); readback - (rβadback»portBit.rβm) & 0x01; //printf("Channel 9 : %x\r", readback); return(readback) ; } ♦endif UI048 DOT H PROGRAM LISTING DIOCON.H / * uiocon . h Author : J. Brayton History : Created 6/1/95 Description : Constants for uio48 Contents: */ II- ♦ifndef _UIOC0N_DOT_H ♦define _UIOCON_DOT_E ♦include "iotypes.h" //Base Address defined in ioconfig.h ♦endif UIOCON DOT H PROGRAM LISTING MλlN.PAS -206- unit Main; inter ce uses SysUtilβ, WinTypeβ, WinProcβ, Messages, Classes, Graphics, Controlβ, Forms, Dialogs, StdCtrlβ, BxtCtrlβ, Buttons; type TMβdicsGui - claββ(TForm) label4: TLabel; Label5: TLabel; btnSystem: TButton; lblHeartRate: TLabel; lblTβmp: TLabel; OXβatLbl: TLabel; bpmLbl: TLabel; btnBxit: TButton; breathRateLbl: TLabel; Label2: TLabel; tidalVolLbl: TLabel; lblSuctionlndicator: TLabel; Label9: TLabel; lblDefiblndicator: TLabel; BitBtnl: TBitBtn; Labelβ: TLabel; BitBtn2: TBitBtn; LabellO: TLabel; BitBtn3: TBitBtn; Labelll: TLabel; BitBtn4: TBitBtn; Labell2: TLabel; BitBtnδ: TBitBtn; BitBtnδ: TBitBtn; Label13: TLabel; Label14 : TLabel; Shapel: TShape; warningRectl: TShape; readylndicator: TShape; resu ebtn: TButton; ventPowerBtn: TButton; defibFlaβhCheck: TTimer; fireBtn: TButton; Labell7: TLabel; Labellδ: TLabel; Labell9: TLabel; Label20: TLabel; Label21: TLabel; Label22: TLabel; Shape2 TShape; Label23 TLabel; Label24: TLabel; Label25: TLabel; Label26: TLabel; Label27: TLabel; Label3: TLabel; flasherLbl: TLabel; Labe16: TLabe1; fireBtnCounterLabel: TLabel; Label7: TLabel; rcrdMenuBtn: TButton; recordMenuPanel: TPanel; Labell: TLabel; flowRecBtn: TButton; pulsRecBtn: TButton; co2Recbtn: TButton; Labell5: TLabel; Labell6: TLabel; Label28: TLabel; flowRecShape: TShape; co2recShape: TShape; pulsRecShape: TShape; retrnRecBtn: TButton; reclickLbl: TLabel; allRecBtn: TButton; allRecShape: TShape; toCuffBtn: TBitBtn; Label31: TLabel; Shape3: TShape; systolicLbl: TLabel; diastolicLbl: TLabel; setBPpanel: TPanel; cycleModeLbl: TLabel; Label37: TLabel; Label38: TLabel; pumpBtn: TButton; diβplayCuffBtn: TButton; Button4 : TButton; βetCycleBtn: TButton; Label33: TLabel; cuffReturnBtn: TButton; setCyclePnl: TPanel; RadioButtonl: TRadioButton; RadioButton2: TRadioButton; cancelCycleBtn: TButton; RadioButton5: TRadioButton; RadioButton6: TRadioButton; RadioButtonδ: TRadioButton; RadioButton9: TRadioButton; Label34: TLabel; okBtn: TButton; BPhistoryPnl: TPanel; BPreturnBtn: TButton; βetBPbtn: TButton; bpBackgndimage: TImage; procedure btnSyβtemClick(Sender: TObject); procedure btnExitClick(Sender: TObject) procedure BitBtnlClick(Sender: TObject) procedure BitBtn2Click(Sender: TObject) procedure BitBtn3Click(Sender: TObject) procedure BitBtn4Click(Sendβr: TObject) procedure BitBtn5Click(Sender: TObject) procedure BitBtn6Click(Sender: TObject) procedure defibFlashCheckTimer(Sender: TObject) ; procedure resumebtnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure resumebtnHouseU (Sender: TObject; Button: TMouseButton; Shift: TShiftState? X, Y: Integer); procedure reβumebtnClick(Sender: TObject); procedure ventPowerBtnClick(Sender: TObject); procedure fireBtnClick(Sender: TObject); procedure rcrdMenuBtnClick(Sender: TObject) ; procedure retrnRecBtnClick(Sender: TObject) ; procedure flowRecBtnClick(Sender: TObject); procedure pulsRecBtnClick(Sender: TObject) ; procedure co2RecbtnClick(Sender: TObject) ; procedure allRecBtnClick(Sender: TObject); procedure toCuffBtnClick(Sender: TObject) ; procedure cancelCycleBtnClick(Sender: TObject) ; procedure setCycleBtnClick(Sender: TObject); procedure RadioButtonlClick(Sender: TObject); procedure RadioButton2Click(Sender: TObject) ; procedure RadioButton5Click(Sender: TObject) ; procedure RadioButton6Click(Sender: TObject) ; procedure RadioButton8Click(Sender: TObject) ; procedure RadioButton9Click(Sender: TObject) ; procedure okBtnClick(Sender: TObject) ; procedure setBPbtnClick(Sende : TObject); procedure BPreturnBtnClick(Sender: TObject) ; procedure cuffReturnBtnClick(Sender: TObject); private { Private declarations } public { Public declarations } end; procedure spin(delaylnterval : integer); {GLOBAL VARS} var MedicsGui: TMedicsGui; rate, temp: integer; 3 {Important Program Wide Global Variables} suctionOnToggle, ventOnToggle, defibOnToggle, condFanOnToggle, modeOnToggle: Bool; NOHARDWARE : Bool; fireBtnCouπter : integer; const POWERON - 1; const POWEROFF - 0; const FIRE - 3; const MO - 2; const COND - 1; const POWER - 1; const RESUME - 2; const READYLITE - 2? const EQPTXST - 4; const PATSUP - 6; const CPU - 9; const DISPLAY - 8; implementation uses Repair, Ventdet, Dispspac, Comnunit, Diagvent, Neuro; {$R *.DFM} type arrayOfChar «* array[1..20] of char; dllVersionStrPtr - Λ arrayOfChar; function logWaveFoπn(board : integer; command : integer) : integer; far; external 'GUIIF'; {board is 1,2 or 3 for flow, cap and sp02 commands are 1,2 and 3 for start, continue, stop} function startEtC02 : integer; far; external 'GUIIF'; function getDllVersion : dllVersionStrPtr; far; external 'GUIIF'; unction defibControl(deFibDevice, OnOff : integer) : integer; far; external 'GUIIF'; function defibSenseD(deFibDevice : integer; var fromDLL : integer) : integer; far; external 'GUIIF'; function fanControl(fanNumber, OnOff : integer) : integer; far; external 'GUIIF'; function ventControl(ventDevice, OnOff : integer) : integer; far; external 'GUIIF'; function initControl(mode : integer) : integer; far; external 'GUIIF'; { mode =* 1 means close all files opened in the .dll} function pumpControl(whichPu p : integer; ctrlState : integer) : integer; far; external 'GUIIF'; function systemControl(sysEvent : integer; var ctrlState : integer) : integer; far; external 'GUIIF'; 4 procedure spin(delaylntβrval : integer); var innβrLoopIndex : longint; outerLoopIndex : integer; ans : real; begin for outerLoopIndex :- 1 to delaylnterval do begin for innerlooplndex :- 1 to 10 do anβ :- sqrt(37.9); end; end; procedure TMedicβGui.btnSyβtemClic (Sender: TObject); var βtringOfVersionPntr : dllVersionStrPtr; i : integer; strBuff : string[20]; begin SyBtemGUI.Visible :- True; SystemGUI.hrdwrHlthMonCycler.Enabled :- True; MedicsGUI.Visible :- False; {DISPLAY OF VERSION NUMBER} SystemGUI.delphVerβionLbl.Caption :- 'LSTAT6 May 1996'; stringOfVersionPntr :- getDllVersion; for i:- 1 to 20 do begin strBuff[i] :- stringOfVersionPntr Λ [i] ; end; SyβtemGUI.dllVersionLbl.Caption :- strBuff; end; procedure TMedicsGui.btnExitClick(Sender: TObject); begin fanControl{COND, 0) ; powerState :- OFF; pumpReturn :- pumpControl(VENTPOWER, powerState); if pumpReturn < 0 then messageDlg( 'Code pump98 hasn''t implemented this yet.' ,mtlnformation, [mbOK] , 0); initControl( 1) ; { argument - 1 means close all files in the dll} Close; end; procedure TMedicsGui.BitBtnlClick(Sender: TObject); begin EtC02Enabled :- False; flowEnabled : False; pulsOxEnabled :=■ True; firstBurst :- True; {This is part of the way to make first polyline call same color as background.} {It is βet to falβe AFTER each call to drawBurβt. } DisplaySpace. floShrtRcdLbl.Visible :- True; DisplaySpace.floShrtRcdShape.Viβiblβ :- True; MedicsGUI.Visible :- Falββ; DisplaySpace.Visible ι- True; if suctionOnToggle - True then begin DisplaySpace.Labell0.Caption :■ ON'; DisplaySpace.BitBtnδ.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end else begin DisplaySpace.LabellO.Caption :- 'OFF'; DiβplaySpace.BitBtn6.Glyph.LoadFromFile( 'βuction2.bmp' ) ; end; DisplaySpace.oxSatTitleLbl.Visible :- True; DisplaySpace.Shapel.Visible :- False; DisplaySpace.Shape2.Visible :- False; DisplaySpace.Shape3.Visible :- True; DisplaySpace.Imagel.Visible :- True; DisplaySpace.Image2.Visible :- True; DisplaySpace.timelnMinutesLbl.Caption :- 'Time'; DisplaySpace.hrBarBaσkgndShape.Visible :- True; DisplaySpace.nowLbl.Visible :- True; DisplaySpace.hrBarLbl.Visible :- True; DisplaySpace.beatsLbl.Visible :- True; DisplaySpace.Label32.Visible :- True; DisplaySpace. abel46.Visible :- True; DisplaySpace.Image7.Visible :- True; DisplaySpace.oxScalelmage.Visible :- True; DisplaySpace.Image7h.Visible :- True; DisplaySpace.Labell4.Visible :- True; DisplaySpace.Labell5.Visible :- True; DisplaySpace.Label 3.Visible :- True; DisplaySpace.Label47.Visible :» True; DisplaySpace.Shape3.Height :- 313; {273} DisplaySpace.BitBtnl.Visible :- Falae; DisplaySpace.BitBtn2.Visible :- True; DisplaySpace.BitBtn3.Visible :- True; DisplaySpace.BitBtn4.Visible :- True; DisplaySpace.÷imelnMinutesLbl.Caption :- 'TIME'; Application.processmessages; drawHRCurve; end; procedure TMedicsGui.BitBtn2Click(Sender: TObject); begin MedicsGUI.Visible :- Falβe; DisplaySpace.Viβible :- True; { capnostat button on diβplaceSpacβ form } flowEnabled :- Falβe; pulsOxBnabled :- Falβe; BtC02Bnabled :- True; displaySpace.pC02backgndShape.Visible :- True; diβplaySpacβ.floShrtRcdLbl.Viβiblβ ι« True; diβplaySpace.floShrtRcdShapβ.Viβible x- True; {showAirwayGraph } board :- CAPNOSTATBOARD; { board is a global var to tell timer which one to command. } DisplaySpace.floShrtRcdLbl.Viβible :- True; DisplaySpace.floShrtRcdShape.Visible :- True; if suctionOnToggle - True then begin DisplaySpace.LabellO.Caption :- 'ON'; DiβplaySpacβ.BitBtn6.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end else begin DisplaySpace.LabellO.Caption :- 'OFF'; DisplaySpace.BitBtn6.Glyph.LoadFromFile( 'suction2.bmp' ) ; end; DiβplaySpace.oxScalelmage.Viβible :- Falβe; DisplaySpace.Shapel.Visible :- False; DisplaySpace.Shape2.Visible :- True; DisplaySpace.Shape3.Visible :- False; DisplaySpace.Imagel.Visible :- False; DisplaySpace.Image8.Viβible :- False; DisplaySpace.Labell7.Visible :- Falβe; DisplaySpace.Labell6.Visible :- Falβe; DiβplaySpace.Image2.Viaible :- True; DisplaySpace.hrBarBackgndShape.Visible :- Falβe; DiβplaySpacβ.nowLbl.Viβible :- False; DisplaySpace.hrBarLbl.Visible :- False; DisplaySpace.beatsLbl.Visible :- False; DisplaySpace.Label32.Visible :- False; DisplaySpace.Label46.Visible :- False; DisplaySpace.oxSatTitleLbl.Visible :- False; DisplaySpace.ekgBtn.Visible :- True; DisplaySpace.Image7.Visible :- False; DisplaySpace.Image7h.Vieible :- False; DisplaySpace.Labell4.Visible :- False; DisplaySpace.Labell5.Visible :- False; DisplaySpace.BitBtnl.Visible :- True; 7 DisplaySpace.BitBtn2.Visible :- False; DisplaySpace.BitBtn3.Viβible :- True; DisplaySpace.BitBtn .Visible :- True; DisplaySpace.timelnMinutββLbl.Caption :- 'Time in Minutes / . Application.procesemessages; end; procedure TMedicβGui.BitBtn3Click(Sender: TObject); begin MedicsGUI.Viβible :- False; DisplaySpace.Viβible :- True; EtC02Enabled :- Falβe; flowEnabled :- False; pulsOxEnabled :- False; DisplaySpace.floShrtRcdLbl.Visible :- False; DisplaySpace.floShrtRcdShape.Visible :- Falβe; if suctionOnToggle » True then begin DisplaySpace.LabellO.Caption :- 'ON'; DisplaySpace.BitBtn6.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end else begin DisplaySpace.LabellO.Caption :- 'OFF'; DiβplaySpace.BitBtn6.Glyph.LoadFromFile( 'suction2.bmp' ) ; end; DisplaySpace.oxScalelmage.Visible :- False; DisplaySpace.oxSatTitleLbl.Visible :- False; DisplaySpace.Shapel.Visible :- True; DisplaySpace.Shape2.Visible :- False; DisplaySpace.Shape3.Visible :- False; DisplaySpace.Imagel.Visible :- True; DisplaySpace.Labell7.Visible :- True; Di8playSpace.Labell6.Visible :- True; DisplaySpace.Image2.Visible :- False; DisplaySpace.hrBarBackgndShape.Visible :- False; DisplaySpace.nowLbl.Visible :- False; DisplaySpace.hrBarLbl.Visible :- Falβe; DisplaySpace.beatsLbl.Visible :- Falβe; DisplaySpace.Label32.Visible :- Fa'lse; DisplaySpace.Label46.Visible :- False; DisplaySpace.ekgBtn.Visible :- True; DisplaySpace.Image7.Viβible :- False; DisplaySpace.Image7h.Visible :- False; DisplaySpace.Labell4.Visible :- False; {DisplaySpace.Labell5.Visible :- False;} {DisplaySpace.EKGTimerl.Enabled :- Falβe;} 8 DisplaySpace.BitBtnl.Visible :- True; DisplaySpace.BitBtn2.Visible :- True; DiβplaySpace.BitBtn3.Viβible :- Falββ; DisplaySpace.BitBtn4.Viβible :- True; DisplaySpace.timβlnMinutβsLbl.Caption :- 'Time in Minutes'; Application.proceasmeββagββ; drawTempCurve; end; procedure TMedicβGui.BitBtn4Click(Sender: TObject); begin MedicsGUI.Visible :- Falββ; DisplaySpace.Visible :- Falβe; VENTDETAIL.Visible :- True; VENTDETAIL. orβBreathPnl.Visible :- Falββ; if suctionOnToggle - True then begin VENTDETAIL.Labell.Caption :- 'ON'; VENTDETAIL.BitBtnlO.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end else begin VENTDETAIL.Labell.Caption :- 'OFF'; VENTDETAIL.BitBtnlO.Glyph. oadFromFile( 'suction2.bmp' ) ; end; if ventOnToggle - True then begin VENTDETAIL.btnShutDown.Caption :- 'SHUT OFF VENTILATOR'; end else begin VENTDETAIL.btnShutDown.Caption :- 'TURN ON VENTILATOR'; end; end; procedure TMedicsGui.BitBtn5Click(Sender: TObject); {MASTER ON/OFF SWITCH OF THE DEFIB. THIS MOSTLY CONTROLS THE APPEARENCE OF THE VARIOUS LABLES AND BUTTONS. IT ALSO CALLS JOHN'S DEFIBcONTROL.} begin if defibOnTogglβ - True then begin {TURNING DEFIB OFF} if defibControl(POWER,0) > 0 then meββageDlg( 'The .dll haβn''t implemented this yet.' ,mtInformation, [mbOK], 0); defibOnToggle :- False; readyIndicator.Viβible :- False; defibFlashCheck.Enabled :- Falβe; resumeBtn.Visible :- False; firβBtn.Visible :- Falββ; BitBtnS.Glyph.LoadFroβFile( 'hartxapO.bβp' ) ; lblDβfiblndicator.Caption :- 'IS OFT'; arningRβctl.Viβiblβ :- Falβe; {inβureβ it ends up as Falβe} end else begin {TURNING DEFIB ON} if defibControl(POWER, 1) > 0 then »βββagβDlg( 'The .dll haβn"t implemented this yet.' ,» In ormation, [ bOK], 0); de ibOnTogglβ :- True; defibFlaβhChβck.Enabled :- True; rββumeBtn.Visible :■ True; fireBtn.Visible :- Falβe; BitBtn5.Glyph.LoadFrc«Filβ( 'hartzapl.bap' ) ; lblDefiblndicator.Caption :- 'IS OH'; warningRectl.Viβiblβ :- True; firβBtnCountβr :- 0; end; end; procedure TMβdicsGui.BitBtn6Click(Sβndβr: TObject); begin if suctionOnToggle - True then begin suctionOnToggle j- False; lblSuctionlndicator.Caption :- 'OFF'; BitBtnδ.Glyph.LoadFroβ-Filβ( 'suction2.bmp' ) ; if pu pControl(SUCPOWER, POWEROFF) > 0 then messageDlg( 'The .dll hasn''t implemented this yet.' ,mtlnformation, [mbOK] , 0) ; end else begin suctionOnToggle :- True; lblSuctionlndicator.Caption :- 'ON'; BitBtn6.Glyph.LoadFroβ-Filβ( 'suctionl.bsqp' ) ; if pumpControl(SUCPOWBR, POWBRON) > 0 then mβββageDlg( 'The .dll haβn''t implemented thiβ yet.' ,mtlnformation, [mbOK], 0); end; end; var tempCounter : integer; procedure TMβdicβGui.dβ ibFlaβhCheckTimβr(Sender: TObject); {Thiβ timer cyclββ ββdiuβi speed to detect the flaβhing of the defib ready light. It displays a big red button if it dβtβctβ the ready light wants to be on. } var 10 rβadylndicatorStatβ, i : integer; nuβtring : string; mγMβg : βtring; begin dβfibSβnββD(RBADYLITB,readyIndicatorstate) ; if readylndicatorStatβ ■ 1 then begin readylndicator.Viβiblβ :- True; { GOING ON } firβBtnCountβr :■ firβBtnCcuntβr + 1; firβBtnCounterLabβl.Caption : ■ intToStr(firβBtnCounter) ; end begin rβadylndicator.Viβiblβ :- False; { GOING OFF } end; if (fireBtnCounter > 3) then fireBtn.Visible :- True; tempCounter :- tempCounter + 1; flaβherLbl.Caption :- intToStr(tempCounter) ; end; procedure TMedicsGui.re8umebtnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin defibControl(RESUME, 1); end; procedure TMedicsGui.resumebtnMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin defibControl(RESUME, 0) ; end; procedure TMedicβGui.rββumebtnClic (Sender: TObject); begin rβnumebtn.visible :- Falβe; fireBtn.Visible :- False; end; procedure TMedicβGui.vβntPowerBtnClick(Sender: TObject); begin if vβntOnToggle - True then begin ventOnToggle :« Falβe; ventBoardRDY :- Falββ; {being turned off} VENTDETAIL.btnShutDown.Caption :- 'TURN ON VENTILATOR'; MedicβGUI.ventPowerBtn.Caption :- 'TURN ON'; powerState :- OFF; pumpReturn : « pumpControl(VENTPOWER, powerState); 11 if pumpReturn < 0 then messageDlg( 'Code pump98 haan''t implemented thiβ yet.' ,mtlnformation, [mbOK], 0); ventSamplerEnabled :- False; end begin ventOnToggle :- True; {being turned on} VENTDETAIL.btnShutDown.Caption :- 'SHUT OFF VENTILATOR'; MedicsGUI.ventPowerBtn.Caption :- 'TURN OFF'; powerState :- 1; pumpReturn :- pumpControl(VENTPOWER, powerState); if pumpReturn < 0 then messageDlg( 'pumpControl hasn''t implemented this yet.' ,mtlnformation, [mbOK], 0); ctrlState :- 1; syBtemReturn :- systemControl (VBNTINIT,ctrlState) ; if systemReturn < 0 then messageDlg( 'systemControl hasn''t implemented this yet.' ,mtlnformation, [mbOK], 0); VENTDETAIL.initDelay.Enabled :- True; {this calls systemControl again and again until IMVMODE state} { if (ventBoardRDY - False) then begin VENTDETAIL.selfTestPnl.Visible :- True; VENTDETAIL.selfTestLbl.Visible :- True; end else begin VENTDETAIL.self estPnl.Visible :- False; VENTDETAIL.selfTestLbl.Visible :- False; end; } end; end; procedure TMedicsGui.fireBtnClick(Sender: TObject); begin defibControl(FIRE, 1); {defibFlashCheck.Enabled :- Falβe;} fireBtn.Visible :- False; fireBtnCounter :- 0; {reset counter} warningRectl.Visible :- False; readylndicator.Visible :- False; end; procedure TMedicsGui.rcrdMenuBtnClick(Sender: TObject); begin recordMenuPanel.Visible :- True; end; procedure TMedicsGui.retrnRecBtnClick(Sender: TObject) ; begin MedicsGui.recordMenuPanel.Visible :- Falβe; end; 12 procedure TMedicsGui. flowRecBtnClick(Sender: TObject); begin board :- FLOWBOARD; if flowRecShape.Visible - True then begin flowRecShape.Viβible :- Falβe; onβPerSecondBnabled :- False; flowBoardEnablβd :- False; logWavθForm(board, 3); {end} end else begin flowRecShape.Visible :- True; flowBoardEnabled :- True; logWaveForm(board, 1); {start} onePerSecondEnabled :- True; end; if (allRecShape.Visible or flowRecShape.Visible or pulsRecShape.Visible or co2recShape.Viβible) then reclickLbl.Viβible :« True else reclickLbl.Visible :- Falβe; end; procedure TMedicsGui.pulBRecBtnClick(Sender: TObject); begin board :- SP02BOARD; if pulsRecShape.Visible - True then begin pulsRecShape.Visible :- False; onePerSecondEnabled :- False; spo2BoardEnabled :- False; logWaveForm(board, 3); {end} end else begin pulsRecShape.Visible :- True; spo2BoardEnabled :- True; logWaveForm(board, 1); {start} onePerSecondEnabled :- True; end; if (allRecShape.Visible or flowRecShape.Visible or pulsRecShape.Visible or co2recShape.Viβible) then reclickLbl.Visible :- True else reclickLbl.Visible :- False; end; procedure TMedicsGui.co2RecbtnClick(Sender: TObject); begin board :- CAPNOSTATBOARD; if co2recShape.Visible - True then begin co2recShape.Visible :- False; onePerSecondEnabled :- False; capnoBoardEnabled :- False; logWaveFor (board, 3); {end} 13 end else begin co2recShapβ.Visible :- True; capnoBoardEnablβd :■ True; logWaveFora(board, 1); {βtart} onePerSecondEnabled :- True; end; if (allRecShape.Viβiblβ or flowRecShape.Visible or pulβRecShapβ .Viβible or co2recShapβ.Viβible ) then reclickLbl.Viβiblβ :- True else reclickLbl.Viβiblβ i- Falβe; end; procedure TMedicsGui.allRβcBtnClick(Sender: TObject); begin if allRecShape.Viβible - True then begin allRecShape.Viβible :- Falββ; onePerSecondEnabled :- Falβe; allBoardsEnabled :- Falβe; logWavθForm(CAPNOSTATBOARD, 3); {end} logWavoForm(FLOWBOARD, 3); {end} logWaveForm(SP02BOARD, 3); {end} end else begin allRecShape.Visible :« True; allBoardsEnabled :- True; logWaveForm(CAPN0STATBOARD, 1); {start} logWaveForm(FLOWBOARD, 1); {βtart} logWaveForm(SP02BOARD, 1); {start} onePerSecondEnabled :- True; end; if (allRecShape.Viβible or flowRecShape.Visible or pulsRecShape.Visible or co2recShape.Visible) then reclickLbl.Viβible :- True elβe reclickLbl.Viβible :- Falβe; end; procedure TMedicsGui.toCuffBtnClick(Sender: TObject); begin MedicsGui.BPhistoryPnl.Visible :- True; end; procedure TMedicβGui.cancelCyclβBtnClick(Sender: TObject) ; begin cycleModeLbl.Caption :- '—'; setCyclePnl.Visible :- False; end; procedure TMedicsGui.eetCycleBtnClick(Sender: TObject); 14 begin setCyclePnl.Visible :- True; end; procedure TMedicsGui.RadioButtonlClick(Sender: TObject); begin cycleModθLbl.Caption :- '1'; setCyclePnl.Visible :- False; end; procedure TMedicsGui.RadioButton2Click(Sender: TObject); begin cycleModθLbl.Caption :- '2'; setCyclePnl.Visible :- False; end; procedure TMedicsGui.RadioButton5Click(Sender: TObject) ; begin cycleModeLbl.Caption :- '5'; setCyclePnl.Visible :- False; end; procedure TMedicsGui.RadioButton6Click(Sender: TObject); begin cycleModeLbl.Caption :- '10'; setCyclePnl.Visible :«• False; end; procedure TMedicsGui.RadioButtonθClick(Sender: TObject); begin cycleModeLbl.Caption :- '30'; setCyclePnl.Visible :- False; end; procedure TMedicsGui.RadioButton9Click(Sender: TObject); begin cycleModeLbl.Caption :- '60'; setCyclePnl.Visible :- False; end; procedure TMedicsGui.okBtnClick(Sender: TObject); begin setCyclePnl.Visible :- False; end; 15 procedure TMedicsGui.βetBPbtnClick(Sender: TObject); begin MedicsGui.setBPpanel.Visible :- True; end; procedure TMedicsGui.BPreturnBtnClick(Sender: TObject); begin BPhistoryPnl.Visible :- False; setBPpanel.Visible :- False; end; procedure TMedicsGui.cuffReturnBtnClick(Sender: TObject) ? begin MedicsGui.setBPpanel.Visible :- False; end; initialization tempCounter :- 1; fireBtnCounter := 0; end. 16 PROGRAM LISTING REPAIR.PAS unit Repair; interface uses SysUtilβ, WinTypββ, WinProcβ, Mββsagββ, Claββeβ, Graphics, Controls, Forms, Dialogβ, StdCtrlβ, ExtCtrlβ, Mβnuβ, Buttons; type TSyβtemGUI - claββ(TFom) Ventilator: TButton; Control: TButton; Button2: TButton; Button3: TButton; Button4 : TButton; commBtn: TButton; Button9: TButton; Buttonl: TButton; shapeVentMore: TShape; sucMorShp: TShape; vβntMorLbl: TLabel; sucMorLbl: TLabel; ECSpanel: TPanel; Label3: TLabel; Button7 : TButton; circFanOnLabel: TLabel; ecsMorShp: TShape; ecβMorLbl: TLabel; powMorShp: TShape; powerPanel: TPanel; lblPower: TLabel; Imagel: TImage; powMorLbl: TLabel; ButtonlO: TButton; condFanOnLabel: TLabel; preβFanOnLabel: TLabel; Buttonl1: TButton; OBOGSpanel: TPanel; Label7: TLabel; comMorShp: TShape; comMorLbl: TLabel; commPanel: TPanel; Image2: TImage; dispMorShp: TShape; dispMorLbl: TLabel; displayPanel: TPanel; LabellO: TLabel; dispTempLbl: TLabel; Label12: TLabel; defibMorShp: TShape; defibMorLbl: TLabel; defibPanβl: TPanel; Labell4: TLabel; βuctionPanel: TPanel; Labell5: TLabel; Labellδ: TLabel; chargβBtn: TButton; chargeLbl: TLabel; Buttonl2: TButton; stepoFanOnLabel: TLabel; Label17: TLabel; eqpXstTempLbl: TLabel; Labelll: TLabel; Labell8: TLabel; patβupTempLbl: TLabel; Label20: TLabel; Labell9: TLabel; cpuTempLbl: TLabel; wordβCPUlabel: TLabel; touchLbl: TLabel; Labell: TLabel; Image : TImage; Label2: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Labelθ: TLabel; Label9: TLabel; hrdwrHlthMonCycler: TTimer; returnBtn: TBitBtn; delphVersionLbl: TLabel; dllVersionLbl: TLabel; procedure Button6Click(Sender: TObject) ; procedure zigZag(lineColor, startX, startY, endX, endY: Integer) ; procedure Button4MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure VentilatorKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure VentilatorMouβeDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure VentilatorMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure commBtnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button2MouβeDown ( Sender : TObject ; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button9MouβeDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button9MouβeUp(Sender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); procedure Button3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ButtonlMouseDownfSender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ButtonlMouβeUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button3MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button4MouβeUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure commBtnMouseUp(Sender: TObject; Button: TMouseButton? Shift: TShiftState; X, Y: Integer); procedure Button7Click(Sender: TObject); procedure ecsMorShpMouseDown(Sender: TObject; Button: TMouseButton; . Shift: TShiftState; X, Y: Integer); : procedure ButtonlOClick(Sender: TObject); procedure ECSpanelClick(Sender: TObject); procedure ventilatorPanelClick(Sender: TObject) ; procedure powerPanelClick(Sender: TObject) ; procedure powMorShpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure powMorLblMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ButtonllClick(Sender: TObject) procedure OBOGSpanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure dispMorShpMouseDown(Sender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); procedure commPanelClick(Sender: TObject); procedure displayPanelClick(Sender: TObject) ; procedure comMorShpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure defibMorShpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure defibPanelClick(Sender: TObject); procedure sucMorShpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure suctionPanelClick(Sender: TObject); procedure chargeBtnClick(Sender: TObject) ; procedure Buttonl2Clic (Sender: TObject); procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure VentilatorClick(Sender: TObject); procedure shapeVentMoreMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure comMorShpMouseU (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ecsMorShpMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure shapeVentMoreMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormDestroy(Sender: TObject); procedure hrdwrHlthMonCyclerTimer(Sender: TObject) ; procedure returnBtnClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var SystemGUI: TSystemGUI; implementation uses Ventdet, Main, Dispspac, Comnunit, Diagvent; {$R *.DFM} var a__ScreenHappening: TScreenControl; const COND - 1; const CIRC - 3; conβt PRES » 4; const CHARGE - 1; function fanControl(FanNum, OnOff : integer) : integer; far; external 'GUIIF'; 4 function powerControl(powerDβvice, onOff : integer) : integer; far; external 'GUIIF'; function ecsControl(ECSDevice, onOff : integer) : integer; far; external 'GUIIF'; function tempSenseA(tempDevice : integer; var fromDLL : integer) : integer? far; external 'GUIIF'; procedure TSystemGUI .Button6Click(Sender: TObject); begin a_ScreenHappening :- TScreenControl.Create; SystemGUI .Visible :- False; SystemGUI .hrdwrHlthMonCycler.Enabled :- False; VENTDETAIL.Visible :- False; a_ScreenHappening.TurnOnMedicsScreen; end; procedure TSystemGUI. zigZag(lineColor, startX, startY, endX, endY: Integer) ; var pointlX, point2X, pointlY, point2Y: Integer; begin Canvas.Pen.Width :- 2; if lineColor =» 0 then Canvas.Pen.Width := 4; {to erase every pixel} if lineColor 0 then Canvas.Pen.Color - clSilver; if lineColor 1 then Canvas. en.Color - clOlive; if lineColor 2 then Canvas.Pen.Color - clRed; if lineColor 3 then Canvas.Pen.Color - clGreen; if lineColor 4 then Canvas.Pen.Color - clNavy; if lineColor 5 then Canvas.Pen.Color - clPurple; if lineColor 6 then Canvas.Pen.Color m clTeal; if lineColor 7 then Canvas.Pen.Color - clLime; if lineColor 8 then Canvas.Pen.Color - clBlue; if lineColor 9 then Canvas.Pen.Color - clFuchsia; if lineColor 10 then Canvas.Pen.Color - clAqua; if lineColor 11 then Canvas.Pen.Color - clMaroon; if lineColor 12 then Canvas.Pen.Color - clBlack; if lineColor 13 then Canvas.Pen.Color - clWhite; pointlX := (endX - startX) div 2 + startX; pointlY :■* startY; point2X := pointlX; point2Y := endY; Canvas.MoveTo(startX, startY); Canvas.LineTo(pointlX, pointlY) ; Canvas.LineTo(point2X, point2Y) ; Canvas.LineTo(endX, endY) ; end; procedure TSystemGUI.Button4MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin zigZag(3, Control.Left + Control.Width, Control.Top + Control.Height div 2 + 5 , Button .Left, Button4.Top + Button4.Height div 2); powMorShp.Visible :- True; powMorLbl .Visible :- True; end; procedure TSystemGUI.VentilatorKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key - 27 then begin SystemGUI.Visible :- Falβe; MedicsGUI.Visible :- Falβe; VENTDETAIL.Visible :- False; end; end; procedure TSystemGUI.ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin zigZag(3, Ventilator.Left + Ventilator.Width, Ventilator.Top + Ventilator.Height div 2 , Control.Left, Control. op + Control.Height div 2-5); zigZag(3, Button3.Left + Button3.Width, Button3.Top + Control.Height div 2 , Control.Left, Control. op + Control.Height div 2 +5); zigZag(3, Button2.Left + Button2.Width, Button2.Top + Control.Height div 2 , Control.Left, Control. op + Control.Height div 2 +0); zigZag(2, commBtn.Left + commBtn.Width, commBtn.Top + Control.Height div 2 , Control.Left, Control.Top + Control.Height div 2 - 5); zigZag(3, Control.Left + Control.Width, Control.Top + Control.Height div 2 , Button9.Left, Button9.Top + Button9.Height div 2); zigZag(3, Control.Left + Control.Width, Control.Top + Control.Height div 2 + 5 , Button4.Left, Button4.Top + Button4.Height div 2); zigZag(3, Control.Left + Control.Width, Control.Top Control.Height div 2 , Buttonl.Left, Buttonl. op + Buttonl.Height div 2); {The rectangles around the buttons.} Canvas.Pen.Color :- clGreen; Canvas.Pen.Width :- 4; Canvas.RoundRoct(Ventilator.Left - 2, Ventilator.Top - 2 , Ventilator.Left + Ventilator. idth + 2, Ventilator.Top + Ventilator.Height + 2, 5,5)? Canvas.Pen.Color :- clRed; Canvas.Pen. idth j- 4; Canvaβ.RoundRect(commBtn. eft - 1, commBtn.Top - 1 , commBtn.Left + commBtn. idth + 2, commBtn.Top + commBtn.Height + 2, 5,5); Canvaβ.Pen.Color :- clGreβn; Canvaβ.Pen. idth :- 4; Canvaβ.RoundRect(Button2.Left - 1, Button2.Top - 1 , Button2.Left + Button2.Width + 2, Button2.Top + Button2.Height + 2, 5,5); Canvas.Pen.Color :- clGreen; Canvaβ.Pen.Width :- 4; Canvas.RoundRect(Button9.Left - 1, Button9.Top - 1 , commBtn.Left + Button9.Width + 2, Button9.Top + Button9.Height + 2, 5,5); Canvas.Pen.Color :- clGreen; Canvaβ.Pen.Width :- 4; Canvas.RoundRect(Button3.Left - 1, Button3.Top - 1 , Button3.Left + Button3.Width + 2, Button3.Top + Button3.Height + 2, 5,5); Canvas.Pen.Color :- clGreen; Canvas.Pen.Width :- 4; Canvaβ.RoundRect(Buttonl.Left - 1, Buttonl.Top - 1 , Buttonl.Left + Buttonl.Width + 2, Buttonl.Top + Buttonl.Height + 2, 5,5); Canvas.Pen.Color :- clGreen; Canvas.Pen.Width :- 4; Canvas.RoundRect(Button4.Left - 1, Button4.Top - 1 , Button4.Left + Button4.Width + 2, Button4.Top + Button4.Height + 2, 5,5); end; ϊ procedure TSystemGUI.VentilatorMouseDown(Sender: .TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin zigZag(3, Ventilator.Left + Ventilator.Width, Ventilator.Top + Ventilator.Height div 2, Control.Left, Control.Top"+ Control.Height div 2-5) ; end; procedure TSystemGUI.VentilatorMouseUp(Sender: TObject; 7 Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Canvas.Pen.Color :- clGreen; Canvas.Pen.Width :- 4; Canvaβ.Pen.Style :- pβSolid; Canvaβ.RoundRect(Ventilator.Left - 3, Ventilator.Top - 3 , Ventilator.Left + Ventilator. idth + 3, Ventilator.Top + Ventilator.Height + 3, 5,5); end; procedure TSystemGUI.commBtnMousβDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin zigZag(2, commBtn.Left + commBtn.Width, commBtn.Top + commBtn.Height div 2, Control.Left, Control.Top + Control.Height div 2 - 5) ; comMorShp.Viβible :- True; comMorLbl.Visible :- True; end; procedure TSystemGUI.Button2MouββDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin zigZag(3, Button2.Left + Button2.Width, Button2.Top + Button2.Height div 2, Control.Left. Control. op + Control.Height div 2 +0) ; ecsMorShp.Visible :- True; ecsMorLbl.Visible :- True; end; procedure TSystemGUI.Button2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Canvas.Pen.Color :- clGreen; Canvas.Pen.Width :» 4; Canvas.RoundRect(Button2.Left - 1, Button2.Top - 1 , Button2.Lβft + Button2.Width + 2, Button2.Top + Button2.Height + 2, 5,5); end; procedure TSystemGUI.Button9MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin zigZag(3, Control.Left + Control. idth, Control.Top + Button9.Height div 2, Button9.Left, Button9.Top + Button9.Height div 2) ; dispMorShp.Visible :- True; dispMorLbl.Visible :- True; end; 8 procβdure TSystemGUI.Button9MouβeUp(8βndβr: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); begin Canvas. en.Color :- clGreen; Canvaβ.Pen. idth :- 4; Canvaβ.RoundRect(Button9. eft - 1, Button9.Top - 1 , commBtn.Left + Button9.Width + 2, Button9.Top + Button9.Beight + 2, 5,5); end; procedure TSystemGUI.Button3MouββDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin zigZag(3, Button3.Left + Button3. idth, Button3.Top + Button3.Height div 2 , Control.Left. Control.Top + Control.Height div 2 +5) ; sucMorShp.Viβiblβ :- True; βucMorLbl.Viβible :- True; end; procedure TSystemGUI.Button3MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Canvas.Pen.Color :- clGreen; Canvas.Pen.Width :- 4; Canvas.RoundRect(Button3.Left - 1, Button3.Top - 1 , Button3.Left + Button3.Width + 2, Button3.Top + Button3.Height + 2, 5,5); end; procedure TSystemGUI.ButtonlMouβeDown(Sender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); begin zigZag(3, Control.Left + Control.Width, Control.Top + Control.Height div 2 , Buttonl.Left, Buttonl.Top + Buttonl.Height div 2); defibMorShp.Viβiblβ :- True; defibMorLbl.Visible :- True; end; procedure TSystemGUI.ButtonlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Canvas.Pen.Color :- clGreen; Canvas.Pen.Width :- 4; Canvas.RoundRect(Buttonl.Left - 1, Buttonl.Top - 1 , Buttonl. oft + Buttonl. idth + 2, Buttonl. op + Buttonl .Height + 2, 5,5); end; procedure TSyβtββGUI.Button4MoυβeUp(Sender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); begin Canvaβ.Pen.Color :• clGreen; Canvaβ.Pen.Width :- 4; Canvaβ.RoundRect(Button4. eft - 1, Button4.Top - 1 , Button4.Left + Button .Width + 2, Button4.Top + Button4.Height + 2, 5,5); end; procedure TSyBtβmGUI.coββaBtnMouββUp(Sβndβr: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Canvaβ.Pen.Color :- clRβd; Canvaβ.Pen. idth :- 1; Canvaβ.Pen.Style :- pβDot; Canvas .RoundRect (comaBtn. Left - 1, coe.aBtn.Top - 1 , commBtn.Left + conα-Btn. Width + 2, coeβBtn.Top + coβsaBtn. Height + 2, 5,5); end; procedure TSystemGUI.Button7Click(Sender: TObject); var errorNum : integer; begin if circFanOnLabβl.Caption - 'ON' then begin circFanOnLabβl.Caption :- 'OFF'; if fanControl(CIRC, 0) > 0 then s»βeageDlg( 'The .dll haβn''t implemented thiβ yet.' ,»tInformation, [mbOK], 0); end begin circFanOnLabβl.Caption :- ON'; if fanControl(CIRC,l) > 0 then *eeeageDlg( 'The .dll haβn"t implemented thiβ yet.' ,«tInformation, [mbOK], 0); end; end; procedure TSyβtβmGUI.βcβMorShp*iouββDovn(Sender: TObject; Button: TMouseButton; Shift: TShi State; X, Y: Integer) j 10 begin ECSpanβl.Viβiblβ :- True; if condFanOnTogglβ - True then condFanOnLabβl.Caption :- 'ON' βlββ condFanOnLabel.Caption :- 'OFF'; end; procedure TSyβtemGUI.ButtonlOClick(Sendβr: TObject); v * r errorCodβ : integer; begin if condFanOnTogglβ - True then begin condFanOnTogglβ :- Falβe; condFanOnLabel.Caption :- 'OFF'; if fanControl(COND, 0) > 0 then messageDlg( 'The .dll hasn''t implemented thiβ yet.' ,βrtlnformation, [ bOKJ, 0); end begin condFanOnTogglβ :- True; condFanOnLabel.Caption :- 'OR'; if fanControl(COND, 1) > 0 then messageDlg( 'The .dll hasn"t implemented this yet.' ,βtlnformation, [mbOK], 0); end; end; procedure TSystemGUI.ECSpanβlClick(Sender: TObject); begin ECSpanβl.Visible :- Falβe; end; procedure TSyβtβmGUI.vβntilatorPanelClick(Sender: TObject); begin {diag_vent.Visible :- False;} {Walter, see if this disβappearβ. } end; procedure TSyβteβGUI.powerPanelClick(Sender: TObject); begin powerPanβl.Viβiblβ :« Falβe; end; procedure TSyβtemGUI.powMorShpMouβeDow fSender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); begin PowerPanβl.Viβiblβ :• True; powMorShp.Visible :- Falβe; powMorLbl.Viβible :- Falβe; end; procedure TSyβteaCUI.pcvMorlalMouβeDownlSender: TObject; Button: TMouββButton; 11 Shift: TShiftState; X, Y: Integer); begin powerPanel.Vieible :- True; end; procedure TSyβtemGUI.ButtonllClick(Sender: TObject); begin if preβFanOnLabel.Caption - 'ON' then begin presFanOnLabel.Caption :- 'OFF'; if fanControl(PRES, 0) > 0 then messageDlg( 'The .dll hasn''t implemented this yet.' ,mtInformation, [mbOKJ, 0); end else begin presFanOnLabel.Caption :- 'ON'; if fanControl(PRES, 1) > 0 then messageDlg( 'The .dll hasn''t implemented this yet.' ,mtlnformation, [mbOK], 0); end; end; procedure TSystemGUI.OBOGSpanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin OBOGSpanel.Visible :- False; end; procedure TSyβtemGUI.dispMorShpMouseDown(Sender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); begin displayPanel.Visible :- True; end; procedure TSystemGUI.commPanelClick(Sender: TObject); begin commPanel.Visible :- Falβe; comMorShp.Visible :- False; comMorLbl.Visible :« False; end; procedure TSyβtemGUI.diβplayPanelClick(Sender: TObject); begin diβplayPanel.Visible :- Falβe; diβpMorShp.Viβible :- False; dispMorLbl.Visible :- False; end; procedure TSystemGUI.comMorShpMouβeDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin 12 commPanel.Viβiblβ :- True; end; procedure TSystemGUI. efibMorShpMouββDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin defibPanβl.Viβiblβ :■ True; defibMorShp.Viβiblβ :- Falβe; defibMorLbl.Viβiblβ :- Falβe; end; procedure TSystemGUI.de ibPanβlClick(Sendβr: TObject); begin defibPanel.Visible :- Falββ; end; procedure TSystemGUI.sucMorShpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin sucMorShp.Viβible :- False; BucMorLbl.Viβible :- False; suctionPanel.Visible :- True; end; procedure TSystemGUI.βuctionPanelClick(Sender: TObject); begin suctionPanel.Visible :- Falβe; end; procedure TSystemGUI.chargeBtnClick(Sender: TObject); begin if chargeBtn.Caption - 'OFF' then begin if powerControl(CHARGE,1) > 0 then messageDlg( 'The .dll haβn''t implemented thiβ yet.' ,mtlnformation, [mbOK], 0); chargeBtn.Caption :- 'CHARGING'; end procedure TSystemGUI.Buttonl2Click(Sender: TObject); begin if stepoFanOnLabel.Caption - 'ON' then begin 13 βtβpoFanOnLabel.Caption :- 'OFF'; if ecsControl(POWER,0) > 0 then mesβageDlg( 'The .dll haan''t implemented this yet.' ,mtlnformation, [mbOK], 0); end else begin stβpoFanOnLabel.Caption :- 'ON'; if ecβControl(POWER, 1) > 0 then meββagβDlgf 'The .dll haβn''t implemented this yet.' ,mtInformation, [mbOK], 0); end; end; procedure TSystemGUI.ControlMouββUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin zigZag(0, Ventilator.Left + Ventilator. idth, Ventilator.Top + Ventilator.Height div 2, Control.Left, Control.Top + Control.Height div 2-5); zigZag(0, Button3.Left + Button3.Width, Button3.Top + Button3.Height div 2, Control.Left, Control.Top + Control.Height div 2 +5); zigZag(0, Button2.Left + Button2.Width, Button2.Top + Button2.Height div 2, Control.Left. Control.Top + Control.Height div 2 +0); zigZag(0, commBtn.Left + commBtn. idth, commBtn.Top + commBtn.Height div 2, Control.Left, Control.Top + Control.Height div 2 - 5); zigZag(0, Control. eft + Control.Width, Control. op + Control.Height div 2 , Button9.Left, Button9.Top + Button9.Height div 2); zigZag(0, Control. eft + Control.Width, Control. op + Control.Height div 2 + 5 , Button4.Left, Button4.Top + Button4.Height div 2); zigZag(0, Control.Left + Control. idth, Control.Top + Control.Height div 2 , Buttonl.Left, Buttonl.Top + Buttonl.Height div 2); Canvas.Pen.Color :» clSilver; Canvas.Pen.Width :- 4; Canvas.RoundRect(Ventilator.Left - 3, Ventilator.Top - 3 , Ventilator.Left + Ventilator.Width + 3, Ventilator.Top + Ventilator.Height + 3, 5,5); Canvas.RoundRect(commBtn.Left - 1, commBtn.Top - 1 , commBtn.Left + commBtn. idth + 2, commBtn.Top + commBtn.Height + 2, 5,5); Canvas.RoundRect(Button2.Left - 1, Button2.Top - 1 , Button2.Left + Button2.Width + 2, Button2.Top + Button2.Height + 2, 5,5); Canvas.RoundRect(Button9. eft - 1, Button9.Top - 1 14 , commBtn.Left + Button9.Width + 2, Button9.Top Button9.Height + 2, 5,5); Canvas.RoundRect(Button3.Left - 1, Button3.Top - 1 , Button3.Left + Button3.Width + 2, Button3.Top Button3.Height + 2, 5,5); Canvas. oundRect(Buttonl.Left - 1, Buttonl.Top - 1 , Buttonl.Left + Buttonl .Width + 2, Buttonl. op Buttonl.Height + 2, 5,5); Canvas.RoundRect(Button4.Left - 1, Button4.Top - 1 , Button4.Left + Button4. idth + 2, Button4.Top Button4.Height + 2, 5,5); touchLbl.Refresh; end; procedure TSystemGUI.VentilatorClick(Sende : TObject); begin ventMorLbl.Visible :- True; shapeVentMore.Visible :■» True; end; procedure TSystemGUI. shapeVentMoreMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin ventMorLbl.Visible :- False; shapeVentMore.Visible := False; end; procedure TSystemGUI.comMorShpMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ; begin comMorShp.Visible :- False; comMorLbl.Visible :- False; end; procedure TSystemGUI.ecsMorShpMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin ecsMorShp.Visible :- False; ecsMorLbl.Visible := False; end; procedure TSystemGUI .shapeVentMoreMouseDown(Sender: TObject; Button: TMouseButton? Shift: TShiftState; X, Y: Integer); begin diag_vent.Visible :» True; end; procedure TSystemGUI.FormDestroy(Sender: TObject); begin a_ScreenHappening.Free; end; 15 procedure TSystemGUI.hrdwrHlthMonCyclerTimer(Sender: TObject); {Every two seconds; temperatures of hardware. The PATSUP temperature should be moved elsewhere someday.} var patTemp, eqpTemp : integer; begin if tempSenseA(PATSUP,patTemp) > 0 then messageDlg( 'The PATSUP, .dll not implemented yet.' ,mtlnformation, [mbOK], 0); patsupTempLbl.Caption :- intToStr(patTemp div 10); if tempSenseA(EQPTXST,eqpTemp) > 0 then messageDlg( 'EQPTXST, .dll hasn''t implemented this yet.' ,mtInformation, [mbOK], 0); e q p X s t T e m p L b l . C a p t i o n : •=> floatToStrF( (eqpTemp*1.0/10.0) ,ffFixed,7,1) ; if tempSenseA(DISPLAY,eqpTemp) > 0 then messageDlg( 'DISPLAY, .dll hasn''t implemented this yet.' ,mtlnformation, [mbOK], 0); dispTempLbl.Caption :- floatToStrF( (eqpTemp*l.0/10.0) ,ffFixed,7, 1) ; if tempSenseA(CPU,eqpTemp) > 0 then messageDlg( 'The CPU, .dll haβn''t implemented this yet.' ,mtlnformation, [mbOK], 0); cpuTempLbl.Caption := floatToStrF( (eqpTemp*! .0/10.0) , ffFixed, 7,1); end; procedure TSystemGUI.returnBtnClick(Sender: TObject)? begin {a_ScreenHappening :- TScreenControl.Create; } SystemGUI.Visible :» False; SystemGUI.hrdwrHlthMonCycler.Enabled :- False; VENTDETAIL.Visible := False; a_ScreenHappening.TurnOnMedicsScreen; end? end. 16 PROGRAM LISTING 239 ~VBNTDET.PAS unit Ventdet; interface uses SyβUtilβ, WinTypββ, WinProcβ, Mβββageβ, Claββes, Graphics, Controls, Forms, Dialogβ, BxtCtrlβ, StdCtrlβ, Buttonβ; type TVBNTDBTAIL - claββ(TForm) Label4: TLabel; LabellO: TLabel; minVolLbl: TLabel; LabβU4: TLabel; BitBtn7: TBitBtn; BitBtnβ: TBitBtn; BitBtn9: TBitBtn; Shaρβ2: TShape; BitBtnlO: TBitBtn; Labell: TLabel; ventLbl: TLabel; Labellδ: TLabel; coreTe pLbl: TLabel; Labell7: TLabel; breathRateLbl: TLabel; beatβPerLbl: TLabel; Label20: TLabel; btnShutDown: TButton; Labellβ: TLabel; Shapel: TShape; Label23: TLabel; Label24: TLabel; Label25: TLabel; Label26: TLabel; Label27: TLabel; Labell2: TLabel; Label31: TLabel; returnBtn: TBitBtn; Image2: TImage; Image3: TImage; Label32: TLabel; neuroBtn: TButton; moreBreathPnl: TPanel; BitBtnδ: TBitBtn; BitBtnll: TBitBtn; Label8: TLabel; setPreβMaxLbl: TLabel; Label30: TLabel; Label33: TLabel; BitBtnl2: TBitBtn; BitBtnl3: TBitBtn; 1 ββtPresMinLbl: TLabel; Shape4: TShape; Label37: TLabel; inβpirTimelibl: TLabel; Label39: TLabel; BitBtnl4: TBitBtn; BitBtnl5: TBitBtn; BitBtnlδ: TBitBtn; bpmDesirβdLbl: TLabel; Label41: TLabel; BitBtnl7: TBitBtn; Label42: TLabel; Shape5: TShape; minLbl: TLabel; Labellδ: TLabel; numeratorLbl: TLabel; Label35: TLabel; denominatorLbl: TLabel; BitBtn5: TBitBtn; Labβl3: TLabel; Label5: TLabel; patientPreββLbl: TLabel; Labell3: TLabel; Label21: TLabel; peakPressLbl: TLabel; Label22: TLabel; Label28: TLabel; Shape6: TShape; capNoStatLbl: TLabel; Image4 : TImage; Image5: TImage; Labelll: TLabel; Label19: TLabel; Labβl29: TLabel; tidalVolLbl: TLabel; Shape7: TShape; Shapeδ: TShape; BitBtnl: TBitBtn; BitBtn2: TBitBtn? targetPressLbl: TLabel; Label45: TLabel; Label46: TLabel; selfTestPnl: TPanel; selfTestLbl: TLabel; selfTestCounterLbl: TLabel; Label47: TLabel; oxSatLbl: TLabel; Label49: TLabel; Label50: TLabel; ventWarnPnl: TPanel; faillndicatorShape: TShape; Label6: TLabel; Label51: TLabel? Label52: TLabel; Label53: TLabel; Label54: TLabel; Label55: TLabel; Label56: TLabel; Label57: TLabel; alqlWhite: TShape; alqlRed: TShape; alq2White: TShape; alq2Red: TShape; alq3White: TShape; alq3Red: TShape; alq4White: TShape; alq4Red: TShape; 10 alq5White: TShape; alq5Red: TShape; alq6White: TShape; alq6Red: TShape; alq7White: TShape; alq7Red: TShape; Label40: TLabel; initDelay: TTimer; 15 alarmResβtBtn: TButton; Shape9: TShape; toGraphsBtn: TButton; Label48: TLabel; Label58: TLabel; Label59: TLabel; Label60: TLabel; Labelδl: TLabel; 20 RBRlbl: TLabel; Label62: TLabel; ShapelO: TShape; patientPressLbl2: TLabel; flowExplbl: TLabel; Label44: TLabel; ventRBRlbl: TLabel; « £ . modeBtn: TButton; Label64: TLabel; Label65: TLabel; flowIoverElbl: TLabel; Label66: TLabel; Label67: TLabel; Label68: TLabel; Label70: TLabel; 30 Label71: TLabel; Label72: TLabel; Label73: TLabel; Label74: TLabel; flowPeakLbl: TLabel; Label75: TLabel; 35 flowRBRlbl: TLabel; vβntMθBβage2 : TLabel; capRRbackgndShape: TShape; capRRbarShape: TShape; oxSatBackgndShapβ: TShape; oxSatBarShape: TShape; Label2: TLabel; Label43 : TLabel; oxSatBarLbl: TLabel; Label93: TLabel; Label94: TLabel; Label95: TLabel; C02barLbl: TLabel; Label96: TLabel; tempLabel: TLabel; tempLabel_2 : TLabel; tempLabel_3 : TLabel; { procedure Label6MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Label6MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure flasherTimer(Sender: TObject) ; } procedure BitBtn8Click(Sender: TObject) ; procedure BitBtn9Click(Sender: TObject) ; procedure BitBtn7Click(Sender: TObject); procedure Image2Click(Sender: TObject); procedure Shape2DragDrop(Sender, Source: TObject; X, Y: Integer) ? procedure BitBtnlOClick(Sender: TObject); procedure btnShutDownClick(Sender: TObject) ? procedure returnBtnClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure neuroBtnClick(Sender: TObject); procedure FormClic (Sender: TObject); procedure BitBtnl2Click(Sender: TObject); procedure BitBtnl3Click(Sender: TObject); procedure BitBtn6Click(Sender: TObject); procedure BitBtnllClick(Sender: TObject); procedure BitBtnl6Click(Sender: TObject) ; procedure BitBtnl7Click(Sender: TObject); procedure BitBtnl4Click(Sender: TObject); procedure BitBtnl5Click(Sender: TObject); procedure BitBtn5MoueeDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BitBtnlClick(Sender: TObject); procedure BitBtn2Click(Sender: TObject); procedure initDelayTimer(Sender: TObject); procedure alarmResetBtnClick(Sender: TObject) ; procedure toGraphsBtnClick(Sender: TObject) ; procedure modeBtnClick(Sender: TObject); 4 procedurθ oxSatBackgndShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure capRRbackgndShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end; {GLOBAL FORWARDS} procedure ventSampler; procedure drawBreathCurvβ(breathsPerMin : integer); {GLOBAL VARS} var VENTDETAIL: TVENTDETAIL; 02Desired : real; count : integer; setPresMinVar, βetPresMaxVar, pressOffSet : integer; inspirTopLimit, inspirBotLimit : real; setBreathRateVar : integer; setlnspirVar : real; BPMDesired : integer; ventBoardRdy : boolean; ventState : integer; {used to for the ventControl state parameter} ctrlState : integer; {used to for the systemControl state parameter} readyForSecond : bool; {used to send second ventControl command.} lastVentValue : integer; pumpReturn : integer; systemReturn : integer; powerState : integer; targPrDesired : integer; initDelayCounter : integer; ventSamplerCntr : integer; {initialized in module Lstat} captionForTheRecord : string; {my constants} const OFF - 0; const BREATHDISPLAYSIZE - 250; {200} const LEFTSIDE - 250; {pumpControl Events} const SUCPOWER - 1; const VENTPOWER - 2; {βystemCtrl States} const RDYWAIT - 1; const ONWAIT - 2; conat IMVWAIT - 3; const IMVMODE - 4; {ventControl States} conβt COMMANDSTATE - 0; conβt WAIT4RBSPONSB - 1; conβt RESPONSBRCVD - 2; conβt CMDNOTACCEPTBD - 3; {systemControl Event} conβt VENTINIT - 0; {ventCtrlWait Commands; 1st param these are going to John's function} alarm query } alarm reset } mode assist control } manual breath } mode inquire } mode: IMV } mode: On } mode: standby/charge } pressure maximum } pressure minimum } patient pressure } read breath rate } read inspiration time } reset ventilator } set breath rate } set inspiration time } nds; 1st param these are going to alarm query } alarm reset } mode assist control } manual breath } mode inquire } mode: IMV } mode: On } mode: standby/charge } pressure maximum } pressure minimum } patient pressure } read breath rate } read inspiration time } reset ventilator } set breath rate } set inspiration time } {ventCtrlWait responses when 1st parameter is ALQ } { when ALQ is firβt parameter the function returnβ aβ... 0: no alarm 1: minimum pressure not attained 2: maximum pressure exceeded 3: primary power loss 4 : battery low 5: valve fault 6: general hardware fault 7: inlet pressure lose } {return value error codes} { > zero or positive means succeββ > NORESP - -1 (not really an error? indicates still waiting for response > INVALIDVENTSTATE- -2 > VALUEOUTOFRANGB - -3 > VENTSBRTIMBOUT - -4 > VENTALQTIMEOUT - -5 > VENTALRTIMEOUT - -6 > VENTPMAXTIMEOUT - -7 > VENTPMINTIMEOUT - -8 > VENTPPTIIMEOUT - -9 > VENTSITTIMEOUT - -10 } implementation {$R *.DFM} uses Main, Dispspac, Repair, Comnunit, Neuro; type pointArray - array[1. -BREATHDISPLAYSIZE] of Tpoint; var breathDataArray : displayArray; {make this go away when I give up on drawBreathCurvβ} minVolDataArray : displayArray; {make this go away when I give up on drawBreathCurve} breathRateArray : pointArray; breathEraβeArray : pointArray; minVolArray : pointArray; minEraseArray : pointArray; i : integer; theScreen: TScreenControl; globalXvalue: integer; {all are global (to this form)} topCount, linesDown : integer; farRight, xPos : integer; dispSize, safeDispSize: integer; topLimit, bottomLimit : integer; presTopLi it, presBotLxmit, bpmTopLimit, bpmBotLimit : integer; eraseColor: TColor; event : integer; minVolValue : integer; peakCounter : integer; alfTstCntr : integer; valueFromVent : integer; βetlnβpirVarlntegβrized : integer; peakValArray : displayArray; msg : string; function βtartEtC02 : integer; far; external 'GUIIF'; function getFlow(var tidalVol : integer; var expVol : integer; var pPreas : integer) : integer; far; external 'GUIIF'; { in in in the return is function health } { the argument returnβ must be > 0 } function getCapnostat(var entC02 : integer; var rr : integer) : integer; far; external 'GUIIF'; { in in the return is function health } { the argument returns must be > 0 } function getPulβox(var avg02 : integer; var avgHR : integer; var StatusCode : integer) : integer; far; external 'GUIIF'; { in in in the return is function health } { return must be > 0 and then StatusCode must be - 0 } function tempSenseA(tempDevice : integer; var fromDLL : integer) : integer; far; external 'GUIIF'; { out in the return is function health } function systemControl(sysEvent : integer; var ctrlState : integer) : integer; far; external 'GUIIF'; { out in/out returns + values if OK (uselss)} {systemControl is like a one time initialization control.} function pumpControl(whichPump : integer; ctrlState : integer) : integer; far; external 'GUIIF'; { out in/out returns + values if OK (uselss)} {pumpControl is compressor or other motorized fluid thing.} function ventCtrlWait(commandName: integer; outvalue : integer) : integer; far; external 'GUIIF'; { out out returns the answer to the query (- values are errors)} {The reason for the word "wait" in the name of the function that controls and reads the ventilator is because this function actually takes up time so that it can return the answer. The answer always comes back by way of the function name. The second parameter is the value you want the ventilator to accept if the first value is a command. If the first value iβ not a command, it doesn't look at (or change) the second parameter.} procedure getAlarm(ventVal : integer) ; forward; procedure iOverBthing; forward; procedure reβet2gray; forward; procedure patientPres(ventVal : integer); forward; procedure drawBreathCurve(breathsPerMin : integer); { I don't think I call this anymore May96. draws the entire array of points with polyLinβ() and moves it left five pixels. It βtoreβ in RAM the last X minutes worth of data. } var realBreathsPerMin, breathsPerMinAverage : integer; reβetMinuteVol, resetBreathRate, minVolDataAverage, limit : integer; breathGraphOf set, breathGraphGain : integer; minVolGraphGain, minVolGraphOffset : integer; RRfloor, minVolfloor : integer; begin farRight :- 468; xPos :- farRight; eraβeColor :- clSilver; {topCount declared above and initialized to 1 at bottom} randomize; {LOADING THE BREATH RATE ARRAY one element per call to this procedure} breathGraphOffββt :- 0; {80} breathGraphGain :- 38; {38} RRfloor :- 170; breathDataArray[topCount+l] :- RRfloor - ( ( (BreathaPerMin * breathGraphGain) div 100) + breathGraphOffset) ; {LOADING THE MINUTE VOLUME ARRAY one element per call to this procedure Algorithm: breathrate times tidal volume. But since breathratβ is ten times too high and the 750 is too big by a factor of 1000, I have to divide by 1000*10} minVolGraphGain :- 20; {60,47,94} minVolGraphOffset :- 0; {260} minVolfloor :- 400; {368} m i n V o l V a l u e : - ( b r e a t h β P e r M i n * strToInt(VENTDETAIL.tidalVolLbl.Caption) ) div 1000; minVolDataArrayltopCount+1] :- minVolfloor - ( (minVolValue • minVolGraphGain) div 100) + minVolGraphO βct; {DRAWING THE ARRAY8 the entire polyline, each call} VENTDBTAIL.Canvaβ.Pen.Color :- βraβeColor; VBNTDBTAIL.Canvaβ.Pen. idth :- 1; VENTDETAIL.Canvan.PolyLine(breathBraeeλxray) ; VBNTDBTAIL.Canvaβ.PolyLinβ( inBraβeλ ray) ; if topCount-2 >- BREATHDISPLAYSIXB then limit :- BRBATHDISPLAYSIZB -1 elβe limit :- topCount -2; for i:- 0 to limit do begin breathBraββArray[BRBATHDI8PLAYSIΣB-i].X x- xPoβ-i; brβathEraββArray[BRBATHDISPLAYSIΣB-i ] . Y : - breathDataArray [ opCount-i ] ; breathRatβArray[BRBATBDISPLAYSIZB-i).X :- xPoβ-i; breathRatβArray[ BRKΛTHDISPLΛY8IΣB-i ] . Y : - breathDataArray [ topCount-i] ; minEraββArray[BRBATHDISPLΛYSIΣK-i] .X :- xPoβ-i; minEraββΛrray [ BREATHDISPLAYSI ΣB- i ) . Y : - minVolDataArray[ topCount-i] ; minVolArray[BREATHDISPLAYSIXB-i].X ι- xPoe-i; minVolArray [ BREATBDI S PLAYS I Z B- i ] . Y : - minVolDataArray [ topCount-i ] ; end; VENTDETAIL.Canvaβ.Pen.Color :- clGreen; VENTDETAIL.Canvas.Pen. idth :- 1; VENTDETAIL.Canvas.PolyLinβ(brβathRatβArray) ; VENTDETAIL.Canvas.PolyLine(minVolArray) ; {DISPLAYING CURRENT VALUES TO LABELS} VENTDETAIL.ventRBRlbl.Caption :- floatToStrF( (brβathβPerMin/10.0) , ffFixed,4,l) ; {ADVANCING THE DATA ARRAY INDEX (not the diβplay array)} breathsPerMinAvβrage :- 11; if topCount < 499 then begin {the 499 haβ to be one less than array size} topCount :- topCount + 1; end else begin {If 499 or more, then the entire array takes on an average value.} topCount :- 1; { minVolValue :■ breathβPβrMi nAvera g e * (βtrToInt(VENTDBTAIL.tidalVolLbl.Caption) ) div 1000; } { reβetMinutβVol : » round(xinVolValue * minVolGraphGain) + minVolGraphOffset; } { reβetBrβathRatβ :- brβathβPβrMinAvβragβ * breathGraphGain + breathGraphOffeet; } for i :- 1 to BRBATHDISPLAYSIZB do begin breathRateArray[i] .Y :- 100; { reββtBreathRatβ; } 10 minVolArray[i) .Y :- 300; { reββtMinutβVol; } breathBraseArray[i] .Y : ■ 100; { reββtBrβathRate; } minBraseArray[i].Y :- 300; { reββtMinutβVol; } end; end; end; {procedure drawBreathCurvβ} procedure TVENTDETAIL.BitBtn8Click(Sender: TObject); begin BtC02Bnabled :- Falββ; flowEnabled :- Falβe; pulβOxBnabled i- True; firβtBurβt :- True; {Thiβ iβ part of the way to make firβt polyline call βame color aβ background.} {It iβ βet to false AFTER each call to drawBurst. } VBNTDBTAIL.Viβiblβ :- Falββ; DiβplaySpace.Viβible :- True; if βuctionOnToggle - True then begin DiβplaySpace.LabellO.Caption :- 'ON'; DisplaySpace.BitBtnδ.Glyph.LoadFromFile( 'euctionl.bmp' ) ; end else begin DisplaySpace.LabellO.Caption :- 'OFF'; DiβplaySpacβ.BitBtn6.Glyph.LoadFromFile( 'βuction2.bmp' ) ; end; DiβplaySpace.pC02backgndShape.Viβible :- Falβe; DiβplaySpace.floShrtRcdLbl.Visible :- True; DiβplaySpace.floShrtRcdShape.Viβible :- True; DiβplaySpace.Labell4.Viβible :- True; DiβplaySpace.Labellδ.Viβible :- True; DiβplaySpace.oxSatTitleLbl.Viβible :- True; DiβplaySpace.Shapel.Viβible :- False; DiβplaySpace.Shape2.Viβible :- Falβe; DisplaySpace.Shapβ3.Viβible :- True; DiβplaySpace.oxScalelmage.Viβible :- True; DisplaySpace.shapeMeeβageSpace.Visible :- True; DiβplaySpace.Imagβl.Viβiblβ :- Falβe; DiβplaySpace.Imagβδ.Viβiblβ :- False; DisplaySpace.Labell7.Viβible :- False; DiβplaySpace.Labellδ.Viβiblβ :- Falβe; DiβplaySpace.Image2.Viβiblβ :- False; DiβplaySpacβ.BitBtnl.Viβiblβ :- Falββ; DiβplaySpacβ.Imagβ7.Viβible :- True; DiβplaySpace.Imagβ7h.Viβiblβ :- True; DiβplaySpace.ekgBtn.Viβiblβ :- True; 11 DisplaySpacβ.Visible :- True; DiβplaySpace.BitBtn2.Viβiblβ :- True; DiβplaySpace.BitBtn3.Viβiblβ :- True; DiβplaySpacβ.BitBtn4.Viβiblβ :- True; DiβplaySpace.timβlnMinutββLbl.Caption :- 'Time in Minutes'; {DisplaySpace.drawCurve;} DisplaySpace.Shape3.Height :- 313; {273} Application.processmesβagββ; drawHRCurve; end; procedure TVENTDETAIL.BitBtn9Click(Sender: TObject); begin VENTDETAIL.Viβiblβ :- Falβe; SystemGUI.Visible :- Falββ; MedicsGUI.Viβible :- Falβe; flowEnabled :- False; pulsOxEnabled :- False; EtC02Enabled :- True; firstBurst :- True; {This is part of the way to make firβt polyline call same color aβ background.} {It iβ βet to false AFTER each call to drawBurst. } diβplaySpace.pC02backgndShape.Viβible :- True; diβplaySpace.oxSatTitleLbl.Viβible :- False; diβplaySpace.floShrtRcdLbl.Visible :- True; diβplaySpace.floShrtRcdShape.Viβible :- True; {showAirwayGraph; } board :- CAPNOSTATBOARD; { board is a global var to tell timer which one to command. } if suctionOnToggle - True then begin DiaplaySpace.LabellO.Caption :- 'ON'; DisplaySpace.BitBtn6.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end begin DisplaySpace.LabellO.Caption :- 'OFF'; DisplaySpace.BitBtnδ.Glyph.LoadFromFile( 'suction2.bmp' ) ; end; DisplaySpace.Visible :- True; DisplaySpace.timelnMinutβsLbl.Caption :- 'TIME IN MINUTES'; DisplaySpace.Shapβl.Viβiblβ :■ Falββ; DisplaySpace.Shape3.Viβiblβ :- Falββ; DiβplaySpace.Imagβl.Viβiblβ :- Falββ; DisplaySpace.Imagββ.Visible :- False; DisplaySpace.Labell7.Viβible :- Falβe; 12 DiβplaySpace.Label16.Viβiblβ :- Falβe; DiβplaySpacβ.BitBtn2.Viβiblβ :- Falββ; DiβplaySpacβ.Label43.Viβible :- Falββ; DiβplaySpace.Labβl47.Viβiblβ :» Falββ; DiβplaySpace.hrBarBackgndShape.Viβible :- Falβe; DiβplaySpace.nowLbl.Viβible :- Falβe; DisplaySpace.hrBarLbl.Viβiblβ :- Falββ; DiβplaySpace.bβatβLbl.Viβiblβ :- Falβe; DiβplaySpace.Label32.Viβible :- Falβe; DiβplaySpace.Label46.Viβible :- Falββ; DisplaySpace.oxSatTitlβLbl.Viβiblβ :■ Falββ; DisplaySpace.oxScalβlmage.Viβiblβ :- Falβe; DisplaySpace.Imagβ7.Visible :- Falβe; DiβplaySpace.Imagβ7h.Viβiblβ :- Falβe; DiβplaySpace.Labell4.Viβiblβ :- Falββ; DiβplaySpace.Label15.Viβiblβ :- Falβe; DiβplaySpace.timβlnKinutββLbl.Caption :- 'Time in Minutes'; DisplaySpace.βhapeMesβagβSpace.Viβible :- True; DisplaySpace.Image2.Viβible :- True; DiβplaySpace.Shape2.Visible :- True; DiβplaySpace.BitBtnl.Viβible :- True; DisplaySpace.BitBtn3.Visible :- True; DisplaySpace.BitBtn4.Visible :- True; DisplaySpace.βkgBtn.Visible :- True; end; procedure TVENTDETAIL.BitBtn7Click(Sender: TObject); begin VENTDBTAIL.Visible :- False; SystemGUI.Viβible :- False; MedicsGUI.Visible :- False; EtC02Enabled :- False; flowEnabled :- False; pulsOxEnabled :- False; if suctionOnToggle - True then begin DisplaySpace.LabellO.Caption :- 'ON'; DisplaySpace.BitBtn6.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end else begin DisplaySpace.Label10.Caption :- 'OFF'; DiβplaySpace.BitBtn6.Glyph.LoadFromFile( 'βuction2.bmp' ) ; end; DiβplaySpace.Visible :- True; 13 DisplaySpace.timelnMinutβsLbl.Caption :- 'TIME IN MINUTES'; DiβplaySpace.pC02backgndShape.Viβiblβ :- Falβe; DisplaySpace.Shape2.Visible :- False; DisplaySpace.Shape3.Visible :- Falβe; DisplaySpace.BitBtn3.Visible :- False; DisplaySpace.Image2.Visible :- False; DisplaySpace.Label43.Visible :- Falβe; DisplaySpace.Label47.Visible :- Falβe; DisplaySpace.hrBarBackgndShape.Visible :« False; DiβplaySpace.nowLbl.Visible :- False; DiβplaySpace.hrBarLbl.Visible :- False; DisplaySpace.beatsLbl.Visible :- False; DisplaySpace.Label32.Visible :- False; DisplaySpace.Label46.Viβible :- False; DisplaySpace.oxSatTitleLbl.Visible :- False; DisplaySpace.oxScalelmage.Visible :- False; DiBplaySpace.Image7.Visible :- False; DisplaySpace.Imagβ7h.Visible :- False; DisplaySpace.Labell .Visible :- Falβe; DisplaySpace.Labβll5.Visible :- False; DisplaySpace.shapeMessageSpace.Viβible :- True; DisplaySpace.Imagel.Visible :- True; DisplaySpace.ImageB.Visible :- True; DisplaySpace.Labβll7.Visible :- True; DisplaySpace.Labell6.Visible :- True; DiβplaySpace.Shapel.Viβible :- True; DisplaySpace.BitBtnl.Visible :- True; DisplaySpace.BitBtn2.Visible :- True; DisplaySpace.BitBtn4.Visible :- True; DisplaySpace.ekgBtn.Visible :- True; Application.processmessageβ; drawTempCurve; end; procedure TVENTDETAIL.Image2Click(Sender: TObject); begin SystemGUI.Visible :- False; MedicsGUI.Visible :- True; VENTDETAIL.Visible :- False; end; procedure TVENTDETAIL.Shape2DragDrop(Sender, Source: TObject; X, Y: integer); begin SystemGUI.Visible :- False; MedicsGUI.Visible :- True; VENTDETAIL.Visible :- False; 14 end ; procedure TVENTDETAIL.BitBtnlOClick(Sender: TObject); begin if suctionOnToggle - True then begin suctionOnToggle :- False; Labell.Caption :- 'OFF'; BitBtnlO.Glyph.LoadFromFile( 'euction2.bmp' ) ; powerState :- OFF; if pumpControl(SUCPOWER, powerState) > 0 then messageDlg( 'The .dll hasn''t implemented thiβ yet.' ,mtlnformation, [mbOK], 0); end else begin suctionOnToggle := True; Labell .Caption :- 'ON'; BitBtnlO.Glyph.LoadFromFile( 'suctionl .bmp' ) ; powerState :- POWERON; if pumpControl(SUCPOWER, powerState) > 0 then messageDlg( 'The •dll hasn''t implemented this yet.' ,mtInformation, [mbOK], 0); end; end; procedure TVENTDETAIL.btnShutDownClick(Sender: TObject); {Calls John's pumpControl and systemControl when turning on. Calls only the pumpControl when turning off. Oh and enables and disables ventDataSampler (the vent data thing) } begin if ventOnToggle = True then begin ventOnToggle :- False; ventBoardRDY := ■ Falβe; {TURNING OFF COMPRESSOR} btnShutDown.Caption :- 'TURN ON VENTILATOR'; MedicsGUI.ventPowerBtn.Caption :- 'TURN ON'; powerState := OFF; pumpReturn :=■ pumpControl(VENTPOWER, powerState); if pumpReturn < 0 then messageDlg( 'Code pump98 hasn''t implemented this yet.' ,mtlnformation, [mbOK], 0); ventSamplerEnabled := False; {This (and the off-button in the main screen) are the only } end {turn-off of the static VentDisplay procedure} else begin ventOnToggle := True; {TURNING ON COMPRESSOR} btnShutDown.Caption :=* 'SHUT OFF VENTILATOR'; MedicsGUI.ventPowerBtn.Caption :** 'TURN OFF'; powerState : α 1; 15 pumpRetu n :- pumpControl (VENTPOWER, powerState); if pumpReturn < 0 then messageDlg( 'pumpControl hasn''t implemented this yet.' ,mtlnformation, [mbOK] , 0); ctrlState :- 1; systemReturn :- systemControl(VENTINIT,ctrlState) ; if systemReturn < 0 then messageDlg( 'systemControl hasn''t implemented this yet.' ,mtlnformation, [mbOK], 0); initDelay.Enabled :- True; {this calls systemControl again and again until IMVMODE state} end; { ventDataSampler.Enabled :- True;} {Never do this in this procedure. Not enough time for the init.} {Reset values from ventilator} end; procedure TVENTDETAIL.returnBtnClick(Sender: TObject); begin theScreen :- TScreenControl.Create; theScreen.TurnOnMedicsScreen; VENTDETAIL.Visible := False; end; procedure ventSa pler? { Static label displays of vent related values. It calls John's ventControl() function and displays: * alarms * patient pressure (and calculated peak) * breath rate * and it records two files: VENT SETTINGS AND VENTDATA ( Λ —this also has some Nova stuff) In this procedure I do not test for values less than 0.} var ventAlarmVal, ventPressVal : integer; vSettingβ : TextFile; begin randomize; iOverEthing; {This is the one I calculate. It displays from there. } {ALARMS} ventAlarmVal := ventCtrlWait(ALQ, 0); {0 to 7} getAlarm(ventAlarmVal) ; {My procedure for displaying the alarm state. } {PEAK AND PATIENT PRESSURE} ventPressVal :=■ ventCtrlWait(PP, 0); { 3-digit nu from -10 to 120} 16 { ventPressVal :- random(40) + 80; {ventVal has a range from 80 to 120} patientPres (ventPressVal) ; {diβplays and calculates peak pressure and displays that too.} { PREP THE FILE STUFF } {These tests are to see if the file existB. It's only a 3% hit on performance.} AssignFile(vSettings, 'C:\LSTATLOG\VENTSET.TXT') ; if FileExists( 'C:\LSTATLOG\VENTSET.TXT' ) then Append(vSettings) else Rewrite(vSettings) ; { OUTPUT vent settings TO FILE } if (ventSa plerCntr - 0) then Begin Writeln (vSettings, ") Writeln (vSettings, ") Writeln (vSettings, '') Writeln (vSettings, ' VENTILATOR "COMMANDS" SENT') ; Writeln (vSettings, '(This record only avail, when ventilator is on.) '); Writeln (vSettings, 'New Patient Begins: ' + DateToStr(Date) ) ; end; if (ventSamplerCntr mod 24 - 0) then begin Writeln (vSettings, ''); Writeln (vSettings, Tx eToStr(Time) ) ; Writeln (vSettings, ' —floBrd— '); Writeln (vSettings, ' Sensed Patnt calcd VENTILATOR SETTINGS Alarm'); Writeln (vSettings, ' Pres Pres I:E I:E pMax pMin b pDes InspT targPres mode Conditn')? end? Writeln(vSettings, + ' + intToStr(ventPressVal) + ' ' + intToStr(globalFlowMeanPress) + ' + intToStr(globalloverEratio) + ' ' + VENTDETAIL.numeratorLbl.Caption + ':' + VENTDETAIL.denominatorLbl.Caption + ' ' + VENTDETAIL.setPreaMaxLbl.Caption + ' ' + VENTDETAIL.setPresMinLbl.Caption + ' ' + VENTDETAIL.bpmDesiredLbl.Caption + ' + VENTDETAIL.inspirTi eLbl.Caption + ' + VENTDETAIL.targetPressLbl.Caption + ' ' + captionForTheRecord + ' ' + intToStr(ventAlarmVal) ) ; CloseFile(vSettings) ; ventSamplerCntr :- ventSamplerCntr + 1; end; procedure patientPres (ventVal : integer)? {CALCULATE PEAK PATIENT PRESSURE SINCE SOME INTERVAL.} var 17 peakVal : integer; isReady : integer; {peakCounter declared globally and initialized down below} ToVentValue, fromVentValue, anlnteger : integer; peaklnterval : integer; begin VENTDETAIL.patientPressLbl.Caption :- intToStr(ventVal) ; {from -10 to 120 cm } peakValArray[peakCounter] : » ventVal; peaklnterval : π 4; peakVal := 1; if peakCounter <« 4 then peaklnterval :=■ peakCounter else peaklnterval :- 4; for i := » peakCounter downto peakCounter - peaklnterval do begin if peakVal < peakValArrayfi] then begin peakVal :- peakValArray[i] ; end; end; if peakCounter < 500 then peakCounter :- peakCounter + 1 else peakCounter := 1; VENTDETAIL.peakPressLbl.Caption := intToStr(peakVal) ; end; procedure getAlarm(ventVal : integer) ; begin {VENTILATOR ALARMS ARE QUERIED HERE.} if ventVal > 0 then begin VENTDETAIL.ventWarnPnl.Visible :- True; case ventVal of 1 : begin reset2gray; VENTDETAIL.alqlRed.Brush.Color := clRed? end; 2 : begin reset2gray; VENTDETAIL.alq2Red.Brush.Color :=• clRed; end? 3 : begin reset2gray? VENTDETAIL.alq3Red.Brush.Color :=■ clRed; end? 4 : begin reset2gray; VENTDETAIL.alq4Red.Brush.Color :=■ clRed; end; 5 : begin reset2gray; VENTDETAIL.alq5Red.Brush.Color := clRed; end; 6 : begin reset2gray; VENTDETAIL.alqδRed.Brush.Color :=■ clRed; end; 7 : begin reset2gray; VENTDETAIL. lq7Red.Brush.Color := clRed; end; end; 18 end else VENTDETAIL.ventWarnPnl.Visible :- False; end; procedure iOverEthing; var IE_fraction, inTime, bRate : real; begin {It uses BPMdesired and inspirTi e labels which are (as of January 30 '96) determined by a setting of a label which is done via the real function call.) } bRate := strTofloat(VENTDETAIL.BPMdesiredLbl.Caption) ; inTime :- strTofloat(VENTDETAIL.inspirTimeLbl.Caption) ? if (inTime > 0.0) and (bRate > 0.0) then begin {so there's no divide by 0} IE_fraction :- inTime * bRate/60.0; if IE_fraction < 0.58 then begin VENTDETAIL.numeratorLbl.Caption :=» '1'; {answer.Caption :- floatToStr(IE_fraction) ; } VENTDETAIL . de n o in atorLbl . C ap t ion : = floatToStr(round(1.0/IE_fraction) ) ; end else begin if (IE_fraction > 0.58) and (IE_fraction < 0.71) then begin VENTDETAIL.numeratorLbl.Caption :- '2'; VENTDETAIL.denominatorLbl.Caption := '3'; end; (IE_fraction > 0.71) and (IE_fraction < 0.87) then begin VENTDETAIL.numeratorLbl.Caption := '3'? VENTDETAIL.denominatorLbl.Caption :«=■ '4'; end? if (IE_fraction > 0.87) then begin VENTDETAIL.numeratorLbl.Caption := '1'; VENTDETAIL.denominatorLbl.Caption :=> '0'; end; end; end else begin VENTDETAIL.numeratorLbl.Caption ' — ' VENTDETAIL.denominatorLbl.Caption :- '-'; end; end; procedure reset2gray? begin VENTDETAIL.alqlRed.Brush.Color := » clGray; VENTDETAIL.alq2Red.Brush.Color :*= clGray; VENTDETAIL.alq3Red.Brush.Color :- clGray; VENTDETAIL.alq4Red.Brush.Color := clGray; 19 VENTDETAIL.alq5Rβd.Brush.Color :- clGray; VENTD3TAIL.alq6Rβd.Brush.Color :- clGray; VENTDETAIL.alq7Red.Brush.Color :- clGray; end; procedure TVENTDETAIL.FormDestroy(Sender: TObject); begin theScreen.Free; end; procedure TVENTDETAIL.neuroBtnClick(Sender: TObject) ; begin neuroSurg.Visible :- True; end; procedure TVENTDETAIL.FormClick(Sender: TObject); begin {This is done because the left part of this form sticks through when the Neuro screen is up.} neuroSurg.Visible :- False; VENTDETAIL.Visible :- True; if suctionOnToggle = True then begin VENTDETAIL.Labell.Caption :- 'ON'; VENTDETAIL.BitBtnlO.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end end; procedure TVENTDETAIL.BitBtnl2Click(Sender: TObject); begin if setPresMinVar < setPresMaxVar - pressOffSet then begin setPresMinVar :- setPresMinVar + 1; valueFromVent := ventCtrlWait(PMIN, setPresMinVar); { valueFromVent :- setPresMinVar; { use this until the ventCtrl works} if valueFromVent < 0 then messageDlg( 'ventCtrlWait(PMINup, ) NG' ,mtlnformation, [mbOK], 0); setPresMinLbl.Caption :- IntToStr(setPresMinVar) ; end; end; procedure TVENTDETAIL.BitBtnl3Click(Sender: TObject); begin if setPresMinVar > PresBotLxmit then begin setPresMinVar :- setPresMinVar - 1; valueFromVent :- ventCtrlWait(PMIN, setPresMinVar); { valueFromVent := setPresMinVar; {use this until the ventCtrl works} if valueFromVent < 0 then messageDlg( 'ventCtrlWait(PMINdown, ) NG' ,mtlnformation, [mbOK], 0); 20 setPresMinLbl.Caption :- IntToStr(setPresMinVar) ; end? end; procedure TVENTDETAIL.BitBtn6Click(Sender: TObject); begin if setPresMaxVar < PresTopLimit then begin setPresMaxVar :- setPresMaxVar + 1; valueFromVent :- ventCtrlWait(PMAX, setPresMaxVar); { valueFromVent :- setPresMaxVar; {use this until the ventCtrl works} if valueFromVent < 0 then messageDlg( 'ventCtrlWait(PMAXup, ) NG' ,mtlnformation, [mbOK], 0); setPresMaxLbl.Caption :- IntToStr(setPresMaxVar) ; end; end; procedure TVENTDETAIL.BitBtnllClick(Sender: TObject); begin if setPresMaxVar > setPresMinVar + pressOffSet then begin {Note that PresBotLimit is used even for} setPresMaxVar : α setPresMaxVar - 1; {the setMax button a littler further down.} valueFromVent := ventCtrlWait(PMAX, setPresMaxVar); valueFromVent :■=■ setPresMaxVar; {use this until the ventCtrl works} if valueFromVent < 0 then messageDlg( 'ventCtrlWait(PMAXdown) NG' ,mtlnformation, [mbOK], 0); setPresMaxLbl.Caption := IntToStr( setPresMaxVar) ; end; end; procedure TVENTDETAIL.BitBtnl6Click(Sender: TObject) ; begin if setBreathRateVar < bpmTopLimit then begin setBreathRateVar := setBreathRateVar + 1; valueFromVent := ventCtrlWait(SBR, setBreathRateVar); { valueFromVent :- setBreathRateVar; {use this until the ventCtrlWait works} if valueFromVent < 0 then messageDlg( 'ventCtrlWait NG' ,mtlnformation, [mbOK], 0); bpinDesiredLbl.Caption := ■ intToStr( setBreathRateVar) ? MedicsGui.bpmLbl.Caption :- intToStr(valueFromVent) ; end; end; procedure TVENTDETAIL.BitBtnl7Click(Sender: TObject)? begin if setBreathRateVar > bpmBotLxmxt then begin setBreathRateVar :=» setBreathRateVar - 1? valueFromVent :- ventCtrlWait(SBR, setBreathRateVar)? { valueFromVent :=• setBreathRateVar? {use this until the ventCtrlWait works} 21 if valueFromVent < 0 then messageDlg( 'ventCtrlWait NG' ,mtlnformation, [mbOK], 0); bpmDesiredLbl.Caption :- intToStr(setBreathRateVar) ; MedicsGui.bpmLbl.Caption :- intToStr(valueFromVent) ; end; end; procedure TVENTDETAIL.BitBtnl4Click(Sender: TObject); begin if setlnspirVar < inspirTopLi it then begin setlnspirVar :- setlnspirVar + 0.1; setlnspirVarlntegerized :- round(setlnspirVar * 10); valueFromVent :> » ventCtrlWait(SIT, setlnspirVarlntegerized); { valueFromVent :- setlnspirVarlntegerized; {use this until the ventCtrlWait works} if valueFromVent < 0 then messageDlg( 'ventCtrlWait(SIT) NG' ,mtlnformation, [mbOK], 0); setlnspirVar := setlnspirVarlntegerized / 10; InspirTimeLbl.Caption :- floatToStrF(setlnspirVar, ffFixed,4 , 1) ; end; end; procedure TVENTDETAIL.BitBtnl5Click(Sender: TObject); begin if setlnspirVar > inspirBotLimit then begin setlnspirVar := setlnspirVar - 0.1? setlnspirVarlntegerized :»= round(setlnspirVar * 10)? valueFromVent := ventCtrlWait(SIT, setlnspirVarlntegerized); { valueFromVent := setlnspirVarlntegerized? {until the ventCtrlWait works} if valueFromVent < 0 then messageDlg( 'ventCtrlWait(SIT) NG' ,mtlnformation, [mbOK] , 0)? InspirTimeLbl.Caption := floatToStrF(setlnspirVar,ffFixed, , 1) ; end; end; procedure TVENTDETAIL.BitBtn5MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if moreBreathPnl.Visible = False then begin moreBreathPnl.Visible := True; BitBtn5.Glyph. oadFromFile ( 'vent.bmp' ) ; end else Begin moreBreathPnl.Visible :«=■ False; BitBtn5.Glyph.LoadFromFile( 'ventset.bmp' ) ; end ? end; var tim4Counter : integer; 22 procedure TVENTDETAIL.BitBtnlClick(Sender: TObject); begin targPrDesired :- targPrDesired + 1; targetPreβsLbl.Caption : « IntToStr(targPrDesired) ; end; procedure TVENTDETAIL.BitBtn2Click(Sender: TObject); begin targPrDesired :- targPrDesired - 1; targetPressLbl.Caption :- IntToStr(targPrDesired) ; end; procedure TVENTDETAIL.initDelayTimer(Sender: TObject); {On at first, but turns off by itself. But not with a time interval but after OK from call to vent) . It could come back several times to test if it's OK; that's why the need to be in a (once per second) timer control. To test if it's NOT OK, it callβ John's systemControl to see if its initialized yet. In addition it holds a screen over the buttons during this delay. } begin initDelayCounter := initDelayCounter - 1; selfTestCounterLbl.Caption :- intToStr(initDelayCounter) ; systemReturn := systemControl (VENTINIT,ctrlState) ; if systemReturn < 0 then messageDlg ( 'systemControl rtrnd a: '+ intToStr(systemReturn) ,mtlnformation, [mbOK], 0); if ctrlState - IMVMODE then begin {normal mode} initDelay.Enabled :- False; ventBoardRDY := True; end; if ventBoardRDY - False then begin selfTestPnl.Visible :- True; selfTestLbl.Visible :» True; end else begin selfTestPnl.Visible :- False; selfTestLbl.Visible :» False; initDelayCounter :- 18; ventSa plerEπabled :- True; { this is the one and only turn-on of the ventSa pler } end; end; procedure TVENTDETAIL . alarmResetBtnClick ( Sender : TObj ect ) ; var ventVal : integer; begin 23 ventVal :- ventCtrlWait(ALR, 0); VENTDETAIL.ventWarnPnl.Viβiblβ :- Falβe; end; procedure TVENTDETAIL.toGraphβBtnClick(8βndβr: TObject); begin moreBreathPnl.Viβible :- Falββ; BitBtnδ.Glyph.LoadFromFile( 'vβntββt.betp' ) ; end; procedure TVENTDETAIL.modeBtnClick(Sender: TObject); begin if modeBtn.Caption - 'GO TO ASSIST' then begin modeBtn.Caption :- 'GO TO FORCED'; captionForTheRecord :■ 'ASSIST'; ventCtrlWait(MAC, targPrDeβired) ; end else begin modeBtn.Caption :- 'GO TO ASSIST'; captionForTheRecord :- 'FORCED'; ventCtrlWait(MIMV, targPrDββired) ; end; end; procedure TVENTDETAIL.oxSatBackgndShapeMouββDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin EtC02Enabled :- False; flowEnabled :- Falβe; pulsOxEnabled :- True; firstBurst :- True; {This iβ part of the way to make first polyline call same color as background.} {It is βet to falβe AFTER each call to drawBurst. } VENTDETAIL.Visible :- False; DisplaySpace.Visible :- True; if suctionOnToggle - True then begin DisplaySpace.Label10.Caption :- ON'; DisplaySpace.BitBtn6.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end begin DisplaySpace.LabellO.Caption :- 'OFF'; DisplaySpace.BitBtn6.Glyph.LoadFromFile( 'euction2.bmp') ; end; DisplaySpace.timelnMinuteβLbl.Caption :- 'TIME'; 24 DiBplaySpace.pC02backgndShape.Viβible :- Falβe; Diβplay8pacβ.floShrtRcdLbl.Viβiblβ :- True; DisplaySpace.floShrtRcdShape.Viβiblβ :- True; DiβplaySpace.Labell4.Viβiblβ :- True; DiβplaySpacβ.Labell5.Viβiblβ :- True; DiβplaySpacβ.oxSatTitlβLbl.Viβiblβ :- True; DiβplaySpace.Shapβl.Viβible :- Falβe; DiβplaySpace.Shape2.Visible :- Falββ; DiβplaySpace.Shape3.Viβible :- True; DisplaySpace.oxScalβlmagβ.Viβiblβ :- True; DiβplaySpace.βhapeHeββageSpace.Viβible :- True; DiβplaySpace. magel.Viβible :- Falβe; DiβplaySpace.I agβθ.Viβible :- Falββ; DiβplaySpacβ. abel17.Viβible :» Falβe; DiβplaySpacβ. abel16.Viβiblβ :- Falββ; DiβplaySpace.Image2.Visible :- Falββ; DiβplaySpacβ.BitBtnl.Viβible :- Falβe; DiβplaySpacβ.hrBarBackgndShape.Viβible :- True; DiβplaySpace.nowLbl.Viβible :- True; DiβplaySpace.hrBarLbl.Viβiblβ :- True; DiβplaySpacβ.beatβLbl.Viβible :- True; DiβplaySpace.Label32.Viβible :- True; DiβplaySpacβ. abel46.Viβible :- True; DiβplaySpace.Image7.Visible :- True; DisplaySpace.Image7h.Visible :- True; DiβplaySpace.ekgBtn.Viβible :- True; DisplaySpace.Labβl43.Visible :- True; DisplaySpace.Label47.Visible :- True; DiβplaySpace.Viβible :- True; DiβplaySpace.BitBtn2.Viβible :- True; DisplaySpace.BitBtn3.Viβible :- True; DisplaySpace.BitBtn4.Visible :- True; {DisplaySpace.drawCurve;} DiβplaySpace.Shape3.Height :- 313; {273} Application.proceβsmeββages; drawHRCurve; end; procedure TVENTDETAIL.capRRbackgndShapeMouβeDown(Sende : TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin VBNTDBTAIL.Viβiblβ :- Falβe; SyβtemGUI.Viβible :- Falβe; MedicsGUI.Viβible :- Falβe; flowEnabled :- False; pulβOxEnabled :- Falβe; 25 EtC02Bnabled :- True; firβtBurβt :- True; {This iβ part of the way to make first polyline call same color as background.} {It is set to false AFTER each call to drawBurβt. } displaySpace.pC02backgndShape.Viβible :- True; displaySpace.oxSatTitleLbl.Visible :- Falβe; displaySpace.floShrtRcdLbl.Visible :- True; displaySpace.floShrtRcdShape.Visible :- True; {showAirwayGraph; } board :- CAPNOSTATBOARD; { board is a global var to tell timer which one to command. } if suctionOnToggle - True then begin DisplaySpace.LabellO.Caption :- , ON'; DiβplaySpace.BitBtn6.Glyph.LoadFromFile( 'suctionl.bmp' ) ; end else begin DisplaySpace.LabellO.Caption :- 'OFF'; DisplaySpace.BitBtn6.Glyph.LoadFromFile( 'suction2.bmp' ) ; end; DisplaySpace.Visible :- True; DisplaySpace.Shapel.Visible :- False; DisplaySpace.Shape3.Visible :- False; DisplaySpace.Imagel.Visible :- Falβe; DisplaySpace.Imageδ.Visible :- False; DisplaySpace.Labell7.Visible :- False; DisplaySpace.Labellδ.Visible :- False; DisplaySpace.BitBtn2.Visible :- False; DisplaySpace.oxSatTitleLbl.Visible :- False; DieplaySpace.oxScalelmage.Visible :— False; DisplaySpace.Image7.Visible :- False; DisplaySpace.Image7h.Visible :- False; DisplaySpace.Labell4.Visible :- False; DisplaySpace.Labell5.Visible :- False; DisplaySpace.timelnMinutesLbl.Caption :- 'Time in Minutes'; DisplaySpace.shapβMessagβSpacβ.Visible :- True; DisplaySpace.Image2.Visible :- True; DisplaySpace.Shape2.Visible :- True; DisplaySpace.BitBtnl.Visible :- True; DisplaySpace.BitBtn3.Visible :- True; DisplaySpace.BitBtn4.Visible :- True; DisplaySpace.ekgBtn.Visible :- True; end; 26 initialization linesDown :- 2; topCount :- 1; topLimit :- 29; bottomLimit :- 5; presTopLimit :- 80; presBotLimit :- 3; bpmTopLimit :- 99; bpmBotLimit :- 5; pressOffSet :- 5; inβpirTopLimit :- 2.9; inβpirBotLimit :- 0.2; peakCounter :- 1; 02Des'ired :- 3.0; targPrDesired :- 30; initDelayCounter :- 18; captionForTheRecord :- 'FORCED'; for i :- 1 to BREATHDISPLAYSIZE do begin breathDataArrayfi] :- 100; minVolDataArray[i] :- 300; breathRateArrayfi] .X :- LEFTSIDE; breathRateArrayfi] .Y :- 100; breathEraseArray[i] .X :- LEFTSIDE; breathEraseArrayfi] .Y :- 100; minVolArra i .X :- LEFTSIDE; for i :- 1 to 500 do pβakValArrayfi] :- 99; ventBoardRdy := False; slfTstCntr :» 1; peakCounter :- 1; ventState := 0; end. 27 PROGRAM LISTING COMM4.H /* comm4 . h Author : J. Brayton, T223/GB History : 10/10/95 Description : Serial communcation 10 module for COM4 board. Contents: */ // lifndef _C0MM4_DOT_H Idefine _COMM4_DOT_H linclude "comm4con.h" linclude <conio.h> linclude <time.h> linclude <iostream.h> linclude <math.h> linclude <string.h> linclude <stdlib.h> linclude <βtring.h> //Old stuff //V ΓVΓVVVVV ΓVVΛΓVVVVVVVVVVVVVVΛΓVVV //Define a type to hold the indices for all channel buffers. typedef struct Bfrlndxβ { int sob; //start of buffer int eob; //end of buffer int bfrlndx; //current buffer ptr (points to the next position available int offset; //offset into large buffer >; typedθf Bfrlndxs AllBfrIndxs[CHNLSPERBRD]; //One for each of the 4 channels static AllBfrlndxs com4BfrIndx[NUMOFCOM4BRDS] - //One for each of the two //C0M4 boards // {start of buffer, end of buffer, buffer index, offset} { {{0,0,0,0}, // \ {0,0,0,CHNLBFRSIZE}, // \ Com4 board 1 1 { 0 , 0 , 0 , CHNLBFRSIΣE *2 } , // / { 0 , 0 , 0 , CHHLBFRSIΣB* 3 } } , / / / {{0,0,0,0}, // \ {0,0,0,CHNLBFRSIZB}, // \ Com4 board 2 {0,0,0,CHNLBFRSIΣB*2}, // / {0,0,0,CHNLBFRSIΣB*3}} }; // / // where βtart of buffer - poβition to βtart reading data // end of buffer , - bfrlndx - 1 or last character received // buffer index - poβition where isr will place next char // offββt - channel offβet into buffer //Define a buffer for each channel //Note : Types are in iotypeβ.h static BrdBfr brdBfrβ[NUMOFCOM4BRDS] ; //large buffer to hold data //from all channels on com boards. static ChnlBfrs chnlBfre[NUMOFCOM4BRDS] ; //smaller channel buffers void * brdBfrPtrs[2][4] -{ {&brdBfrs[COM4BRDl] [com4BfrIndx[COM4BRDl] [CHNLl] .offset] , &brdBfrs[COM4BRDl] [com4BfrIndx[COM4BRDl] [CBNL2] .offset) , t,brdBfrs[COM4BRDl][com4BfrIndx[COM4BRDl] [CHNL3] .offset], &brdBfrs[C0M4BRDl] [com4BfrIndx[C0M4BRI)l] [CHNL4 ] .offset]}, {&brdBfrs[COM4BRD2] [com4BfrIndx[COM4BRD2] [CHNLl] .offset], _-brdBfrs[COM4BRD2][com4BfrIndx[COM4BRI)2][CHNL2].offβet], -.brdBfrs[COM4BRD2] [com4BfrIndx[COM4BRD2] [CHNL3] .offβet] , ..brdBfre[COM4BRD2] [com4BfrIndx[COM4BRD2] [CHNL4 ] .offset]}} ; //pointer to channel bufferβ // [board] [channel] void * chnlBfrPtrβ[2][4] - {{fcchnlBfrβ[C0M4BRDl] [0] , fcchnlBfre[C0M4BRD1] [1] , ichnlBfrs[COH4BRD1] [2] , ichnlBfre[C0M4BRD1] [3] } , {J-chnlBfre[COM4BRD2] [0] , JichnlBfre(COH4BRD2] [ 1] , tchnlBfrβ[COM4BRD2] [2] , tchnlB rs[COM4BRD2] [3] }} ; // int blchnlblksize[CHNL8PBRBRD] - {BRDlCHNLlBLKSIZB, BRD1CHNL2BLKSIZB, BRD1CHNL3BLKSIZB, BRD1CHNL4BLKSIZB}; int b2chnlblkβize[CHNLSPBRBRD] - {BRD2CHNL1BLKSIZB, BRD2CHNL2BLKSIZB, BRD2CHNL3BLKSIZB, BR 2CHNL4BLKSIZB} ; //Board One Buffers (doubled) unsigned char brdlchnllbfr[ OUBLE] [BRDlCHNLlBLKSIZB] ; //Ventilator £ 9600 unsigned char brdlchn!2bfr[DOUBLE] [BRD1CHNL2BLKSIZE] ; //Status Port 8 19200 unsigned char brdlchnl3bfr[DOUBLE] [BRD1CHNL3BLKSIZE] ; //Not Available unsigned char brdlchnl4bfr[DOUBLE] [BRD1CHNL4BLKSIZE] ; //Not Available //Board Two Buffers (doubled) unsigned char brd2chnllbfr[DOUBLE] [BRD2CHNL1BLKSIZE] ; //Flow e 19200 unsigned char brd2chnl2bfr[DOUBLE] [BRD2CHNL2BLKSIZE] ; //EtC02 t 9600 unsigned char brd2chnl3bfr[DOUBLE] [BRD2CHNL3BLKSIZE] ; //Spθ2 § 4800 unsigned char brd2chnl4bfr[DOUBLE] [BRD2CHNL4BLKSIZB] ; //Alternate Status Port //BOARD 1 // buffer Indx Last Savelndx TSta p BfrStuff blclcurBfrlnfo - {brdlchnllbfr[0] , 0, 0, 0, NULL}; BfrStuff blclflushBfrlnfo - {brdlchnllbfr[1] , 0, -1, 0, NULL}; BfrStuff blc2curBfrInfo - {brdlchnl2bfr[0] , 0, NULL}; BfrStuff blc2flushBfrInfo - {brdlchnl2bfr[1] , 0, NULL}; BfrStuff blc3curBfrInfo - {brdlchnl3bfr[0] , 0, NULL}; BfrStuff blc3flushBfrInfo - {brdlchnl3bfr[1] , 0, NULL}; BfrStuff blc4curBfrInfo - {brdlchnl4b r[0] , 0, 0, 0, NULL}? BfrStuff blc4flushBfrInfo - {brdlchnl4b r[1], 0, -1, 0, NULL}; //BOARD 2 // buffer Indx Last Savelndx TStamp BfrStuff b2clcurBfrInfo - {brd2chnllbfr[0] , 0, 0, 0, NULL} ; BfrStuff b2clflushBfrInfo - {brd2chnllb r[1J , 0, -1, 0, NULL}; BfrStuff b2c2curBfrInfo - {brd2chnl2bfr[0] , 0, NULL}; BfrStuff b2c2fluβhBfrInfo - {brd2chnl2bfr[1] , 0, NULL} ; BfrStuff b2c3curBfrInfo - {brd2chnl3bfr[0] , 0, NULL}; BfrStuff b2c3fluβhBfrInfo - {brd2chnl3bfr[1] , 0, NULL}; BfrStuff b2c4curBfrInfo - {brd2chnl4bfr[0] , 0, NULL} ; BfrStuff b2c4flushBfrInfo - {brd2chnl4bfr[1] , 0, NULL} ; /♦WAS ChnlBlks brdlBlks {brdlchnllbfr[0], brdlchnllbfr[l], NULL, 0, "c:WVENT.DAT", 0, BRD1CHNL1BLKSIZE}, {brdlchnl2bfr[0], brdlchnl2bfr[l], NULL, 0, "c:\\LOG.DAT", 0, BRD1CHNL2BLKSIZE}, {brdlchnl3bfr[0] brdlchnl3bfr[l], NULL, 0, "c:\\BRD1CHN3.DAT", 0, BRD1CHNL3BLKSIZE} {brdlchnl4bfr[0], brdlchnl4bfr[l], NULL, 0, "c:\\BRDlCHN4 DAT", 0, BRD1CHNL4BLKSIZE} >? */ //BOARD 1 ChnlBlks brdlBlks { SblclcurBfrlnfo, &blclflushBfrInfo, NULL, "c : \\LSTATLOG\\VENT DAT BRDlCHNLlBLKSIZB} , { &blc2curBfrInfo, &blc2flushBfrlnfo, NULL, c: \\LSTATLOGWLOG. DAT BRD1CHNL2BLKSIZB}, iblc3curBfrInfo, Jiblc3fluβhBfrInfo, NULL, "c: WLSTATLOGWBRD1CHN3. DAT 1 BRD1CHNL3BLKSIZB} , tblc4curBfrInfo, iiblc4fluβhBfrInfo, NULL, "c: \\LSTATL0G\\BRD1CHN4. DAT BRD1CHNL4BLKSIZE}} ; //BOARD 2 ChnlBlks brd2Blkβ - { { Sb2clcurBfrInfo, ib2clf lushBf rlnf o, NULL, "c : \ \LSTATLOG\ \FLOW.DAT BRD2CHNL1BLKSIZE} , &b2c2curBf rlnfo, &b2c2f lushBf rlnf o, NULL, " c : \\ STATLOGWCAPHO.DAT BRD2CHNL2BLKSIZE}, { &b2c3curBfrInfo, ib2c3f lushBf r Info, NULL, "c : WLSTATLOGW PULSOX . DAT BRD2CHNL3BLKSIZE}, J<b2c4curBfrInfo, &b2c4f lushBf rlnf o, NULL, "c: \\LSTATLOG\\BRD2CHN . DAT 1 BRD2CHNL4BLKSIZE}}; /*Was ChnlBlks brd2Blks {brd2chnllbfr[ 0], brd2chnllbfr[l], NULL, 0, "c:\\FLOW.DAT", 0, BRD2CHNL1BLKSIZE}, {brd2chnl2bfr[0], brd2chnl2bfr[l], NULL, 0, "c:\\ETC02.DAT", 0, BRD2CHNL2BLKSIZE} , {brd2chnl3bfr[0], brd2chnl3bfr[l], NULL, 0, "c:\\SP02.DAT", 0, BRD2CHNL3BLKSIZE}, {brd2chnl4bfr[0], brd2chnl4bfr[l], NULL, 0, "BRD2CHN4.DAT", 0, BRD2CHNL4BLKSIZE} } /*Was ChnlBlks brd2Blks - { { {brd2chnllbfr[0] , 0, 0, 0}, {brd2chnllbfr[l], 0, -1, 0}, NULL, "c:\\FLOW.DAT", BRDlCHNLlBLKSIZE} , { {brd2chnl2bfr[0], 0, 0, 0}, {brd2chnl2bfr[l], 0, -1, 0}, NULL, "c:\\ETC02.DAT", BRD1CHNL2BLKSIZE} , { {brd2chnl3bfr[0], 0, 0, 0}, {brd2chnl3bfr[l], 0, -1, 0}, NULL, "c:\\SP02.DAT", BRD1CHNL3BLKSIZE}, { {brd2chnl4bfr[0], 0, 0, 0}, {brd2chnl4bfr[l], 0, -1, 0}, NULL, "BRD2CHN4.DAT", BRD1CHNL4BLKSIZE}}; */ //Probably not needed. //ChnlBlks * brdlBlksPtr - ibrdlBlkβ; //ChnlBlks * brd2BlksPtr - -.brd2Blks; //Some test strings. Iifdef ENABLE_AUDIBLE_ERROR char statusMsgf100] ; char tempstring[ 10] ; // ,„ „.. .„..-. „ -. /* comm4 : :isrlog Description : Write message to console from ISR, hopefully. Similar to sβndCommand function. Returns */ //* // void isrlo (int brd, int chnl, char * cmd, int length-0) { Boolean ready - TRUE; int lngth, base; clock_t timel; if (length « 0) lngth - strlen(cmd); lngth - length; if (brd-1 — 0) base - COM4BlCHNLS[chnl-l] ; else //Hopefully, the other board. base - COM4B2CHNLS[chnl-l]; for (int i - 0; i < lngth; i++) { TRUE ( Iendif ENABLE AUDIBLE ERROR /* rcvCom4BrdlINTRPT (double buffered using single partitioned buffer) Description : Interrupt service routine for receipt of charactera on 16550 UARTS on COM4 board 1. This routine assumes interrupt sharing and will exit only when no more interrupts are pending. NOTE: This ISR will eventually be replace by the one just above as soon I as I can get around to changing the ventilator buffering scheme. I But for now, since ventilator bandwidth is low (and things seem I to be working) , this will have to wait until I get everything else J working. Note that the ISR handling the Novametrix boards are using the new buffering scheme with success. Returns : N/A */ / / ■ // /* void rcvCom Brd1INTRPT(void * buf) { Boolean morelnta - TRUE; //Set to FALSE when there are no more interrupts. int Isr; int intid; char cinput; unβigned int base; int index; //Reading the interrupt ID register to determine channel //requesting service is preferred. But for now, let's just //loop through all channels until no more data is read and //no interrupt is pending. //Check channels 1-4 for data while (morelnts) { morelnts - FALSE; //This will be set to true if at least one channel //has data in the receive holding register. for (int i-0; i < 4; i++) { base - COM4BlCHNLS[i]; //Dandy.astound - Take this switch out. It should not be needed. //It doesn't appear that base gets set correctly in the above //statement. This switch should be removed once ISR is verified //to be working. But for now, the switch will explicitly set //the base. Why the above statement doesn't appear to work is //a real mystery. When checked out in the debugger, when i-0, //base is set to some mystery value. As i is incremented, base //is set TO COM4B2CHNLS[i-l] . Further investigation is //required. //switch (i) { // case 0 base - 0X3E8; break; // case 1 base - 0X2E8; break; // case 2 base =» 0X3A8; break; 8 // caβe 3 : base - 0X2A8; break; // default : base - 0X3E8; //} //First read LSR Isr - inp(base+5); //while there iβ data to be read while ((Isr k 0x01) — 1) { index - com4BfrIndx[COM4BRDl][i] .bfrlndx + com4BfrIndx[COM4BRDl][i].offset; //Place data in board buffer. ((char *)buf) [index] - inp(base); //Update bfrlndx to point to next available position //com4BfrIndx[COM4BRDl] [i] .bfrlndx - // fmod(++(com4BfrIndx[COM4BRDl] [i] .bfrlndx) , // CHNLBFRSIZE) ; co 4BfrIndx[COM4BRDl] [i] .bfrlndx - ++(com4BfrIndx[COM4BRDl] [i] .bfrlndx) %CHNLBFRSIZE; //Read the LSR to advance to next char. This doesn't really //make sense, but it seems to work and be necessary to //get next character. Otherwise the same character is //read over and over. //dandy.asound - may want to take this out when all is it still works. //Loop through all channels again when at least one channel //required servicing. That is, we will exit this ISR //only when we have looped through all channels sequentially //and found all receive holding buffers empty, morelnts - TRUE; > } //read ISR to determine if interrupts are pending //This works in dos, but has problems under Windows, //if (inp(base+2) « 1) morelnts - FALSE; //Try reading the IID for windows version I lit {((intid - inp(COM4IWTID) ) i. OxOF) — 0) morelnts - FALSE; //read the interrupt ID rβgiβtβr //intid - inp(COM4IHTID); > return; > */ /* rcvCoa4BrdlINTRPT (double buffering using two buffers-using old data βtructr) Description : Interrupt service routine for receipt of characterβ on 16550 UARTS on COM4 board 1. Thiβ routine assumes interrupt sharing and will exit only when no more interrupts are pending. Returnβ : N/A */ // /* void rcvCom4Brd1INTRPT(void * buf) { //Wβ need to modify contentβ of a block in buf, βo use pointer variable. static ChnlBlks * localBlkβ; Boolean morelntβ - TRUE; //Set to FALSE when there are no more interrupts. int Isr; int intid; char cinput; unsigned int base; int index; //Reading the interrupt ID rβgiβter to determine channel //requesting service iβ preferred. But for now, let's just //loop through all channelβ until no more data is read and //no interrupt iβ pending. //Check channβlβ 1-4 for data while (morelntβ) { 10 morelnto - FALSE; . //Thiβ will be βet to true if at least one channel //has data in the receive holding register. for (int i-0; i < CHNLSPERBRD; i++) { localBlks - (ChnlBlks *)buf; baβe - C0M4BlCHNLS[i]; //First read LSR //while there is data to be read while ((Isr & 0x01) — 1) { //Get byte using info in buffer passed to ISR. •( (*localBlkβ) [i] .curBfr+(*localBlks ) [i] .bfrlndx) inp(base) ; //Update bfrlndx to point to next available position index - ( *localBlks) [ i ] . bfrlndx ( (*localBlkβ) [i] .bfrlndx + 1)% (•localBlks) [i] .block≤ize; if (index — 0) { //Swap buffers //dandy.astound //The following beep will indicate when we have possibly lost //data. The reader should have set temp buffer to null to //indicate flush buffer has been processed. This should //come out when things are working properly. This bell //will probably cause severe problems down the line and //βyβte crash iβ likely. // ifdef ISR_DEBUG_ENABLED if ( (*localBlkβ) [i].tempBfr 1- NULL) { i i/i/it nit nit it/iiiiiiiititinii/ttmtiiiii/im char bell - 0x07; cout « bell « endl; ! ! 111111 i 1111111 ! 111111111 !! 11111111 / 11 H 111111 ! 111 //Build βtatuβ string... strcpy(βtatuβMβg, "Data loss: board 1, channel 1 1 strncat(etatuβMβg,itoa(i+l,tβmpβtring, 10) ,5) ; strncat(βtatuβMβg, "\n\r",5) ; isrlog(STA BRD,STATCHNL,statusMsg) ; } Iendif ISR_DBBUG_BNABLED (♦localBlks) [i] .tempBfr - {*localBlks) [i] .curBfr; ( ♦ localBlks) [i] .curBfr - { ♦ localBlks) [i] . flushBfr; ( ♦ localBlks) [i] .fluβhBfr - ( ♦ localBlkβ) [i] .tempBfr; } //Read the LSR to advance to next char. This doesn't really //make sense, but it seems to work and be necessary to //get next character. Otherwise the same character iβ //read over and over. //dandy.asound - may want to take thiβ out when all is //working and see if it still workβ. Isr - inp(base+5)? //Loop through all channels again when at least one channel //required βervicing. That is, we will exit this ISR //only when we have looped through all channelβ sequentially //and found all receive holding buffers empty, morelntβ - TRUE? } } > return; ♦ / / ♦ rcvCom BrdlINTRPT Description t Interrupt lervioo routine for receipt of αherβαtβre on 16550 UART8 on COM4 board 1. Thiβ routine aββumeβ interrupt βharing and will exit only when no more interrupts are pending. Returns : N/A ♦ / 11- 12 // void rcvCom Brd1INTRPT(void ♦ buf) { //WΘ need to modify contents of a block in buf, βo use pointer variable. static ChnlBlks * localBlks; Boolean morelnts - TRUE; //Set to FALSE when there are no more interrupts. base; //Reading the interrupt ID rβgiβtβr to determine channel //requesting service is preferred. But for now, let's just //loop through all channels until no more data is read and //no interrupt is pending. //Check channelβ 1-4 for data while (morelnts) { morelntβ - FALSE; //Thiβ will be βet to true if at leapt one channel //has data in the receive holding register. for (int i-0; i < CHNLSPERBRD; i++) { localBlks - (ChnlBlks ♦ Jbuf; base - C0M BlCHNLS[i]; //First read LSR Isr - inp(base+5); //while there is data to be read while ((lβr & 0x01) — 1) { //Get byte using info in buffer passed to ISR. ♦( (♦localBlks) [i] .curBfrlnfo->bfr+( ♦ localBlkβ) [i] . curBfrlnfo->b rlnd ) //Update bfrlndx to point to next available position index - ( ♦ localBlks) [i] .curBfrlnfo->bfrIndx - ( ( ♦ localBlks) [i] .curBfrln o->bfrIndx + l)%(nocalBlks) [i].blockSize; if (index — 0) { //Swap buffers //dandy.astound 13 //Thβ following beep will indicate when we have possibly lost //data. The reader should have set temp buffer to null to //indicate flush buffer haβ been processed. This should //come out when things are working properly. This bell //will probably cause severe problems down the line and //system crash iβ likely. // ifdef ISR_DEBUG_ENABLED if ( ( ♦ localBlks) [i] .tempBfr i- NULL) { /////////////////////////////////////////////////// char bell - 0x07; cout « bell << endl; /////////////////////////////////////////////////// //Build status βtring... strcpy(statuβMsg, "Data loss: board 1, channel " ) ; strncat(statusMβg,itoa(i+l,tempstring, 10) ,5) ; strncat(βtatusMβg, "\n\r",5) ; isrlog(STATBRD,STATCHNL,statusMsg) ; } endif ISR_DEBUG_ENABLED ( ♦ 1 oc a 1 B 1 k β ) [ i ] . t empB f r I n f o ( ♦ localBlks) [i] .curBfrlnfo; ( ♦ l oc al B l k s ) [ i ] . c u rB f r l n f o -(♦localBlks) [i] . f lushBf rlnf o; ( ♦localBlks ) ( i] . f lushBf rln o (♦localBlks) [i] . tempBfrlnf o; } //Read the LSR to advance to next char. This doesn't really //make sense, but it seems to work and be necessary to //get next character. Otherwise the same character is //read over and over. //dandy.asound - may want to take this out when all is //working and see if it still works. Isr - inp(base+5); //Loop through all channels again when at least one channel //required servicing. That is, we will exit this ISR 14 //only when we have looped through all channels sequentially //and found all receive holding buffers empty. morelnts - TRUE; } return; } It- /♦ rcvCom4Brd2INTRPT Description : Interrupt service routine for receipt of characters on 16550 UARTS on COM4 board 2. This routine assumes interrupt sharing and will exit only when no more interrupts are pending. Returns N/A ♦ / ti¬ ll void rcvCom4Brd2INTRPT(void ♦ buf) { //We need to modify contents of a block in buf, so use pointer variable. static ChnlBlks ♦ localBlks; Boolean morelnts - TRUE; //Set to FALSE when there are no more interrupts . int Isr; int intid; char cinput; unsigned int base; int index; //Reading the interrupt ID register to determine channel //requesting service is preferred. But for now, let's just //loop through all channels until no more data is read and //no interrupt is pending. //Check channels 1-4 for data while (morelnts) { morelnts = FALSE; //This will be set to true if at least one channel 15 //haβ data in the receive holding register. for (int i-0; i < CHNLSPERBRD; i++) { localBlkβ - (ChnlBlks ♦ )buf; baβe - COM B2CHNLS[i]; //First read LSR Isr - inp(base+5); //while there is data to be read while ((Isr & 0x01) « 1) { //Get byte using info in buffer passed to ISR. ♦ ( ( ♦ localBlks) [i] .curBfrlnfo->bfr+ ( ♦ localBlks) [i] . curBfrlnfo->bfrlndx) - inp(base) ; //Update bfrlndx to point to next available position index - ( ♦ localBlks) [i] .curBf lnfo->bfrlndx = ( (♦localBlks) [i] .curBfrlnfo->bfrlndx + l)%(*localBlks) [i] .blockSize; if (index « 0) { //Swap buffers //dandy.astound //The following beep will indicate when we have possibly lost //data. The reader βhould have set temp buffer to null to //indicate flush buffer has been processed. This should //come out when things are working properly. This bell //will probably cause severe problems down the line and //system crash is likely. // Iifdef ISR_DEBUG_ENABLED if ( (♦localBlks) [i] .tempBfr 1- NULL) { I//I I//////I /// /I//I III III I///III/ III I/II/II I char bell - 0x07; cout << bell << endl; II/ II/I//II II//I II I//II III/II III //Build status string... strcpy(statusMsg, "Data loss: board 2, channel "); strncat(statusMsg,itoa(i+l,tempstring, 10 ) , 5 ) ; strncat(statusMsg, "\n\r" ,5) ? 16 isrlog(STATBRD,STATCHNL, statusMβq) ; } lendif ISR DEBUG ENABLED ( ♦ localBlks ) [ i ] . tempBf rInf o ( ♦ localBlks) [i] .curBfrlnfo; ( ♦ l oc a l B l k s ) [ i ] . c u r B f r l n f o -( ♦ localBlks) [i] . f lushBfrlnf o; ( ♦localBlks ) [ i ] . f lushBf rlnf o ( ♦ localBlks) [i] . tempBfr Inf o; } //Read the LSR to advance to next char. This doesn't really //make sense, but it seems to work and be necessary to //get next character. Otherwise the same character is //read over and over. //dandy.asound - may want to take this out when all is //working and see if it still works. Isr - inp(base+5); //Loop through all channels again when at least one channel //required servicing. That is, we will exit this ISR //only when we have looped through all channels sequentially //and found all receive holding buffers empty, morelnts = TRUE; } } } return; /* Boolean morelnts = TRUE; //Set to FALSE when there are no more interrupts. int Isr; int intid; char cinput; unsigned int base; 17 int index ; //Reading the interrupt ID register to determine channel //requesting service is preferred. But for now, let's just //loop through all channels until no more data is read and //no interrupt is pending. //Check channels 1-4 for data while (morelnts) { morelnts = FALSE; //This will be set to true if at least one channel //has data in the receive holding register. for (int i=0; i < 4; i++) { base =* COM4B2CHNLS[i] ; //First read LSR Isr = inp(base+5); //while there is data to be read while ((Isr & 0x01) == 1) { index = com4Bfrlndx[COM4BRD2 ][i] .bfrlndx + com4Bfrlndx[COM4BRD2] [i] .offset; //Place data in board buffer, ((char * )bu ) [index] = inp(base)? //Update bfrlndx to point to the next available position. //com4BfrIndx[COM4BRD2] [i] .bfrlndx - // fmod(++(com4BfrIndx[COM4BRD2] [i] .bfrlndx) , // CHNLBFRSIZE) ; com4BfrIndx[COM4BRD2] [i] .bfrlndx - ++(com4BfrIndx[COM4BRD2] [i] .bfrlndx) %CHNLBFRSIZE; //Read the LSR to advance to next char. This doesn't really //make sense, but it seems to work and be necessary to //get next character. Otherwise the same character is //read over and over. //dandy.asound - may want to take this out when all is //working and see if it still works. Isr = inp(base+5); //Loop through all channels again when at least one channel //required servicing. That is, we will exit this ISR 18 //only when we have looped through all channels sequentially //and found all receive holding buffers empty, morelnts - TRUE; } > //read ISR to determine if interrupts are pending //This works in dos, but has problems under Windows, //if (inp(base+2) -- 1) morelntβ - FALSE; //Try reading the IID for windows version //if (((intid - inp(COM4INTID) ) i, OxOF) — 0) morelnts - FALSE; //read the interrupt ID register //intid - inp(COM4INTID) ; } return; */ } //Define an ISR type which will handle receipt of character typedef void ( *handler) (void ♦ ); //Declare function pointer to point to ISR. handler rcvcharbrdllSR - rcvCom4BrdlINTRPT; handler rcvcharbrd2ISR - rcvCom4Brd2lNTRPT; //define a test buffer and initialize to 0 //static char buffer - 0; class comm4 { Chnladdr base; //The base address of each port ChnlConfig cnfig[4]; //Board configuration unsigned char calcChksm(unsigned char ♦ cmd, int length-0) ; void sendCommand(int brd, int chnl, char ♦ cmd, int length-0); int sendCmdToVent(const char ♦ cmd, const int cmdlen - 0); public: comm4 (const unsigned int ♦ bases, const ChnlConfig ♦ config); //Hopefully, getChnlData will be going away when everything is //converted to double buffering using two buffers instead of //double buffer using a single partioned buffer, (dandy.astound) ChnlBfr ♦ getChnlData(int board, int chnl, int tbfrSize) ; void intrnlReset(int board, int channel); 19 int cmdVβnt ( ventCmd ) ; //Ventilator related com andβ int cmdALQ( ) ; int cmdALRO ; int cmdMAC(char ♦ nn) ; int cmdMB() ; int cmdMI( ) ; int cmdMIMVO ; int cmdMOO ; int cmdMSCO; int cmdPMAX(char ♦ nn) ; int cmdPMIN(char ♦ nn) ; int cmdPP{ ) ; int cmdRBR( ) ; int cmdRITO; int cmdRSTO ; int cmdSBR(char *br) ; int cmdSIT(char ♦ndotn) ; //Capnostat related commands int cmdC02(unsigned char *cmd, int length); //General call to command EtC02 int cmdC02swrev( ) ; int cmdC02cont( ) ; //Flow Board related commands int cmdFLOWswrev( ) ; int cmdFLOWwfdata() ; int cmdFLOWwfstop( ) ; //Blood Pressure board related commands int bpcmdRBSlO; int bpcmdSTRIMEDO ; char readChar(); void _far srvcINTRPT( ) ; int rβadISR( ) ; int rβadLSR( ) ; int readRHR( ) ; int readIER( ) ; int writeStatuβ(char *); }; //comm4 20 / / -, — ... —. .._. »-_ «-«™»™„ / * comm : : comm4 Description : Constructor for comm4 Returns N/A */ II- II comm4 : :comm4 (const unsigned int * bases, const ChnlConfig * config) { 1 0 //Initialize base and configuration variables for (int i - 0; i < 4; i++) { basefi] = *(bases+i); cnfi.g[i] .baud - (config+i) ->baud; cn igfi] .parity •= (config+i) ->parity; cnfig[i] .data = (config+i)->data; cnfig[i) . stop - (config+i) ->stop; 15 } for (i => 0; i < 4; i++) { //Set bit 7 of LCR to enable divisor latch to set baud rate outp(base[i]+3,0x80) ; //Enable divisor latch outp(base[i] ,cnfig[i] .baud) ; //Low byte divisor outp(base[i]+l,0X00) ; //High byte is 0 20 //Set LCR (DLL enable, set break,set parit ,even,parity enable, stop bits, // word length bit 1, word length bit2) int mask = cn ig[i] .parity |cnfig[i] .dataJcnfig[i] . stop; outp(base[i]+3,mask) ; ? c . //Set MCR (RTS,DTR to high*) outp(base[i]+4,0X0B) ; //Set IER out (base[i]+l,0X01) ; //dandy.astound - taken out to prevent checkirq mystery //Set FCR 30 //outp(C0M4CHNLl+2,0x07) ; //Set FCR //outp(base[i]+2,0x01) ; outp(base[i]+2,0x07) ; //outp(base[i]+2,0x00) ; //EtC02 board commands 35 21 // // //Continuous Waveform Mode (3.3.1) C02cont[0] = 0x80; //command C02cont[l] - 0x02; //data rate byte C02cont[2] - calcChksm(C02cont,C02CONTLNGTH-l) ; //Data Request Mode (no waveform) (3.3.3) CO2dataReqNWF[0] - 0x88; //command C02dataReqNWF[l] - 0x00; //retrieve one data set C02dataReqNWF[2] - calcChksm(C02dataReqNWF,C02DRNWFLNGTH-1 ) ; // //Set ETC02 Time Period (3.3.4) CO2setTimePer[0] = 0x89; //command C02setTimePer[l] = 0x01; 111 breath C02setTimePer[2] = 0x08; C 0 2 s e t T i m e P e r [ 3 ] calcChksm(C02setTimePer,C02SETTIMEPERLNGTH-l) ; // //Get ETC02 Time Period (3.3.5) CO2getTimePer[0] =• 0x8a; //command C 0 2 g e t T i m e P e r [ l ] calcChksm(C02getTimePer,C02GETTIMEPERLNGTH-l) ; // //Set Respriation Rate Editor (3.3.6) C02setRReditor[0] - 0x8b; C02setRReditor[l] D 0; C02setRReditor [ 2 ] = calcChks ( C02 s e tRRedi t or , C02SETRREDIT0RLNGTH-1) ; // //Get Respiration Rate Editor (3.3.7) CO2getRReditor[0] » 0x8c; C02getRReditor [ 1 ] = calcChksm ( C02 getRRedi or , C02GETRREDIT0RLNGTH-1) ; // //Set Compensation Values (3.3.8) C02setCompVal[0] = 0x8d; C02setCompVal[l] » 0; C02setCompVal[2] = 0; C02setCompVal[3] - 0; C02setCompVal[4] « 0; C02 se tCompVal [ 5 ] - c alcChksm ( C02 s e t Comp Va 1 C02ΞETCOMPVALLNGTH-1) ; // 11 Get Compensation Values (3.3.9) CO2setCompVal[0] - 0x8e; C02 se tCompVal [ 1 ] - c 1 cC h s ( C 02 s e t C omp Va 1 CO2GETC0MPVALLNGTH-1) ; // //Stop Continuous Mode (3.3.10) CO2stop[0] =■ 0x8f; C02stop[l] = calcChksm(C02stop, C02ST0PLNGTH-1 ) ; 22 // //Get Complete Status (3.3.11) CO2getStatus[0] - 0x90; C02getStatus[l] - calcChksm(C02getStatus, C02GETSTATUS) ; // //Reset Monitor Parameters to Factory Defaults CO2reset[0] - 0x91; C02reset[l] - calcChksm(C02reβet, C02RESETLNGTH) ; // //Get Sensor Serial Number (3.3.12) CO2senSerial[0] - 0x92; C02 s enSer ial [ 1 ] - c a 1 c C hk s ( C 02 s e nS e r i a 1 , C02SENSERIALLNGTH-1) ; // //Get Software Revision (3.3..14) CO2swrev[0] - 0x93; //command C02swrev[l] - calcChksm(C02βwrev,C02SWREVLNGTH-1) ; // //Get Self Test Results (3.3.15) CO2test[0] - 0x94; //command C02test[l] - calcChksm(C02test,C02TESTLNGTH-l) ; // //Set No Respriation Timer (3.3.16) C02setNoResTmr[0] - 0x9c; C02setNoResTmr[l] - 60; C02setNoResTmr [ 2 ] - calcChksm ( C02 se tNoRe sTmr , C02SETN0RESTMRLNGTH-1) ; // //Get No Respriation Timer (3.3.17) C02getNoResTmr[0] - 0x9d; C02getNoResTmr [ 1 ] - calcChksm ( C02 getNoRe sTmr , C02GETN0RESTMRLNGTH-1) ; // //Start Cell Zero CO2strtCell0[0) - 0xa4 ; C02 s trtCe 110 [ 1 ] - c a 1 c C h s ( C 02 s t r t C e 110 , CO2STRTCELL0LNGTH-1) ; // //Start Adapter Zero (3.3.19) CO2strtAdptr0[0] - 0xa6; C02 strtAdptrO [ 1 ] - c lcChksm ( C02 s t r t Adp t r 0 , CO2STRTADPTR0LNGTH-1) ; // //Stop Current Zero Command (3.3.20) C02stop0[0] - 0xa7; C02stopO[l] - calcChksm(C02stopO, C02STOP0LNGTH) ; u //Set Sampling Pump Status (3.3.21) CO2setSmplPump[0] - 0xa8; C02setSmplPump[l] ■ 0; C02setSmplPump[ 2 ] - calcChksm ( C02 s etSmplPump , C02SETSMPLPUMPLNGTH-1) ? 23 / / / /Ge t Sampling Pump Statue (3.3.22) CO2 gβ tSmplPump [ 0 ] - 0xa9 ; C02 g e t S mp l P ump [ 1 ] - calcChkem(C02getSmplPump, C02GETSMPLPUMPLNGTH-1 ) ; //FLOW board commands // //Get Software Revision FLOWswrβvfO] - OxCA; //command FLOWswrev[l) - 0x02; //number of bytes to follow FLOWβwrβv[2] - 0x00; //rβviβion format FLOWBwrβv[3] - calcChks (FLOWswrev,ΓLOWSWRBVLNGTH-1 ) ; //Stop Waveform/Data continuous Mode FLOWwfβtop[0 ] - 0xC9; //command FLOWwfstop[1 ] - 0x01; //number of bytes to follow FL0Wwfβtop[2 ) - calc hkβm(FlΛWwfβtop,FIΛ*WFSTOPLNGTH-l) ; // //Start Waveform/Data Mode FLOWwfdata[0 ] - 0xD2; //command /* This worked, but let's try more flexible approach... FLOWwfdata[l ] - 0x07; //Number of bytββ to follow (inc. chksm) FLOWwfdata[2] - 0x01 //Flow waveform requested. FLOWwfdata[ 3] - 0x16 //Tidal volume FLOWwfdata[4] - 0x18 //Expiratory volume FLOWwfdata[5] - 0X1E //Peak Inspiratory Pressure FLOWwfdata[6] - OxlF //Mean Airway Pressure FLOWwfdata[7] - 0x23 //I:E ratio FLOWwfdata[8] - calcChkβm(FLOWwfdata,FLOWWFDATALNGTH-1 ) / char bell - 0x07; int i - 1; FLOWwfdata[i++] - FLOWDPICOUNT + 2; //lof bytββ (inc. chksa) //Request waveforms if (i >- FLOWWFDATALNGTH) //Something iβ really wrong. c 1o 1u /t n «i/mbelilm«iibieilml « nibiemllm«ibuelml «/iibteililii<m< bieilil << bell « bell « bell « bell << bell « bell; /////////////////////////////////////////////////// else { FLOWwfdata[i) - 0; for (int j - 0; j < FLOWWFCOUNT; j++) FLOWwfdata[i] |- REQWAVEFORMS[j ] ; i++; } //Request patient parameters 24 I I tor (j - 0; j < FLOWDPICOUNT; FLOWwfdata[i++] DPIPOS[ j++] ) for (int j - 0; j < FLOWDPICOUNT; j++) if (i >- FLOWWFDATALNGTH) //Something iβ really wrong. /////////////////////////////////////////////////// cout « bell « bell « bell « bell « bell « bell « bell « bell « bell « bell « bell « bell; /////////////////////////////////////////////////// else FLOWwfdata[i++] - DPIPOS[j]; if (i >- FLOWWFDATALNGTH) //Something is really wrong. /////////////////////////////////////////////////// cout « bell « bell « bell « bell « bell « bell << bell << bell « bell « bell « bell « bell; /////////////////////////////////////////////////// FLOWwfdata[i] - calcChksm(FLOWwfdata,FLOWWFDATALNGTH-1 ) ; //Configuration complete } } ; / ™™ — .-..- «... «-.-----.-.-. »— -.«« _«_, :- /* comm4 : :intrnlReβet Description : Reset internal double buffering structures to an initial value. Board and Channel values are actual values, not indices. Returns : N/A */ II- // void comm4 : :intrnlReset(int board, int channel) { ChnlBlk ♦ lchnlblk; if (board « 1) lchnlblk - &brdlBlks[channel-l] ; else //ASSUME the other board (given two boards) lchnlblk - &brd2Blks[channel-l] ; //Reβet appropriate values. lchnlblk->tempBfrInfo - NULL; lchnlblk->curBfrlnfo->bfrlndx - 0; 25 lchnlblk->flushBfrInfo->bfrIndx - 0; //Last byte in the buffer rβββrvβd for laβt index read. lchnlblk->curBfrInfo->laβtrβad - 0; lchnlblk->flushBfrlnfo->laβtrβad - -1; } // ■ I * comm4 : :cmdAIrQ Description : Prototype to command the ventilator to default mode Returns N/A '/ li¬ lt int comm4 : :cmdAIrQ( ) { return(sendCmdToVent(VCMD_ALQ, βtrlen(VCMD_ALQ) ) ) ; }; ^ αnκαnnππnoBnαBMHB aaa«liMaBBB9π*aaaκ«a» Hi_«MK_r_πB)inκ»Mnι /* comm : :cmdALR Description : Prototype to command the ventilator to default mode Returns : N/A ♦ / // int comm4 ::cmdAL ( ) { return(sendCmdToVent(VCMD_ALR, strlen(VCMD_ALR) ) ) ; }; II- / ♦ comm : :cmdMAC Description : Prototype to command the ventilator to default mode 26 Returna : N/A I ti¬ ll int comm4: :cmdMAC(char *nn) { ♦ (VCMD_MAC+4) - ^nn; ♦ (VCMD_MAC+5) - ♦ (nn+1); return{sendCmdToVent(VCMD_MAC, strlen(VCMD_MAC) ) ) }; It- / ♦ comm4 : :cmdMB Description : Prototype to command the ventilator to default mode Returns : N/A / li¬ lt int comm : :cmdMB( ) { return(sendCmdToVent(VCMD_MB, atrlen(VCMD_MB) ) ) ; }; it- / ♦ comm4::cmdMI Description : Prototype to command the ventilator to default mode Returns N/A / li¬ lt int comm4 : :cmdMI( ) { return(sendCmdToVent(VCMD_MI, strlen(VCMD_MI) ) ) ; 27 }; II- I * comm4 : :cmdMIMV Description : Prototype to command the ventilator to default mode Returns N/A */ II- // int comm4 ::cmdMIMV( ) { return(sendCmdToVent(VCMD_MIMV, strlen(VCMD_MIMV) ) ) ; }; //- /* comm4::cmdM0 Description : Prototype to command the ventilator to default mode Returns N/A ti¬ l l int comm4 : :cmdM0( ) { return( sendCmdToVent(VCMD_M0, strlen(VCMD_M0) ) ) ; }; / -=.= E3 i 3 X3 αx a 3 χ- 3 B3 aκnz 3 aamaBaamMam κBBOTa* /* comm4 : :cmdMSC Description : Prototype to command the ventilator to default mode Returns : N/A // > 28 // int comm : :cmdMSC ( ) { return(sendCmdToVent(VCMD_MSC, strlen(VCMD_MSC) ) ) ; }? It- / / int comm : :cmdPMAX(char *nn) { *(VCMD_PMAX+4) = ♦ nn; * (VCMD_PMAX+5) = ♦(nn+1); return( sendCmdToVent(VCMD_PMAX, strlen(VCMD_PMAX) ) ) ; }; t / ♦ comm4 : :cmdPMIN Description : Prototype to command the ventilator to default mode Returns : N/A αaa aKaB xx∑a ssxiaf ε // int comm4 : :cmdPMIN(char ♦ nn) { *(VCMD_PMIN+4) - ♦ nn; *(VCMD_PMIN+5) - ♦ (nn+1); return(sendCmdToVent(VCMD_PMIN, strlen(VCMD_PMIN) ) ) ; 29 //• /* comm4::cmdPP Description : Prototype to command the ventilator to default mode Returns : N/A */ / , =aπ=i--:-- ϊ -==:=:a=:=s=:t=-ii-iβ«3fflπϊ3aα iHBtxix t-iB-r- -rCns ιnmBπκan--icι = // int comm4 : :cmdPP( ) { return(sendCmdToVent(VCMD_PP, strlen(VCMD_PP) ) ) ; }; /* comm : :c dRBR Description : Prototype to command the ventilator to default mode Returns N/A 7 //== // int comm4 ::cmdRB ( ) { return(sendCmdToVent(VCMD_RBR, strlen(VCMD_RBR) ) ) ; }; / ♦ comm4 : :cmdRIT Description : Prototype to command the ventilator to default mode Returns : N/A II int comm4 ::cmdRIT( ) { 30 return(sendCmdToVent(VCMD_RIT, strlen(VCMD_RIT) ) ) ; }; / / ιaxx 3mβ maβ) K3Bis3 asa--t 8ai8-xmEi /* comm4 : :cmdRST Description : Prototype to command the ventilator to default mode Returns : N/A */ / / nsιariBr-Bαsιsi-3-3-aan-aa-κa nBai aiHai // int comm : :cmdRST( ) { return(sendCmdToVent(VCMD_RST, strlen(VCMD_RST) ) ) ; }; / ♦ comm4 : :cmdSBR Description : Prototype to set breath rate to 15 Returns : N/A */ // int comm4 : :cmdSBR(char ♦br) { ♦ (VCMD_SBR+3) = ♦ br; ♦ (VCMD_SBR+4) = ♦ (br+1); return(sendCmdToVent(VCMD_SBR, strlen(VCMD_SBR) ) ) ; } ; / ™™ , ™ , — ^ -: —_», / ♦ comm4 : :cmdSIT Description : Prototype to set breath rate to 15 Returns : N/A 31 */ I jaαcacnaπnai // int comm4 : :cmdSIT(char *ndotn) *(VCMD_SIT+3) => *ndotn; *(VCMD_SIT+4) « ♦(ndotn+1); *(VCMD_SIT+5) = ♦(ndotn+2); return(sendCmdToVent(VCMD__SIT, strlen(VCMD_SIT) ) ) =sr=3 K3C3X-riιaBaatBi-s π-aa[aaι /* comm4 : :cmdC02 Description : Sende EtC02 novametrix board the specified command. Returns : Positive or 0 for success; otherwise negative. */ /Bn aaaBaKMn anaaaMaBBaN a aaan BaHWHa BB aaaaB aan Baaaa // int coπun : :cmdC02 (unsigned char * cmd, int length) { sendCommand(NOVABRD,ETC02CHNL,cmd,length) ; return( 0) ; α==_x:a = =3r-3--i-aaan aaaiBBBBBBnBa[BBBwnBBaiHnnnnxιaBWBBBtRBvnBanαaaαα-βt-: ι /* comm4 : :cmdC02swrev Description : Sends EtC02 novametrix board a command to get s/w revision number. Returns : Positive or 0 for success? otherwise negative. */ // int comm4 : :cmdC02swrev( ) { sendCommand( OVABRD,ETC02CHNL,C02swrev,C02SWREVLNGTH) ; 32 / ♦ //This will be quick and dirty for now. Boolean ready - TRUE; int temp; clock_t timel - clock(); while ( ( (inp(C0M4B2CHNLS[CHNL2]+5) & (1 « 5)) — 0) && ( (clock( ) -timel) /CLOC S_PER_SEC<-XMT_TIMEOUT ? TRUE (ready=FALSE) ) ) ; outp(COM4B2CHNLS[CHNL2] ,0x93) ; timel = clock(); while ( ( (inp(COM4B2CHNLS[CBNL2]+5) & (1 « 5)) — 0) &£. ( (clock() -timel)/CLOCKS_PER_SEC<-XMT_TIMEOUT ? TRUE (ready=FALSE) ) ) ; outp(COM4B2CHNLS[CHNL2], (~(0x93)+1) &0x7F) ; */ return(0) ; } / / t^=zzsxΛ=Λ^s ιsκx tsxa ta=i^^9xιtMτΛXMMΛ^x*^fβtwt m ^m ^mita*amt mt ^wm ΛtxιwtmtaimιmtmΛ m m mιw 9ΛWMmiwmΛimtm vtwM mιwΛ^ m / * comm4 : :cmdC02cont Description : Commands the C02 board into continuous waveform mode. Returns : Positive or 0 for success; otherwise negative. */ // int comm4 : :cmdC02cont( ) { sendCommand( OVABRD,ETC02CHNL,C02cont,C02C0NTLNGTH) ; } ====-===-.:==-=s:3α /* comm4 : :cmdFLOWswrev Description : Sends Flow novametrix board a command to get s/w revision number. 33 Rβturnβ : Poβitivβ for βuccβββ; othβrwiββ negative. 7 ti¬ ll int co-nm4: :cmdFLOWβvrβv( ) { ββndCommand( OVABRD,FLOWCHNL,FLOWtwrβv,FLOWSWREVLNGTH) ; /•dandy.aβtound - take out when above iβ teβted and works //This will be quick and dirty for now. Boolean ready - TRUE; int temp; //Command byte clock_t timel - clock( ) ; while (( (inp(COM4B2CHNLS[FLOWCHNL-1]+5) (. (1 « 5)) -- 0) it ( (clock( )-tia>βl)/CLOCKS_PER_SEC<-XM _TIMEOUT ? TRUE (ready-FALSE) jI ) ; outp(COM4B2CBNLS[FLOWCHNL-l],OxCA) ; //NBF - Number of bytes to follow including checksum timel - clock(); while (( (inp(COM4B2CHNLS[FLOWCHNL-1]+5) & (1 « 5)) — 0) -.£ ( (clock()-timel)/CLOC S_PER_SEC<-XMT_TIMEOUT ? TRUE (ready-FALSE))); outp{COM 32CHNLS[ LOWCHNL-1] ,0x02) ; //Revision format (0 - full string) timel ■ clock{ ) ; while {( (inp(COM4B2CHNLS[FLOWCHNL-l]+5) k (1 « 5)) — 0) ii ( (clock()-timel)/CLOCKS_PER_SEC<-XMT_TIMEOUT ? TRUE (ready-FALSE) ) ) ; outp(COM4B2CHNLS[FLOWCHNL-1],0x00) ; //Checksum which haβ been computed by hand timel - clock( ) ; while (( (inp(COM4B2CHNLS[FLOWCHNL-1]+5) i, (1 « 5)) — 0) && ( (clock( )-timel)/CLOCKS_PBR_SEC<-XMT_TIME0UT ? TRUE (ready-FALSE) ) ) ; outp(COM B2CHNLS[FLOWCHNL-1],0x36) ; */ 34 return ( O ) ; } / / ■ - a xα lat - /* comm4 : :cmdFLOWwfdata Description : Sends Flow novametrix board a command to start waveform/data mode. Returns : Positive for success; otherwise negative. */ // int comm4 ::cmdFLOWwfdata( ) { sendCommand(NOVABRD,FLOWCHNL,FLOWw data ,FLOWWFDATALNGTH) ; } /* comm4 : :cmdFLOWwfstop Description : Sends Flow novametrix board a command to stop wave orm/data (continuous) mode. Returns : Positive for success; otherwise negative. */ //' EØBSK: // int comm4 ::cmdFLOWwfstop( ) { sendCommand(NOVABRD,FLOWCHNL,FLOWwfstop,FLOWWFSTOPLNGTH) ; I * comm : :bpcmdRES1 Description : Sends blood pressure RES1 command to blood pressure board. Returns : Positive for success; otherwise negative. */ 35 // int comm4 : :bpcmdRESl ( ) { sendCommand(BPBRD, BPCHNL, BPCMDS[RESl] , strlen(BPCMDS[RESl])) ; } / /=-=-;-:=-a=-i-:-ι=z-ι->-tB-n-l-cnsB-eaztκmn-r- -:vaBD_i-ιaBiι-na_sκ-ca- B_ι-ι-i£i3aι--ι_ι-ι-ι /* comm4 : :bpcmdSTRIMED Description : Sends blood pressure RESl command to blood pressure board. Returns : Positive for success; otherwise negative. */ //• // int comm :: bpcmdSTRIMED ( ) { // sendCommand ( BPBRD , BPCHNL, BPCMDS [ STRIMED ] , strlen ( BPCMDS [STRIMED] ) ) ; } /* comm4 ::getChnlData Description : Copies the contents of the portion of the board buffer allocated to a channel to a channel buffer. Returns : Pointer to channel data. */ // ChnlBfr * comm4 ::getChnlData(int board, int chnl, int ϋbfrSize) { ♦include <mem.h> bfrSize - CHNLBFRSIZE; /* Taken out as mod to design 1/22/96 if (com4BfrIndx[board-l] [chnl-1] .bfrlndx ■« 0) 36 com4BfrIndx[board-l] [chnl-1] .eob - CHNLBFRSIZE-1; else c om4 B f r I ndx [ boa rd - l ] [ c hn l - 1 ] . e ob com4BfrIndx[ board- 1] [chnl-1] . bfrlndx- 1; */ return( (ChnlBfr *)memcpy(chnlBfrPtrs[board-1 ] [chnl-1] , brdBfrPtrs[board-l] [chnl-1] ,CHNLBFRSIZE) ) ; > It- I* comm4 : :readChar Description : Prototype to read characters. Returns : N/A */ ti¬ ll char comm4 : :readChar( ) { Boolean ready - TRUE; int temp; clock_t timel - clock(); while ( ( (inp(COM4BlCHNLS[CHNLl]+5) & 0X01) — 0] ( (clock( )-timel)/CLOCKS_PER_SEC<-RCV_TIMEOUT ? TRUE (ready=FALSE) ) ) ; if (ready) return(inp(COM4BlCHNLS[CHNLl ]) ) / a=:3eaaaMaaBattxιnnBBaiBBBa-*B«BBa BBBBa MHBBMBBWBr BBWBBMBBMn-a.nMn«-caaiB =3=aκxx BtrB --« B .a B ta B a- f -ιa--:a H /* comm4 : :srvcINTRPT Description : Prototype to service interrupt generated from COM4 board. Returns N/A */ ti¬ ll void _far comm4 : :srvcINTRPT( ) { 37 int temp; char cinput; cout << "Com4 βrvcINTRPT executing... " « endl; /* This was the firβt attempt which did not βeβn to work. The next attempt will juβt look at the LSR and not the ISR since we are not βharing intβrruptβ. R R A R R A R A R A R A R A R A R A R R A R A R A R R A R A R A R R A Rβtart A R A R R A R A R A R A R A R R ^ R A R A R A R A R R A R A R A R A R A R R A R R R //First read ISR temp - inp(COM4CHNLl+2) ; //cout « "Interrupt Statue Regiβter : " « tβatp « endl; //while there are intβrruptβ pending while ((temp && 0x01) — 0) { //cout << "here" << endl; cinput - inp(COM4CHNLl) ; //Read the LSR to advance to next char inp(COM4CHNLl+5) ; temp - inp(COM4CHNLl+2) ; } A R A R R A R R A R A R A R A R A R A R A R R R A R R A R R R R A R A Rβnd A R A R R A R R-R-R Λ R-R A R R R Λ R"R A R A R A R A R A R A R A R A R A R R A R */ /* This attempts to read LSR until all data iβ read. The ISR is not read. We are not βharing interrupta. .R R A RR AA R Λ R A R A R A R A R A R A R A R A R R Λ R R A R A R A R A R A R A Rβtart A R A R A R A R A R A R R R A R R A 1R A R A R A R A R A R A R A Rr.R A Rr.R A R A R */ //First read ISR temp - inp(COM4BlCHNLS[CHNLl]+5) ; cout << "ISR : " « temp << endl; //while there is data in FIFO while ((temp & 0x01) — 1) { //cout << "here" « endl; cinput - inp(C0M4B1CHNLS[CHNLl]) ; cout « "cinput : " « cinput « endl; //Read the LSR to advance to next char temp - inp(COM4BlCHNLS[CHNLl]+5) ; //cout « "ISR : " « temp « endl; } 38 K R A R A R A R A R A R A R A R A R R A R A R R A R A R A R A R A R A R A R A R A Rend A R A R A R A R A R A R A R A R R 'R A R A R A R A R A R A R A R A R R A R A R A R A R A R A R •/ /* Thiβ is uββd when βharing intβrruptβ. R R A R A R A R A R A R A R A R A R A R A R A R A R A R R A R A R A R A R A Rβtart A R A R A R A R Λ R A R Λ R Λ R A R R A R A R A R A R A R A R A R A R A R A R A R A R A R A R //while there are interruptβ pending while ({temp .. 0x01) -« 0) { if ( ((temp .. (1«1)) 1- 0) . ( (temp .. (1«2) ) 1- 0) ) //LSR (Receiver Line Statue Register) cinput - inp (COM CHNLl) ; temp - inp(COM4CHNLl+2) ; cout « "Interrupt Status Register : " « temp « "\r"; } k R A R A R A R A R A R R A R R A R A R A R R Λ R A R A R A R R A R A R A R A Rend A R Λ R A R A R A R A R A R A R R 'R A R A R A R R A R A R A R R A R A R Λ R A R A R A R A R */ return; } II- comm : :readlSR Description : Reads ISR register Returns : Returns value of ISR register // int comm : :readISR( ) { return(inp(COM4BlCHNLS[CHNLl)+2) ) ; } It- /* comm : :readLSR Description : Reads LSR register 39 Returns : Returns value of ISR register 7 //• // int comm : :readLSR( ) { return{inp(C0M4B1CHNLS[CHNLl]+5) ) ; } //• /* comm4: :readHBR Description : Reads RBR register Returns : Returns value of ISR register * / I I int comm : :readRHR( ) { return(inp(COM4B1CHNLS[CHNLl] ) ) ; } /* comm4: :readIER Description : Reads IER register Returns : Returns value of IER register * / //__ ^ -. M - — // int comm : :readIER( ) { return(inp(C0M4BlCHNLS[CHNLl]+l) ) ; } It- I* comm4 : :writeStatus 40 Description : Sends a message to error/status log, Returns : 7 ti¬ ll int comm4 : :writeStatus(char * meg) { //Use send command function even though thiβ is really not a command. sendCommand(STATBRD,STATCHNL,msg) ; } I * comm4::calcChksm Description : Calculates checksum. Returnβ : Returnβ checksum value Note : This function is duplicated in GUIIF.cpp for test urposes */ //« — „ : — :«: „ :„. -_»««„ nsaia 3BBOMtia -Rain // unsigned char comm4 ::calcChks (unsigned char * cmd, int length) { unsigned char sum - 0; int i; if (length — 0) for (i - 0; i < strlen(cmd); sum +- cmd[i++]); else for (i - 0; i < length; sum +- cmd[i++]); //Calculate checksum. return( ( (-sum) + 1) & 0x7F) ; //• I * comm4 ::sendCommand 41 Description : Send a command cmd on board # brd, channel # chnl. Returns : Returns checksum value */ li¬ lt void comm4 ::sendCommand(int brd, int chnl, char * cmd, int length) { Boolean ready - TRUE; int lngth, base; clock_t timel; if (length =- 0) lngth - strlen(cmd); else lngth «» length; if (brd-1 — 0) base » C0M4BlCHNLS[chnl-l]; else //Hopefully, the other board. base = COM4B2CHNLS[chnl-l]; for (int i - 0; i < lngth; i++) { ? TRUE : ISBBEB: Send command to ventilator, Assumes ventilator talking to comm4 board 1. 42 // • xjjaczsntπj--:: // int comm4 :: sendCmdToVent(const char *cmd, const int cmdlen) { Boolean ready - TRUE; clock_t timel; int lcmdlen - cmdlen; static const char *VENTCMD - "Vent Command : "; static const char *VERRORMSG - "Ventilator Command Rejected / "; #ifdef ENABLE_SENDCMDTOVENT_DISPLAY strcpy(statusMsg, VENTCMD); strncat(statusMsg, cmd, strlen(statusMsg) - strlen(VENTCMD) -i ) ; strncat(εtatusMsg, "\π",l); sendCommand(STATBRD,STATCHNL,statusMsg) ; tendif ENABLE SENDCMDTOVENT DISPLAY if (cmdlen == 0) lcmdlen =■ strlen(cmd); for (int i=0; i<lcmdlen; i++) { timel = clock( ) ; while ( ( (inp(COM4BlCHNLS[CHNLl]+5) & (1 « 5)) == 0) && ( (clock()-timel)/CLOCKS_PER_SEC<=XMT_TIMEOUT ? TRUE (ready-FALSE) ) ) ; if (ready) outp(C0M4BlCHNLS[VENTCHNL-l],*(cmd+i) ) ; else { //Timed out - abort this command. #ifdef ENABLE_VENT_CMD_ERRORS strcpy(statusMsg, VERRORMSG); strncat(statusMsg, cmd, strlen(statusMsg) strlen(VERRORMSG) -1); sendCommand(STATBRD,STATCHNL, statusMsg) ; «endif ENABLE_VENT_CMD_ERRORS return(-1) ; } } return(l); } #endif _C0MM4_D0T_H 43 PROGRAM LISTING S518.H -312- // linclude "debug.h" linclude "iotypes.h" linclude "β518con.h" linclude <timβ.h> linclude <conio.h> linclude <doβ.h> linclude <stdio.h> linclude <ioβtream.h> //dandy.astound int cflag - 0; / / l l l l l # l l f * l l # l # * # * i # # # * # # # S E N S O R 5 18 !l!lf!!l! t*#H!tt#ff###HH*!## //SENSOR518 CLASS - Defines operations of Senβoray 518 board // lifndef SENSOR518_ Idefine SENSOR518 -313 - CIQBB βensor518 { //Board physical constants //enum {numOfChanβ - 8); //Save last 10 error codeβ enum {errorSIZE - 10}; //Board attributes // conβt unβigned int baβeAddr; //board base address unβigned int defChan; //default channel //Board state static unsigned int channelUse[numOfChana-l] ; //array[chan] - sensor_code; 0-not used //Array of last 10 errors encountered, int errCds[errorSIZE] ; int eclndex; Boolean putEr(int); Boolean writeByte(unsigned int port, unβigned char byte); Boolean readByte(unsigned int port, unβigned char &byte) ; public: sensor518 (unβigned base, long initialize); -sensor518() { lifdef DEBUGl cout « "Destructor for sensor518 called..." « endl « endl; lendif DEBUGl } //-sensor518( ) Boolean getEr(char*) ; Boolean writeCommand(unsigned char command); Boolean writeControl(unsigned char control); Boolean readData(unsigned int channel, unsigned int &data) ; Boolean boardReβet( ) ; Boolean rβadStatua(unsigned char status); //Not implemented Boolean declareSensor(unsigned char sensorCode, unsigned int channel) ; int readProdID( ) ; }; //sensor518 //Following is a static array of channel use. unsigned int sensor518: :channelUse[numOfChans-l] ; -314- II- sensor518 : Constructor parameters are board baββ address and flag to determine if board is to be initialized. /A l l Bβnβor518 : :senβor518(unsigned base. long initialize) baseAddr(base) { lifdef DEBUGl cout « "Constructor for 8βnor518 called (base - " << base << ")" « endl « endl; lendif DEBUGl //Initialize channel-use array to "no channels assigned" // for (int i - 0; i < nu OfChans; i++) channelUse[i++] - 0; //Initialize error array for (eclndex - 0; eclndex < 10; eclndex++) errCds[ecIndex) - 0; eclndex - 0; if (initialize) senBor518: :boardReβet( ) ; } //sensor518(unsigned) II- /* senβor518: :putEr(int) Description : Stores error code in error array, Returns : Always returns 0 (FALSE) */ It- It Boolean βensor518: :putEr(int erCode) { -315- lifdef DBBUG2 print ( " ββnβorPhyβical i : putEr ( βrCodβ : %d) called.\n" ,erCode) ; lendif DEBUG2 errCdβ[ecIndβx++] - βrCodβ; //if (eclndex > (βrrorSIZE-1) ) eclndex - 0; eclndex - (βclndβx+l) % errorSIZE; return(FALSE) ; } //putEr /* βenβor518: :getBr(char w ) Deβcription : Printβ error code deβcriptionβ in moβt recent to oldeβt. Returns : Always returnβ 0 (FALSE) */ li¬ lt Boolean sensor518: :getEr(char * description) { lifdef DEBUG2 printf( "sensorPhysical: :getEr( ) called.\n" ) ; lendif DEBUG2 int tlndex - eclndex; while (—tlndex I- eclndex) { if (tlndex < 0) tlndex - errorSIZE-1; if (errCdβ[tlndex] ) printf( , erDescription[errCds[tlndex]-BASE_ERR0R_C0DE] ) ; if (errCds[tlndex]) printf("%β\n", erDescription[errCdβ[tlndex]-BASE_ERROR_CODB]) ; printf("*********** ERRORS ***********\ n ") ; printf("\n") ; return(FALSE) ; } //getEr 4 /* ββnβor518ι ιwritβBytβ(unβigne<l int port, unβignβd char byte) Deβcription : Writes byte to port addreββ. If addr iβ baβe addreββ, then command j byte is being written; if addr iβ baββ addrβββ + 1, then control register iβ being written. Returns i TRUE (send successful) FALSE (timeout occurred) */ ti¬ l l Boolean sensor518: :writβByte(unβigned int port, unβigned char byte) < lifdef DEBUG2 printf( "aeneorPhyβicalx xwriteByte(port : %x, byte : %x) called.\n", port, byte) ; lendif DEBUG2 if (port « baβeAddr) { //Command register being written Boolean ready - TRUE; clock_t timel - clock(); while ( ((inp(port+l) « (1 « 7)) — 0) && //wait for CRMT bit ( (clock()-timel)/CLOCKS_PER_SEC<-SEND_TIME0UT ? TRUE : (ready-FALSE) ) ) ; if (ready) { //Command register is ready to accept command byte outp(port, byte) ; if (cflag) printf( "writeByte(port,byte) -> byte : %d\r". byte) ; return(TRUE) ; else { //Timeout rcurred lifdef DEBUG3 cout « "Timeout occurred in writeByte." << endl << endl; 5 -317- lendif DBBUG3 //Tiaβout return(putEr(TIMEOUT_ON_SBND) ) ; } βlββ { //Control rβgiβtβr being written outp(port, byte) ; return(TRUE) ; } } //writeByte // /* ββnβorS18: xreadByte(unβignβd int port, unβigned char ibyte) Description x Reads byte from port addrβββ. If addr iβ base addreββ, then data byte iβ being read; if addr iβ baβe addrβββ + 1, then status register is being written. Returns : TRUE (read βucceββful) FALSE (timeout occurred) */ // Boolean Bensorδ18: xreadByte(unsigned int port, unsigned char &byte) { lifdef DEBUG2 printf( "βensorPhyaical: xreadByte(port x %x, byte : %x, ) called.\n" , port, byte) ; lendif DEBUG2 if (port « baseAddr) { //Data register being written Boolean ready - TRUE; clock_t timel - clock(); lifdef DEBUG4 cout << "Checking DAV bit in readByte... " << endl; printf( H Port+l : %x\n\n" , port+1); lendif DEBUG4 while ( ( (inp(port+l) & (1 « 6)) « 0) && //wait for DAV bit ( (clock( )-timel)/CLOCKS_PER_SEC<-R£CV__TIMEOUT ? TRUE : (ready-FALSE) ) ) ; 6 if ( ready ) { //Data available // //dandy.aβtound (read and print βtatuβ rβgiβtβr) //byte - inp(port+l); //printf( "βtatuβ rβgiβtβr in rβadbytβ ; %x\r", byte); byte - inp(port) ; //printf( "port in readbyte : %x\r", port); return( RUB) ; } θlβe { //Timeout occurred lifdef DBBUG3 cout « "Timeout occurred on readBtye." << endl « endl; lendif DBBUG3 //Timeout return(putEr(TIMEOUT_ON_READ_BY E) ) ; } } else { //Status register being read byte - inp(port) ; return(TRUE) ; } > //readByte /* sensor518: :writeCommand(unsigned char command) Description : Writes a command byto to 518 command register. Returns : * / li¬ lt Boolean sensorδ18: :writeCommand(unsigned char command) { //Writes <command> to 518 base address return(writeByte(baeeAddr, command) ) ; I t- I * βenβor518x writeControl(unβigned char control) Deβcription x Writes a control byte to 518 control rβgiβtβr. Returns x */ f i¬ l l Boolean Bβnaor518: :writβControl(unsigned char control) { //Writes <control> byte to 518 base addreββ + 1 return(writeByte( (baaeAddr+1) , control) ) ; } It- /* sensor518: :readData(unβigned int channel, unβigned int tdata) Description : Reads data from 518 data port. (2 bytes read) If channel is not valid, then no command byte sent. Returns */ //> // Boolean senaor518: :readData(unsigned int channel, unsigned int &data) { unsigned char dataLO, dataHI; data - 0; //Send command to read channel. lifdef DEBUG4 cout « "readData(" « channel « ") " « endl « endl; lendif DEBUG4 Boolean retVal - TRUE; //Send command to read channel only if valid channel. //dandy.astound (cflag) //cflag - 1; if (channel <- 7) rβtVal - writβCoπuaand(channel) ; //cflag - 0; if (retVal) { lifdef DBBUG4 cout « "Succβββful readData/writeCommand( " << channel « ") " « endl << endl; lendif DBBUG4 //Read high byte if (readBytβ(baβθAddr, dataHI)) if (rβadByte(baβeAddr, dataLO) ) { //dandy.aβtound waβ x data - (dataHI « 8) | dataLO; data - (dataHI « 8) ; data |- dataLO; //printf( "Temp aβ read in β518 iβ %d\r", data); return(TRUΕ) ; lifdef DEBUG4 cout << "Data βuccesβfully read from sensor in readData : " « data « endl << endl; lendif DEBUG4 } else { //Failed to read low byte lifdef DEBUG3 cout << "Timeout occurred in readData/reading low byte..." << endl << endl; lendif //Timeout return(putEr(TIMEOUT_ON_READ_LO) ) ; } else { //Failed to read high byte lifdef DEBUG3 cout « "Timeout occurred in readData/reading high byte... " << endl << endl; lendif //Timeout return(putEr(TIMEOUT_ON_READ_HI) ) ; - 321- elβe / / Failed to ββnd coβsaand return( utEr(RI-AD_CRAH_CKP K7r_SEirr) ) ; } //readData /• aβnβor518: xboardRβββt( ) Deβcription x Reads byte from port addrβββ. If addr iβ baβe address, then data byte ie being read; if addr iβ baβe addreββ + 1, then status register iβ being written. Rβturnβ x TRUE (βucceββful) FALSE (failure) 7 // Boolean iβmorS18x xboardReeβt( ) { //Control wordβ // conβt unsigned char BOARD_RESET - 0x00; //Soft reset //reset board lifdef DEBUG4 cout << "Setting control register to 0 (reαet)... " << endl; lendif DEBUG4 //cflag - 1; writeControl(BOARD_RESBT) ; //cflag - 0; //Wait 300 -βllliββcondβ //delay{300); //Wait for FAULT bit to be reββt to 0 indicatinc reset iβ complete. //Get current tiate clock_t timel - clock{); Boolean ready - TRUE; unsigned int dvaluβ; unβigned int pλddrβ - baβeAddr; while ((((dvalue - inp(pAddrβ+l ) ) . ( 1 « ) ) — 16) .. //wait for FAULT bit 10 -322- ( ( c lc :k ( ) -t-U8e l ) /CL CKS_PKR_8BC<-RST_TIMB0Uτ ? TRUE i ( ready - FALSE ) ) ) , lifdef DEBUG4 printf("8tatuβ rβgiβtβr value after reβet iβ %x\n\n", dvaluβ) ; lendif DBBUG4 if (ready) rβturn(TRUB) ; βlβe { //Could not rβββt board lifdef DBBUG4 cout « "Timeout waiting for FAULT bit on reset..." << endl « endl; lendif DEBUG4 return(putEr(RBSET_FAILBD) ) ; } } //boardRββot /* βenβor518x xdeclareSβneor Description x Returnβ x */ // Boolean senβor518: xdeclareSβnβor(unβigned char βenβorCode, unsigned int channel) { lifdef DBBUG2 printf( "ββneor518x xdeclarβSβnβor(%d %d) called. \n", βenβor, channel); lendif DBBUG2 if ( (channelUββ[channβl] >« noChannelChβck) || ( IchannelUββfchannβl] ) ) //COMMAND (16+CRAN), (SBNSOR DEFINITION CODB) //Send command byte to register if (writβCoaB*and(DECLARE_CHAN | channel)) //Command ββnt βuccβββfully; send sensor definition code, if (writβCoππaand(sensorCode) ) { //Sβnβor code identified successfully; return success. 11 -323 - channβlUβeJchannβl] - ββnβorCodβ; return(TRUE) βlβe //Failure to tranβmit ββnβorCode; indicate fatal error . return(putEr(SBNSOR_CODB_NOT_SENT) ) ; else //Failure to tranβmit command; indicate fatal error, return(putE (COMMAND_NOT_SBNT) ) ; else //Tried to declare a channel already in use return(putEr(DUPLICATE_CHNL_DECLARE) ) ; } //declareSensor // ————-1—«— /* aenaor518x xreadProdID( ) Description : Returns product id. Returns Product ID */ ti¬ ll int Bβnβor518: :readProdID( ) { //Command (240), (4), (0) //writeCommand(unβigned char command) writeCommand(240) ; writeCommand(4) ; writeCommand(0) ; //Boolean readData(unβigned int channel, unsigned int ϋdata); //Specify invalid channel to prevent channel read command being sent. unsigned int pid - 0; readData(8, pid) ; return(pid) ; } //readProdID lendif SENSOR518_ 12 -324- // // // // ■ Senβor speci ic classes // ■ II It // / / I I I I I I I I I t f I f f ff I VOLTAGE +/-5V III tiff fit* //VOLTAGB CLASS // lifndef VOLTAGE_ Idefine VOLTAGE_ class voltage : public sensor518 { unsigned int vchannel; //Set to valid channel on declareSensor public : voltage(unsigned int base, unsigned int channel, unsigned char sensorCode - VOLTAGE); -voltage( ) { lifdef DEBUGl cout << "Destructor for voltage called..." << endl « endl; lendif DEBUGl } Boolean readData(unsigned int &data) ; }; //voltage class /* voltage: :voltage Description : Returns 13 // voltage::voltage(unsigned int base, unβigned int channel, unβignβd char ββnβorCode) : sensor518(base, NULL) { lifdef DBBUG1 printf("Conβtructor for voltagβ(%x, %d, %x) called...\n\n", baβe, channel, sensorCode lendif DEBUGl if (declareSensor(sensorCode, channel)) //SUCCΘBB - save channel in vchannel vchannel - channel; else //Failure to declare sensor - set to invalid channel vchannel - 8; } // m ——-.——-.- « ™ . « ™ « ™™™ «-_, -- . ™™- . /* readData(int data) Description : Returns 7 ti¬ ll Boolean voltage: :readData(unsigned int Sdata) { return(sensor518: :readData(vchannel, data) ) ; } //voltage: :readData lendif VOLTAGE l l t i * i t i i i i * * i t i * * t t * * t t t i * t i t THERMOCOUPLE //THERMOCOUPLE CLASS // lifndef THERMOCOUPLE_ Idefine THERMOCOUPLE_ class thermocouple : public sensor518 { unsigned int tchannel; //Set to valid channel on declareSensor public : thermocouple(unsigned int base, unsigned int channel, unsigned char sensorCode - THERMOCOUPLE) ; 14 -326- -thermocouple( ) { lifdef DEBUGl cout << "Destructor for thermocouple called..." << endl << endl; lendif DEBUGl } Boolean readData(unsigned int idata) ; } ; //thermocouple class /* thermocouple: thermocouple Description : Returnβ ■ I ti¬ l l thermocouple::thermocouple(unsigned int base, unsigned int channel, unsigned char sensorCode) : sensor518 (base, NULL) { lifdef DEBUGl printf( "Constructor for thermocouple(%x, %d, %x) called... \n\n" , base, channel, sensorCode lendif DEBUGl if (declareSensor(sensorCode, channel)) //Success - save channel in tchannel tchannel - channel; else //Failure to declare sensor - set to invalid channel tchannel - 8; } /* readData(int data) Description : Returns : 15 * / / / ■ Boolean thermocouple: xreadData(unsigned int fcdata) return(βensor518x readDat (tchannel, data) ) ; } //thermocouple: :readData lendif THERMOCOUPLE 16 PROGRAM LISTING QTEST.CCP //Muβt specify size of array for dimensions > 1 //Idefine ENABLE_GUIIF typedef enum Boolean { TRUE - 10, FALSE - 0}; lifdef ENABLB_GUIIF linclude "guiif.h" elβe linclude <windows.h> lendif ENABLE_GUIIF linclude <iostream.h> linclude <βtdio.h> linclude <stdlib.h> linclude <time.h> linclude <string.h> linclude <conio.h> linclude <fcntl.h> linclude <dos.h> linclude <io.h> linclude <sys\stat.h> linclude <fstream.h> const testNo - 26; //CASE 1 stuff (from here until you see CASE 2 stuff) int boardl,chnll,sob,eob; typedef POINT PointArray[ 10] ; PointArray pta; POINT *ptra; const char * t - "test\r"; const char s[] - "TEST\r"; const char * a - "ALQ-2\r"; int array[2](3]- {{2 , 3,4} , {4 ,5 , 6}} ; int i, n; double dvalue - 10.4; int deci,sign; char * nn; //CASE 2 stuff //This testj the calling of clock( ) in a very quick sequence //and whether or not this is a problem when comparing times. clock_t times[100]; clock_t initTime; //CASE 4 stuff unsigned char datapacket[20] ; -330- unβigned char chk; unβigned char result; //CASE 5 stuff fstream filel , file2 , file3, file4 ; char buffer[1000]; char * abfr - "0123456789"; //CASE 7 stuff const char * dllVersion; //CASE 8 stuff unsigned char chararrayf 10] ; unsigned char *charptr; //Case 11 stuff struct overlayβtruct { unsigned char cmd; int waveform; unsigned char sab; unsigned char chk; } overlay, *overlayptr; overlayβtruct temp; int waveform; unsigned char dataStreamf ] - {0x0, 0x0, 0x80, 0x09, OxaO, 0x01, Oxfe} ; //Case 12 stuff i nr - chksm; //Case 13 stuff int handle; unsigned char buffr[100]; //Case 14 stuff FILE *filel0; FILE *filell; //Case 15 stuff dostime_t timeS; const char startbyte - Oxff; unsigned char csum; //Case 17 stuff FILE *filel2; FILE *filel3; dostime_t ti eSl; dostime_t timeS2; dostime_t timeS3; dostime_t timeS4; 2 //Caβo 19 stuff conat FLOWWFMAX - 3; //Flow, Pressure, and Volume waveform (in that order) conβt FLOWWFSIZE - 20; //Maxixmim number of waveform values passed back conβt FLOWAVGSIZE - 4; //Number of points to average. atatic int flowWF[FLOWWFSIZE] ; atatic int preββWF[FLOWWFSIZE] ; static int volWF[FLOWWFSIZE] ; atatic int *flowWFβ[FLOWWFMAX] - {flowWF, preββWF, volWF} ; static int flowWFsize[FLOWWFMAX] ; static int avgcount[FLOWWFMAX] - {0,0,0}; βtatic long int flowAvg[FLOWWFMAX] ; int goon - 1; int j; static unsigned char flowbfr[ 100] ; //Case 21 stuff char statusmsgf50] ; char astring[] - "0123456789\n" ; char *bstring - "Testing"; char *cβtring - "Another Test"; //Case 22 stuff class Aclass { public: Aclass( ) ; afunc(int) ; int a; private: βtatic void afuncl(); βtatic void afunc2(); void (*ftable[2] ) () ; }; Aclass::Aclass( ) { cout « "Aclass constructor called..." « endl; ftable[0] - afuncl; ftable[l] - afunc2; return; } int Aclass: :afunc(int no) { //Call private function based. ftable[no] ( ) ; } void Aclass::afuncl( ) { cout « "afuncl () called..." « endl; return; void Aclassx afunc2 ( ) { cout << "afunc2() called., << endl; return; } Aclaββ x; //Caβe 23 βtuff void (*fptr[2])(); void afuncl () {cout « "afuncl called" « endl;}; void afunc2() {cout « "afunc2 called" « endl;}; //Case 25 atuff char *response[ 16] [2] } , int res, plength; //Case 26 stuff char *βtringl - "Testing"; char string2[] - "Testing"; int value; unsigned char calcChksm(unsigned char * cmd, int length-0) { unsigned char sum - 0; int i; if (length — 0) for (i - 0; i < Btrlen(cmd); sum +- cmd[i++]); for (i - 0; i < length; sua +- c_τad[i++]); //Calculate checksum. rβturn( ( (-sum) + 1) fc 0x7F) ; } int validChksm(conβt char * bfr, const int bfrlen) { unsigned char sum - 0; for (int i - 0; i < bfrlen-1; sun +- *(bfr+i++)); if ( ( ( (βum«0x7F) + *(bfr+i) )fc0x7F) « 0) //Valid checksum return( 1) ; else return(-1) ; } int findlnBuffer(const char *bfr, const char *pattern, const char *altpattern, int .plength) { static char lbfr[50], *pos, *savepoa; static int i, mult; atatic const char *laltpattern; mult - 1; plength - strlen(bfr); //If altpattern is NULL, then set local alt pattern to pattern. Thia //is used below when checking for both patterns without having to worry //about dereferencing a null pointer. // v And I do mean "-" if ( I (laltpattern-altpattern) ) laltpattern - pattern; //First copy bfr to enable us to modify string. strcpy(lbfr, bfr); //Replace all digits with 'n'. for (i-'0'; i<-'9'; i++) while (poa-strchr(lbfr,i) ) ' ■ pos 'n' if ( ( i strcmp(lbfr,pattern) ) | | ( I strcmp(lbfr,laltpattern) ) ) { //We have a match, cout << "We have a match" << endl; //First copy original string. βtrcpy(lbfr, bfr); //Firβt replace all '-' with blank βtarting at poβition 1 savepos - lbfr; while (poβ-βtrchr( (char *)( lbfr+1),'-') ) { βavepoβ - poβ; } if any precedes an /r. . ') ) { //Convert to integer, return(atoi(βavepoβ) *mult) ; } else cout « "We DO NOT have a match." « endl; return(-1 ) ; II- I * ventFindlnBuffer(bfr, length, pattern, altpattern, value) - new way ll Boolean ventFindlnBuffer(const char *bfr, const int plength, const char *pattern, const char ♦ altpattern, int Svalue) { const int LBFRSIZE - 50; βtatic char lb [LBFRSIZEJ , *poβ, *savepos; βtatic int i, mult; static const char "laltpattern; value - 0; mu11 - 1 ; //Return the length of etring matched to be ueed in calling routine //to update buffer index if a match iβ found, //plength - βtrlen(bfr); //If altpattern ia NULL, then ββt local alt pattern to pattern. This //ia useful below when checking for both patterns without having to worry //about dereferencing a null pointer. // v And I do mean "-" if ( 1 (laltpattern-altpattern) ) laltpattern - pattern; //First copy bfr to enable us to modify string. We can not use //strcpy since bfr may not be null terminated, //strcpy(lbfr, bfr); //First copy bfr to enable us to modify string. if (plength > LBFRSIZE-1) { //We need to increase the size of our array, lifdef ENABLE_FATAL_ERROR_MSGS strcp (statusMsg, "Array too email in ventFindlnBuffer. \n\r" ) ; 8tatuβlog(8tatusMsg) ; Iendif ENABLE_FATAL_ERROR_MSGS } else { memcpy( (void *)lbfr, (void *)bfr, plength); lbfr[plength] - '\0'; //Add null terminated character. } //Replace all digits with 'n'. for (i-'O'; i<-'9'; i++) while (pos-strchr(lbfr,i) ) if ( ( J strcmp(lbfr,pattern) ) | | ( 1 strcmp(lbfr,laltpattern) ) ) //We have a match. //cout « "We have a match" « endl; 7 //Pirβt copy original etring. βtrcpy(lbfr, bfr); //Firβt replace all '-' with blank βtarting at position 1 savepos - lbfr; while (poβ-βtrchr( (char *) (lbfr+1 ) , ' - ' ) ) { savepos ■« poβ; } any '.' precedes an /r. ) { βtrcpy(poβ,poβ+l) ; } //Convert to integer, value - atoi(βavepoe)*mult; return(TRUE) ; } else //cout << "We DO NOT have a match." « endl; return(FALSE) ; void main( ) { switch(testNo) { case 1 : ptra - pta; for (i - 0; i<10; pta[i++].x - pta[i].y - i) ; for (i - 0; i<10; i++) cout « pta[i].x « " " « pta[i].y « endl; for (i - 0; i<10; i++) { cout « ptra->x « " " « ptra->y << endl; ptra++; } cout << "bytes in POINT : " « sizeof(POINT) <■> endl; //Testing atoi n - atoi((char *)(a+4)) cout << "atoi conversion yields x " << n << endl; nn - fcvt(dvaluβ,l,Sdβci,tβign) ; break; case 2: initTi β - clock{); /* for (i-0; i<100; i++) tiatββ[i] - clockO; //Now print out differencββ... for (i-0; i<99; i++) cout « (times[i+1] - t_Unee.[i] ) /CLOCKS_PER_SEC l; cout << "Now from initial time..." « endl; for (i-0; i<100; i++) cout « (timββfi] - initTimβ)/CLOCKS_PER_SEC « endl; */ initTimβ - clock(); cout << "Wait for 20 seconds..." « endl; while ( ((clock()-initTime)/CLOCKS_PER_SEC)<20); break; i-0; cout « (i++)+l « endl; break; caβe 4: //Checksum randomize( ) ; datapacket[0] ■ rand{ )tOxlOO; for (i-1; i<10; datapackβt[i++]-rand( ) %0x80) ; for (i-0; i<10; printf("%x\n",datapacket[i++] )) ; chk - 0; for (i-0; i<10; chk +- datapacket[i++] ) ; chk - ((-chk) + 1) & 0x7F; printf("CHK x %x\n", chk); result — 0; for (i-0; i<10; result+-datapacket[i++] ) ; result - ( (rββulti0x7F)+chk)S0x7F; printf( "Reβult x %x\n", result); break; case 5: //File 10 9 filel.open("fI \\letatio2\\buildlWdataWthruput.dat" , ioβ: out I ioextin); for (i-0; i<100; buffϋr[i++] - (**ijfr+(i%10) ) ) ; filel.writefbuffer, 100); fil β l.open("fι\\l β tatio2\\buildl\\data\\thruput.dat", ioβxxout I ioe: :in); for (i-0; i<1000; buffer[i++] - 'A'); filel.write(buf er, eixeof(bu far) ) ; filβ2.open("fx\\lβtatio2\\btιildl\\da *\\flow.daf, file3.open( "fxWlatatio2\\buildl\\data\\EtC02.d*t",ioβx xout|ioβx x in); buffβr[0] - 0x93; buffer[l] - 0x6d; file3.write(buffer, 2); file4.open("f \\lβtatio2\\buildl\\data\\flowcont.dat",ioβx xout| io ex xin) ; buffβr[0] - 0xd2; buffer[l] - 0x02; buffβr[2] - 0x01; buffβr[3] - 0x2b; filβ4.writβ(buffβr, 4); break; case 6: cout « ( (-(0x93)+l)-.0x7P) « endl; lifdef BHABLE_GUIIF dllVβrβion - gβtDllVβrβion( ) ; cout « dllVβrβion « endl; lendif BKABLB_GUIIF break; caββ 8: //Chβckβum reviβited //Calculated chβckaua. for soae βpecific blocks of data i - 0; datapackβt[i++] - 0xa4; 10 datapackβt[i++] - 0x39; datapackβt[i++] - 0x01; datapacket[i++] - 0x96; datapackβt[i++] - 0x2c; datap*ckβt[i++] - Oxde; datapackβt(i++] - 0xf3 datapackβt[i++] - 0x5f; datapacket[i++] - 0x3c; datapackβt[i++] - 0x50; datapackβt[i++] - 0x00; for (i-0; i<10; printf("%x\n",datapackβt[i++])) ; chk - 0; for (i-0; i<10; chk +- dataracket[i++] ) ; chk - ((-chk) + 1) - 0x7F; printf ("CHK (expected i 0x24) x %x\n", chk); //Now call function to calculate chkβm printf ( "CHKSM from function x %x\n" , calcChkβm(datapackβt) ) ; rββult - 0; for (i-0; i<10; rββult+-datapackβt[i++] ) ; rββult - ( (rββultl.0x7F)+chk)t0x7F; printf ("Rββult : %x\n", result); cout « "Here's another one - CA 02 00 " « endl; i - 0; datapacket[i++] - Oxca; dataρacket[i++] - 0x02; datapacket[i++] - 0x00; for (i-0; i<3; printf("%x\n",datapackβt[i++] )) ; chk - 0; for (i-0; i<3; chk +- datapacket[i++] ) ; chk - ((-chk) + 1) f. 0x7F; printf("CHK : %x\n", chk); rββult - 0; for (i-0; i<3; rββult+-datapacket[i++J ) ; rβeult - ( (rββultt0x7F)+chk)i0x7F; printf( "Rββult x %x\n", rββult); //Now call function to calculate chkβm printf ( "CHKSM from function x %x\n" , calcChkβm(datapackβt, 3) ) ; - ^ reβult - 0; for (i-0; i<3; rββult+»datapackβt[i++] ) ; 11 reβult - ( (reeult.0x7P)+chk)_.0x7F; printf("Rββult i %x\n", rββult); cout « "Here's another one - 93 " « endl; i - 0; datapackβtri] - 0x93; for (i-0; i<l; print ( "%x\n",datapeckβt[i++] )) ; chk - 0; for (i-0; i<l; chk +- datapaσkβt[i++] ) ; chk - {(-chk) + 1) * 0x7F; printf("CHK x %x\n", chk); result - 0; for (i-0; i<l; reβult+-datapacket[i++] ) ; rβeult - ((rββult40x7F)+chk)-i0x7F; printf("Rββult x %x\n", rββult); cout << "Herβ'β another one for flow continuous waveform ndl; i - 0; datapackβt[i++] - 0xd2; datapackβt[i++] - 0x02; datapackβt[i++] - 0x01; for (i-0; i<3; printf("%x\n",datapacket[i++] )) ; chk - 0; for (i-0; i<3; chk +- datapacket[i++] ) ; chk - ((-chk) + 1) t 0x7F; printf("CHK x %x\n", chk); result - 0; for (i-0; i<3; rββult+-datapacket[i++] ) ; reβult - ( (rββultt0x7F)+chk)t0x7F; printf( "Rββult : %x\n", rββult); break; case 9x //AIO ekgSenβeA checkout lifdef BNABLE_GUIIF while (lkbhitO) printf("%d\r", βkgSenββA( ) ) ; lendif BNABLB_GUIIF break; 12 caβe 10x //Just checking βoroβ char * issues... for (i - 0; i<10; chararray[i] - i++); for (i - 0; i<10; i++) printf ( "chararray[ %d] - %x\n", i, chararray[i] ) ; charptr - chararray; for (i - 0; i<10; i++) printf("charptr + %d - %x\n", i, *(charptr+i) ) ; break; case 11: //Does overlaying a struct over an array work? overlayptr - (overlayatruct *) (&(dataStream[2] ) ) ; printf("cmd x %x, waveform x %x, ββb x %x, chk : %x \n", ovβrlayptr->cmd, overlayptr->waveform, overlayptr->ssb, overlayptr->chk) ; waveform - (dataStream[3] << 8) | dataStream[4 ) ; //is what we want printf("Calculated waveform : %x\n", waveform); break; //Answer: yes, but the order of the high byte and low byte is // reversed, unfortunately. case 12: //Let's checkout the function which validates checksum. dataStream[0] - 0x81; dataStream[l] - 0x01; dataStream[2] - 0x34; dataStream[3] - 0x9f; dataStream[4] - 0x05; dataStream[5] - calcChksm(dataStream,5) ; cout << validChksm(dataStream, 6) « endl; case 13: fmode - 0_BINARY; 7/handle - creat ( " f : \buildl\\data\\qtest . dat" , S_IREAD | S_IWRITE ) ; handle - creat ( " f : \\lBtatio2 \\buildl\\data\\qtest . dat " , S_IWRITE ) ; 13 -342- cout « "handle: " « handle « endl; for (i-0; i < 100; buffr[i] - i++); write(handlβ,buffr,100) ; cloβe(handle) ; break; case 14: //fwrite f i 1 e 1 0 fopen("f:\\l8tatio2\\buildl\\data\\qteBt.dat","wb" ) ; for (i-0; i < 100; buffr[i] - i++); fwrite(buffr, 100, 1, filelO); fclose(filelθ); break; _doe_gettime(ϋti eS) ; filell - fopen("f:\\lBtatio2\\buildl\\data\\txme.dat","wb' fwrite("OxFF", 1, 1,filell); fwrite(fistartbyte, 1, 1, filell); fwrite(fitimeS, sizeof(timeS) , 1, filell); fclose(filell) ; break; case 16: //Debugger bug buffer[0] - 0xd3; bufferf 1] - 0x06; buffer[2] - 0x40; buffer[3] - 0x06; buffer[4] - 0x23; buffer[5] - 0x00; buffer[6] - 0x00; csuin - calcChksm(buffer,8) ; printf( "chksm - %x\n", cβuin) ; break; case 17: //Test for file open/close performance hit. filel2 - fopen("cx\\junk.dat","wb" ); for (i-0; i < 100; buffr[i++] - i) ; //First make a big file, for (i-0; i< 100; i++) 14 fwritβ(buffr, sizeof(buffr) , 100, filel2); //Now write 100 more blocks withoug closing . _dos_gettime(&ti eS1) ; for (i-0; 1< 100; i++) fwrite(buffr, βizeof(buffr) , 1, filel2); _dos_gettime(&timeS2) ; //Now close file fclose(filel2) ; //Reopen and write 100 more blocks. _doβ_gettime(&timeS3) ; filel2 - fopen( "c: Wjunk.dat" , "ab" ); //Now write 100 more blocks withoug closing . for (i-0; i< 100; i++) fwrite(buffr, aizeof(buffr) , 1, filel2); _dos_gettime(&timeS4 ) ; filel3 - fopen( "c:\\results.dat" , "wb" ); fwrite(&timeSl, sizeof(timeSl) , 1, filel3) fwrite(&timeS2, sizeof(timeS2 ) , 1, filel3) fwrite(&timeS3, sizeof(timeS3) , 1, filel3) fwrite(&timeS4, sizeof(timeS4 ) , 1, filel3) fclose(filel2) ; closejfilel3) ; break; case 18: //Test for file append. filel2 - fopen("c:\\junk.daf , "wb" ) ; fwrite(buffr, sizeof(buffr) , 1, filel2); fclose(filel2) ; filel2 - fopen("c:\\junk.dat","ab") ; fwrite(buffr, sizeof(buffr) , 1, filel2); fclose(filel2) ; break; case 19: //Quick test for averaging valueβ into long ints. //Zero out averaging array. for (j-0; j < FLOWWFMAX; j++) flowAvgfj] - 0; 15 while (goon) for (j-0; j<FLOWWFMAX; j++) { flowAvg[j] +- ((flowbfr[(j*2)+2]«8) I flowbfr[ ( j*2)+3]) ; avgcount[j]++; if (avgcount[ ]>-FLOWAVGSIZE) { //Average the values. f 1 owWF s [ j ] [ f 1 owWF s i z e [ j ] ] lowAvg[ ] /FLOWAVGSIZE; fIOWWFBize[ ]++; avgcount[j] - 0; } > break; case 20: // cout « (int) r' ; break; case 21: strcpy(statusmsg, "This is a test"); cout << "sizeof (statusmsg) : " << sizeo (statusmsg) << endl; cout « "sizeof(astring) << sizeof(astring) << endl; cout << "sizeof (bstring) « sizeof (bstring) « endl; cout << "sizeof(cstring) « sizeof (cstring) << endl; cout « "astring[0] : " « astring[0] « endl; cout « "*(bstring+l) : " « *(bstring+l) « endl; cout << "astring : " << astring << endl; cout « "strlen(bstring) : " « strlen(bstring) « endl; cout << "strlen(astring) : " « strlen(astring) << endl; cout << "strcpy(astring, \"321\") : " « strcpy(astring, "321") « endl; break; case 22: x.afunc(0) ; break; case 23: 16 fptr[0] - afuncl; fptrfl] - afunc2; fptr[0](); fptr[l](); break; case 24: for (i - '0'; i <- '9'; i++) cout « i « endl; cout « (int)'O' « endl; cout « (int)'l' « endl; cout « (int) '9' « endl; break; case 25: //Testing using old findlnBuffer. //ALQe cout « findInBuffer{ π ALQ-0\r", response[0] [0] , responsef0] [ 1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "ALQ-l\r" , response[0] [ 0 ] , re8ponse[0] [1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "ALQ-2\r" , response[0] [ 0] , response! 0] [ 1 ] , plength); cout « " / " « plength << endl; cout « findlnBuffer( "ALQ-3\r" , response[0] [ 0] , response[0] [ 1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "ALQ-4\r" , response[0] [0) , response!0] [ 1 ] , plength); cout « " / " << plength << endl; cout « findlnBuffer( "ALQ-5\r" , response!0] [ 0] , response!0][ 1] , plength); cout << " / " « plength « endl; cout « findlnBuffer("ALQ-6\r", response[0] [ 0 ] , response[0] [ 1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "ALQ-7\r" , response[0] [0 ] , responsefO] [1] , plength); 17 cout << " / " « plength « endl; cout < findlnBuffer( "ALQ-8\r" , response! 0] (0] , response[0][l], plength); cout « " / " << plength « endl; cout « findInBuffer("ALQ-9\r", response[ 0] (0] , responβef 0] [ 1 ] , plength); cout « " / " << plength « endl; cout « findlnBuffer("ALQ-A\r", response[0] [0] , response[0] [ 1] , plength); cout « " / " « plength « endl; //ALRe cout « n " « endl; cout « findlnBuffer( "ALR\r" , response[ 1 ][0] , response[ 1][ 1] , plength); cout « " / " « plength « endl; cout << findlnBuffer( "ALQ\r" , response[ 1 ][ 0 ] , responsef 1 ] [ 1] , plength); cout « " / " « plength « endl; //MAC-nne cout << " " « endl; cout « findlnBuffer("A/C-00\r", response[2 ][0 ] , response[2][l], plength); cout « " / " « plength « endl; cout « findlnBuffer("A/C-01\r", response[2][0] , response[2] [ 1) , plength); cout « " / " « plength << endl; cout « findlnBuffer("A/C-02\r", responsef2 ] {0] , response[2] [ 1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "A/C-03\r" , response[ 2][0] , response[2] [ 1] , plength); cout << " / " « plength « endl; cout « indlnBuffer( "A/C-04\r" , response!2 ][0] , response!2][ 1] , plength); cout << " / " << plength << endl; cou t « findlnBuffer( "A/C-05\r" , response[2 ][0 ] , response[2 ] [ 1] , plength); cout « " / " « plength « endl; cout « findInBuffer( "A/C-95\r", responsef2 ] [ 0] , response!2] [ 1] , plength); 18 cout « " / " « plength « endl; cout « findInBuffβr("A/C-96\r", response!2 ] ! 0) , response!2 ][ 1 ] , plength); cout « " / " « plength « endl; cout « findlnBuffer("A/C-97\r", rβeponββ[2] [0] , reaponse[2 ] [ 1 ] , plength); cout « " / " « plength « endl; cout « findlnBuffer("A/C-98\r", rββponββ!2] (0] , response!2 ]! 1 ] , plength); cout << " / " « plength « endl; cout « findlnBuffer("A/C-99\r" , response!2] [0] , response!2 ] [ 1] , plength); cout « " / " « plength « endl; cout « findlnBuffer! "A/C-9A\r", rββponβe!2] [0] , response!2] [ 1] , plength); cout << " / " « plength « endl; //MBEe cout « " " « endl; cout << findlnBuffer("MBC\r", response[ 3 ] [ 0 ] , response!3] ! 1] , plength); cout « " / " « plength « endl; cout << findlnBuffer( "MBT\r" , response [ 3 )! 0 ] , response!3] [ 1 ) , plength); cout « " / " « plength « endl; //MIe cout « " " « endl; cout « findInBuffer("A/C-00\r", responβe[4 ] [0] , response[4 ] [1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "A/C-01\r" , response[ ] ! 0] , response!4 ][ 1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "A/C-98\r", rββponse[4 ] [ 0] , response!4 ]! 1) , plength); cout << " / " « plength « endl; cout « findInBuffer("A/C-99\r", response[4 ] [ 0 ] , response[4 ] ! 1] , plength); cout << " / " « plength « endl; cout « findlnBuffer( "IMV\r" , response[ ][ 0 ] , response[4][l], plength); 19 cout << ■ / - « plength « endl; cout « rββponββ!4 ] [0] , response[4 ) [ 1] , plength); cout << " / " « plength « endl; 5 //MIMVe cout « " " « endl; cout << indlnBuf e ( "IMV", response! 5 ][ 0 ] , response!5]( 1] , plength); cout << " / " « plength « endl; cout << findlnBuffer{ "IMv" , response[ 5 ][ 0 ] , - . n reeponse!5] [ 1] , plength); cout « " / " « plength « endl; //HOe cout << " " « endl; cout << findlnBuffer( "ON\r" , response[ 6 ][ 0] , response!6] [ 1] , plength); cout << " / " « plength « endl; 15 cout « findlnBuffer( "ON", response!6] [0] , response!6] [ 1] , plength) ; cout << " / " « plength « endl; //MSCe cout « " " « endl; cout << findlnBuffer( "SC\r" , response[ 7 ][ 0 ] , o response[7] [ 1] , plength); cout « " / " « plength « endl; cout << findlnBuffer ( "SCe" , response[ 7 ][ 0 ) , response[7] [ 1] , plength); cout « " / " « plength « endl; 5 //PMAXnne cout « " " « endl; cout << findlnBuffer( "00\r" , response[8 ][ 0 ] , response[8] [1] , plength); cout « " / " « plength « endl; cout << findlnBuffer( "01\r" , response[ 8 ][ 0 ] , response[8] [1] , plength); 0 cout « " / " « plength « endl; cout << findlnBuffer( "02\r" , response[ 8 ][ 0 ] , response[8] [1] , plength); cout « " / " « plength « endl; 5 20 cout << findInBuffer( "97\r", response[ 8 ][ 0 ] , response! 8 ][ 1 ] , plength); cout « " / " « plength « endl; cout « findlnBuffer! "98\r" , response! 8 ][ 0 ] , responee[8] [ 1) , plength); cout << " / " « plength « endl; cout << findlnBuffer( "99\r" , response[8 ][ 0] , response! 8 ][ 1] , plength); cout << " / " « plength « endl; cout << findlnBuffer( "-99\r" , response! 8 ][ 0) , response!8) ! 1 ] , plength); cout « " / " « plength « endl; //PMINnne cout « ( " " « endl; cout " << findlnBuffer ( "00\r" , response ! 9 ][ 0 ] , response!9]! 1] , plength); cout << " / " « plength << endl; cout << findlnBuffer( "01\r" , response[ 9 ][ 0 ] , response! 9] [ 1 ] , plength); cout « " / " « plength « endl; cout << findlnBuffer( "02\r" , response [ 9 ][ 0 ] , response!9][1] , plength); cout « " / " « plength « endl; cout << findlnBuffer ( "97\r" , response [ 9 ][ 0 ] , response[ ] [ 1] , plength); cout « " I " « plength « endl; cout << findlnBuffer( "98\r" , response [ 9 ][ 0 ] , response! ] [1] , plength); cout « " / " « plength « endl; cout << findlnBuffer( "99\r" , response[ ][ 0 ] , response[ 9][ 1] , plength); cout « " / " « plength « endl; cout << findlnBuffer( "-99\r" , response[ 9 ][ 0 ] , response!9][1] , plength); cout « " / " « plength << endl; //PPe cout « " " « endl; cout « findlnBuffer( "OOOcπΛr" , response! 10][0] , response[ 10] [ 1] , plength); cout « " / " « plength « endl; 21 cout « findlnBuffer( "001cm\r", response! 10] [ 0] , response! 10]! 1 ] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "002cm\r", response! 10] [ 0] , response! 10] [ 1 ] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "003cm\r", response[ 10 ] [ 0] , response! 10] [ 1 ] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "998cm\r", response[ 10] [ 0 ] , response! 10][ 1 ) , plength); cout « H / " « plength « endl; cout « findlnBuffer( n 999cm\r" , response[ 10 ] [ 0 ] , response! 10] [ 1 ] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "-001cm\r" , responβe[ 10] [ 0] , response! 10]! 1 ] , plength); cout « " / " << plength « endl; cout << findlnBuffer("-002cm\r", response[ 10] [ 0] , response! 10][ 1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "-003cm\r", response! 10] [0] , response! 10] [ 1 ) , plength); cout << " / " « plength « endl; cout << findlnBuffer( "-998cm\r" , response[ 10] [0] , response! 10] [ 1] , plength); cout « " I " « plength « endl; cout « findlnBuffer( "-999cm\r" , response! 10][0] , response! 10 ][ 1 ] , plength);. cout « " / " << plength « endl; cout « findlnBu fer( "-999c\r" , response[ 10 ][ 0] , response! 10][ 1 ] , plength); cout « " I " « plength « endl; //RBRe cout « " " « endl; cout « findlnBuffer( "00.0\r" , response! 11 ][0] , response! 11] [ 1 ] , plength); cout << " / " « plength « endl; cout « findlnBuffer( "00. l\r", response! 11 ][ 0] , response! 11] [ 1] , plength); 22 cout << " / " << plength << endl; cout « findlnBuffer( "00.2\r" , response! 11 ]! 0 ] , response! 11 ][ 1 ] , plength); cout << " / " « plength « endl; cout « findlnBuffβr("01.0\r" , response! 11]!0] , response! 11] [ 1] , plength); cout « " / " « plength « endl; cout « findInBuffer("01.1\r", response! 11 ] [ 0] , response! 11]! 1] , plength); cout << " / " « plength « endl; cout « findInBuffer("01.2\r", response! 11 ][0] , response! 11]! 1 ] , plength); cout « " / " « plength « endl; cout « findInBuffer("02.2\r" , response! 11 ]{0] , response! 11 ][ 1 ] , plength); cout << " / " << plength << endl; cout « findlnBuffer( "03.2\r" , response! 11 ][ 0] , response! 11 ] t 1] , plength); cout « " I " « plength << endl; cout « findInBuffer( "09.2\r", response[ 11 ]!0] , response! 11] [ 1] , plength); cout « " / " « plength « endl; cout « findInBuffer( "19.9\r", response!11]!0] , response! 11 ][ 1] , plength); cout « " / " « plength « endl; cout « findInBuffer("29.9\r", response[ 11 ]! 0] , response! 11] [ 1] , plength); cout << " / " « plength « endl; cout « findInBuffer("89.9\r" , response[ 11 ]( 0 ) , response!11][ 1] , plength); cout « " / " « plength « endl; cout « findInBuffer("99.9\r" , response[ 11 ][0 ] , response! 11] [ 1] , plength); cout « " / " « plength « endl; cout « findInBuffer( M 000.\r", response! 11](0] , response! 11] [1] , plength); cout « " / " « plength « endl; cout « findlnBuffer( "999. \r", response! 11 ][0] , response! 11] [1] , plength); 23 cout « " / " << plength << endl; cout « rββponβe! 11 ) (0] , response! 11 ] [ 1 ) , plength); cout << " / " « plength « endl; cout << " " « endl; cout « findInBuffβr{ response! 12] (0] , response! 12][1] , plength); cout << " / " « plength « endl; cout << findlnBu er( "0. response! 12] [0) , response!12][ 1J , plength); cout << " / " « plength « endl; cout « findlnBuffer("1. response! 12 J !0) , response! 12) !1) , plength); cout « " / " « plength << endl; cout << findlnBuffer("2.2β\r", rββponβe( 12 ]! 0 ] , response!12] [1] , plength); cout « " / " « plength « endl; cout « findInBuffer("8.2β\r", response! 12) [0] , response! 12]!1 ] , plength); cout « " / " « plength « endl; cout « findlnBuffβr("9.2s\r", response! 12 ] [0] , response! 12] [1] , plength); cout << " / " « plength « endl; cout << findlnBuffer! response! 12 ) ! 0] , response! 12 ] [1 ] , plength); cout « " / " « plength « endl; cout « findInBuffβr( "9.9\r", response( 12] [ 0 ] , response! 12] ( 1] , plength); cout << " / " « plength « endl; ItRSTe cout << " " « endl; cout « findlnBuffer("RDY\r", response! 13 ] ! 0 ] , response! 13] [1] , plength); cout « " / " « plength « endl; cout « findlnBuf e ( "RDY", rββponβe[ 13 ][ 0 ] , response! 13] [ 1] , plength); cout << " / " « plength << endl; //SBRnne 24 -353- cout << " " « endl; cout << , response( 14 ]!0) , reeponee! 14][ 1 ] , plength); cout << " / " << plength « endl; cout << reeponee! 1 ]!0] , reeponee! 14 ][ 1) , plength); cout << " / " « plength « endl; cout « indlnBuffer( "02\r", reeponee( 14 ]!0] , reβponβe[ 14 ]( 1) , plength); cout << " / " « plength « endl; cout « findInBuffer("90\r", reeponee( 14 ]!0] , response! 14 ][ 1) , plength); cout << " / " « plength « endl; cout << findlnBuffer( "98\r", response[ 14 ] [0) , response! 14 )[ 1) , plength); cout << " / " « plength « endl; cout « findlnBuffer( "99\r" , response[ 14 )! 0] , reeponee! 1 ]( 1] , plength); cout « " / ■ « plength « endl; cout « findlnBuffer( "990\r" , response! 14 ][0] , response! 1 ]! 1] , plength); cout << " / " « plength « endl; //SITn.ne cout << " " « endl; cout « findInBuffβr("0.0β\r", response!15] [0] , reeponee[ 15][ 1] , plength); cout « " / " « plength « endl; cout « findlnBuffβr("0. response! 15][0] , response! 15] ! 1] , plength); cout « " / " « plength « endl; cout « findInBuffer("0.2β\r", response! 15]!0] , response! 15] ! 1] , plength); cout << " / " « plength « endl; cout « findlnBuffβr("3.0s\r", response! 15] [0] , response! 15] ! 1] , plength); cout « " / " « plength « endl; cout « findlnBuffor( "5. , reeponee[ 15][0 ] , reeponee! 15]!1) , plength); cout « " / " « plength << endl; 25 -354- cout « findlnBuffer( response[ 15]! 0] , response! 15 ]! 1 ] , plength); cout << " / " « plength « endl; cout « findlnBuffer( "9.9\r" , reeponee[ 15 ][ 0] , response! 15) [ 1] , plength); cout << " / " « plength « endl; case 26: //Testing using new ventFindlnBuffer. //ALQe cout << ventFindInBuffβr("ALQ-0\r", strlen( "ALQ-0\r" responβefO) [0] , response[0] 1] value cout << " / " « value « endl; cout « ventFindlnBuffer( "ALQ-l\r", strlen( "ALQ-l\r" response!0) [0] , reaponse(0] 1], value) ; cout << " / " << value << endl; cout << * ; > ntFindInBuffer( "ALQ-2\r", strlen( "ALQ-2\r" reβponse[0] (0] , reβponse[0] 1] value! cout << " / " << value << endl; cout << ventFindInBuffer("ALQ-3\r", strlen( "ALQ-3\r" response[0] [0] , responsefO] 1] value) ; cout << " / " « value « endl; cout « ventFindlnBuffer("ALQ-4\r" , strlen( "ALQ- \r" response[0] [0] , response[0] i] value) ; cout « - I " « value « endl; cout « ventFindInBuffer("ALQ-5\r", strlen( "ALQ-5\r" response[0] [0 ] , response! 0] i] value) ; cout << " / " << value « endl; cout « ventFindInBuffer("ALQ-6\r", strlen( "ALQ-6\r" response[0] [0] , responsefO] i], value) ; cout << " / " « value « endl; cout « vβntFindInBuffer("ALQ-7\r", strlen ( "ALQ-7\r" response!0] [0] , response! 0] 1)/ value) ; 26 cout << " / " « value « endl; cout « ventFindInBuffer("ALQ-8\r", strlen{ "ALQ-8\r" ) , responBe(0] [0] , response[0] [ 1] , value) ; cout « " / " « value « endl; cout « ventFindlnBuffer("ALQ-9\r", strlen( "ALQ-9\r M ) , reβponsefO] [0] , response! 0][ 1 ] , value) ; cout << " / " << value << endl; cout « ventFindlnBuffer("ALQ-A\r" , strlen{ "ALQ-A\r" ) , reβponsefO] [0] , response!0][ 1] , value) ; cout << " / " << value « endl; //ALRe cout << " " << endl; cout « ventFindlnBuffer( "ALR\r" , strlen( "ALR\r" ) , response! 1] [0] , response! 1 ]! 1 ] , value) ; cout « " / " << value << endl; cout « ventFindInBuffer("ALQ\r", strlen( "ALQ\r" ) , response! 1][0] , response[ 1][ 1] , value) ; cout « " / " « value << endl; //MAC-nne cout << " " « endl; cout « ventFindlnBu fer( "A/C-00\r" , strlen( "A/C-00\r" ) , response[2] [0] , response!2)! 1] , value) ; cout << " / " « value « endl; cout « ventFindlnBuffer("A/C-01\r" , strlen( "A/C-01\r" ) , response[2][0], response[2][ 1] , value); cout << " / " << value << endl; cout << ventFindInBuffer("A/C-02\r", strlen( "A/C-02\r M ) , response!2] !0] , response[2 ] [ 1 ] , value) ; 27 cout << " / " << value << endl; cout « vβntFindInBuffer("A/C-03\r", βtrlen( "A/C-03\r" ) , response[2] JO] , response[2 ) ! 1] , value) ; cout « " / " << value « endl; cout « ventFindInBuffer("A/C-04\r", strlen( "A/C-04\r" ) , response[2] [0] , response!2 ][ 1] , value) ; cout << " / " << value << endl; cout « ventFindInBuffer("A/C-05\r" , strlen{ "A/C-05\r" ) , response[2] [0] , response!2 ][ 1) , value) ; cout << " / " << value << endl; cout « ventFindInBuffer("A/C-95\r", strlen( "A/C-95\r" ) , response!2] [0] , response!2 ][ 1] , value) ; cout « " / " « value « endl; cout « ventFindInBuffer("A/C-96\r", strlen( "A/C-96\r" ) , response[2] [0] , response[2 ] [ 1 ] , value) ; cout << " / " << value << endl; cout « ventFindInBuffer("A/C-97\r", strlen( "A/C-97\r" ) , response!2] [0] , response!2 ][ 1 ] , value) ; cout << " / " << value << endl; cout « ventFindInBuffer("A/C-98\r", strlen( "A/C-98\r" ) , response[2] [0] , response!2 ][ 1 ] , value) ; cout << " / " << value « endl; cout « ventFindInBuffer("A/C-99\r", strlen( "A/C-99\r" ) , responβe[2] [0] , response[2] [ 1] , value) ; cout « " / " « value « endl; cout « ventFindInBuffer("A/C-9A\r π , βtrlen{ "A/C-9A\r" ) , 28 response[2] [0] , response!2 ][ 1 ] , value) ; cout « " / " « value « endl; //MBEe cout « " " « endl; cout « ventFindInBuffer( M MBC\r", strlen( "MBC\r" ) , response[3] [0] , response[3] [ 1 ] , value) ; cout << " / " « value « endl; cout « ventFindInBuffer("MBT\r", strlen( "MBT\r" ) , reβponse!3] [0] , response[ 3][ 1 ] , value) ; cout << " / " << value « endl; //MIe cout « " " « endl; cout « ventFindlnBuf er("A/C-00\r", strlen( H A/C-00\r" ) , response!4] [0] , response!4]! 1 ] , value) ; cout « " / " << value « endl; cout « ventFindInBuffer("A/C-01\r", strlen( "A/C-01\r" ) , responBe[4 ] [0] , response! ][ 1] , value); cout << " / " « value « endl; cout « ventFindInBuffer("A/C-98\r", strlen( "A/C-98\r" ) , response[4 ] [0] , response! ]! 1 ] , value) ; cout « " / " « value « endl; cout « ventFindInBuffer("A/C-99\r", strlen( "A/C-99\r" ) , response[4 ] [0] , reβponse[4] [1], value) ; cout « " I " « value « endl; cout « ventFindInBuffer("IMV\r", strlen( M IMV\r" ) , response[4 ] [0] , reBponβe[4] [ 1] , value) ; cout « " I " « value << endl; cout «ventFindlnBuffer( "A/C--99\r" , strlen( "A/C~99\r n ) , 29 response[4 ] [0] , response! 4 ][ 1 ] , value) ; cout « " / " << value « endl; //MIMVe cout « " " « endl; cout « ventFindInBuffer("IMV", strlen( "IMV" ) , response[5] [0] , response[5] [ 1] , value) ; cout << " / " « value << endl; cout << ventFindlnBuffer( "IMv" , strlen( "IMv" ) , response[5)[0], response[5] [ 1] , value) ; cout << " / " << value << endl; //MOe cout << " " « endl; cout « ventFindInBuffer("ON\r", øtrlen( "0N\r" ) , response!6][0] , response! 6 ][ 1 ] , value) ; cout << " / " « value << endl; cout « ventFindlnBuffer("ON", strlen( "ON" ) , response!6] [0] , response! 6 ][ 1] , value); cout « " / " « value « endl; //MSCe cout << " " « endl; cout « ventFindlnBuffer( "SC\r" , strlen( "SC\r" ) , re8ponβe[7 ] [0] , response[ 7 ][ 1 ] , value) ? cout << " / " « value « endl; cout << ventFindlnBuffer( "SCe" , strlen( "SCe" ) , response[7] !0] , response!7 ]! 1 ] , value) ; cout << " / " « value << endl; //PMAXnne cout « " " « endl; cout « ventFindlnBuffer( "00\r" , βtrlen( "00\r" ) , 30 response[8] [0 ] , response! 8] [ 1 ] , value) ; cout << " / " << value << endl; cout « ventFindInBuffer("01\r", strlen( "01\r" ) , responsefβ] [0] , response[8] f 1] , value) ; cout « " / " « value « endl; cout « ventFindInBuffer("02\r", βtrlen( "02\r" ) , responsefδ] [0] , response!8]! 1) , value) ; cout « " I " « value << endl; cout « ventFindInBuffer("97\r", strlen( "97\r" ) , response!8][0] , response!8]! 1] , value) ; cout << " / " « value << endl; cout « ventFindlnBuffer( "98\r", strlen( "98\r" ) , response!8] [0] , response[8][ 1] , value) ; cout << " / " << value << endl; cout « ventFindlnBuffer( r -99\r", strlen( 99\r" ) , response!8] !0] , response!8)[ 1] , value) ; cout « " / " « value << endl; cout « ventFindInBuffer("-99\r", strlen( "-99\r" ) , response[8] [0] , response[ 8] [ 1 ) , value) ; cout << " / " << value << endl; //PMINnne cout « " " « endl; cout « ventFindInBuffer("00\r", βtrlen( "00\r" ) , response[9] [0] , response!9 ] [ 1] , value) ; cout << " / " « value << endl; cout « ventFindlnBuffer( "01\r", strlen) "01\r" ) , response! ] [0] , response!9 ] f 1] , value) ; 31 cout << << value << endl; cout « ventFindInBuffer("02\r", strlen( "02\r" ) , response!9] [ 0 ] , response! 9][ 1 ] , value ) ; cout << « value << endl; cout « ventFindInBuffer("97\r", strlen( "97\r" ) , response[9] [0] , response!9] ! 1 ] , value) ; cout « " / " « value « endl; cout « ventFindInBuffer("98\r", βtrlen( "98\r" ) , response! ] [0] , response! 9][ 1 ] , value) ; cout << " / " << value << endl; cou t « ventFindInBuffer("99\r", strlen( "99\r" ) , response!9] [0] , response!9][ 1] , value) ; cout « " / " « value << endl; cout « ventFindInBuffer("-99\r", strlen( "-99\r" ) , response! 9] [0] , response[ ][ 1 ] , value) ; cout « " / " « value « endl; //PPe cout « " " « endl; cout « ventFindInBuffer("000cm\r", strlen( "OOOcmXr" ) , responseflO] [0] , response! 10] [ 1] , value' cout « " I " « value « endl; cout « ventFindlnBuffer( "OOlcmXr", βtrlen( "OOlcmXr" ) , response!10] [0] , response! 10] [ 1 ] , value) ; cout << " / " « value << endl; cout « ventFindInBuffer("002cm\r", strlen( "002cm\r" ) , response!10] [0] , response! 10] ! 1] , value) ; cout << " / " << value << endl; 32 cout << ventFindInBuffer("003ce\r", βtrlen("003cm\r" ) , rββponββ[10] [0] , reeponee( 10] ( 1] , value) ; cout « " / " « value « endl; cout << ) , [1], value) ; cout « " / " « value « endl; cout « ventFindInBuffβr("999cβ\r", βtrlen( "999cxnXr" ) , [0J, reeponee[10) !1] , value) ; cout « " / " « value « endl; cout << βtrlβn( "-OOlcβXr" ) , 0] , reeponee[10] [1] , value) ; cout « " / " « value « endl; cout « ) , ] , value) ; cout << " / " << value « endl; cout « ventFindInBuffβr("-003cm\r", βtrlen( "-003cm\r" ) , reeponee[10] [0], reeponee[10] [ 1), value) ; cout « " / " « value « endl; cout << ventFindInBuffβr("-998cm\r", βtrlβn( "-998cm\r" ) , reβponse[10] [0] , response[10) [1] , value) ; cout << " / " « value « endl; cout « ventFindInBuffer("-999cm\r", atrlen( "-999cm\r" ) , reβponee[10] [0] , response!10] [1] , value) ; cout « " / " « value « endl; cout « ventFindInBuffβr("-999c\r", βtrlen{ "-999c\r" ) , rβsponsβ[10] [0], response[10) [ 1) , value) ; 33 cout « << value << endl; //RBRe cout « " " « endl; cout « ventFindlnBuffer( "00.OXr", strlen( "OO.OXr" ) , response!11) [0] , response! 11)! 1] , value) ; cout « " / " « value « endl; cout « ventFindlnBuffer( "00. IXr", strlen( "00. l\r" ) , responBef11] [0] , response! 11] [ 1] , value); cout << " / " << value << endl; cout « ventFindInBuffer("00.2\r", strlen( "00.2\r" ) , response! 11] [0] , response! 11] ! 1] , value) ; cout « " I " « value << endl; cout « ventFindlnBuffer( "01.0\r", strlen("01.0\r" ) , response!11] [0] , response! 11] [ 1 ) , value) ; cout « " I " « value « endl; cout « ventFindInBuffer("01.lXr", strlen("01. IXr" ) , response!11] [0] , response! 11] [ 1] , value) ; cout « " / " « value « endl, cout « ventFindlnBuffer( "01.2 x " , strlen( "01.2\r" ) , response[11] [0] , response! 11] [ 1) , value) ; cout << " / " « value « endl; cout << ventFindlnBuffer("02.2\r", strlen( "02.2\r" ) , response!11] [0] , response! 11] [ 1] , value) ; cout << " / " « value « endl; cout « ventFindInBuffer("03.2\r", strlen( "03.2\r" ) , response! 11] [0] , response! 11 ] [ 1] , value) ; cout << " / " « value « endl; 34 cout « ventFindInBuffer("09.2\r", strlen ( "0 .2\r" ) , response! 11] [0] , response! 11) [ 1] , value) ; cout << " / " « value « endl; cout « ventFindInBuffer("19.9\r", strlen("19.9\r" ) , response[11] [0] , response[ 11] [ 1] , value) ; cout << " / " << value « endl; cout « ventFindInBuffer("29.9\r", strlen( "29.9\r" ) , response! 11 ] [0] , response! 11][ 1] , value) ; cout « " / " << value << endl; cout « ventFindlnBuffer( "89.9\r", strlen( "89.9\r" ) , response! 11] [0] , response! 11] [ 1] , value) ; cout << " / " « value « endl; cout « ventFindlnBuffer( "99.9\r", strlen( "99.9\r" ) , response[ 11] [0] , response[ 11 ] [ 1] , value) ; cout « " I " « value << endl; cout « ventFindlnBuffer( "000. \r", strlen( "000. \r" ) , response[ 11] [0] , response[ 11] [ 1] , value) ; cout << " / " << value « endl; cout « ventFindlnBuffer( "999. \r", strlen( "999. \r" ) , responsefll] [0] , response[ 11] [ 1] , value) ; cout << " / " « value << endl; cout « ventFindlnBuffer( "9999. \r", strlen ("9999. \r" ) , response! 11] [0] , response[ 11] [ 1] , value) ; cout « " / " « value « endl; //RITe cout << " " « endl; cout « ventFindlnBuffer("0.0s\r" , strlen( "0.0s\r" ) , 35 response[ 12] [0] , response! 12 ][ 1 ] , value) ; cout << " / " << value << endl; cout « ventFindInBuffer(" ) , re 2] [ 1] , value) cout << " / " « value « endl; cout « ventFindlnBuffer( "1. ls\r" , βtrlen( "1. ls\r" ) , response! 12] [0] , response!12] [ 1] , value) ; cout << " / " « value << endl; cout « ventFindlnBuffer( "2.2s\r", atrlen( "2.2s\r" ) , response!12] [0] , reeponee[ 12]!1] , value) ; cout « " / " << value << endl; cout « ventFindlnBuffer( "8.2s\r", strlen("8.2s\r" ) , response[12] [0] , response! 12] ! 1] , value) ; cout << " / " << value << endl; cout « ventFindlnBuffer( "9.2s\r", strlen( "9.2s\r" ) , response! 12] [0] , response! 12][ 1 ] , value) ; out << " / " « value << endl; cout « ventFindInBuffer("9.9s\r", strlen( "9.9s\r" ) , response! 12] [0] , response! 12][ 1) , value) ; cout << " / " « value << endl; cout « ventFindlnBuffer("9.9\r" , strlen( "9.9\r" ) , response! 12) [0] , response! 12] [ 1) , value) ; cout << " / " « value << endl; //RSTe cout « " " « endl; cout « ventFindInBuffer("RDY\r", strlen( "RDY\r" ) , response!13] [0] , response! 13] [ 1] , value) ; 36 cout << " / " << value « endl; cout << ventFindlnBuffer( "RDY" , βtrlen( "RDY" ) , response! 13) [0] , response! 13][ 1] , value) ; cout « " / " << value « endl; //SBRnne cout « " " « endl; cout « ventFindInBuffer("00\r", βtrlen( "00\r" ) , response!14) [0] , response!14 )! 1] , value); cout « " / " « value « endl; cout « ventFindInBuffer("01\r", strlen( "01\r" ) , response! 14] [0] , response! 14 ][ 1] , value) ; cout << " / " << value << endl; cout << ventFindInBuffer("02\r", strlen( "02\r" ) , response!14] [0] , response!14]!1] , value) ; cout << " / " « value << endl; cout << ventFindInBuffer("90\r" , strlen{ "90\r" ) , response! 14] [0] , response! 1 ][ 1] , value) ; cout << " / " « value << endl; cout « ventFindInBuffer("98\r", atrlen( "98\r" ) , response! 14] [0] , response! 14 ][ 1] , value); cout « " / " « value « endl; cout « ventFindInBuffer("99\r", strlen( "99\r" ) , response! 14] [0] , response! 14 ][ 1 ] , value) ; cout << " / " « value « endl; cout « ventFindlnBuffer( "990\r", strlen( "990\r") , respon8e[14] [0] , response[ 14 ][ 1 ] , value) ; cout « " / " << value « endl; 37 value) ; cout « " / " « value « endl; cout « value) ; cout « " / " « value « endl; cout « ventFindlnBuffβr( ) , reeponee! 5J[ ), rββponβe! 15) [ 1 ) , value) ; cout « " / " « value « endl; cout « ventFindlnBuffer( "3.Oβ\r", βtrlβn( "3.0β\r" ) , reeponee! 15) [0], reeponee! 15][ 1 ) , value) ; cout « - ■ / " « value « endl; cout « ventFindlnBuffβr( "5. ls\r", βtrlβn( "5. ) , response!15] [0], response! 15] [ 1 ] , value) ; cout « " / " « value « endl; cout << ventFindlnBuffer( "9.9β\r", βtrlβn( "9.9β\r" ) , reeponee! 15] [0], reeponee( 15][ 1 ] , value) ; cout « " / " « value << endl; cou t « ventFindlnBuffer( "9.9\r", βtrlβn( "9.9\r" ) , reeponee!15] [0], reeponee( 15 ]( 1 ) , value) ; cout « " / " « value << endl; break; βtring2!7] - 'a'; cout « Btrcmp(βtringl, βtring2) « endl; default: ; 38 > > 39 PROGRAM LISTING DISPSPAC.PAS unit Dispspac; { The depressed state of a bitMap button is acheived by setting its enabled :•=» false. But that means every other button has to have all the rest enabled equals true. } interf ce uses SysUtils, WinTypes, inProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Buttons; type myArray - array[ 1..1000] of integer; diβplayArray - array!1..500] of integer; TDisplaySpace - class(TFoπn) Shapel: TShape; Shape2: TShape; Shape3: TShape; Labell: TLabel; shapeMessageSpace: TShape; BitBtnl: TBitBtn; BitBtn2: TBitBtn; BitBtn3: TBitBtn; BitBtn : TBitBtn; ERlbl: TLabel; Label3: TLabel; breathRateLbl: TLabel; coreTe pLbl: TLabel; Labelβ: TLabel; ventVol: TLabel; Labelθ: TLabel; BitBtnβ: TBitBtn; Label9: TLabel; LabellO: TLabel; Shape4: TShape; Shape5: TShape; Image4 : TImage; Shape9: TShape; ShapelO: TShape; Shapell: TShape; displaySpaceMessageLbl: TLabel; Image5: TImage; Imageβ: TImage; Labell3: TLabel; ekgBtn: TButton; Labell6: TLabel; Labell7: TLabel; Image8: TImage; Imagel: TImage; airWaveFormLbl: TLabel; airWayYaxisLbl: TLabel; Image2: TImage; Image9: TImage; EKGpanel: TPanel; ekgTitleLbl: TLabel; gridShapel: TShape; Image7: TImage; Label14: TLabel; Image7h: TImage; Image3: TImage; PaintBoxl: TPaintBox; PaintBox2: TPaintBox; gridShape2: TShape; PaintBox3: TPaintBox; gridShape3: TShape; gridShape4 : TShape; PaintBox4 : TPaintBox; gridShape5: TShape; PaintBox5: TPaintBox; ti elnMinutesLbl: TLabel; Label15: TLabel; dotl: TShape; dot2: TShape; dot3: TShape; dot4 : TShape; dot5: TShape; ekgReturnLbl: TLabel; touchShape: TShape; Label23: TLabel; returnBtn: TBitBtn; oxSatBtn: TButton; Label2: TLabel; Label7: TLabel; Label21: TLabel; expVolLbl: TLabel; peakPresLbl: TLabel; avgPresLbl: TLabel; Label24: TLabel; flowR-Rlbl: TLabel; Label25: TLabel; iOverElbl: TLabel; rcrdShrtShape: TShape; rcrdShrtLbl: TLabel; rcrdLngShape: TShape; rcrdLngLbl: TLabel; Label26: TLabel; entC021bl: TLabel; Label27: TLabel; capRRlbl: TLabel; Label28: TLabel; tdlVolLbl: TLabel; Label29: TLabel; recordlntervalCyclesLbl: TLabel; Label30: TLabel; recordCyclesLbl: TLabel; Label31: TLabel; timesThruLbl: TLabel; xPosLbl: TLabel; capNoStatBtn: TBitBtn; flowBtn: TBitBtn; timeDisplay: TLabel; Label33: TLabel; capNoStatRecordShape: TShape; flowRecordShape: TShape; twentyHz: TTi er; Label35: TLabel; testBtn: TButton; testLbl: TLabel; Buttonl: TButton; bursSizeLbl: TLabel; snglRealBurstBtn: TButton; Labell8: TLabel; tidalVolLbl: TLabel; Labell9: TLabel; ExpiatoryLbl: TLabel; Label20: TLabel; meanAirPressLbl: TLabel; Label22: TLabel; startLbl: TLabel; Label36: TLabel; waveSizeLbl: TLabel; Label34: TLabel; RespRateLbl: TLabel; oxSatTitleLbl: TLabel; pressBtn: TButton; volBtn: TButton; floShrtRcdShape: TShape; floShrtRcdLbl: TLabel; flowStopShape: TShape; flowStopLbl: TLabel; pC02backgndShape: TShape; oxScalelmage: TImage; Label4: TLabel; PeaklnLbl: TLabel; Label5: TLabel; flowIoverELbl: TLabel; Label37: TLabel; FlowCurveSampleValueLbl: TLabel; dpiS: TLabel; ■ dpiSizeLbl: TLabel; Label38: TLabel; inStartNotEqZeroLoopLbl: TLabel; Label39: TLabel; inStartEqZeroLoopLbl: TLabel; recordingLbl: TLabel; diagOnOffswitchLbl: TLabel; pulsOxRedSquareShape: TShape; gainUp: TButton; gainDn: TButton; moveUp: TButton; oveDn: TButton; gainValLbl: TLabel; offSetValLbl: TLabel; hrBarBackgndShape: TShape; Label32: TLabel; Label40: TLabel; Label41: TLabel; oxSatBackgndShape: TShape; Label42: TLabel; oxSatBarLbl: TLabel; oxSatBarShape: TShape; nowLbl: TLabel; hrBarLbl: TLabel; beatsLbl: TLabel; Label46: TLabel; Label43: TLabel; Label47: TLabel; rateOLbl: TLabel; arrowlimg: TImage; arrow2img: TImage; arrow4img: TImage; arrow3img: TImage; arrow5img: TImage; Label48: TLabel; Label44: TLabel; te perWarnShape: TShape; flowRateDataArrayLbl: TLabel; setBPpanel: TPanel; pumpBtn: TButton; displayCuffBtn: TButton; Button4 : TButton; setCycleBtn: TButton; cuffReturnBtn: TButton; setCyclePnl: TPanel; RadioButtonl: TRadioButton; RadioButton2: TRadioButton; cancelCycleBtn: TButton; RadioButton5: TRadioButton; RadioButtonβ: TRadioButton; RadioButtonθ: TRadioButton; RadioButton9: TRadioButton; okBtn: TButton; Panell: TPanel; LabelδO: TLabel; Label51: TLabel; Label52: TLabel; Label53: TLabel; Button2 : TButton; Button3: TButton; Button5: TButton; Buttonδ: TButton; Button7: TButton; Panel2: TPanel; Label54: TLabel; RadioButton3: TRadioButton; RadioButton4 : TRadioButton; Buttonδ: TButton; RadioButton7 : TRadioButton; RadioButton10 : TRadioButton; RadioButtonll: TRadioButton; RadioButtonl2 : TRadioButton; Button9: TButton; procedure ShapelMouseDown(Sender: TObject; Button TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ImagelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState? X, Y: Integer); procedure Shape3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Shape2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Image2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BitBtn6Click(Sender: TObject); procedure ShapelOMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormDestroy(Sender: TObject); procedure ekgBtnClick(Sender: TObject) ; procedure BitBtnlMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure gridShapelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure gridShape2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure gridShape3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure gridΞhape4MouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure gridShape5MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure touchShapeMouseDow (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BitBtn2MouseDown(Sender: > TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BitBtn3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BitBtn4MouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure returnBtnClick{Sender: TObject); procedure oxSatBtnClick(Sender: TObject) ; procedure rcrdShrtLblMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure rcrdLngLblMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure capNoStatBtnClick(Sender: TObject) ; procedure flowBtnClick(Sender: TObject); procedure twentyHzTimer(Sender: TObject); procedure testBtnClick(Sender: TObject); procedure ButtonlClick(Sender: TObject); procedure snglRealBurstBtnClick(Sender: TObject) ; procedure pressBtnClick(Sender: TObject); procedure volBtnClick(Sender: TObject); procedure floShrtRcdShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure flowStopShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure diagOnOffswitchLblClick(Sender: TObject); procedure gainUpClick(Sender: TObject); procedure moveUpClick(Sender: TObject); procedure moveDnClick(Sender: TObject); procedure gainDnClic (Sender: TObject); private { Private declarations } public { Public declarations } end; {These are forwards, but the keyword "forward" makes an error.} procedure drawBRcurve; procedure drawSysBPcurve; procedure drawDisBPcurve; procedure drawOxcurve; procedure drawTe pCurve; procedure drawHRcurve; procedure drawMINcurve; procedure drawDispCurve(dataArray: displayArray; farRight, dispSize, bottom, datAralndex: integer; eraseColor, drawColor: TColor; floor : integer) ; procedure drawVentCurve(datarray: displayArray; farRt, dispSize, bottom, datAralndex: integer; eraseColor, drawColor: TColor; floor : integer); procedure drawMainCurve(datarray: displayArray; farRt, dispSize, bottom, datAralndex: integer; eraseColor, drawColor: TColor; floor : integer); procedure sampleNovaBoards; procedure toggleTheDiagnosticLabels(diagLabelVisibleState : Bool); var {Global to program} diagLabelVisibleState : Bool; oxGain : integer; DisplaySpace: TDiβplaySpace; NovaSamplerWriteCntr : Longint; capnoSamplerCounter : Longint; barGraphCounter , onePerCounter, novaSa plerCounter , ventSamplerCounter, curvePlotCounter : integer; ventSamplerEnabled : Bool; firstBurat, flowEnabled, EtC02Enabled, pulsOxEnabled : Bool; globalInspiC02, globalC02RespRate, globalOxSat, globalEndTidal, globalHeartRate : integer; globalloverErat o, globalTidalVol, globalFlowMeanPress , globalFlowPeaklnPress : integer; globalFlowRespRate, globalFlowExpiatory : integer; whichFlow, board : integer; onePerSecondEnabled : Bool; allBoardsEnabled, spo2BoardEnabled, capnoBoardEnabled, flowBoardEnabled : Bool; anyRecOn : Bool; sendCounter : integer; burstPosition, burβtGain : integer; flowPos, presPos, volPos, flowGain, presGain, volGain : integer; drawCol, eraseCol : TColor; coreTemp, avgHR, avg02sat : integer; {static variables for the 20Hz timer procedure} { LOGGING COMMAND CONSTANTS } const FLOWBOARD = 1; const CAPNOSTATBOARD = 2; const SP02BOARD =« 3; const FLOW_FLOW = 1 const FL0W_PRES = 2; const FLOW VOL = 3; const CAPNO_BTN - 4; const PULSOX_BTN - 5; implementation uses Repair, Ventdet, Main, Co nunit, Dxagvent, Neuro; {$R *.DFM} var { GLOBAL to just this form} defibOnToggle : Bool; theScreen: TScreenControl; i, xPo, xPo20 : integer; { for the various drawCurve definitions} powerState : integer; waveFoπnModeNumber : integer; drawEKGenabled : Bool; testOnePerCountr, onePerCountr integer; recordFlowCapCycles : integer; shoAroCntr : integer; const DISPLAYSIZE = 379; {379} const SMALLDISPSIZE - 95; {100} const CPU = 9; const COND =» 1; const POWER = 1; {pumpControl Events} const SUCPOWER «= 1; const VENTPOWER =» 2; type oxWave = array [ 1..1000] of char; intWave = array! 1..20] of integer; Params = array fl..10] of integer; triplet = array [1..3] of integer; arrayPntr π A intWave; arrayOf Pointers «= array fl..3] of arrayPntr; wavePntr = Λ oxWave; FlowPointer - Λ Params; staticDataPntr = Λ triplet; CapnostatPointer = A Params; ArrayOf enPntr = Λ Params; intWavePntr β A intWave; f lowWaveFormPntr = Λ arrayOf Pointers; PointArray = array [ 1..DISPLAYSIZE] of Tpoint; {1.. DISPLAYSIZE} SmallPointArray = array [ 1.. SMALLDISPSIZE] of Tpoint; {1..SMALLDISPSIZE} {myArray - array f 1..1000] of integer; now typed in global area} MyList = class (TStringList) ; 8 burstArray - arrayfl..50] of integer; largeBurotArray - array!1..400] of integer; TwentyTwoPointArray - array[1..22] of Tpoint; TwentyOnePointArray - array[1..21] of Tpoint; TwentyPointArray - array[1..20] of Tpoint; ineteenPointArray - array[1..19] of Tpoint; EighteenPointArray - arrayf1..18] of Tpoint; SeventeenPointArray «* array[1..17] of Tpoint; SixteenPointArray ■=« array!1..16] of Tpoint;. FifteenPointArray «= array[1..15] of Tpoint; FourteenPointArray ** array[1..14] of Tpoint; 10 ThirteenPointArray ■=• array[1..13] of Tpoint; TwelvePointArray ° array[1..12) of Tpoint; ElevenPo.intArray = array[1..11] of Tpoint; TenPointArray α array[1..10] of Tpoint; NinePointArray - array[1..9] of Tpoint; EightPointArray = arrayfl..8] of Tpoint; SevenPointArray - array[1..7] of Tpoint; SixPointArray •=» array[1..6] of Tpoint; 15 FivePointArray = array[1..5] of Tpoint; FourPointArray = arrayfl..4] of Tpoint; ThreePointArray = array[1..3] of Tpoint; TwoPointArray = array[1..2] of Tpoint; OnePointArray = array[1..1] of Tpoint; tempPointArray = array[1..220] of Tpoint; 20 function logWaveForm(board : integer; command : integer) : integer; far; external 'GUIIF'; {board is 1,2 or 3 for flow, cap and sp02 commands are 1,2 and 3 for start, continue, stop} function startEtC02 : integer; far; external 'GUIIF'; function startFlσw : integer; far; external 'GUIIF'; function getAHCapno( ar C02wavePntr : intWavePntr; var waveSize : 25 integer; var waveStart : integer; var patDataPntr : staticDataPntr; var dataSize : integer; var status : integer; var extStatArPntr : staticDataPntr; var size : integer) : integer; far; external 'GUIIF'; function getAllPulsox(var pulsOxDataPntr : staticDataPntr; var 02WavePntr : intWavePntr; var sizeOfWav, start : integer) : integer; far; external 'GUIIF'; { an array of 3 ints " They are: Avg02sat, HR, and 30 Status } { The 02WavePntr points to a variable size array. sizeOfWav is that size; from 2 to 9. } { The start point may be used for when the previous grab was more than it could hold. } { function getPulsox(var avg02 : integer; var avgHR : integer; var StatusCode) : integer; far; external 'GUIIF'; . { in in . in the return is functxon health } HEET RULE 26 function getAllFlσw(var pointβrToWavβFormβ : lowWaveFormPntr; var waveSizes : etaticDrtaPntr; var waveStartβ : staticDataPntr; var dpiβ : ArrayOfTenPntr; var dpiValueβ ArrayOfTenPntr; var dpiSize x integer; var βtatuβl : integer; var etatuβ2 x integer; var βtatuβ3 x integer) : integer b far; external 'GUIIF'; function tempSenseA{tβmpDevice : integer; var fromDLL : integer) integer; far; external 'GUIIF'; function ekgSenaeA x integer; far; external 'GUIIF'; function fanControl(fanNumber, OnOff : integer) j integer; far; external 'GUIIF'; function pumpControl(whichPump x integer; ctrlStato x integer) : 1 0 integer; far; external 'GUIIF'; {pumpControl ia co presβor or other motorized fluid thing.} procedure sendoxBurβt; forward; procedure sendCapBurβt; forward; procedure βendFlowBurβt; forward; procedure show rrow(posX, posY x integer); forward ; 1 1 3 5 var rateOchanAra : displayArray; pulsOxDat, yTempDat, yRateDat : displayArray; BRdat, MINdat : dieplayArray; sysBPdat, diaBPdat x displayArray; yPoFlowAry : displayArray; flowRatβDataArray x burβtArray; 20 globalXvalue: integer; drawMINcount, drawOxCount, drawTβmpCount, drawBRcount, drawBRcount, drawBPcount : integer; Cnt, bottom, bottom2, bottom3, bottom20 x integer; bloodPressList : MyLiβt; index : integer; {ueed in drawCurve} recordFlowCapEnabled, recordEnablβd : Bool; recordlnterval x integer; 25 resetFlσw, flowArrayReβetValuβ x integer; {ueed at the bottom of this .pas file.} farRight20, x20Poβ, limit x integer; xPos, xErasβPos, burβtLeftEdgβ : integer; topCount : integer; flowDataArray : dieplayArray; flowRateArray : SmallPointAr ay; flowEraβeArray : SmallPointArray; 30 testSwitchTogglβ x integer; eraseArray : largβBurβtArray; { 400 intβgerβ } nextEraselndex, oldEraβelndex : integer; layTwenty : TwentyOnePointArray; layNineteen : TwentyPointArray; layEighteen : NinetβenPointArray; laySeventepin : EighteenPointArray; 35 laySixteen : SeventeenPointArray; layFifteen : SixteβnPointArray; 10 SUBSTITUTESHEET(RULE26 layFourteen : FifteenPointArray; layThirteen x FourteenPointArray; lay welve : ThirteenPointArray; layEleven : TwelvePointArray; layTen : ElevenPointArray; layNinβ : TenPointArray; layEight : NinePointArray; laySeven : EightPointArray; laySix : SevenPointArray; layFivβ x SixPointArray; layFour : FivePointArray; layThrβe : FourPointArray; layTwo : ThreePointArray; layOne : TwoPointArray; eraβeTwenty : TwentyTwoPointArray; eraβeNineteen : TwentyOnePointArray; eraβeEighteen : TwentyPointArray; eraβeSeventβen : NineteenPointArray; eraβeSixteen x EighteenPointArray; eraseFifteen : SeventeenPointArray; eraseFourteen : SixteenPointArray; eraβeThirteen : FifteenPointArray; eraseTwelve i FourteenPointArray; eraseEleven x ThirteenPointArray; eraseTen x TwelvePointArray; eraβeNine : ElevenPointArray; eraβeEight : TenPointArray; eraβeSeven : NinePointArray; eraseSix x EightPointArray; eraβeFive x SevenPointArray; eraβeFour : SixPointArray; {} eraβeThrβe : FivePointArray; eraseTwo x FourPointArray; eraseOne : ThreePointArray, testPointArray : tempPointArray; eraseLink-Elem, firstLinkElem, linkElem : integer; inc, eraseLink : integer; beenThere : Bool; buttonValue : integer; Glol : integer; (some universal counter that's global} procedure βhowAirwayGraph; begin DiβplaySpace.Shapel.Visible :- False; DiβplaySpace.Shape2.Viβible x» True; DiβplaySpace.Shape3.Visible :- False; DiβplaySpace.βhapeMeββagβSpace.Visible x- True; DiβplaySpace.Imagel.Viβiblβ :« Falββ; DisplaySpace.Imageβ.Visible :« False; DisplaySpace.Labell7.Visible :» False; DiβplaySpace.Labellβ.Visible :- False; DisplaySpace.Image2.Visible :■ True; 11 DisplaySpace.hrBarBackgndShape.Visible :- False; DisplaySpace.nowLbl.Visible :- False; DisplaySpace. hrBarLbl.Visible := False; DisplaySpace.beatβLbl.Viβible :- False; DisplaySpace.Label32.Visible :» False; DisplaySpace.Label46.Visible :- False; DisplaySpace.Image7.Visible :- False; DisplaySpace.oxScalelmage.Visible :«■ False; DisplaySpace.Image7h.Visible :» False; DisplaySpace.Labell4.Visible :» False; DisplaySpace.Labell5.Visible := False; DisplaySpace.oxSatTitleLbl.Visible :■* False; DisplaySpace.EKGpanel.Viβible := False; drawEKGenabled :» False; DisplaySpace.BitBtnl .Visible :■ True; DisplaySpace.BitBtn2.Visible :=* False; DisplaySpace.BitBtn3.Visible : β True; DisplaySpace.BitBtn4.Visible :<=» True; DisplaySpace.timelnMinutesLbl.Caption := 'Time in Seconds'; end; procedure drawNeraseOneSegment(flowRateData, xPoAir, cnt : integer; yDat : displayArray; drawColor : Tcolor) ; var eraseColor : Tcolor; inc : integer; begin inc :=■ 2; DisplaySpace.Canvas.Pen.Width : ** 1; DisplaySpace.Canvas.moveTo(xPoAir+inc, bottom20 - yDatfcnt] div 10) ; { cnt } DisplaySpace.Canvas.Pen.Color :»■ eraseColor; DisplaySpace.Canvas .LineTo(xPoAir+2*inc, bottom20 - yDat[cnt+l] div 10) ; { cnt+1 } yPoFlowAry[cnt] :=» flowRateData; DisplaySpace.Canvas.moveTo(xPoAir, bottom20 - yDat[cnt-l] div 10) ; { cnt-1 } DisplaySpace.Canvas.Pen.Color := drawColor; DisplaySpace.Canvas.LineTo(xPoAir+inc, bottom20 - yDatfcnt] div 10); { cnt } end; * procedure drawBurst(varSizeArray : burstArray; burstSize : integer; curveColor : Tcolor); {Here the data to be drawn comes as a variable size array; 3,5 maybe 20 values. I'm to use polyline to add some line segments to the existing curve. It has a ceiling and a floor to make centering easier.} var inc, safeSize, ndx : integer; 12 burstRightEdge, ceiling, floor : integer; flowFile : TextFile; largerText : arrayf0..3000] of Char; smalTxt : arrayf0..4] of Char; eraseColor, drawColor : Tcolor; tempTotal : integer; const { delim : PChar » ' , ' ; } delim : PChar » ' ' ; {true tab} begin burstRightEdge := 570; {590 575 keeps the erase line in } ceiling := 80; {34 is the very top of the colored shapes} floor := 310; {303, 300 is very bottom of colored shapes} inc := 1; {2 how many pixels wide is each data point } drawColor := curveColor; eraseColor := clLime; { ADJUSTING PEN COLORS } if drawColor = clBlue then DisplaySpace.Canvas.Pen. idth :» 2 else DisplaySpace.Canvas.Pen. idth := 1; if DisplaySpace.Shapel.Visible «=■ True then eraseColor : ™ clWhite; {clWhite} if DisplaySpace.Shape2.Visible ** True then eraseColor := clYellow; {clYellow} if DisplaySpace.Shape3.Visible α True then eraseColor :» clLime; {clLime} { INITIALIZING THE ERASE ARRAY } if firstBurst then begin for i:=l to 400 do eraseArray[i] :=» varSizeArrayf 1] ; end; { PUTTING LIMITS ON THE DATA so inputB that are way off, still show up. } tempTotal := 0; for i:=l to burstSize do begin if varSizeArray[i] < ceiling then varSizeArray[i] :- ceiling; if varSizeArray[i] > floor then varSizeArray[i] := floor; tempTotal :» tempTotal + varSizeArray[i] ; end; DisplaySpace.flowRateDataArrayLbl.Caption : α intToStr(tempTotaldiv i); if burstSize <> 0 then begin xPos :™ xPos - inc; { common to all } if nextEraselndex β 1 then xErasePos : α xErasePos - inc; 13 xErasePos :•» xErasePos - inc; if nextEraselndex - 1 then begin firstLinkElem :- linkElem; eraβeLinkElem :- linkElem; end; end else for i:«l to 50 do begin varSizeArrayfi] :» linkElem; end; if burstSize - 1 then begin { ERASE ONE } eraseOnef1) .X :« xErasePos; xErasePoB :« xErasePos + inc; eraseOne[ 1] .Y :*■ eraaeLinkElem; for i:- 2 to (burstSize + 2) do begin eraseOne[i] .X :»• xErasePos; eraseOnefi] .Y :•» eraseArray[oldEraselndex] ; { 500 integers } oldEraselndex :=» oldEraselndex + 1; xErasePos : π xErasePos + inc; end; eraseLinkElem : α eraseArray[oldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color :« eraseColor; i f f i r s t B u r s t - F a l s e t h e n DisplaySpace . Canvas . PolyLine ( eraseOne ) ; end ; if burstSize - 1 then begin { DRAW ONE } layOne[l].X :- xPos; layOneflj.Y :« linkElem; xPos :- xPos + inc; for i :■ 2 to (burstSize+1) do begin layOne[i].X :- xPos; layOne[i].Y :- varSizeArray!i-1] ; xPos :■ xPos + inc; end; DisplaySpace.Canvas.Pen.Color x- drawColor; DisplaySpace.Canvas.PolyLine(layOne) ; end; if burstSize - 2 then begin { ERASE TWO } eraseTwof1] .X :■ xErasePos; xErasePos :- xErasePos + inc; eraseTwof 1] .Y :- eraseLinkElem; for i:- 2 to (burstSize + 2) do begin eraseTwofi] .X :■ xErasePos; eraseTwofij .Y :■ eraseArray[oldEraselndex]; 14 SUBSTITUTE SHEET (RULE 26 oldEraselndex :- oldEraselndex + 1; xErasePos :- xErasePos + inc; end; eraseLinkElem :- eraseArray[oldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color : ■ eraseColor; i f f i r s t B u r s t - F a l s e t h e n DisplaySpace.Canvas.PolyLine(eraaeTwo) ; end; if burstSize «* 2 then begin { DRAW TWO } layTwofl].X :» xPos; layTwoflj.Y := linkElem; xPos :=■ xPos + inc; for i :■ 2 to (burstSize+1) do begin lay wo[i].X := xPos; layTwofij.Y := varSizeArray[i-1] ; xPos :=■ xPos + inc; end; DisplaySpace.Canvas.Pen.Color :° drawColor; DisplaySpace.Canvas.PolyLine(layTwo) ; end; if burstSize *• 3 then begin { ERASE THREE } eraseThree[ 1] .X := xErasePos; xErasePos := xErasePos + inc; eraseThreef1] .Y := eraseLinkElem; for x:» 2 to (burstSize + 2) do begin eraseThree[i] .X :*» xErasePos; eraseThreefi] .Y := eraseArray[oldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; end; eraseLinkElem := eraseArray[oldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color : α eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace.Canvas.PolyLine(eraseThree) ; end; if burstSize « 3 then begin { DRAW THREE } lay hreefl] .X :- xPos; layThree[ 1) ,Y :- linkElem; xPos :- xPos + inc; for i :» 2 to (burstSize+1) do begin layThree[i] .X :» xPos; layThree[i] .Y :- varSizeArray[i-1] ; xPos :- xPos + inc; end; DisplaySpace.Canvas.Pen.Color :■ drawColor; DisplaySpace.Canvas.PolyLine(layThree) ; 15 end; if burstSize = 4 then begin { ERASE FOUR } eraseFour[1) .X :=■ xErasePos; xErasePos := xErasePos + inc; eraseFour[1] .Y := eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraseFourfi] .X := xErasePos; eraseFourfi] .Y := eraseArray[oldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; end; eraseLinkElem := eraseArray[oldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace . Canvas . PolyLine ( eraseFour ) ; end; xf burstSxze = 4 then begxn { DRAW FOUR } layFou [1).X := xPos; layFour[1].Y := linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1) do begin layFour[i].X := xPos; layFourfi] .Y := varSizeArray[i-1] ; xPos := xPos + inc; end; DisplaySpace.Canvas.Pen.Color :=* drawColor; DisplaySpace.Canvas.PolyLine(layFour) ; end; if burstSize = 5 then begin { ERASE FIVE } eraseFive[1] .X := xErasePos; xErasePos := xErasePos + inc; eraseFive!1] .Y := eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraβeFive[i] .X :=» xErasePos; eraseFivefi] ,Y := eraseArray[oldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; end; eraseLinkElem := eraseArray[oldEraseIndex-l] ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace . Canvas . PolyLine ( eraseFive ) ; end; if burstSize = 5 then begin { DRAW FIVE } layFive[l].X := xPos; 16 layFive[l].Y := linkElem; xPos := xPos + inc; for i :■ 2 to (burstSize+1) do begin layFive[i].X := xPos; layFivefij.Y := varSizeArray[i-1) ; XPOB := xPos + inc; end; DisplaySpace.Canvas.Pen.Color := drawColor; DisplaySpace.Canvas.PolyLine(layFive) ; end; if burstSize «= 6 then begin { ERASE SIX } eraseSixf 1] -X := xErasePos; xErasePos := xErasePos + inc; eraseSixf1] .Y := eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraseSixfi] .X := xErasePos; eraseSixfi] .Y :=■ eraseArray[oldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; end; eraseLinkElem := eraseArrayfoldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace . Canvas . PolyLine ( eraseSix ) ; end; if burstSize = 6 then begin { DRAW SIX } laySix[l].X := xPos; laySix[l].Y := linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1) do begin laySix[i].X := xPos; laySix[i].Y := varSizeArray[i-1) ; xPos := xPos + inc; end; DisplaySpace.Canvas.Pen.Color := drawColor; DisplaySpace.Canvas.PolyLine(laySix) ; end; if burstSize = 7 then begin { ERASE SEVEN } eraseSeven[ 1] .X :=* xErasePos; xErasePos := xErasePos + inc; eraseSeven[ 1] .Y := eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraseSevenfi] .X := xErasePos; eraseSevenfi] .Y := eraseArray[oldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; 17 nd; eraseLinkElem := eraβeArrayfoldEraselndex-l) ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace . Canvas . PolyLine ( eraseSeven ) ; end; if burstSize => 7 then begin { DRAW SEVEN } laySevenf1] .X := xPos; laySevenf1) .Y := linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1) do begin laySevenfi] .X := xPos; laySevenfi] .Y := varSizeArray[i-1] ; xPos := xPos + inc; end; DisplaySpace.Canvas.Pen.Color := drawColor; DisplaySpace.Canvas.PolyLine(laySeven) ? end; if burstSize = 8 then begin { ERASE EIGHT } eraseEight[ 1] .X := xErasePos; xErasePos := xErasePos + inc; eraseEight[ 1] .Y := eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraseEight[i) .X := xErasePos; eraseEightfi] .Y := eraseArray[oldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; end; eraseLinkElem := eraseArray[oldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace. Canvas .PolyLxne ( eraseEight ) ; end; if burstSize = 8 then begin { DRAW EIGHT } layEightf1] .X := xPos; layEightfl] .Y := linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1) do begin layEightfi] .X := xPos; layEight[i] .Y :=* varSizeArray[i-1] ; xPos := xPos + inc; end; DisplaySpace.Canvas.Pen.Color := drawColor; DisplaySpace.Canvas.PolyLine(layEight) ; end; {if nextEraselndex = 1 then xErasePos := xErasePos - inc; now done above over all } 18 {xErasePos := xErasePos - inc; ditto } if burstSize = 9 then begin { ERASE NINE } eraseNine[ 1] .X := xErasePos; xErasePos := xErasePos + inc; eraseNine[ 1] .Y := eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraseNine[i] .X := xErasePos; eraseNinefi] .Y := eraseArray[oldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; end; eraseLinkElem := eraseArray[oldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace .Canvas .PolyLine ( eraseNine ) ; end; if burstSize = 9 then begin { DRAW NINE } layNine[l].X := xPos; layNine[l].Y := linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1) do begin { loading the draw data } layNinefi].X := xPos; layNine[i].Y := varSizeArrayfi-1] ; xPos := xPos + inc; end . DisplaySpace.Canvas.Pen.Color := drawColor; DisplaySpace.Canvas.PolyLine(lay ine) ; end; if burstSize = 10 then begin { ERASE TEN } eraseTenf 1] .X := xErasePos; xErasePos := xErasePos + inc; eraseTenf 1] .Y := eraseLinkElem? for i:= 2 to (burstSize + 2) do begin eraseTenfi] .X := xErasePos; eraseTenfi] .Y := eraseArrayfoldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; end; eraseLinkElem := eraseArray[oldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n Display Space. Canvas .PolyLine (eraseTen) ; end; if burstSize = 10 then begin { DRAW TEN } layTen[l].X := xPos; layTen[l].Y := linkElem; 19 xPos :■» xPos + inc; for i :■ 2 to (burstSize+1 ) do begin { loading the draw data } layTen[i].X :■ xPos; layTen[i].Y :» varSizeArray!i-1] ; xPos :=■ xPos + inc; end; DisplaySpace.Canvas.Pen.Color : β drawColor; DisplaySpace.Canvas.PolyLine( layTen) ; end; if burstSize = 11 then begin { ERASE ELEVEN } eraseEleven! 1] .X :» xErasePos; xErasePos := xErasePos + inc; eraseElevenf 1 ] .Y :=« eraseLinkElem; for i:» 2 to (burstSize + 2) do begin eraseEleven[i] .X := xErasePos; eraseElevenfi] .Y :- eraseArray[oldEraselndex] ; oldEraselndex :- oldEraselndex + 1; xErasePos : ™ xErasePos + inc; end; eraseLinkElem := eraseArray!oldEraselndex-l ] ; DisplaySpace.Canvas.Pen.Color : ** eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace . Canvas . PolyLine ( eraseEleven ) ; end ; if burstSize = 11 then begin { DRAW ELEVEN } layEleven!1] .X := xPos; layElevenf 1] .Y := linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1) do begin { loading the draw data } layElevenfi] .X :=■ xPos; layEleven!i] .Y := varSizeArray[i-1 ] ; xPos :- xPos + inc; end; DisplaySpace.Canvas.Pen.Color := drawColor; DisplaySpace.Canvas.PolyLine(layEleven) ; end; if burstSize = 12 then begin { ERASE TWELVE } eraseTwelvef 1) .X := xErasePos; xErasePos :»=> xErasePos + inc; eraseTwelvef 1] .Y := eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraseTwelvefi] .X := ■ xErasePos; eraseTwelvefi] .Y := ■ eraseArrayfoldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos :=■ xErasePos + inc; end; eraseLinkElem := eraseArrayfoldEraselndex-l] ; 20 DisplaySpace.Canvas.Pen.Color :- eraseColor; i f f i r s t B u r s t » F a l s e t h e n DisplaySpace . Canvas . PolyLine ( eraseTwelve ) ; end; if burstSize = 12 then begin { DRAW TWELVE } layTwelvef 1] .X := xPos; layTwelvef 1] .Y := linkElem; xPos := xPos + inc; for i : ■ 2 to (burstSize+1) do begin { loading the draw data } layTwelvefi] .X := xPos; layTwelvefi] .Y := varSizeArrayfi-1 ] ; xPos := xPos + inc; end; DisplaySpace.Canvaβ.Pen.Color :» drawColor; DisplaySpace.Canvas.PolyLine(layTwelve) ; end; if burstSize = 13 then begin { ERASE THIRTEEN } eraseThirteen! 1] .X := ■ xErasePos; xErasePos := xErasePos + inc; eraseThirteen( 1] .Y :=* eraseLinkElem; for i:=- 2 to (burstSize + 2) do begin eraseThirteen(i) .X := xErasePos; eraseThirteenfi] .Y := eraseArray[oldEraselndex] ; oldEraselndex := oldEraselndex + 1; xErasePos := xErasePos + inc; end; eraseLinkElem := eraseArray[oldEraselndex-l ) ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n DisplaySpace.Canvas.PolyLine(eraseThirteen) ; end; if burstSize = 13 then begin { DRAW THIRTEEN } layThirteen[l] .X :«- xPos; layThirteenf 1] .Y := linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1 ) do begin { loading the draw data } layThirteenfi] .X := xPos; layThirteenf i] .Y := varSizeArrayfi-1] ; xPos := xPos + inc; end; DisplaySpace.Canvas.Pen.Color := drawColor; DisplaySpace.Canvas.PolyLine(layThirteen) ; end; if burstSize = 14 then begin { ERASE FOURTEEN } eraseFourteenf 1] .X :=* xErasePos; xErasePos := xErasePos + inc; 21 eraseFourteenf 1) .Y :-. eraseLinkElem; for i:» 2 to (burstSize + 2) do begin eraseFourteenfi] .X :« xErasePos; eraseFourteen[i] .Y :- eraseArray[oldEraselndex] ; oldEraselndex :- oldEraselndex + 1; xErasePos :»» xErasePos + inc; end; eraseLinkElem :« eraseArray[oldEraselndex-l ] ; DisplaySpace.Canvas.Pen.Color : «■ eraseColor; i f f i r s t B u r s t - F a l s e t h e n DisplaySpace .Canvas .PolyLine ( eraseFourteen) ; end; if burstSize •= 14 then begin { DRAW FOURTEEN } layFourteen! 1}.X :■» xPos; layFourteen! 1] .Y :■ linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1 ) do begin { loading the draw data layFourteen!i] .X := xPos; layFourteen i] .Y := varSizeArray[i-1] ; xPos := xPos + inc; end; DisplaySpace.Canvas-Pen.Color := drawColor; DisplaySpace.Canvas. olyLine(layFourteen) ; end; if burstSize = 15 then begin { ERASE FIFTEEN } eraseFifteen[ 1 ] .X :=» xErasePos; xErasePos := xErasePos + inc; eraseFxfteenf 1 ] .Y :*» eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraseFifteenfi] .X := xErasePos; eraseFifteenfi] .Y : «■ eraseArray[oldEraselndex] ; oldEraselndex :» oldEraselndex + 1; xErasePos :=» xErasePos + inc; end; eraseLinkElem := eraseArray[oldEraselndex-l ] ; DisplaySpace.Canvas.Pen.Color := eraseColor; i f f i r s t B u r s t = F a l s e t h e n Display Space. Canvas . PolyLine (eraseFif teen) ; end; if burstSize = 15 then begin { DRAW FIFTEEN } layFifteenf 1 ).X :- xPos; layFifteenfl] .Y := linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1) do begin { loading the draw data } layFifteen[i) .X := xPos; layFifteenfi] .Y := varSizeArray[i-1] ; xPos := xPos + inc; 22 end; DisplaySpace.Canvaβ .Pen.Color :» drawColor; DisplaySpace.Canvas.PolyLine(layFifteen) ; end; if burstSize - 16 then begin { ERASE SIXTEEN } eraseSixteenf 1 ] .X :- xErasePos; xErasePos :« xErasePos + inc; eraseSixteenf 1 ] .Y :- eraseLinkElem; for i:*» 2 to (burstSize + 2) do begin eraseSixteen(i) .X :■ xErasePos; eraseSixteenfi] .Y :- eraβeArray[oldEraβelndex] ; oldEraselndex :- oldEraselndex + 1; xErasePos :«■ xErasePos + inc; end; eraseLinkElem :- eraseArray[oldEraselndex-l] ; DisplaySpace.Canvas.Pen.Color :** eraseColor; i f f i r s t B u r s t « F a l s e t h e n DisplaySpace .Canvas .Poly Line (eraseSix teen) ; end; if burstSize - 16 then begin { DRAW SIXTEEN } laySixteenf 1 ] .X :» xPos; laySixteenf 1] .Y :«=■ linkElem; xPos := xPos + inc; for i := 2 to (burstSize+1 ) do begin { loading the 'iraw data } laySixteenfi] .X := xPos; laySixteenfi) .Y :«* varSizeArray{i-1 ] ; xPos :** xPos + inc; end; DisplaySpace.Canvas.Pen.Color :- drawColor; DisplaySpace.Canvas.PolyLine(laySixteen) ; end; if burstSize - 17 then begin { ERASE SEVENTEEN } eraseSevenTeenf 1 ] .X :™ xErasePos; xErasePos :«= xErasePos + inc; eraseSevenTeenf 1 ] .Y :- eraseLinkElem; for i:= 2 to (burstSize + 2) do begin eraseSevenTeenfi) .X :- xErasePos; eraseSevenTeenfi] .Y :- eraseArray[oldEraselndex] ; oldEraselndex :- oldEraselndex + 1; xErasePos :» xErasePos + inc; end; eraseLinkElem :» eraseArray[oldEraselndex-l ] ; DisplaySpace.Canvas.Pen.Color :- eraseColor; i f f i r s t B u r s t - F a l s e t h e n DisplaySpace.Canvas.PolyLine(eraseSevenTeen) ; end; if burstSize » 17 then begin { DRAW SEVENTEEN } 23 laySeventeen! 1 ] .X j- xPos; laySeventeen! 1] .Y i- linkBlβa; xPos :- xPos + inc; for i :■ 2 to (burβtSize+1) do begin { loading the draw data } - xPos; - varSizeArray[ i-1 ) ; DiβplaySpace.Canvaβ.Pen.Color :• drawColor; DiβplaySpace.Canvaβ.PolyLine{laySeventeen) ; end; if burβtSize - 18 then begin { ERASE EIGHTEEN } eraβeEighteen! 1] .X :« xEraββPoβ; xErasePos :- xErasePos + inc; eraseEighteenf 1 ] .Y :- eraseLinkElem; for i:- 2 to (burβtSize + 2) do begin eraβeEighteen!i] .X :- xEraβePoβ; eraseEighteen!i) .Y i- eraseArray[oldEraselndex] ; oldEraselndex :- oldEraselndex + 1; xErasePos :■ xErasePos + inc; end; eraseLinkElem :- eraβeArray[oldEraββlndβx-l ) ; DisplaySpace.Canvaβ.Pen.Color i- eraβeColor; i f f i r s t B u r s t - F a l s e t h e n DisplaySpace.Canvas.PolyLine(eraseEighteen) ; end; if burstSize - 18 then begin { DRAW EIGHTEEN } xPoβ; linkElem; for i :■ 2 to (burβtSize+1 ) do begin { loading the draw data } layExghteenfx] .X :- xPos; layEighteenfi) .Y :- varSizeArray[i-1 ) ; xPos :- xPos + inc; end; DisplaySpace.Canvas.Pen.Color t- drawColor; DiβplaySpace.Canvas.PolyLine(layEighteen) ; end; if burstSize - 19 then begin { ERASE NINETEEN } oraβeNineteen! 1] .X :- xBraβePos; xErasePos :- xErasePos + inc; eraseNineteen! 1) .Y :- eraseLinkElem; for i:« 2 to (burstSize + 2) do begin eraseNineteenfi] .X t« xErasePos; eraseNineteenfi) .Y : ■ eraseArray[oldEraselndex] ; oldEraselndex J- oldEraselndex + 1; xErasePos :- xErasePos + inc; 24 end; eraseLinkElem i" eraseArray(oldEraselndex-1 ] ; DiβplaySpace.Canvaβ.Pan.Color :- eraseColor; i f f i r s t B u r s t - F a l β e t h e n DisplaySpace.Can aβ.PolyLine{eraβeNineteen) ; end; if burstSize - 19 then begin { DRAW NINETEEN } xPoβ; linkElem; tSizβ+1) do begin { loading the draw data > layNineteen! i) .X :- xPos; layNineteenj[i] .Y :- varSizeArray! i-1 ) ; xPos i- xPos + inc; end; DiβplaySpace.Canvaa.Pen.Color :■ drawColor; Diepi ySpace.Canvaβ.PolyLine(layNineteen) ; end; if burβtSize - 20 then begin { ERASE TWENTY } eraseTwenty[ 1 ] .X :- xErasePos; xErasePos :- xErasePos + inc; eraseTwenty[ 1 ] .Y :- eraseLinkElem; for i:- 2 to (burstSize + 2) do begin eraseTwenty(i) .X :■• xErasePos; eraseTwenty[i] .Y :» eraseArray[oldEraselndex] ; oldEraselndex :- oldEraselndex + 1; xEraβePoβ :- xErasePos + inc; end; eraseLinkElem :- eraseArray[oldEraβelndex-l] ; {if firstBurst - Falβe then eraseColor :- clRed } { experiment for the aim version of John's .dll } {else eraseColor :- clWhite; } { experiment for the aim version of John's .dll } DisplaySpace.Canvas.Pen.Color :- eraseColor; i f f i r s t B u r s t - F a l s e t h e n Display Space. Canvas .PolyLine (eraseTwenty) ; end; if burβtSize - 20 then begin { DRAW TWENTY } Pos; inkElem; tSize+1) do begin { loading the draw data } layTwentyfi] .X :- xPos; layTwenty[i] .Y :- varSizeArrayfi-1 ] ; xPos :« xPoa + inc; end; DisplaySpace.Canvaβ .Pen.Color :■ drawColor; 25 DisplaySpace.Canvas.PolyLine (layTwenty) ; end; { ASSEMBLING THE ARRAY USED TO ERASE THE OLD STUFF } {if burstSize <> 0 then begin < I dunno why I have that there.} linkElem :- varSizeArray[i-1 ] ; { common to all } if nextEraselndex ■ 1 then begin eraseArray[ 1 ] :- firstLinkElem; nextEraselndex :- nextEraselndex + 1; end; for i :- 1 to burstSize do begin eraseArray{ nextEraselndex] :- varSizeArray[i] ; nextEraselndex :- nextEraselndex + 1; end; { end; } { SENSING THE RIGHT EDGE } if xPos > burstRightEdge then begin { Diβplays the erase array as a whole. } { xPos :- burstLeftEdge; raselndex do begin testPointArray[i] .X :- xPos; testPointArray[i] .Y :- eraseArrayfi] -50; xPos :- xPos + inc; end; DisplaySpace.Canvas.Pen.Color :- clBlue; DisplaySpace.Canvas.PolyLine(testPointArray) ; } if (recordFlowCapEnabled - True) then begin {RECORDING} { ventSa plerEnabled :» False; } { onePerSecondEnabled :» False; no longer disabled during waveForm record } AssignFilefflowFile, 'C:\LSTATLOG\FLOWDATA.TXT') ; if FileExists ( 'C: \LSTATLOG\FLOWDATA.TXT' ) then Append( flowFile) else Rewrite(flowFile) ; if recordFlowCapCycles - 1 then begin Writeln(flowFile, "); if whichFlow - FLOW_FLOW then Writeln( flowFile, TimeToStr(Time) + ' board Number: ' + intToStr(board) + "Flow" ' ) ; if whichFlow - FL0W_PRES then Writeln( flowFile, TimeToStr(Time) + ' board Number: '+ intToStr(board) + ' "Pressure" ' ) ; if whichFlow - FL0W_V0L then Writeln( flowFile, TimeToStr(Time) + ' board Number: ' + intToStr(board) + "Volume"'); 26 if whichFlow - CAPN0_BTN then Writeln( flowFile, TimeToStr(Time) + ' board Numberx ' + intToStr(board) + ' "Percent C02"' ) ; if whichFlow - PULSOX_BTN then Writeln(flowFile, TimeToStr(Time) + ' board Number: ' + intToStr(board) + ' "Pulse Ox" ' ) ; end; atrCopy(largerText, ''); {this resets the largerTβxt} for i:-l to nextEraselndex do begin { \\\\\\\\\\\\\\\\ } Str(eraseArray[i] , smalTxt) ; StrCat(largerText, smalTxt); StrCat(largerText, delim); end; { 111111111 / 111111 / } Write( flowFile, largerText) ; DisplaySpace.recordingLbl.Caption :» 'times thru: ' + intToStr(recordFlowCapCycles) ; CloseFile(flowFile) ; recordFlowCapCycles :■ recordFlowCapCycles + 1; end ? beenThere :«= True; xPos :■» burstLeftEdge; xErasePos :- burstLeftEdge; oldEraselndex :•» 1; nextEraselndex :- 1; end; end; procedure drawTest20HzData(flowRateData, presData, p_C02data : integer) ; { In this new version, it draws flowRate, volume and presData together on one graph and if they click on P C02, then it draws the p_C02data. This curve drawing routine uses lineTo and connects-the-dots (you might say) as the data comes in. I will be borrowing from drawCurve, some two or three procedures below. The curves come in aβ a variable length array, some 4 or 8 maybe aβ many as 20 points (at first) . The master event is the TwentyHz timer. Depending on how pre-occupied Windows is, the array being received is different. The three curves will be done simultaneously one cluster segment for each before advancing to the right. The one curve version will merely do the first one only. } var 27 farLeft, dispSize, inc, safeSize, ndx : integer; eraseColor, drawColor : Tcolor; begin farLeft :- 310; dispSize :- 70; {140 when inc - 2 } inc :- 4; { how many pixels wide is each data point } if cnt > dispSize then begin { bottom20 :- bottom20 - 8; } 10 cnt :■» 1; end; if cnt <- 1 then begin xPo20 :- farLeft; drawColor :■ clYellow; end else drawColor :«« clBlack; -■ £ - drawNeraseOneSegment( flowRateData, xPo20, cnt, yPoFlowAry, drawColor) ; xPo20 :- xPo20+inc; cnt : - cnt + 1; { DisplaySpace.testLbl.Caption :- intToStr(cnt) + ' + intToStr(xPo20) + ' ' + intToStr( flowRateData) ; } 0 end ; procedure draw20HzData{flowRateData : integer); { draws any of three arrays (of type point) and moves curve left five pixels. It stores in RAM the last X minutes worth of data. This turns out to be too slow even if displaying only one at a time. 5 > var flowGraphO set, flowGraphGain : integer; flowFloor : integer; eraseColor : TColor; begin {farRight20 is initialized at 468 at the bottom} 0 {Initializing the flowRateArray is done at the bottom of this .pas file.} {topCount declared globally and initialized to 1 at bottom} x20Pos :- farRight20; eraseColor := clYellow; flowRateData := flowRateData div 6; {Labels} 5 { 28 if board - CAPNOSTATBOARD then displaySpace.airWaveFormLbl.Caption := 'PERCENT C02 ' ; if board - FLOWBOARD then displaySpace. irWaveFormLbl .Caption : β 'FLOWRATE AND PRESSURE'; if allboardsEnabled = True then displaySpace.airWaveFormLbl.Caption := 'FLOW, PRESS, VOL, C02 AND PULSOX'; } {LOADING THE flow RATE ARRAY one element per call to this procedure} flowGraphOffset := 0; {80} flowGraphGain := 40; {38} flowFloor := 170; flowDataArray[topCount+1 ] := flowFloor - (((flowRateData * flowGraphGain) div 100) + flowGraphOffset); {DRAWING THE ARRAYS the entire polyline, each call} DisplaySpace.Canvas.Pen.Color := eraseColor; DisplaySpace.Canvas .Pen.Width := 1; DisplaySpace.Canvas .PolyLine(flowEraseArray) ; if topCount-2 >=> SMALLDISPSIZE then limit := SMALLDISPSIZE -1 else limit := topCount -2; for i:= 0 to limit do begin { 0 to limit-1 works and limit := topCount-1} flowEraseArray[SMALLDISPSIZE-i] .X := x20Pos-3*i; f l o w E r a s e A r r a y [ S M A L L D I S P S I Z E - i ] . Y : = f lowDataArray [ topCount-i ] ; flowRateArray[SMALLDISPSIZE-i] .X := x20Pos-3*i; flowRateArray[SMALLDISPSIZE-i] .Y := flowDataArray[topCount-i] ; end; DisplaySpace-Canvas.Pen.Color := clGreen; DisplaySpace.Canvas. en.Width := 1; DisplaySpace.Canvas.PolyLine{flowRateArray) ; {ADVANCING THE DATA ARRAY INDEX (not the display array)} if topCount < 499 then begin {the 499 has to be one less than array size} topCount :■= topCount + 1; end else begin {If 499 or more, then the entire array takes on an average value.} topCount := 1; resetFlow := flowArrayResetValue; for i := 1 to SMALLDISPSIZE do begin flowRateArrayfi] .Y := resetFlow; end; end; end; {procedure draw20HzData} 29 procedure drawDispCurve(dataArray: displayArray; farRight, dispSize, bottom, datAralndex: integer; eraseColor, drawColor: TColor; floor : integer) ; { This drawing function needs a canvas to draw on. There's another version of this (drawVentCurve and drawMainCurve) in the VENTDETAIL unit. Draws a curve starting at the right and going to the left. If there's not "dispSize" number of points it draws just a small amount. If more than "dispSize" it displays only "dispSize". The curve is moved "leftlnc" to the left each time this procedure is called. That way it appears to grow to the left. } var SafeDispSize, leftlnc : integer; begin leftlnc := 5; xPo := farRight; index := datAralndex; {Amplitude Confiner} for i:=l to 499 do begin if dataArray[i] < (10 * floor) then dataArrayfi] := (10 * floor) ; {floor is frd call} end /' if datAralndex <** dispSize then safeDispSize := datAraIndex-3 {to protect index < 1} else safeDispSize := dispSize; DisplaySpace.Canvas .MoveTo(xPo, bottom - dataArray[index-1 ] div 10); for i:=l to safeDispSize do begin {These Canvas Calls draw a line segment —going left— which erases a piece of the old array followed by a black line on the new improved array. } DisplaySpace.Canvas.Pen.Width := 1; DisplaySpace.Canvas.Pen.Color := » eraseColor; DisplaySpace.Canvas.LineTo(xPo, bottom - dataArray(index-1 ] div 10) ; DisplaySpace .Canvas .LineTo (xPo-leftine , bottom dataArray[index-2] div 10); DisplaySpace.Canvas.LineTo(xPo-2*leftine, bottom dataArray[index-3] div 10); if i > 1 then begin DisplaySpace.Canvas.Pen.Width :=» 1; DisplaySpace.Canvas.Pen.Color := drawColor; DispiaySpace.Canvas.MoveTo(xPo, bottom- dataArray!index] div 10); 30 DisplaySpace .Canvas .LineTo(xPo-leftine, bottom dataArray[index-1] div 10); DisplaySpace.Canvas.MoveTo(xPo-leftine, bottom dataArray[index-2] div 10); end; xPo i " xPo-leftlnc; index :- index-1; end; end; { I I I I I I I I I I I I I I I I I end o f drawDi s pCu rve ////////////////////////////////////////////} procedure drawVentCurve(datarray: displayArray; farRt, dispSize, bottom, datAralndex: integer; eraseColor, drawColor: TColor; floor : integer) ; { This drawing function needs a canvas to draw on. That needs reference to a form. I dunno how to do that for curves on different forms. Hence there's a copy of the procedure in both forms. DrawB a curve starting at the right and going to the left. If there's not "dispSize" number of points it draws just a small amount. If more than "dispSize" it displays only "dispSize". The curve is moved "leftlnc" to the left each time this procedure is called. That way it appears to grow to the left. } var SafeDispSize, leftlnc, xPo, index : integer; begin leftlnc :- 5; xPo :- farRt; index :- datAralndex; {Amplitude Confiner) for i:-l to 499 do begin if datarray[i] < (10 * floor) then datarrayfi] :« (10 * floor); {floor is from call} end; {These Canvas Calls draw a line segment —going left— which erases a piece of the old array followed by a black line of the new array.} if datAralndex <■ dispSize then βafeDispSize :■ datAraIndex-3 {to protect index < 1} else safeDispSize :- dispSize; VENTDETAIL.Canvaβ.MoveTo(xPo, bottom - datarray[index-1] div 10) ; for i:»l to βafeDispSize do begin {draw two erase line segments) VENTDETAIL.Canvas.Pen.Width i- 1? 31 VENTDETAIL.Canvas.Pen.Color x- eraseColor; VENTDETAIL.Canvaβ.LineTo(xPo, bottom - datarray[index-1 ] div 10); VENTDETAIL. Canvas . LineTo( xPo-leftine, bottom datarray! index-2) div 10); VENTDETAIL.Canvaβ.LineTo(xPo-2*leftine, bottom datarray! index-3) div 10); {draw line segment} if i > 1 then begin VENTDBTAIL.Canvas.Pen.Width :- 1; VENTDETAIL.Canvaβ.Pen.Color :- drawColor; VENTDETAIL.Canvaβ.MoveTo(xPo, bottom - datarray[index) div 10); VENTDBTAIL.Canvaβ.LineTo( xPo-leftlnc, bottom datarray! index-1] div 10); VENTDETAIL.Canvas.MovβTo(xPo-leftine, bottom datarray(index-2) div 10); end; xPo :- xPo-leftlnc; index :- index-1; end; end; { I I t I f I t I I I I I t I I I I end of drawVentCurve I I I Itltllll lll t I till } procedure drawMainCurve(datarray: dieplayArray; farRt, dispSize, bottom, datAralndex: integer; eraseColor, drawColor: TColor; floor : integer); { This drawing function neβdβ a canvas to draw on. That needs reference to a form. I dunno how to do that for curves on different forms. Hence there's a copy of the procedure in three forms. Draws a curve βtarting at the right and going to the left. If there'β not "diβpSize" number of pointβ it draws just a small amount. If more than "dispSize" it displays only "dispSize". The curve is moved "leftlnc" to the left each time this procedure is called. That way it appears to grow to the left. } var SafeDispSize, leftlnc, xPo, index : integer; begin leftlnc :■> 5; xPo :» farRt; index :» datAralndex; {Amplitude Confiner} for i:-l to 499 do begin 32 if datarray[i] < (10 * floor) then datarray[i] :=» (10 * floor); {floor is from call} end; {These Canvas Calls draw a line segment —going left— which erases a piece of the old array followed by a black line of the new array.} if datAralndex <=• dispSize then safeDispSize :«* datAraIndex-3 {to protect index < 1} else safeDispSize := dispSize; { MedicsGui.bpBackgndimage.Canvas.MoveTo(xPo, bottom datarray[index-1 ] div 10);} MedicsGui . bpBackgndimage .Canvas . MoveTo (xPo, bottom datarray[index-1 ] div 10); for i:-l to safeDispSize do begin {draw two erase line segments} MedicsGui.bpBackgndimage.Canvas.Pen.Width := 1 ; MedicsGui.bpBackgndimage.Canvas.Pen.Color :=» eraseColor; MedicsGui.bpBackgndimage.Canvas.LineTo(xPo, bottom datarray[index-1] div 10); MedicsGui.bpBackgndimage.Canvas.LineTo(xPo-leftInc, bottom - datarray[index-2 ] div 10); MedicsGui.bpBackgndimage.Canvas.LineTo(xPo-2*leftlnc, bottom - datarray!index-3] div 10); {draw line segment} if i > 1 then begin MedicsGui.bpBackgndimage.Canvas.Pen.Width := 1; MedicsGui.bpBackgndimage.Canvas.Pen.Color := drawColor; MedicsGui.bpBackgndimage.Canvas .MoveTo(xPo, bottom datarray(index] div 10); MedicsGui .bpBackgndimage .Canvas .LineTo (xPo-leftlnc, bottom - datarray[index-l] div 10); MedicsGui.bpBackgndimage .Canvas .MoveTo(xPo-leftlnc, bottom - datarray[index-2) div 10); end ' xPo := xPo-leftlnc; index : - index-1; end; end; { I I I I I I I f I I I I I I I I I e nd o f d r awM a i n C u r v e 11111 til 11 II I II I II II I III III III I III III I lilt! 1} var {static variables for EKG} farRight : integer; EKGdataArray : PointArray; gridlStopToggle : Bool; grid2StopToggle : Bool; grid3StopToggle : Bool; grid4StopToggle : Bool; 33 grid5StopToggle : Bool; ■ timesThru : integer; recordCycles : integer; procedure drawEKG; var ekgValue, i, veryBotto , limit, bk, xPos : integer; largerOxText, largerText : array O ..3000] of Char; smalOxTxt, smalTxt : arrayfO..4) of Char; OxWavFil : TextFile; ekgFile : TextFile; oxWavPntr : wavePntr; wavSize, waveFormSize, wplnt, Code : integer; recordlntervalCycles : integer; penColor : Tcolor; const { delim : PChar = ' , ' ; } delim : PChar = ' ' ; begin bk := 34; {number of data points blank} farRight := 380; { 380 A larger number moves curve to the right, old: 600 corres DISPLAYSIZE 720} randomize; while (drawEKGenabled = True) do begin { WHILE BEGINS i/iifin/fnimmiiiiniinniiii y if ( (recordEnabled = True) and (recordCycles = 0)) then begin if (waveFormModeNumber = 1) then begin AssignFile(ekgFile, 'C:\LSTATLOG\EKGDATA.TXT' ) ; if FileExists ( 'C: \LSTATLOG\EKGDATA.TXT ' ) then Append(ekgFile) else Rewrite(ekgFile) ; Writeln(ekgFile, ''); Writeln(ekgFile, TimeToStr( ime) ) ; end; if (waveFormModeNumber = 2) then begin AssignFile(OxWavFil, 'C:\LSTATLOG\0XDATA.TXT') ; if FileExists ( 'C : \LSTATLOG\OXDATA.TXT' ) then Append(OxWavFil) else Rewrite(OxWavFil) ; Writeln (oxWavFil, "); Writeln (oxWavFil, TimeToStr(Time) ) ; end; end; xPos := farRight; { Unless farRight is larger than DISPLAYSIZE XPOB takes on minus values.} {OBTAINING THE DATA} 34 { FAST LOADING OF THE ARRAY... the entire array, each call to this procedure} strCopy(largerText, ' ' ) ; strCopy(largerOxText, ''); wavSize := DISPLAYSIZE; if (waveFormModeNumber - 1) then waveFormSize :» DISPLAYSIZE; if (waveFormModeNumber « ■ 2) then waveFormSize :- wavSize; for i:=l to waveFormSize do begin { Begin quick for-loop {THIS IS THE SYNTHESIZED E G SIGNAL} { @ee@e@§eeeeeee§§e@ } { if (i mod bk - 0) or ((i-1) mod bk - 0) or (,(i-2) mod bk - 0) or ((i-3) mod bk - 0) or ((i-4) mod bk - 0) then begin EKGvalue : ~ random(50) + 10 end else EKGvalue :- random(4) + 33; } EKGvalue := ekgSenseA div 25 - 20; { 35-10 25, 45} wplnt := random(12) + 25; Str(wplnt, s alOxTxt); StrCat(largerOxText, smalOxTxt) ; StrCat(largerOxText, delim); St (EKGvalue, smalTxt); StrCat(largerText, smalTxt) ; StrCat(largerText, delim); if (waveFormModeNumber = 1) then EKGdataArray[i] .Y := EKGvalue; if (waveFormModeNumber «■ 2) then EKGdataArray[i] .Y :>■ wplnt; { ee§ } EKGdataArray[i] .X :=■ xPos; { eeeeee @ y xPos :- xPos - 1; { eeeee§§i§§eeeeee@§eee } spin(2); {spin(20) makes simulator about 3 seconds per trace. 2 is for real data} e n d ; { e n d q u i c k f o r - l o o p §ee@§-.@e§ee§e@ee@eeeeeeeeeee§eeeeeie§eee§eeeee§ee§e > if (record-Enabled - True) then begin Application.processMessages; if . (waveFormModeNumber - 1) then Write(ekgFile, largerText); if (waveFormModeNumber - 2) then Write(OxWavFil, largerOxText) ; end; { Writeln(ekgFile, IntToStr(EKGvalue) ) ; ...inside the quick loop worXs just as fast.} 35 if (recordEnabled - True) then penColor :- clRed else penColor :- clBlue; if (timesThru - 1) and (gridlStopToggle - False) then begin DisplaySpace.PaintBox1.Refresh; DisplaySpace.GridShapel.Refresh; DisplaySpace.PaintBoxl.Canvas.Pen.Color :■- penColor; DiβplaySpace.PaintBoxl.Canvas.PolyLine(EKGdataArray) ; end; if (timesThru - 2) and (grid2StopToggle » False) then begin DisplaySpace.PaintBox2.Refresh; DisplaySpace.GridShape2.Refresh; DisplaySpace.PaintBox2.Canvaβ.Pen.Color :- penColor; DisplaySpace. aintBox2.Canvas.PolyLine(EKGdataArray) ; end; if (timesThru « 3) and (grid3StopToggle *» False) then begin DisplaySpace.PaintBox .Refresh; DisplaySpace.GridShape3.Refresh; DisplaySpace.PaintBox3.Canvas.Pen.Color :« penColor; DisplaySpace.PaintBox3.Canvas.PolyLine(EKGdataArray) ; end; if (timesThru = 4) and (grid4StopToggle = False) then begin DisplaySpace.PaintBox4.Refresh; DisplaySpace.GridShape4.Refresh; DisplaySpace.PaintBox4.Canvas.Pen.Color :«■ penColor; DisplaySpace.PaintBox4.Canvas.PolyLine(EKGdataArray} ; end; if (timesThru = 5) and (grid5StopToggle = False) then begin DisplaySpace.PaintBox5.Refresh; DisplaySpace.GridShape5.Refresh; DiβplaySpace.PaintBox5.CanvaB .Pen.Color :»* penColor; DisplaySpace.PaintBox5.Canvas.PolyLine (EKGdataArray) ; end; if (timesThru >= 5) then timesThru :» 1 else timesThru :» timesThru + 1; DisplaySpace. timesThruLbl.Caption : ■ intToStr(timesThru) ; if (recordEnabled = » True) then recordCycles :- recordCycles + 1; Application.ProcessMessages; { allows Windows to process pushbuttons. } recordlntervalCycles :• » (recordlnterval div 4); { Value in recordlnterval comes from a panel push button.} DisplaySpace. recordlntervalCyclesLbl .Caption : - intToStr(recordlntervalCycles) ; DisplaySpace.recordCyclesLbl.Caption :•» intToStr(recordCycles) ; if (recordCycles > recordlntervalCycles) then begin if (waveFormModeNumber - 1) then CloseFile(ekgFile) ; if (waveFormModeNumber - 2) then CloBeFile(oxWavFil) ; recordEnabled :» False; 36 -405- DisplaySpace.rcrdShrtLbl.Font,Color :- clWhite; DiβplaySpace.rcrdLngLbl.Font.Color :- clWhite; recordCycles :- 0; end; Application.ProceββMθββagββ; { allows Windows to process pushbuttons. } e n d ; { e n d w h i l e ( d r a w E K G β n a b l e d ) 1111111111111 II 11 i I ! 1111111111 III 11111 III 11111111111 y end; {end ekgdraw) 10 procedure TDiβplaySpace.ShapelMouβeDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin theScreen ι« TScreenControl.Create; theScreen.TurnOnMedicsScreen; end; 15 procedure TDiaplaySpace.ImagelMouββDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin theScreen :- TScreenControl.Create; theScreen.TurnOnMedicsScreen; end; procedure TDi8playSpace.Shape3MoueeDown(Sender: TObject; 20 Button: TMouseButton; Shift: TShiftState; X, Y: Integer); { THIS IS THE TOUCHING OF THE PANEL THAT RETURNS TO THE MEDICS } begin pulsOxEnabled :- Falβe; EtC02Enabled :- Falβe; flowEnabled :- False; theScreen :- TScreenControl.Create; theScreen.TurnOnMedicβScreen; 2 drawEKGenabled :- Falβe; end; procedure TDisplaySpace.Shape2MouaeDown(Sender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); begin EtC02Enabled :- Falβe; pulsOxEnabled :» Falβe; 30 theScreen :■ TScreenControl.Create; theScreen.TurnOnMedicsScreen; end; procedure TDiβplaySpace.I age2Mouse ow (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin -1-. theScreen :- TScreenControl.Create; 37 theScreen.TurnOnMedicβScreen; end; procedure TDi8playSpace.BitBtn6Click(Sender: TObject); begin if suctionOnToggle - True then begin suctionOnToggle :«« False; LabellO.Caption :- 'OFF'; BitBtnβ.Glyph.LoadFromFile( 'auction2.bmp' ) ; powerState :- POWEROFF; if pumpControl (SUCPOWER, powerState) > 0 then messageDlg( 'The .dll haβn''t implemented this yet.' ,mtlnformation, [mbOK], 0); end begin βuctionOnToggle :•■ True; Label10.Caption :- 'ON'; BitBtn6.Glyph.LoadFromFile( 'suctionl .bmp' ) ; powerState :- POWERON; if pumpControl (SUCPOWER, powerState) > 0 then messageDlg( 'The •dll hasn''t implement d this yet.' ,mtlnformation, [mbOK] , 0); end; end; procedure sa pleNovaBoards; { Thiβ ia atatic data displayed on the screen and recorded in the file. The only thing tricky iβ the getting of the data from the boards themselves. If the curves are being drawn, the values are taken from the curve tracing routines. If the curves are not being drawn, then the functions are called and the values read directly. } var {etC02, avg02aat, avgHR, tidalVol, avgPrea, peakPres : integer; inC02, capRR, flowRR, iOverE : integer;} novaDataFile : TextFile; exCapStatAra : staticDataPntr; capNoβtatBoard, pntr to 3 integers } 02Array : staticDataPntr; pulβOxBoard, pntr to 3 integers } waveSizes, waveStarts, patDatArray : staticDataPntr; flowBoard, pntr to 3 integers } 02waveArray : intWavePntr; pulseOxBoard, pntr to 20 integers } C02waveArray : intWavePntr; capNoβtatBoard, pntr to 20 integers } pointerToWaveForms : flowWaveFormPntr; {flow} start, waveSize : integer; {pulsOx} exCapDataSize, capDataSize, capWaveStart, capWaveSize, capStatus integer; {capnostat} 38 dpis, dpiValuea : ArrayOf enPntr; {flow} dpiSizβ, βtatusl, status2, statuβ3, coreTemp : integer; {flow} begin { PRELIMINARY FILE STUFF } AssignFile(novaDataFile, 'C:\LSTATLOG\N0VADAT.TXT' } ; if FileExists{ 'C:\LSTATLOG\NOVADAT.TXT') then Append(novaDataFile) {Thiβ test iβ to see if the file exists. If no time was βpent gathering data it has only a 3% hit on performance.} else Rewrite(novaDataFile) ; { TEMPERATURE } coreTemp :- 97 + random(2); {FAKE STUFF SO FAR1 ! i 1 ! 1 I I 1 I 1 I ! 1 ! 1 I I 1 I 1 i I 1 ! 111 M I I ! 1 ! ! ! ! 1 I I 1 ! ! I I I M I 1 ! } D i s p l a y S p a c e . c o r e T e m p L b l . C a p t i o n : - floatToStrF( (coreTemp .0) ,ffFixed,7, 1) ; M e d i c s G U I . l b l T e m p . C a p t i o n : - floatToStrF( (coreTemp*1.0) ,ffFixed,7, 1) ; V E N T D E T A I L . c o r e T e m p L b l . C a p t i o n : = floatToStrF( (coreTemp*1.0) ,ffFixed,7, 1) ; { CAPNOSTAT BOARD } { END-TIDAL C02 PERCENT —AND— RESP RATE —AND— INSPIRED C02 } if EtC02Enabled - False then begin { inOthrWrds when capNostat wave form is NOT showing } getAllCapno(C02waveArray, capWaveSize, capWaveStart, patDatArray, capDataSize, capStatus, exCapStatAra, exCapDataSize) ; globalEndTidal :- patDatArray Λ [ 1) ; { remember this is a factor of 2 too big (...part of the Novametrix protocol)} globalC02ReβpRate :- patDatArray"[2 ) ; globalInspiC02 :- patDatArray * [3) ; { There is no inspired C02 label, but the value is recorded. } end; {if waveFoπn is displaying then globals are already avalailable} { DISPLAYING THE CAPNOSTAT } {part of Nova protocol v } if globalEndTidal >- 0 then VENTDETAIL.capNoStatLbl .Caption :- floatToStrF(globalEndTidal/2,ffFixed,4 , 1) else begin VENTDETAIL.capNoStatLbl.Caption :- '—'; VENTDETAIL.ventMesβage2.Caption :- 'Error in capnoStat, etC02 - ' + intToStr(globalEndTidal) ; end; if globalC02RespRate >- 0 then begin VENTDETAIL.RBRlbl.Caption :- intToStr(globalC02RespRate) ; { DisplaySpace . breathRateLbl . Caption : - intToStr(globalC02RespRate) ; } { MedicsGui.breathRateLbl.Caption :- intToStr(globalC02RespRate) ; Now done with flow data.} 39 { VENTDETAIL.breathRateLbl.Caption :- intToStr(globalC02RespRate) ; > end else begin DisplaySpace.breathRateLbl.Caption :» '—'; MedicsGui.breathRateLbl.Caption :■ '— '; VENTDETAIL.RBRlbl.Caption I- '—'; VENTDETAIL.breathRateLbl.Caption :- '—'; VENTDETAIL.ventMeseage2.Caption :- 'Error in capnoStat, capRR « ' + intToStr(globalC02ReβpRate) ; end; { PULSE-OX BOARD } 1 0 { HEART RATE And AVERAGE 02 SATURATION } if pulsOxEnabled - False then begin {inOthrWrds, when pulseOx waveForm iβ NOT displaying} getAllPulsOx(02Array, 02waveArray, waveSize, start); globalHeartRate :- 02Array Λ [2]; globalOxSat :■» 02Array Λ !l); end; {if waveForm is displaying - j - then globals are already avalailable} { DISPLAYING THE PULSOX DATA } if globalHeartRate >« 0 then begin DiβplaySpace.HRlbl.Caption :- intToStr(globalHeartRate) ; { MedicsGui.lblHeartRate.Caption :- intToStr(globalHeartRate) ; } MedicsGui.lblHeartRate.Caption :« '62'; { 1 ! I i 1 ! 1 I 111 i i I 1 I } VENTDETAIL.beatsPerLbl.Caption :- intToStr(globalHeartRate) ; 0 end else begin DisplaySpace.HRlbl.Caption :- '— '; MedicsGui.lblHeartRate.Caption := '--'; VENTDETAIL.beatsPerLbl.Caption :- '— '; VENTDETAIL.ventMessage2.Caption := 'Error in pulsOx, H.R. = ' + intToStr(globalHeartRate) ; end; < - if globalOxSat >- 0 then begin VENTDETAIL.oxSatLbl.Caption :- intToStr(globalOxSat) ; MedicsGUI.OXβatLbl.Caption :- intToStr(globalOxSat) ; end else begin VENTDETAIL.oxSatLbl.Caption MedicsGUI.OXsatLbl.Caption : VENTDETAIL.ventMessage2.Caption : « 'Error in pulsOx, OxSat = 0 + intToStr(globalOxSat) ; end; { FLOW BOARD } { FLOW, INTEGRAL OF FLOW AND PRESSURE } if flowEnabled - False then begin getAHFlow(pointerToWaveForms, waveSizes, waveStarts, dpis, dpiValues, dpiSize, statusl, status2, status3); 5 40 for i: ° l to dpiSize do case dpis"!i] of 22 : globalTidalVol := (dpiValues * [i] ) * 10 div 15; { I i i 111 I I I 1PLEASE CHECK THIS SOME DAY1111 I I i 1111 } 24 globalFlowExpiatory :- dpiValues" [i] ; 30 globalFlowPeaklnPress :- dpiValues"[i] ; 31 globalFlowMeanPress :- dpiValues"[i] ; 34 globalFlowRespRate :- dpiValues"Ji] ; 35 globalloverEratio :=• dpiValues * [i] ; end; end; { DISPLAYING THE FLOW BOARD } VENTDETAIL.tidalVolLbl.Caption := intToStr(globalTidalVol) ; VENTDETAIL.ventLbl.Caption :- intToStr(globalTidalVol) ; MedicsGUI.tidalVolLbl.Caption := intToStr(globalTidalVol) ; DiβplaySpace.tidalVolLbl .Caption :- intToStr(globalTidalVol) ; DisplaySpace.ventVol.Caption :- intToStr(globalTidalVol) ; VENTDETAIL. flowIoverElbl.Caption :- intToStr(globalloverEratio) ; DisplaySpace.flowIoverELbl.Caption : ■ = intToStr(globalloverEratio) V E N T D E T A I L . p a t i e n t P r e s s L b l 2 . C a p t i o n : ■ ■ intToStr(globalFlowMeanPress) ; D i s p l a y S p a c e . e a nA i r P r e s s Lb l . C a p t i o n : : intToStr(globalFlowMeanPress) ; VENTDETAIL. flowPeakLbl.Caption " intToStr(globalFlowPeaklnPress) DisplaySpace.PeaklnLbl.Caption » intToStr(globalFlowPeaklnPress) {VENTDETAIL. flowRBRlbl.Caption := intToStr(globalFlowRespRate) ; now done from the 20Hz} Displ ySpace.RespRateLbl.Caption := intToStr(globalFlowRespRate) VENTDETAIL. flowExplbl.Caption := intToStr(globalFlowExpiatory) ; DisplaySpace.ExpiatoryLbl.Caption : « = intToStr(globalFlowExpiator ) D i s p l a y S p a c e . br e a t h R a t e Lb l . C a p t i o n : intToStr (globalFlowRespRate) ; { MedicsGui .breathRateLbl .Caption intToStr ( globalFlowRespRate ; } MedicsGui . breathRateLbl . Caption • 21 VENTDETAIL. breathRateLbl. Caption intToStr(globalFlowRespRate) { NOVAMETRIX OUTPUTS TO FILE } { Some of these Novametrix calls are also done in ventSampler, but just to store along side the vent stuff. It's done there without the status checking, and error messages. } if (NovaSamplerWriteCntr =» 0) then Begin Writeln (novaDataFile, ' ' ) ; Writeln (novaDataFile, ''); Writeln (novaDataFile, ' Novametrix Data (Continuous) ' ) ; Writeln (novaDataFile, 'New Patient Begins, DateToStr(Date) ) ; end; if (NovaSamplerWriteCntr mod 25 = 0) then begin 41 Writeln (novaDataFile, "); Writeln (novaDataFile, TimeToStr(Time) ) ; Write (novaDataFile, ' Oxy AvgHeart EndTid AirwayPreβsure ' ) ; Writeln (novaDataFile, ' ReβRate Tidal Inβpi I/E Core' ) ; Write (novaDataFile, ' Satur Rate C02 Mean Peak Expia' ) ; Writeln (novaDataFile, ' capBord floBord Vol C02 Ratio Temp' ) ; end; Writeln(novaDataFile, + ' ' + intToStr(globalOxSat) + ' ' + intToStr(globalHeartRate) + + floatToStrF(globalEndTidal/2,ffFixed,4, 1) {remember, too big by two) + ' ' + intToStr(globalFlowMeanPreβs) {patient pressure} + ' ' + intToStr(globalPlowPeaklnPreββ) {peak "inspiatory"} + ' ' + intToStr(globalFlowExpiatory) + ' ' + intToStr(globalC02ReβpRate) + ' ' + intToStr(globalFlowRespRate) + ' ' + intToStr(globalTidalVol) + ' ' + intToStr(globalInβpiC02) {not displayed on screen} + ' ' + intToStr(globalloverEratio) + ' ' + intToStr(coreTemp) ) ; CloseFile(novaDataFile) ; NovaSamplerWriteCntr :- NovaSamplerWriteCntr + 1; end; procedure TDisplaySpace.ShapelOMouβeDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) { UPPER LEFT MOST BUTTON } begin {windowsAway; } {Thiβ method flashes too much} VENTDETAIL.Visible :- False; SyβtemGUI.Viβible :- Falβe; {MedicsGUI.Visible :- True; } BitBtn2.Enabled :- True; {test of depressed button} EKGpanel.Viβible :- Palβe; Shapel.Visible :- False; Shape2.Visible :- Falββ; Shape3.Viβible :- True; shapeMesβageSpace.Viβible :- True; Image1.Visible :- Falβe; Image2.Viβible :- Falβe; 42 Image7.Visible :- Falβe; DiβplaySpace.oxScalelmage.Visible :- False; Image7h.Visible :- Falβe; Label14.Visible :- False; Labell5.Visible :- False; oxSatTitlβLbl.Viβiblβ :- False; BitBtnl.Visible :- Falββ; BitBtn2.Viβible :- True; BitBtn3.Viβible :- True; BitBtn4.Viβible :- True; end; procedure TDiβplaySpace.FormDeβtroy(Sender: TObject); begin theScreen.Free; bloodPreββList.Free; end; procedure TDiβplaySpace.βkgBtnClick(Sender: TObject) ; begin twentyHz.Enabled :» Falβe; BtC02Enablβd x« Falββ; pulsOxEnabled :- False; pC02backgndShape.Viβible :- False; floShrtRcdLbl.Visible :- False; floShrtRcdShape.Visible :- False; returnBtn.Visible :- False; dotl.Visible :- False; dot2.Visible :- Falβe; dot3.Visible :- Falβe; dot4.Visible :- False; dot5.Viβible :■ Falβe; gridlStopTogglβ :- Falβe; grid2StopToggle :- Falβe; grid3StopToggle :- Falββ; grid4StopToggle :- Falβe; grid5StopToggle :» Falβe; gridShapel.Pen.Color i- clLime; gridShape2.Pen.Color :- clLime; gridShape3.Pen.Color :» clLime; gridShape4.Pen.Color :- clLime; gridShape5.Pen.Color x- clLime; EKGpanel.Viβible :- True; EKGpanel.Height :- 409; capNoStatBtn.Viβible :- False; flowBtn.Visible :- False; presβBtn.Visible :- False; volBtn.Visible :- Falβe; drawEKGenabled :- True; ekgTitleLbl.Caption :- 'E C G'; 43 Image3.Visible :«■ True; touchShape.Brush.Color : « clGreen; rcrdLngShape.Brush.Color := clGreen; rcrdShrtShape.Brush.Color :- clGreen; EKGpanel.Color := clLime; waveFormModeNumber := 1; drawEKG; end; procedure TDisplaySpace.BitBtnlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); { THIS IS THE HEART KEY } begin {windowsAway; } {This method flashes too much} {VENTDETAIL.Visible :» False; VentSub.Visible : α False; SystemGUI.Visible :«* False; } {MedicsGUI.Visible := True; } BitBtn2.Enabled := True; {test of depressed button} whichFlow := PULSOX_BTN; flowEnabled := False; EtC02Enabled := False; pulsOxEnabled := True; {WaveForm of pulsOx} firstBurst := True; {This is part of the way to make first polyline call same color as background.} {It is set to false AFTER each call to drawBurst.} floShrtRcdLbl.Visible := True; floShrtRcdShape.Visible := True; DisplaySpace.timelnMinutesLbl.Caption := 'TIME'; hrBarBackgndShape.Visible := True; nowLbl.Visible := True; hrBarLbl.Visible := True; beatsLbl.Visible := True; Label32.Visible :=■ True; Label46.Visible := True; board := SP02B0ARD; { board is a global var to tell timer or record part of drawBurst which one to command. } pC02backgndShape.Visible := False; Shapel .Visible := False; Shape2.Visible := False; Shape3.Visible : =• True; shapeMessageSpace.Visible : α True; Imagel .Visible := False; Imageθ.Visible :=» False; Labell7.Visible := False; Labell6.Visible := False; Image2.Visible := False; 44 Image7.Visible :- True; oxScalelmage.Visible := True; Image7h.Visible :*■ True; Labell4.Visible :- True; Labell5.Visible :- True; DisplaySpace.oxSatTitleLbl.Visible :- True; EKGpanel.Visible :- Falβe; drawEKGenabled := False; BitBtnl.Visible :« False; BitBtn2.Visible := True; BitBtn3.Visible := True; BitBtn4.Viβible := True; DisplaySpace.Label43.Visible :«* True; Di8playSpace.Label47.Visible := True; DisplaySpace.Shape3.Height :- 313; {273} firstBurst :** True; {This is part of the way to make first polyline call same color aβ background.} {It is set to false AFTER each call to drawBurst. } Application.processmesBages; drawHRCurve; Image7h.Visible :» True; end; procedure TDisplaySpace.gridShapelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if gridlStopToggle - True then begin dotl.Visible := False; gridlStopToggle :=■ False; end else begin dotl.Visible := True; gridlStopToggle :- True; end; end; procedure TDisplaySpace.gridShape2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ; begin if grid2StopToggle - True then begin dot2.Visible :«• False; grid2StopToggle :» False; end else begin dot2.Visible :- True; grid2StopToggle :- True; end; end; 45 proceduro TDiaplaySpace.gridShape3MousβDown(Sender: TObject; Button: TMouβoButton; Shift: TShiftState; X, Y: Integer); begin if grid3StopToggle - True then begin dot3.Viβible t- Falββ; grid3StopTogglβ ι» False; end elβe begin dot3.Viβible :- True; grid3StopTogglβ :- True; end; end; procedure TDiβplaySpacβ.gridShape4MouβeDown(Sender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); begin if grid4StopToggle - True then begin dot4.Visible :- False; grid4StopTogglβ i- False; end else begin dot4.Viβible :- True; grid4StopToggle :- True; end; end; procedure TDioplaySpace.gridShape5MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if grid5StopToggle - True then begin dot5.Viβible :- Falβe; grid5StopToggle :- Falβe; end elβe begin dot5.Viβible :» True; grid5StopToggle :- True; end; end; procedure TDisplaySpace.touchShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin EKGpanel.Visible :- False; drawEKGenabled :-> Falβe; returnBtn.Visible :• » True; capNoStatBtn.Visible :- True; flowBtn.Viβible :- True; prββsBtn.Viβible :- True; volBtn.Visible :- True; 46 twentyHz.Enabled True; end; procedure TDisplaySpace.BitBtn2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); { second button on left, old pressure button } begin firstBurst :- True; {This is part of the way to make first polyline call same color as background.} {It is set to false AFTER each call to drawBurst. } pulsOxEnabled :» False; displaySpace.oxSatTitleLbl.Visible := False; displaySpace.pC02backgndShape.Visible :** True; displaySpace.floShrtRcdLbl.Visible :« True; displaySpace.floShrtRcdShape.Visible := True; {showAirwayGraph; } EtC02Enabled :- True; board :- CAPNOSTATBOARD; { board is a global var to tell timer which one to command. } firstBurst :=> True; {This is part of the way to make first polyline call same color as background.} {It is set to false AFTER each call to drawBurst. } hrBarBackgndShape.Visible False; nowLbl.Visible False; hrBarLbl.Visible :« False; beatsLbl.Visible :- False; Label32.Visible : - False; Label46.Visible : - False; ρC02backgndShape.Visible :» False; floShrtRcdLbl.Visible := True; floShrtRcdShape.Visible :*» True; Shapel.Viβible :- False; Shape2.Visible :- True; Shape3.Visible :■■ False; shapeMeββageSpace.Visible :™ True; Image1.Visible : α False; Imageδ .Visible :» Falβe; Labell7.Visible :- Falβe; Labell6.Visible :- False; Image2.Visible :» True; Label43.Visible :•" False; Label47.Visible :- False; Image7.Visible :- False; DisplaySpace.oxScalelmage.Visible :■» False; Image7h.Visible :- False; Labell4.Visible :- False; Labell5.Visible :- False; 47 DisplaySpace.oxSatTitleLbl.Visible :- False; EKGpanel.Visible :- Falβe; drawEKGenabled :- False; BitBtnl .Visible :■» True; BitBtn2.Visible :« Falβe; BitBtn3.Visible :- True; BitBtn .Visible :- True; DisplaySpace.timelnMinuteβLbl.Caption : » 'Time in Minutes Application.processmessageβ; end; procedure TDisplaySpace.BitBtn3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); { third button on left, temperature button } begin Application.processmessages; flowEnabled :»■ False; EtC02Enabled :» False; pulsOxEnabled :™ False; DisplaySpace.BitBtn2.Enabled :« True; {test of depressed 2nd button} pC02backgndShape.Visible :- False; floShrtRcdLbl.Visible :- False; floShrtRcdShape.Visible := False; Shapel .Visible := True; Shape2.Visible :■ » False; Shape3.Visible :■» False; shapeMessageSpace.Visible :*= True; Imagel .Visible :=» True; Imageβ.Visible :=» True; Labell7.Visible :- True; Labell6.Visible :«» True; Image2.Visible :— True; Label43.Visible :- False; Label47.Visible :- False; hrBarBackgndShape.Visible :- False; nowLbl.Visible := False; hrBarLbl.Visible :» False; beatsLbl.Visible := False; Label32.Visible := Falβe; Label46.Visible :» False; Image7.Visible : ■ » False; Image7h.Visible :« False; DisplaySpace.oxScalelmage.Viβible :■■ False; Labell4.Visible :« False; Labell5.Visible :» False; DisplaySpace.oxSatTitleLbl .Visible :- False; EKGpanel.Visible :- False; drawEKGenabled : α False; 48 BitBtnl.Visible :- True; BitBtn2.Visible :- True; BitBtn3.Visible :- False; BitBtn4.Visible :- True; DisplaySpace.timelnMinutθsLbl.Caption :- 'Time in Minutes'; Application.proceβsmeasages; drawTempCurve; end; procedure TDisplaySpace.BitBtn4MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); { forth button on left, go to ventilator screen button } begin EtC02Enabled : « False; pulsOxEnabled :» False; EKGpanel.Visible :- Falβe; drawEKGenabled :- False; VENTDETAIL.Visible :- True; VENTDETAIL.moreBreathPnl.Visible :» False; SystemGUI.Visible :- False; MedicsGUI.Visible :=• False; if suctionOnToggle =» True then begin VENTDETAIL.Labell.Caption :~ 'ON'; VENTDETAIL.BitBtn10.Glyph.LoadFromFile ( 'suctionl.bmp' ) ; end else begin VENTDETAIL.Labell.Caption :- 'OFF'; VENTDETAIL.BitBtnlO.Glyph.LoadFromFile( 'suction2.bmp' ) ; end; if ventOnToggle = True then begin VENTDETAIL.btnShutDown.Caption :- 'SHUT OFF VENTILATOR' ; end else begin VENTDETAIL.btnShutDown.Caption :- 'TURN ON VENTILATOR'; end; end; procedure TDisplaySpace.returnBtnClick(Sender: TObject); begin EtC02Enabled :- False; pulsOxEnabled :- Falβe; theScreen := TScreenControl.Create; theScreen.TurnOnMedicsScreen; drawEKGenabled :- False; end; 49 procedure TDisplaySpace.oxSatBtnClick(Sender: TObject); begin EtC02Enabled :- Falae; pulsOxEnabled :- False; floShrtRcdLbl.Visible :- False; floShrtRcdShape.Visible :- False; returnBtn.Visible :- False; dotl.Viβible :- False; dot2.Visible :- False; dot3.Visible :- False; dot4.Visible :•» False; dot5.Visible :- False; gridlStopToggle :- False; grid2StopToggle :- False; grid3StopToggle :- False; grid4StopToggle : - False; grid5StopToggle :•« False; gridShapel.Pen.Color :»■ clAqua; gridShape2.Pen.Color :« clAqua; gridShape3.Pen.Color :- clAqua; gridShape4.Pen.Color :- clAqua; gridShape5.Pen.Color :=■ clAqua; EKGpanel.Visible :- True; EKGpanel.Height :- 409; capNoStatBtn.Visible :« False; flowBtn.Visible : •* False; drawEKGenabled :- True; ekgTitleLbl.Caption :- 'OxSat'; Image3.Visible :>» False; touchShape.Brush.Color :- clBlue; rcrdLngShape.Brush.Color :«• clBlue; rcrdShrtShape.Brush.Color :- clBlue; EKGpanel.Color :- clAqua; waveFormModeNumber :™ 2; drawEKG; end; procedure TDisplaySpace.rcrdShrtLblMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin recordEnabled :■ ■ True; recordlnterval :- 12; rcrdShrtLbl.Font.Color :- clRed; end; procedure TDisplaySpace.rcrdLngLblMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin recordEnabled :- True; recordlnterval :«» 64; {64} rcrdLngLbl.Font.Color :- clRed; 50 end ; procedure TDisplaySpace.capNoStatBtnClick(Sβndβrι TObjoct); begin whichFlow :« CAPNO_BTN; flowEnabled i - Falβe; pulβOxBnabled :- False; pC02backgndShape.Viβible :- True; diβplaySpace.oxSatTitleLbl.Viβible J- Falββ; floShrtRcdLbl.Viβible :- True; floShrtRcdShape.Visible :- True; βhowAirwayGraph; EtC02Enabled :- True; board :- CAPNOSTATBOARD; { board iβ a global var to tell timer which one to command. } firβtBurst :- True; {This iβ part of the way to make firβt polyline call same color aβ background.} {It iβ βet to false AFTER each call to drawBurst. } end; procedure TDisplaySpace. flowBtnClick(Sender: TObject); begin whichFlow := FLOW_FLOW; {which of the three buttonβ that work the flow board} board :- FLOWBOARD; { board iβ a global var to tell timer which one to command. } flowEnabled :- True; firstBurst :*• True; {Thiβ is part of the way to make firβt polyline call same color as background.} {It is βet to false AFTER each call to drawBurst. } EtC02Enabled :- False; pulsOxEnabled :- Falβe; displaySpace.pC02backgndShape.Viβible :- Falβe; displaySpace.oxSatTitleLbl.Viβible :- Falββ; pC02backgndShape.Visible ι« Falβe; floShrtRcdLbl.Visible :- True; floShrtRcdShape.Visible :- True; βhowAirwayGraph; end; procedure drawHeartBarβ (avgHR, avg02sat : integer); var status , dataSize , wavβStart , capRR, waveSize , start : integer ; VentOxSca l eFac t or , di βpOxScale Pac tor , h rSc a l e Fac t o r , capRRscaleFactor , scaleFactor i integer; 51 -420- patDatArray, extβndedStatuβArray, 02Array : staticDataPntr; { pntr to 3 integers } 02wavβArray, C02waveArray : intWavePntr; { pntr to 20 integers ) labelHalfHeight, size, oxBarBottom, diβpOxBarBottom, rrBarBottom, hrBarBottom, capRRbarBottom : integer; begin diapOxScaleFactor :- oxGain ; {should be exactly the same as oxGain (10) which iβ βet inaide 20Hz I think } VentOxScaleFactor :- (oxGain div 2) + 2; {half as big} 10 hrScaleFactor :- 18; {should be same as drawCurve gain} labelHalfHeight :- 8; capRRacaleFactor : » 30; {60} { OX SAT } oxBarBottom :- VENTDETAIL . oxSa tBackg ndShape . Top + VENTDETAIL . oxSatBackgndShape . Height ; VENTDETAIL. oxSatBackgndShape. Re fresh; -, c- VENTDETAIL. oxSatBarShape. Height :- avg02sat * VentOxScaleFactor div 10; VENTDETAIL. oxSatBarShape . Top :- oxBarBottom VENTDETAIL . oxSatBarShape . Height ; VENTDETAIL. oxSatBarLbl. Caption :- intToStr (avg02βat) + '%'; diβpOxBarBottom :- DisplaySpace .oxSatBackgndShape .Top + DisplaySpace . oxSatBackgndShape . Height ; DisplaySpace . oxSatBackgndShape .Refresh ; 0 DisplaySpace .oxSatBarShape. Height :■■ avg02sat * diapOxScaleFactor div 10; DisplaySpace . oxSatBarShape .Top :- dispOxBarBot torn DiβplaySpace . oxSatBarShape . Height ; DisplaySpace. oxSatBarLbl. Caption :- intToStr (avg02sat) + '%'; ahowArrow( DisplaySpace. oxSatBackgndShape . Lef t + D i β p l a y S p a c e . o x S a t B a c k g n d S h a p e . W i d t h , Display Space. oxSatBarShape. Top) ; 5 { HEART RATE } hrBarBottom : ■■ DiβplaySpace . hrBarBackgndShape .Top + DisplaySpace.hrBarBackgndShape.Height; DisplaySpace.hrBarBackgndShape.Refresh; DisplaySpace.nowLbl.Top :■ hrBarBottom - (avgHR * hrScaleFactor div 10) - labelHalfHeight; 0 DisplaySpace.hrBarLbl.Caption :- intToStr(avgHR) ; DiβplaySpace.hrBarLbl.Top :- DiβplaySpace.nowLbl .Top + 16; DiβplaySpace.beatβLbl.Top :» DiβplaySpace.nowLbl.Top + 32; { C02 RESP RATE} if EtC02Enabled - True then capRR : « globalC02RespRate elβe begin getAllCapno(C02waveArray, waveSize, waveStart, patDatArray, 5 dataSize, status, extendedStatusArray, βize); 52 capRR :- patDatArray * ! 2 ] ; end; {capRR :- random(lθ) + 8;} capRRbarBottom :- VENTDBTAIL. capRRbackgndShapo . Top + VENTDETAIL . capRRbackgndShape . Height ; VENTDETAIL. capRRbackgndShape. ef resh; VENTDETAIL. capRRbarShape. Height :- capRR * capRRβcaleFactor div 10; VENTDETAIL. capRRBarShape .Top :- capRRbarBottom VENTDETAIL . capRRbarShape . Height ; VENTDETAIL. C02barLbl. Caption :- intToStr (capRR) ; θnd ' procedure TDiβplaySpace.twentyHzTimer(Sender: TObject); { Thiβ timer is the only timer. It seemβ like the overhead of the timer ia βuch that with more than one, the timing iβ inconsistent. Thiβ timer ia going about aa faat aβ a timer can go; 20 Hz or 50 msec. Counting every 10 or 100 gives 2 second periods or 20 second periods. The fast aβ poβsiblβ events are enabled firβt, but the order doeβn't matter. EVENT PHILOSOPHY Global True/False variables are watched here to allow functions to do their thing. The general philosophy iβ: > waveForms go as fast aβ possible. > Trends and bargraphβ go about twice a second, > numbers displayed on the screen about every other second. > history graphβ about 7.5 seconds (to make it 1/2 hour across the graph) } var flowRateData, presData, p_C02data : integer; { coreTemp, avgHR, avg02sat : integer; moved to global. These have to be static.} 02wavβArray : intWavePntr; { pntr to 20 integera } 02Array : βtaticDataPntr; { pntr to 3 integerβ } waveSize, start : integer; flowBreathRate : integer; flowTidalVol : integer; pointerToWaveFor β : flowWaveFormPntr; {flow} waveSizea, waveStartβ, patDatArray : βtaticDataPntr; { flowBoard, pntr to 3 integerβ } dpis, dpiValues : ArrayOfTenPntr; {flow} dpiSize, statusl, βtatuβ2, status3, coreTemp : integer; {flow} begin { interval « 40 ms iβ 7 in 10 sec} 53 { CAPNOSTAT STUFF } if EtC02Enabled - True then ββndCapBurβt; { PULSBOX STUFF } if pulβOxBnabled - True then sendoxBurβt; { FLOWBOARD STUFF } if flowBnablβd - True then ββndFlowBurst; { NOVAMETRIX RECORDING TIMER } novaSamplerCounter :■ novaSamplerCounter + 1; if novaSamplerCounter « 12 then begin {60} βampleNovaBoardβ; novaSamplerCounter :■ 1; end; { ONE PER SECOND TIMER Thiβ haβ to do with telling John to record. And iβ no longer one per second.} if onePerSecondEnabled » True then begin onePerCounter :- onePerCounter + 1; if onePerCounter - 10 then begin displaySpace.timeDisplay.Caption :- 'OnePerSecond Event'; if flowBoardEnabled then logWaveForm(FLOWBOARD, 2); if capnoBoardEnabled then logWaveFoππ(CAPNOSTATBOARD, 2); if βpo2BoardEnablβd then logWaveForm(SP02BOARD, 2); if allBoardsEnabled then begin logWaveForm{FLOWBOARD, 2); logWaveFormfCAPNOSTATBOARD, 2); logWaveForm(SP02BOARD, 2); end; onePerCounter :- 1; end; end; { VENTSAMPLER TIMER only on if compressor ia turned on} if ventSa plerEnabled - True then begin ventSa plerCounter :- ventSamplerCounter + 1; if ventSamplerCounter ■ 11 then begin ventSampler; {Thiβ iβ in the VentDetail Unit} ventSamplerCounter i- 1; end; end; {BAR GRAPHS AND FAST HISTORY CURVES} barGraphCounter :- barGraphCounter + 1; if barGraphCounter - 18 then begin {18} if pulβOxEnabled - True then begin avgHR :- globalHeartRate; {value from sendOxBurβt} avg02βat :» globalOxSat; {value from sendOxBurst} end else begin getAllPuleOx(02Array, 02waveArray, waveSize, start); 54 avgHR :- 02Array * [2); avg02βat : - 02Array * [l]? end; globalHeartRate :- rando (lθ) + 60; { 888888?88§§ 8 a §} avgHR :- globalHeartRate; -{8ee§§e§e§e8§§§§§§8> globalOxSat :- random(3) + 97; {888888888888888888} { globalOxSat :- random(90) + 07; 88888 88888888 888} avg02sat :- globalOxSat; {888888888888888888} oxGain :» 10; {oxGain is also used by drawBar. Curve is div 10 later, so 14 is actually 1.4 } pulβOxDatfdrawOxCount) :- oxGain * avg02sat + 0; drawOxCount ι« drawOxCount + 1; if drawOxCount > 499 then drawOxCount :- 1; drawOxcurve; barGraphCounter :- 1; drawHeartBars(avgHR, avg02sat); end; {PLOT HISTORY CURVES} {The values being dispTayed here are much less often than those going to the bar graphs, but since these curves are next to their corresponding bar, it'd be nice if the values recorded here were the average of all that were missed. Oh well, someday1} curvePlotCounter :- curvePlotCounter + 1; if curvePlotCounter - 20 then begin {1111 I 1 I 111220J 1111111111111111} { It should be adjusted so as to make it 7.5 seconds to make } { display x-coordinate correct; ie = 30 in. 7.5 sec / 60 s -> 125} {CORE TEMPERATURE} coreTemp := 87 + random(6); {FAKE STUFF} { v curve is div 10 later, so 14 is actually 1.4 } { I v offset is so that increase is up } yTempDat[drawTempCount) : « ■ 10 * coreTemp + 20; {one new data point added to the end of the array} drawTempCount :- drawTempCount + 1; drawTempCurve; {HEART RATE} v curve is div 10 later, so 14 is actually 1.4 I should be same as drawHeartBars gain ! v offset is increase = up } 55 YRateDat[drawHRcount] :- 18 * avgHR + 0; {avgHR is static and comes from several inches above } drawHRcount :» drawHRcount + 1; drawHRcurve; {BREATHING RATE} getAHFlow(pointerToWaveForms, waveSizes, waveStarts, dpis, dpiValues, dpiSize, statusl, Btatus2, status3) ; for i:=l to dpiSize do case dpiβ"[i) of 22 : flowTidalVol :» (dpiValues" [ i] ) * 10 div 15; { 1111111 I 1 I PLEASE CHECK THIS SOME DAYl 1111111111 } 34 : flowBreathRate :- dpiValues" [i] ; end; flowBreathRate := (rando (12) + 12) ; { I 1111 I 11111111 U 11111111111 I 11111111111 } BrDatfdrawBRcount] :- 10 * flowBreathRate + 0; VENTDETAIL. flowRBRLbl.Caption : ■ = intToStr ( flowBreathRate ) ; drawBRcount :•» drawBRcount + 1; drawBRcurve; {MINUTE VOLUME} flowTidalVol :- 750; { M 1111111111 I 1111111 I 11 I 11111111 ! 1 } {Algorithm: minute volume is breathrate times tidal volume.} MINdatfdrawMINcount] := (BrDatfdrawBRcount-1 ] * (flowTidalVol div 10) ) div 100; VENTDETAIL.minVolLbl.Caption := intToStr(MINdat(drawMINcount ] div 10); drawMINcount := drawMINcount + 1; drawMINcurve; {BLOOD PRESSURE} { v curve is div 10 later, so 6 is actually .6 } < I } sysBPdat[drawBPcount) := 7 * (random(4) + 128) ; {1111111111111111111111111111111111} disBPdat[drawBPcount] :- 7 * (random(4) + 78) ; {1111111111111111111111111111111111} drawBPcount :■> drawBPcount + 1; drawSysBPcurve; drawDisBPcurve; {DIAGNOSTIC LABELS} VENTDETAIL.tempLabel.Caption :- 'breathrate is ' + intToStr(flowBreathRate) ; VENTDETAIL.tempLabel_2.Caption := 'MINdat[drawMINcount ] is ' + intToStr(MINdatIdrawMINcount-1] ) ; VENTDETAIL.tempLabel_3.Caption := 'flowTidalVol is ' + intToStr(flowTidalVol) ; 56 curvePlotCounter :-. l; if drawBPcount > 499 then drawBPcount :- 1; if drawHRcount > 499 then drawHRcount : ° 1; if drawMINcount > 499 then drawMINcount := 1; if drawBRcount > 499 then drawBRcount := 1; if drawTempCount > 499 then drawTempCount :- 1; end; e n d ; { e n d T w e n t y H z p r o c e d u r e It J f I til 11111 / II 111 II 1111 till I f I II I It II I fill III 1111 II lly procedure drawBRcurve; {NOTE1 I THIS CALLS THE VENTDETAIL VERSION OF THE DRAWCURVE.} {BRdat, drawBRcount : are global} begin i f ( VENTDETAI L . V i s ib l e - True ) AN D (VENTDETAIL. oreBreathPnl. Visible = False) then {ie., you can see the breath curves.} drawVentCurve ( BRdat, 488, 50, 120, drawBRCount, clSilver, clRed, 0); I . { * ar Iray , I f 'a,rRight, d 'isplaySize, ' bottom, array's index, backGround, curve, floor} end; procedure drawSysBPcurve; {NOTE1I THIS CALLS THE MAIN VERSION OF THE DRAWCURVE.} {sysBPdat, drawBPcount : are global} var rightSide, pushDown : integer; begin rightSide := MedicsGui.BPhistoryPnl .Left + 244; pushDown := MedicsGui.BPhistoryPnl.Top + 102; if (MedicsGui . setBPpanel .Visible «» False) AND (MedicsGui.BPhistoryPnl.Visible » True) then drawMainCurve( sysBPdat, rightSide, 54, pushDown, drawBPCount, clAqua, clRed, 0 ; I , { < ar Iray , I f 'a,rRight, d 'isplaySize, ' bottom, array's index, backGround, curve, floor} end; procedure drawDisBPcurve; {NOTE11 THIS CALLS THE MAIN VERSION OF THE DRAWCURVE.} {sysBPdat, drawBPcount : are global} var rightSide, pushDown : integer; begin 57 rightSide :- MedicsGui.BPhistoryPnl.Le t + 244; pushDown :- MβdicβGui.BPhistoryPnl.Top + 102; if (MedicsGui. setBPpanel.Viβiblβ - Faloβ) AND (MedicβGui.BPhistoryPnl.Visible - True) then drawMainCurvβ( diβBPdat, rightSide, 54, puβhDown, drawBPCount, clAqua, clNavy, 0) J I I < 'l I '» ' ' { array, farRight, displaySize, bottom, array's index, backGround, curve, floor) end; procedure drawMINcurvβ; {NOTEI I THIS CALLS THB VBNTDBTAIL VERSION OF THB DRAWCURVE.} {BRdat, drawMINcount i are global} begin i f ( VENTDETAIL . Viβ ib le - Tr u e ) AN D (VENTDETAIL. moreBreathPnl. Viβible - Falβe) then {ie., you can BOΘ the breath curves.) drawVentCurve ( MINdat, 488, 50, 320, drawMINcount, clSilvβr, clBlue, 0); I I { < ar Iray , I f 'a,rRight, d 'isplaySize, bottom, array's index, backGround, curve, floor} end; procedure drawOxcurve; var rSide : integer; {pulβOxDat, drawOxCount : global) begin rSide :- 426; {428} if (DiβplaySpace.Viβible) AND (DiβplaySpace.βhape3.Viβible) then {shape3 is heart rate, green screen) drawDispCurve(pulβOxDat, rSide, 22, 277, drawOxCount, clLime, clRed, 40); I , ( { ar Iray , I f 'a,rRight, d 'isplaySize, bottom, array's index, backGround, curve, floor} end; procedure drawTempCurvβ; begin if (DisplaySpace.Viβiblβ) AND (DiβplaySpacβ.βhapel .Visible then {shapel is temperature, white screen) drawDiβpCurve(yTβapDat, 596, 58, 260, drawTempCount, clWhite, clBlack, 0); I > 58 { array , farRight, displaySize, bottom, array's index, backGround, curve, floor} end; procedure drawHRcurve; var HRbottom : in eger; begin HRbottom : *= DiβplaySpace . hrBarBackgndShape . Top + DisplaySpace.hrBarBackgndShape.Height; if (DisplaySpace.Visible) AND (DisplaySpace. shape3.Visible) then {shape3 is heart rate, green screen} drawDispCurve(YRateDat, 584, 54, HRbottom, drawHRcount, clLime, clBlack, 0); < . I I I I I I } { array , farRight, displaySize, bottom, array's index, backGround, curve, floor} end; procedure showArrow(posX, posY : integer); var arrowNum, nowValue, pastValue : real; begin {Would sure like to put a circular cue in here.} rateOchanAraf shoAroCntr ] :=* posY; { n owV a l u e : = ra t e Oc h a nA r a [ s h oA r o C n t r ] + rateOchanAra [ ahoAroCntr-1 ] ; } nowValue :- rateOchanAra [ shoAroCntr] ; pas tValue : ■ » rate0chanAra [ s hoAroC n t r - 2 ] + rateOchanAra [ shoAroCntr-3 ] ; arrowNum :- ( pastValue - (nowValue * 2) ) / pastValue; DisplaySpace.rateOLbl.Caption : «■ floatToStr(arrowNum) ; shoAroCntr :- shoAroCntr + 1; f shoAroCntr > 499 then shoAroCntr := 1; DisplaySpace.arrowlimg.Visible :=> False; DisplaySpace. rrow2img.Visible :- False; DisplaySpace.arrow3img.Visible :- False; DisplaySpace.arrow4img.Visible :« Falβe; DisplaySpace.arrowδimg.Visible :- False; if (DisplaySpace.Shape3.Visible - True) then begin {That is, if background is green} if (arrowNum > 0.03) then begin DisplaySpace.arrowlimg.left :- posX -7; DisplaySpace.arrowlimg.top :- posY - 31; DisplaySpace.arrowlimg.Visible :« True; end; if ((arrowNum > 0.006) and (arrowNum <» 0.03) ) then begin DisplaySpace.arrow2img. left :«■ posX -5; DisplaySpace. rrow2img.top :- posY - 18; 59 DisplaySpace.arrow2img.Visible :- True; end; if ((arrowNum >- -0.006) and (arrowNum <- 0.006)) then begin {dn is more pos} DisplaySpace.arrow3i_mg.left :« posX -7; DisplaySpace.arrow3img.top :- posY - 16; DisplaySpace.arrow3img.Visible :•■ True; end; if ((arrowNum <- -0.006) and (arrowNum > -0.03)) then begin Di8playSpace.arrow4img. left :- posX -9; DiβplaySpace.arrow4img.top :- posY - 10; DisplaySpace.arrow4img.Visible :- True; end; if (arrowNum < -0.03) then begin DisplaySpace.arrowδimg.left :- posX -6; DisplaySpace.arrowδimg.top :» posY - 3; DisplaySpace.arrow5img.Visible :- True; end; end; end; procedure TDisplaySpace.teBtBtnClick(Sender: TObject); begin if testSwitchToggle - 0 then testSwitchToggle := 1 else testSwitchToggle :«■ 0; end ; procedure burstCreator; var i, burstSize, localHold, flowRateData, presData, p_C02data : integer; begin presData :» 99; p_C02data :- 99; burstSize :- random(lθ); {burstSize :- 4; } if burstSize <> 0 then begin if testSwitchToggle - 0 then begin for i:-l to burstSize do begin localHold :- Glol + i; flowRateDataArray[i] :- localHold + 110; end; Glol :- localHold; { I'm pretty sure this is a perfectly monotonic ramp.} end else begin 60 for i:*»l to burβtSize do begin flowRateData :■> random(20)+ 150; {I I we're in a test procedure 1111} flowRateDataArray[i] : «■ flowRateData + whichFlow * 40 - 60; end; end; end; drawBurst(flowRateDataArray, burstSize, clBlack) ; displaySpace.bursSizeLbl .Caption :- intToStr(burstSize) ; { if testSwitchToggle - 1 then draw20HzData( flowRateData) else drawTest20HzData( flowRateData, presData, p_C02data); > end; procedure TDisplaySpace.ButtonlClick(Sender: TObject); begin burstCreator; end; procedure TDisplaySpace.snglRealBurstBtnClick(Sender: TObject) ; var 02Array : staticDataPntr; { pntr to 3 integers } 02waveArray : intWavePntr; { pntr to 20 integers } waveSize, start : integer; flowRateDataArray : burstArray; { an array of 50 integers } begin getAllPulβ0x(02Array, 02waveArray, waveSize, start); {02Array is three integers: 02Sat, HeartRate, Status} { THIS CUT OUT TO USE LABELS FOR CAPNOSTAT DisplaySpace.waveSizeLbl.Caption := ■ intToStr(waveSize) ; DisplaySpace.Avg02satLbl.Caption :=> intToStr(02Array * 1 )) ; DisplaySpace.heartRateLbl.Caption :- intToStr(02Array" (2 ]) ; DisplaySpace. statusLbl.Caption :- intToStr(02Array" [ 3 ]) ; DisplaySpace.startLbl.Caption :* » intToStr(start) ; } for i:-l to waveSize do begin flowRateDataArray!i] :- 02waveArray" [i] + 100; end; drawBurst( flowRateDataArray, waveSize, clBlue); end; procedure sendoxBurst; var 02Array : staticDataPntr; { pntr to 3 integers } 02waveArray : intWavePntr; { pntr to 20 integers } waveSize, start : integer; 61 flowRateDataArray : burstArray; { an array of 50 integers } bias, health : integer; drawColor : Tcolor; begin bias :- 310; { 298 larger number lowerβ curve} health :- getAllPulsOx(02Array, 02waveArray, waveSize, start); {02Array is three integers: 02Sat, HeartRate, Status} { THIS CUT OUT TO USE DIAGNOSTIC LABELS FOR CAPNOSTAT DisplaySpace.waveSizeLbl.Caption D xntToStr(waveSize) ; DisplaySpace.Avg02satLbl.Caption - intToStr(02Array"[l] ) ; DisplaySpace.heartRateLbl.Caption :- intToStr(02Array"(2] ) DisplaySpace. atatusLbl.Caption :=> intToStr(02Array"[3] ) ; DisplaySpace.OxStartLbl .Caption : ■ • intToStr(start) ; DisplaySpace.HealthLbl.Caption := intToStr(health) > globalOxSat := 02Array"[l); globalHeartRate :- 02Array * [2]; if start =» 0 then { if 1 - 1 then} for i:»l to waveSize do flowRateDataArray[i] :=■ bias - 02waveArray" [i] div 4 else begin for i:=start+l to waveSize do flowRateDataArray[i-(start) ] := bias - 02waveArray * ( i] div 4; for i:= 1 to start do flowRateDataArray[waveSize-start+i] := bias - 02waveArray" [i] div 4 ; end; if firstBurst then drawColor := clLime else drawColor :- clBlue; drawBurst(flowRateDataArray, waveSize, drawColor); firstBurst := False; {part of vestigial trace problem} end; procedure sendCapBurst; var extendedStatusArray, patDatArray : staticDataPntr; { pntr to 3 integers } C02waveArray : intWavePntr; { pntr to 20 integers } waveSize, waveStart : integer; flowRateDataArray : burstArray; { an array of 50 integerβ } size, dataSize, capReturn, status : integer; bias : integer; drawColor : Tcolor; begin bias := 120; { larger number lowers curve } 62 capReturn :- getAllCapno(C02waveArray, waveSize, waveStart, patDatArray, dataSize, status, extendedStatusArray, size); { endTidalC02, respRate, inspired C02 " > { DIAGNOSTICS DiβplayΞpace.waveSizeLbl.Caption :- intToStr(waveSize) ; DisplaySpace.endTidLbl.Caption :- intToStr(patDatArray"[ 1 ]) ; DiβplaySpace.reβpRateLbl.Caption :- intToStr(patDatArray" ( 2 ]) ; DisplaySpace.inβpC02Lbl.Caption :- intToStr(patDatArray" [ 3] ) ; DisplaySpace . waveDataSampleLbl . Caption : - intToStr(C02waveArray"[3] ) ; } DisplaySpace.βtartLbl.Caption :- intToStr(waveStart) ; globalEndTidal :- patDatArray" [ 1] ; {remember, as a part of Novametrix protocol, this is too big by a factor of two} globalC02RespRate :- patDatArray" [ 2 ] ; globalInspiC02 :*■ patDatArray" [3] ; if waveStart = 0 then { if 1 » 1 then } for i:«l to waveSize do flowRateDataArray!i] :- bias - C02waveArray * [i] div 3 else begin for i:=waveStart+l to waveSize do flowRateDataArray!i- (waveStart) ] :- bias - C02waveArray" [ i] div 3; f° r i := 1 to waveStart do flowRateDataArray!waveSize-waveStart+i] :«* bias C02waveArray"(i) div 3; end; if firstBurst then drawColor : » clYellow else drawColor :- clBlack; drawBurst (flowRateDataArray, waveSize, drawColor); firstBurst :■ False; {part of vestigial trace problem} DisplaySpace.airWaveFormLbl.Caption :- 'EXHALED C02 ' ; end; procedure sendFlowBurst; var pointerToWaveForms : flowWaveFormPntr; { pntr to an array of three pointers of pointers of 9 integers } waveSizes, waveStarts : staticDataPntr; { pntr to 3 integers } dpis, dpiValues : ArrayOfTenPntr; { pntr to 10 integers } flowRateDataArray : burstArray; { an array of 50 integers } flowReturn, βtatusl, status2, status3 : integer; 63 bias, gain, dpiSize : integer; {position and gain are now global} drawColor : TColor; begin bias :- 280; {320 larger number lowers curve } gain : ■ 1; {burβtCreator; {This is a diagnostic which can be accessed with the SIM BURST button} {exit; { <— thiβ iβ to be used when flowReturn is commented out to keep theβe pointerβ from being derefrenced} flowReturn :- getAHFlow(pointerToWaveForms , waveSizes, waveStarts, dpis, dpiValues, dpiSize, statusl, status2, status3); for i:-l to case dpis' globalTidalVol :- dpiValueβ" [i] ; globalFlowExpiatory :- dpiValueβ * [i) ; globalFlowPeaklnPress :- dpiValues * [i) globalFlowMeanPresB :- dpiValues * [i] ; globalFlowRespRate :- dpiValues * [i] ; globalloverEratio :«■ dpiValues * [i] ; DisplaySpace.atartLbl.Caption :- intToStr(waveStarts" ( 1 ]) ; {DisplaySpace.waveSizeLbl.Caption : ■ intToStr(waveSizes * ( 1]) ; DisplaySpace.dpiSizeLbl.Caption :- intToStr(dpiSize) ; } if whichFlow «» FL0W_FLOW then begin burstPosition :- flowPos; burstGain := flowGain; DisplaySpace.airWaveFormLbl.Caption :» 'FLOW'; end; if whichFlow = FLOW_PRES then begin burstPosition :=• presPos; {These space the curves vertically} burstGain := presGain; DisplaySpace.airWaveFormLbl .Caption :- 'PRESSURE'; end; if whichFlow - FLOW_VOL then begin burstPosition :- volPos; burstGain :- volGain; DiβplaySpace.airWaveFormLbl.Caption :- 'VOLUME'; end; { THE WAVEFORMS } if waveStarts"[whichFlow] - 0 then { if 1 - 1 then } for i:-l to waveSizes"[whichFlow] do begin flowRateDataArray! i ] : «■ bias ( burs tGain * pointerToWaveForms"[whichFlow] "fi] ) div 200 + burstPosition ; DisplaySpace.inStartEqZeroLoopLbl .Caption : - intToStr ( i ) ; 64 end else begin DiβplaySpace. inStartNotEqZeroLoopLbl .Caption :- intToStr(i); {1111 I 11 I 11 I 111 I 1 I 11 I I 111 I t 111111 I 1 I } for i:-waveStarts * [ hichFlow]+1 to waveSizes * {whichFlow] do flowRateDataArray{i-(waveStartβ * [whichFlov) ) ] :- bias - (burβtGain * pointβrToWavβForms * f hichFlow) * ( i ] ) div 200 + burβtPoβition; for i:- 1 to waveStarts"{whichFlow] do flowRateDataArray[waveSizes * [whichFlow]-waveStarts * [whichFlo ]+i ] :- bias - (burβtGain * pointerToWavePorms * [whichFlo J * fi) ) div 200 + burstPosition; end; {DiβplaySpace. FlowCurveSampleValueLbl. Caption intToStr( flowRateDataArray[ 1 ] ) ; } if firβtBurst then drawColor :- clYellow elβe drawColor :- clBlack; drawBurst( flowRateDataArray, waveSizes" [whichFlow] , drawColor); firstBurst :■■ False; {part of vestigial trace problem} end; procedure TDisplaySpace.preβsBtnClick(Sender: TObject); begin whichFlow :- FLOW_PRES; {which of the three buttonβ that work the flow board} EtC02Enabled :- Falβe; pulsOxEnabled :- False; board :- FLOWBOARD; { board is a global var to tell timer which one to command. } flowEnabled :- True; {auppoβed to enable preaβ Wave form if the board :» correctly} firβtBurst : - True; {Thiβ iβ part of the way to make firβt polyline call same color aβ background.) {It iβ βet to falβe AFTER each call to drawBurst. } displaySpace.pC02backgndShape.Viβiblβ :- Falβe; displaySpace.oxSatTitleLbl.Viβible :- Falβe; pC02backgndShape.Viβible :- False; floShrtRcdLbl.Viβiblβ :- True; floShrtRcdShape.Viβiblβ :- True; showAirwayGraph; end; procedure TDisplaySpace.volBtnClick(Sender: TObject); begin 65 whichFlow :- FLOW_VOL; {which of the three buttonβ that wcrk the flow board} EtC02Enabled :- Falβe; pulβOxEnabled :- False; board :- FLOWBOARD; { board iβ a global var to tell timer which one to command. } flowEnabled :- True; {βuppoβed to enable press Wave form if board :- is correct} firstBurst :- True; {This iβ part of the way to make firβt polyline call βa e color as background.} {It is set to falβe AFTER each call to drawBurst. } displaySpace.pC02backgndShape.Viβible :«• Falβe; displaySpace.oxSatTitleLbl .Viβiblβ :•» Falβe; pC02backgndShape.Viβiblβ :- Falβe; floShrtRcdLbl.Viβible :- True; floShrtRcdShape.Viβible :- True; βhowAirwayGraph; firβtBurβt : - True; {This is part of the way to make first polyline call βamβ color aβ background.} {It iβ βet to false AFTER each call to drawBurst. } end; procedure TDiaplaySpace.floShrtRcdShapeMouaeDown(Sender: TObject; Button: TMouβeButton; Shift: TShiftState; X, Y: Integer); begin flowStopShape.Viβible :- True; flσwStopLbl.Viβible :«■ True; Application.ProcβββMeββages; { onePerSecondEnabled :- True; {ASKS JOHN'S FOR LOGGING.} recordFlowCapEnabled : » True; {enableβ my logging routine} if ( board - FLOWBOARD ) then begin { logWaveForm ( FLOWBOARD , 1 ) ; 88888888888888888888888888888888888} (commands: 1 iβ βtart, 2 is continue, 3 iβ βtop} flowRecordShape.Viβible :«" True; {red rectangle over three) diβplaySpaceMeββagβLbl.Caption :« 'All Flow Board data being recorded' ; floShrtRcdLbl.Font.Color :- clRed; end; if ( board - CAPNOSTATBOARD ) then begin { logWavβForm(CAPNOSTATBOARD, 1 ) ; } {commands: 1 is βtart, 2 iβ continue, 3 is stop} floShrtRcdLbl.Fc'-Ii.Color :« clRed; diβplaySpaceMesβageLbl.Caption :•• 'All Capnostat board data being recorded'; capNoStatRecordShape.Visible :■ True; {red square around capnoStat button} 66 capNoStatBtn.Font.Color :- clRed; end; if ( Shape3.Viβiblβ - True ) then begin pulsOxRedSquareShape.Viβiblβ :« True; {red square around heart button} diβplaySpaceMesβageLbl.Caption ~ 'Just the pulseOx waveform being recorded'; end; end; procedure TDisplaySpace. flowStopShapeMouββDown(Sender: TObject; Button: TMouββButton; Shift: TShiftState; X, Yx Integer); begin pulsOxRedSquareShape.Viβiblβ x~ False; {red square around heart button} { logWaveFoπn(FLOWBOARD, 3); {turns off John's logging} floShrtRcdLbl.Viβible x- Falβe; loShrtRcdShape.Viβible x- Falβe; flowStopShape.Viβiblβ x- Falββ; flowStopLbl.Visible x- Falββ; capNoStatRecordShape.Viβible x- Falβe; flowRecordShape.Viβible x- False; lowBtn.Font.Color :- clWindowText; capNoStatBtn.Font.Color :- clWindowText; floShrtRcdLbl .Font.Color i- clWindowText; diβplaySpaceMeβsageLbl.Caption :« ''; onePerSecondEnabled :■■ Falβe; recordFlowCapEnabled x- Falββ; { theβe two are for my recorder } recordFlowCapCycleβ x- 1; end; procedure TDiβplaySpace.diagOnOffβwitchLblClick(Sβnder: TObject); begin {diagnostics pragma) if diagLabelVisibleState - Falβe then diagLabelViβibleState :- True else diagLabelViβibleState x- Falββ; toggleTheDiagnosticLabels(diagLabelVisibleState) ; end; procedure toggleTheDiagnoβticLabelβ(diagLabelViβibleState : Bool); {diagnoβtics pragma} begin with DiβplaySpace do begin rateOlbl.Visible :- diagLabelViβibleState; label40.Viaiblβ :- diagLabβlViβibleState; 67 label41.Viaible :- diagLabelVisibleState; label48.Visible :- diagLabelVisibleState; gainUp.Viβible x- diagLabelVisibleState; 5 flowRateDataArrayLbl.Viβible :- diagLabelVisibleState; end; {Just a demo that it works. } DiβplaySpace.gainDn.Viβiblβ :- diagLabelViβibleState; DiβplaySpace.moveUp.Viβible :- diagLabelViβibleState; DiβplaySpace.moveDn.Viβible :- diagLabelViβibleState; DisplaySpace.gainValLbl.Visible :- diagLabelVisibleState; DiβplaySpace.offββtValLbl.Viβiblβ :- diagLabelVisibleState; I Q DiβplaySpace.Label33.Visible :- diagLabelVisibleState; DiβplaySpace.timeDiβplay.Viβible :- diagLabelVisibleState; DiβplaySpacβ.Label31.Viβible :- diagLabelViaibleState; DiβplaySpace.timesThruLbl.Visible :- diagLabelVisibleState; DisplaySpace.Label29.Visible :- diagLabelVisibleState; DisplaySpace . recordlntervalCyclesLbl . Visible : ° diagLabelVisibleState; DisplaySpace ,Label39.Visible :- diagLabelViaibleState; 15 DiaplaySpace.inStartEqZeroLoopLbl.Viβible :«» diagLabelVisibleState; DisplaySpace.Label30.Visible :- diagLabelVisibleState; DisplaySpace.recordCycleβLbl.Visible : »■ diagLabelVisibleState; DiβplaySpace.Label38.Viβible :- diagLabelVisibleState; DisplaySpace . inStartNotEqZeroLoopLbl . Visible : = diagLabelVisibleState; DisplaySpace .Label28.Visible :- diagLabelVisibleState; DisplaySpace.tdlVolLbl.Visible :- diagLabelVisibleState; 0 DisplaySpace.Label2.Visible :- diagLabelVisibleState; DisplaySpace.expVolLbl.Visible :- diagLabelVisibleState; DiβplaySpace.dpis.Visible :- diagLabelVisibleState; DisplaySpace.dpiSizeLbl.Visible :- diagLabelVisibleState; DisplaySpace.Label37.Visible :- diagLabelVisibleState; DisplaySpace . FlowCurveSampleValueLbl . Visible : = diagLabelVisibleState; DisplaySpace.Label7.Visible :- diagLabelVisibleState; 5 DisplaySpace.peakPresLbl.Visible :- diagLabelVisibleState; DisplaySpace.Label21.Visible :- diagLabelVisibleState; DisplaySpace. vgPreaLbl.Visible :"• diagLabelVisibleState; DisplaySpace.Label25.Visible :- diagLabelVisibleState; DisplaySpace.iOverElbl.Viβible :- diagLabelViaibleState; DisplaySpace.Label26.Visible :- diagLabelVisibleState; DisplaySpace.entC021bl.Visible :- diagLabelVisibleState; DisplaySpace.Label27.Visible:- diagLabelVisibleState; 0 DisplaySpace.capRRlbl.Visible :- diagLabelVisibleState; DisplaySpace.Label24.Visible :- diagLabelVisibleState; DisplaySpace. flowRRlbl.Visible :- diagLabelVisibleState; DisplaySpace.Label36.Visible :- diagLabelVisibleState; DisplaySpace.waveSizeLbl.Visible :- diagLabelViβibleState; DisplaySpace.Label22.Visible :- diagLabelVisibleState; DisplaySpace. startLbl.Viβible :- diagLabelViβibleState; DisplaySpace.Labellβ.Visible :- diagLabelVisibleState; 5 DiβplaySpace.tidalVolLbl.Visible :- diagLabelVisibleState; 68 DisplaySpace.Label20.Visible :- diagLabelVisibleState; DisplaySpace.meanAirPressLbl.Visible :- diagLabelVisibleState; DisplaySpace.Labell9.Visible :- diagLabelVisibleState; DisplaySpace.ExpiatoryLbl.Visible :- diagLabelVisibleState; DisplaySpace.Label34.Visible :- diagLabelVisibleState; DisplaySpace.RespRateLbl.Visible := diagLabelVisibleState; DisplaySpace.Label4.Visible :- diagLabelVisibleState; DiβplaySpace.PeaklnLbl.Visible :- diagLabelViβibleState; DisplaySpace.Label5.Viβible :- diagLabelVisibleState; DisplaySpace. lowIoverELbl.Visible := diagLabelVisibleState; DisplaySpace.testLbl.Visible :- diagLabelVisibleState; DisplaySpace.bursSizeLbl.Visible :- diagLabelVisibleState; DisplaySpace.recordingLbl.Visible :- diagLabelVisibleState; DisplaySpace.testBtn.Visible :- diagLabelVisibleState; DisplaySpace.Buttonl .Visible :- diagLabelVisibleState; DisplaySpace.anglRealBuratBtn.Visible :- diagLabelVisibleState; DisplaySpace.oxSatBtn.Visible :- diagLabelVisibleState; with VENTDETAIL do begin Label71.Visible :- diagLabelVisibleState; patientPressLbl2-Visible :- diagLabelVisibleState; Label72.Visible :- diagLabelVisibleState; Label73.Visible :- diagLabelVisibleState; Label74.Visible :- diagLabelVisibleState; flowPeakLbl.Visible :- diagLabelVisibleState; ventMessage2.Visible :* » diagLabelVisibleState; Label68.Visible :« diagLabelVisibleState; Label66.Visible :- diagLabelVisibleState; Label44.Visible :- diagLabelVisibleState; flowExplbl .Visible :- diagLabelVisibleState; Label70.Visible :- diagLabelVisibleState; Label75.Visible := diagLabelVisibleState; Label64.Visible :- diagLabelVisibleState; ventRBRlbl.Visible :- diagLabelVisibleState; Label67.Visible := diagLabelVisibleState; RBRlbl.Visible :- diagLabelVisibleState; Label94.Visible :- diagLabelVisibleState; Label93 -Visible :- diagLabelVisibleState; Label65.Visible :- diagLabelVisibleState; flowIoverElbl .Visible :- diagLabelVisibleState; end; end; . procedure TDiβplaySpace.gaxnUpClxck(Sender: TObject); begin if whichFlow - FL0W_FL0W then begin flowGain :- flowGain + 1; gainValLbl.Caption :- intToStr(flowGain) ; end; if whichFlow - FL0W_PRES then begin presGain :- presGain + 1; gainValLbl.Caption :- intToStr(presGain) ; 69 end; if whichFlow - FLOW_VOL then begin volGain :- volGain + 1; gainValLbl.Caption :- intToStr(volGain) ; end; end; procedure TDisplaySpace.moveUpClick(Sender: TObject); begin if whichFlow - FLOW_FLOW then egin flowPos :- flowPos - 10; offSetValLbl.Caption :- intToStr( flowPos) ; end; if whichFlow - FLOW_PRES then begin presPoβ :- presPos - 10; offSetValLbl.Caption :- intToStr(presPos) ; end; if whichFlow - FLOW_V0L then begin volPos :» volPos - 10; offSetValLbl.Caption :- intToStr(volPos) ; end; end; procedure TDisplaySpace.moveDnClick(Sender: TObject); begin if whichFlow - FLOW_FLOW then begin flowPos :- flowPos + 10; offSetValLbl.Caption :- intToStr(flowPos) ; end; if whichFlow - FLOW_PRES then begin presPos :- presPos + 10; offSetValLbl.Caption :- intToStr(presPos) ; end; if whichFlow - FLOW_V0L then begin volPos :- volPos + 10; offSetValLbl.Caption :- intToStr(volPos) ; end; end; procedure TDisplaySpace.gainDnClick(Sender: TObject); begin if whichFlow - FLOW_FLOW then begin if flowGain >- 2 then flowGain x- flowGain - 1; gainValLbl.Caption :- intToStr(flowGain) ; end; if whichFlow - FLOW_PRES then begin if preβGain >- 2 then prββGain x- preβGain - 1; gainValLbl.Caption x- intToStr(preβGain) ; end; if whichFlow - FLOW_V0L then begin 70 if volGain >- 2 then volGain :- volGain - 1; gainValLbl.Caption :- intToStr(volGain) ; end; end; initialization teatSwitchToggle :- 0; drawBPCount :- 1; drawOxCount :- 1; drawTempCount :- 1; drawHRcount :- 1; drawBRcount :- 1; drawMINcount :- 1; recordEnabled :- False; novaSamplerCounter x- 1; onePerCounter :- 1; ventSamplerCounter :- 1; curvePlotCounter :- 1; barGraphCounter :- 1; {draw20HzData} topCount :- 1; {Initializing the flowRateArray with an eβtimated average value.} farRight20 :« 594; { (468) determines the right aide of the screen } flowArrayReβetValue :- 150; {170} x20Poa :- farRight20; resetFlow :- lowArrayReaetValue; for i :- 0 to SMALLDISPSIZE do begin {0 to SMALLDISPSIZE WORKS} flowRateArray!SMALLDISPSIZE-i] .Y :- resetFlow; flowRateArray[SMALLDISPSIZE-i) .X :- farRight20-3*i; flowEraβeArray[SMALLDISPSIZE-i) .Y :- resetFlow; flowEraaeArrayfSMALLDISPSIZE-i) .X :- farRight20-3*i; end; {draw20HzTestData} cnt :- 1; bottom20 :- 240; for i :- 0 to SMALLDISPSIZE do begin yPoFlowAry[i] :- 500; { flowArrayReaetValue; or 150} end; buratLeftEdge :- 310; xPoa :- buratLeftEdge; xEraβePoβ :- buratLeftEdge; linkElem x- 298; {thiβ alβo sets the values for the first eraseArray} oldEraselndex :- 1; nextEraselndex :- 1; 71 for i:-l to 400 do begin eraβeArray[i] :- linkElem; end; beenThere :- Falβe; Glol i- l; {20 HzTimer } EtC02Bnabled :- Falββ; pulβOxEnabled :- False; firatBurat :- True; recordFlowCapCycles x- 1; recordFlowCapEnabled :- False; βendCounter :- 1; flowPoβ :- 0; presPos :- 40; volPos :- 80; burstPosition :- 40; {juβt incaβe I don't aaaign it on firat paaa} flowGain :- 1; preβGain :- 1; volGain :- 1; burstGain :- 1; {juβt incaβθ I don't aaaign it on first paββ) flowGain :- 1; preaGain :« 10; volGain :- 3; {1,10,3 aβ of 8 March at WRAIR} flowPoβ x- -80; preβPoβ x- -270; volPos :- -150; {-80,-270,-150 as of 8 March at WRAIR} {EKGdraw} timeβThru :- 1; recordCycleβ :- 0; gridlStopToggle :- False; grid2StopToggle :- Falβe; grid3StopToggle x- Falβe; grid4StopToggle :- Falβe; grid5StopToggle x- Falβe; βhoAroCntr x- 8; for i:-l to 8 do rateOchanAra[i] :- 97; teβtOnePerCountr :- 1; end. 72 PROGRAM LISTING GϋlllF.CPP /* guiif.cpp -> DLL (target) Author : J. Brayton History : 7/01/95 Description : This is the main interface module used to export functions to Delphi to perform 10 operations. Contents: Windows (DLL) : LibMain (May need changing as requirements change) WEP (TBD - Windows Exit Procedure) UI048 Operations: (Digital I/O) fanControl ventControl ventCtrlWait defibControl ecsControl defibSenseD readChannel (test only) 518 Operations: (Thermocouples) reset518 (test only) readBoardTemp (test only) AIO Operations: (A/D) (D/A) readChannel */ // ■ // #include "s518.h" #include "uio48.h" #include "aio.h" #include "comm4.h" #include "irqmngr.h" linclude "fileio.h" #include <stdio.h> ..include <string.h> linclude <dos.h> linclude <io.h> linclude <sys\stat.h> 1 linclude <fcntl.h> //linclude <mem.h> //—> moved down to getrs232 // >Note that windows.h is included after where / / Boolean typedef is declared. Since windows // defines TRUE and FALSE in windows.h, the II compiler complainβ if it sees these elements // in an enumeration. linclude <windows.h> linclude <conio.h> lifdef ENABLE_TEST_MODE linclude <stdlib.h> lendif ENABLE TEST MODE linclude "guiif.h" //518 object declarations // sensor518 board518Nol(BASEADDR518N01,INITIALIZE) ; sensor518 board518No2(BASEADDR518N02,INITIALIZE) ; thermocouple equipTempSensor(BASEADDR518N02,EQPX_TMPChnl) ; thermocouple patTempSensor(BASEADDR518N02,PAT_TMPChnl) ; thermocouple dsplyTempSensor(BASEADDR518N02,DSPLY_TMPChnl) ; thermocouple cpuTempSensor(BASEADDR518N02,CPU_TMPChnl) ; //UI048 object declarations // uio48 uio48board; //C0M4 object declarations // comm4 com4boardl(COM4BlCHNLS,COM4BRDlCONFIG) ; comm4 com4board2(COM4B2CHNLS,COM4BRD2CONFIG) J //AIO object declaration(s) // aio aioboard; //System Control global variables // Boolean first - TRUE; static clock__t systemTime; dostime_t timeS; dostime_t logTimes[4]; //One for each channel of comm4 board 2 //★★A********************** *** GLOBAL VARIABLES **************************** // Used to pass patient parameters and waveforms to GUI // //PULSE OXIMETER GLOBAL static int lavg02, laygHR, lstatusCode; static int pulseoxWF //Holds pulseox waveform value; static int pulseoxWFs[SP02WFDATAMAX) ; static int pulseoxSpecData[SP02SPECDATAMAX) ; static Boolean seenFEtoggle » FALSE; static int βeenFEcount - 0; static unsigned char spo2wfbfr[BRD2CHNL3BLKSIZE] ; //CAPNOSTAT GLOBAL static int capnoData[C02DATACOUNT] ; static int capnoESB[3]; //Holds the 3 b te ,extended status of capnostat static int capnoWF; //Holds capno waveform value static int capnoSSB; //Holds capno SSB value static int capnoCSB; //Holds capno command status byte. static unsigned char co2swrevresp[C02SWREVrespLNGTH-l] ; //Null terminated static int cmdlen — 0; static unsigned char tempbfr[TEMPBFRSIZE) ; //Temp storage to build our packets int indx; static int capnowf[CAPNOWFSIZE] ; static int capnodata[CAPNODATASIZE] ; static int capnoetC02; static int capnorr; static int capnoinsp; static int capnossb; static int capnoesb[CAPNOESBSIZE] ; //FLOW GLOBAL static int savenbf, findx; static unsigned char flowbfr[FLOWBFRSIZE], ' static int overrun[FLOWWFMAX) ; //Used to ir 'icate data lose per wf static int flowWF[FLOWWFSIZE) ; static int pressWF[FLOWWFSIZE] ; static int volWF[FLOWWFSIZE] ; static int *flowWFs[FLOWWFMAX] - {flowWF, pressWF, volWF} ; static int flowWFsize[FLOWWFMAX] ? static int flowWFstart[EI-OWWFMAX] ; static int flowDPIs[MAXDPIS] ; static int flowDPIvalues[MAXDPIS] ; static int avgcount[FLOWWFMAX] ■ {0,0,0}; static long int flowAvg[FLOWWFMAX1 ; static int cmdByteSeen ■ 0; static int nbf - 0; //FLUSH GLOBAL static int flowData[FLOWDPICOUN ) ; //Holds pulse ox Special Data. / / * * * * * * * * * * * * * * ** * * * * * * * * * * * File Handles ********************************* //File handles used for data logging. // //Next two lines are for defining file handles using creat/write. int handlesblfCHNLSPERBRD]; int handlesb2[CHNLSPERBRD]; //Next two lines are for defining file handles using fopen/fwrite. FILE *fhandlesbl[CHNLSPERBRD]; FILE *fhandlesb2[CHNLSPERBRD]; //Test variables //dandy. stound - Some of these may not be used anymore. // ChnlBfr * temp; const char far * DLLVERSION = " .dll02/29vl7:30real"; const char far * DLLVERSIONNH » " .dll02/29vl7:30test"; // static int testvar; static int timeindx = 0; dostime t timeSs[100] ; FILE *fTlehndl; //UI048 //void interrupt(*getvect(int interruptno)) ( ... ); extern "C" { int FAR PASCAL _export LibMain(HANDLE, WORD, WORD , LPS R ) ; int FAR PASCAL _export WEP (int nParameter) ; } /* LibMain Description : Window DLL Library Main function. Returns : Integer (not used by Windows) */ ιnaaπα3ssBBB- BrθBi>r*βB t °° :: < 1IIV Biataιxκaιt * I *BB-Biιιι«HB Bααπαnπαn: // int FAR PASCAL _export LibMain(HANDLE hlnstance, WORD wDataSeg, WORD wHeapSize, LPSTR CmdLine) { //dandy.astound /////////////////////////////////////////////////// char bell - 0x07; cout « bell « bell « endl; /////////////////////////////////////////////////// //dandy.astound - convert to double buffering using two buffers //connectToIRQ(IRQ5, brdlBlks, rcvcharbrdllSR); ifndef DISABLE_INTERRUPTS //connectToIRQ(IRQ5, brdBfrs[VENTBRD-l] , rcvcharbrdllSR); connectToIRQ(IRQ5, brdlBlks, rcvcharbrdllSR); connectToIRQ(IRQ7, brd2Blks, rcvcharbrd2ISR) ; lendif DISABLE_INTERRUPTS if (wHeapSize _«■ 0) UnlockData(O) ; lifdef ENABLE_TEST_MODE if (board518Nol.readProdID() 1= 518 && board518No2.readProdID() 1- 518) { //dandy.astound /////////////////////////////////////////////////// char bell - 0x07; cout « bell « bell « bell « bell « endl; /////////////////////////////////////////////////// sysMode = TEST; } lendif ENABLE_TEST_MODE lifdef FORCE_TEST_MODE sysMode - TEST; //Force test mode regardless of system configuration. lendif F0RCE_TEST_M0DE /* //Open file //Change the default file mode from text to binary _f ode = 0 BINARY; //Create a binary fxle for each channel for each board, for (int i = 0; i < CHNLSPERBRD; i++) handlesbl[i] β creat(brdlBlks[i] .fileName, S_IREAD |S_IWRITE) ; for (i = 0; i < CHNLSPERBRD; i++) handlesb2[i] « creat(brd2Blks[i] .fileName, S_IREAD IS IWRITE) ; */ //Open files using fopen (other methods do not seem to work as expected) . lifndef DISABLE_FILE_IO_IN_LIBMAIN for (int i - 0; i < CHNLSPERBRD; i++) fhandlesbl[i] - fopen(brdlBlks[i) .fileName, "wb"); for (i - 0; i < CHNLSPERBRD; i++) fhandlesb2[i] - fopen(brd2Blks[i] .fileName, "wb"); lendif DISABLE_FILE_IO_IN_LIBMAIN lifdef ENABLE_STATUS_LOG_IN LIBMAIN strcpy(statusMsg,getDllVersTon( ) ) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; Iendif ENABLE_STATUS_LOG_IN_LIBMAIN lifdef DISPLAY_FLAGS_IN_LIBMAIN lifdef ENABLE_TEST_MODE strcpy(statusMsg, "ENABLE_TEST_MODE\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_TEST_MODE lifdef FORCE_TEST_MODE strcpy(statusMsg,"FORCE_TEST_MODE\n\r" ) ; statuslog(statusMsg) ; lendif FORCE_TEST_MODE lifdef ENABLE_AUDIBLE_ERROR strcpy(statusMsg, "AUDIBLE_ERROR_ENABLED\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_AUDIBLE_ERROR lifdef STATUS_LOG_ENABLED strcpy(statusMsg,"STATUS_LOG_ENABLED\n\r") ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED lifdef VALIDATE_CHECKSUM_LOG_ENABLED strcpy(statusMsg,"VALIDATE_CHECKSUM_LOG_ENABLED\n\r" ) ; statuslog(statusMsg) ; lendif VALIDATE_CHECKSUM_LOG_ENABLED lifdef CALC_CHECKSϋM_LOG_ENABLED strcpy(statusMsg, "CALC_CHECKSUM__LOG_ENABLED\n\r") ; statuslog(statusMsg) ; lendif CALC_CHECKSUM_LOG_ENABLED lifdef ENABLE_INVALID_CBKSM_NOTIFY 6 -448- strcpy(statusMsg, "ENABLE_INVALID_CHKSM_NOTIFY\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_INVALID_CHKSM_NOTIFY lifdef DISABLE_FILE_IO strcpy{statusMsg, "DISABLE_FILE_IO\n\r" ) ; statuslog(statusMsg) ; lendif DISABLE_FILE_IO lifdef DISABLE_FILE_IO_IN_LIBMAIN strcpy(statusMsg, "DISABLE_FILE_ EO_IN_LIBMAIN\n\r" ) ; statuslog(statusMsg) ; lendif DISABLE_FILE_IO_IN_LIBMAIN lifdef DISABLE_FILE_IO_IN_WEP strcpy(statusMsg, "DISABLE_FILE_IO_IN_WEP\n\r" ) ; statuslog(statusMsg) ; lendif DISABLE_FILE_IO_IN_WEP ifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "E ABLE_FATAL_ERROR_MSGS\n\r") ; statuslog(statusMsg) ; lendif ENABLE_FATAL_ERROR_MSGS lifdef ENABLE_DATA_LOSS_MSGS strcpy(statusMsg, "ENABLE_DATA_LOSS_MSGS\n\r") ; statuslog(statusMsg) ; lendif ENABLE_DATA_LOSS_MSGS lifdef ENABLE_STATUS_LOG_IN_LIBMAIN strcpy(BtatusMsg, "ENABLE_STATUS_LOG_IN_LIBMAIN\n\r" ) ; statuslog(statusMsg) ; Iendif ENABLE_STATUS_LOG_IN_LIBMAIN lifdef ENABLE_STATUS_LOG_IN_START__WF strcpy(statusMsg, "ENABLE_STATUS_LOG__IN_START_WF\n\r") ; statuslog(statusMsg) ; lendif ENABLE_STATUS_LOG_IN_START_WF lifdef ENABLE_STATUS_LOG_IN_STOP_WF strcpy(statusMsg, "ENABLE_STATUS_LOG_IN_STOP_WF\n\r n ) ; statuslog(statU8Msg) ; endif ENABLE_STATUS_LOG_IN_STOP_WF lifdef ENABLE_LOGGING_ERRORS Btrcpy(statusMsg, "ENABLE_LOGGING_ERRORS\n\r") ; statuslog(statusMsg) ; ♦endif ENABLE_LOGGING_ERR0RS lifdef ENABLE_CALLING_STATUS strcpy(statusMsg, "ENABLE_CALLING_STATUS\n\r") ; statuslog!statusMsg) ; Iendif ENABLE_CALLING_STATUS lifdef ENABLE_LOGGING_STATUS Btrcpy(statusMsg, "ENABLE_LOGGING_STATUS\n\r") ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS lifdef ENABLE_AVG_GET_ALL_FLOW strcpy(statusMsg, "ENABLE_AVG_GET_ALL_FLOW\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_AVG_GET_ALL_FLOW lifdef ENABLE_VENT_CMD_ERRORS strcpy(statusMsg, "ENABLE_VENT_CMD_ERRORS\n\r") ; statuslog(statusMsg) ; lendif ENABLE_VENT__CMDJ3RRORS lifdef ENABLE_SENDCMDTOVENT_DISPLAY strcpy(statusMsg, "ENABLE_SENDCMDTOVEN _DISPLAY\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE SENDCMDTOVENT DISPLAY lifdef DISABLE_INTERRUPTS strcpy(statusMsg, "DISABLE_IN ERRUPTS\n\r") statuslog(statusMsg) ; lendif DISABLE INTERRUPTS lendif DISPLAY FLAGS IN LIBMAIN //Initialize interrupt vector for COM4 boards, //dandy.astound (removed boardreset) //board518Nol.boardReset( ) ; //board518No2.boardReset( ) ; //uio48board.resetBoard(0) ; return(1) ; } /* WEP Description : Window DLL Exit Procedure. Returns : Integer (not used by Windows) */ 8 / / _- r == 3X3 X - HS ««ακz- D i-cιrac- xκaα- B a«»<i B χa a>sjBκ sjBHB B a t xa B βn ακt«»Mi B Bsj // //Dandy.astound - Disconnect seems to hose Windows - sometimes int FAR PASCAL _export WEP (int nParameter) { char bell = 0x07; cout « bell « endl; /* //Close files here. for (int i - 0; i < CHNLSPERBRD; close(handlesbl[i++] )) ; for (i - 0; i < CHNLSPERBRD; close(handlesb2[i++) )) ; */ //Closing files here causes system crashes. A separate dll entry //is provided for closing filβB and should be called by GUI priox" //to program termination. lifndef DISABLE_FILE_IO_ΪN_WEP for (int i - 0; i < CHNLSPERBRD; fclose(fhandlesbl[i++] )) ; for (i - 0; i < CHNLSPERBRD; fclose(fhandlesb2[i++] )) ; lendif DISABLE FILE 10 IN WEP lifndef DISABLE_INTERRUPTS disconnectFromIRQ(IRQ5) ; disconnectFromIRQ(IRQ7) ; lendif DISABLE INTERRUPTS // « - xn-αsonnBczs / * validChksm Description Validates data using checksum. This is used internally at the moment(i.e., not an dll entry point). THIS DOES NOT CALCULATE A CHECKSUM. Returns : Success is non-zero */ //==== // Boolean validChksm(const unsigned char * bfr, const int bfrlen) { unsigned char sum - 0; for (int i - 0; i < bfrlen-1; sum +- *(bfr+i++)); Iifdef VALIDATE_CHECKSUM_LOG_ENABLED strcpy(atatuaMβg,"Length is "); strncat(statusMsg,ito (bfrlen,tempβtring,10) ,5) ; strncat(βtatuβMβg,"\n\r",5) ; statuβlog(statusMsg) ; strcpy(βtatuβMβg,"βua iβ • ); 8trncat(BtatusMeg,itoa(8um,te-npetring,10) ,5) ; strncat(βtatuβMβg,"\n\r",5); statuβlog(8tatuβMβg) ; lendif VALIDATE CHECKSUM LOG ENABLED if ((((sum-.0x7f) + *(bfr+i) )S0x7f) — 0) //Valid checksum return(TRUE) ; else { lifdef ENABLE_INVALID_CHKSM N strcpy(statuβMβg,">-»InvalTd ) ; statuslog(βtatuβMβg) ; lendif ENABLE_INVALID_CHKSM_NOTIFY return(FALSE) ; } } //_ ,_.: -—— /* initControl Description : NOT BEING USED. Returns : 0 - success Non-zero error code */ li¬ lt int FAR PASCAL _export initControl(const int event) { int i; //Open file //Change the default file mode from text to binary _fmode - 0_BINARY; /* //The following uses creat/write to log data. Even though files //are opened as binary, they are written .is text. I shall try 10 //using fopen and see if this βolves our problem. // if (event — OPEN) { //Create a binary file for each channel for each board. for (i - 0; i < CHNLSPERBRD? i++) //handlesbl[i] - creat(brdlBlks[i] .fileName, S_IREAD IS_IWRITE) ; handlesbl[i] - creat(brdlBlkβfi] .fileName, S_IWRITE); for (i - 0; i < CHNLSPERBRD; i++) //handlesb2[i] - creat(brd2Blks[i] .fileName, S_IREAD I S_IWRITE) ; handlesb2[i] » creat(brd2Blks[i] .fileName, S_IWRITE) ; } else if (event « CLOSE) { //Close files for (i - 0; i < CHNLSPERBRD; close(handlesbl[i++] )) ; for (i - 0; i < CHNLSPERBRD; close(handlesb2[i++] )) ; > */ // THIS WORKS. Mil J1111111JJJ 1 J 1111 // I have moved this processing to LibMain and WEP procedures. lifndef DISABLE_FILE_IO if (event — OPEN) { //Create a binary file for each channel for each board, for (int i - 0; i < CHNLSPERBRD; i++) fhandlesblfi] - fopen(brdlBlks[i] .fileName, "wb" ) ; for (i - 0; i < CHNLSPERBRD; i++) fhandlesb2[i] - fopen(brd2Blks[i] .fileName, "wb"); } else if (event — CLOSE) { for (i - 0; i < CHNLSPERBRD; fclose(fhandlesbl[i++] )) ? for (i - 0; i < CHNLSPERBRD; fclose(fhandlesb2[i++] )) ; > lendif DISABLE_FILE_IO /* board518No2.boardReset( ) ; return(board518Nol.boardReset( ) | | board518No2.boardReset( ) ( j uio48board.resetBoard(0) ) ; */ //' /* fanControl(fan number, on/off) Description : Sets/Clears appropriate 10 channel of UI048 11 board given fan number and value. Returns : 0 - success Non-zero error code // ™™™ _ ™™™™ « ™ -«« ™^ „„„ // int FAR PASCAL _export fanControl(fanCode fanNo, unsigned int onOff) { //dandy.astound //cout « "fanControl / fanNo = " « fanNo « "\n"; unsigned int channel; switch (fanNo) { case COND: channel - CONDFANchnl; break; case CIRC: channel - CIRCFANchnl; break; case PRES: channel - PRESFANchnl; break; default: channel » NULLchnl; > if (channel 1- NULLchnl) return(uio4δboard.writeChannel{channel, onOff) ) ; else return(l) ; } /* findlnBuffer(buffer, βtartofbuffer, string) - old way dandy.astound) Description : Locates string in buffer starting at sob. Returns : Positive - success (new sob) Negative - error code */ / /=-.;-sas:s≤-=-ca33-3---:-=r3-asκs-KBnBπaBiBV«H 12 // int findlnBuffer(unsigned char * buffer, int sob, const char * string) { Boolean found - TRUE; int savsob - sob; for (int i - 0; i < strlen(string) ; i++) { if (buffer! (sob+i)%CHNLBFRSIZE] 1» string[i] ) { found - FALSE; break; } } if (found) //Return updated aob //dandy.astound1 WAS //return( ( (sob+strlen(string) ) %CHNLBFRSIZE) ) ; return(sob+strlen(string) ) ; else //Return negative sob to indicate not found return(-1) ; } /* ventFindlnBuffer(bfr, length, pattern, altpattern, value) - new : Locates ventilator response in buffer. Also returns embedded values in response, if any. NOTE: First parameter bfr may not be null Returns : TRUE - If found FALSE - No match 1/ Boolean ventFindlnBuffer(const char *bfr, const int plength, const char *pattern, const char ♦ altpattern, int & alue) { const int LBFRSIZE - 50; static char lbfr[LBFRSIZE] , *pos, *savepos; static int i, mult; static const char *laltpattern; 13 value « 0 ; mult - 1 ; //Return the length of string matched to be used in calling routine //to update buffer index if a match is found, //plength - strlen(bfr) ; //If altpattern is NULL, then set local alt pattern to pattern. This //is useful below when checking for both patterns without having to worry //about dereferencing a null pointer. // v And I do mean "=" if ( ! (laltpattern-altpattern) ) laltpattern - pattern; //First copy bfr to enable us to modify string. We can not use //strcpy since bfr may not be null terminated, //strcpy(lbfr, bfr); //First copy bfr to enable us to modify string. if (plength > LBFRSIZE-1) { //We need to increase the size of our array. lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in ventFindlnBuffer.\n\r" ) ; statuslog(statusMBg) ; lendif ENABLE_FATAL_ERROR_MSGS } else { memcpy((void *)lbfr, (void *)bfr, plength); lbfr[plength] «= '\0'; //Add null terminated character. } //Replace all digits with 'n'. for (i-'O'; i<='9'; i++) while (pos-strchr(lbfr,i) ) *pos 'n' if ( ( 1strcmp(lbfr,pattern) ) | | ( 1strcmp(lbfr,laltpattern) ) ) { //We have a match. //cout « "We have a match" « endl; //First copy original string, strcpy(lbfr, bfr) ? 14 //First replace all '-' with blank starting at position 1 savepos - lbfr; while (pos=strchr( (char *)(lbfr+1),'-') ) { *pos - ' ' ; savepos - pos; } //Remove all '.' noting if any '.' precedes an /r. while (pos=strchr(lbfr, ' . ' ) ) { if (*(pos+l) — , \r') mult ■=• 10; //Remove ' . ' strcpy(pos,pos+1) ; } //Convert to integer, value = atoi(βavepos)*mult; return(TRUE) ; } else It cout « "We DO NOT have a match." « endl; return(FALSE) ; / /====-===caaπBsaBaaι-ι--i-iB-ι-ιa-»ι-i-i-ι-ι-αBsa-ι-ιanκ-ι»-maBBBB- B-:ι /* ventControl(cmd, value, state) Description : Sends ventilator commands and looks for response. Returns : Non-negative indicates return value from ventilator Negative value indicates error code. (-1 indicates that no responβe is found) I ti¬ l l int FAR PASCAL _export ventControl(ventCode ventCmd, unsigned int value. int &state) { static clock_t timel; static char nn[17]? static char * nnptr; 15 static char temp[20]; static int i, sob, savesob, bfrsize, br, n, dec, sign; static double dvalue; static unsigned char *bfr; static int diff; Boolean found = TRUE; //dandy.astound //cout « "ventcontrol / event - " « event « "\n"; switch (ventCmd) { case ALQ: switch (state) { case COMMAND: if (VENTBRD — 1) com4boardl.cmdALQ( ) ; else //aβs-ume board 2 com4board2.cmdALQ( ) ; state - WAIT4RESP0NSE; timel - cloc ( ) ; return(NORESP) ; break; case WAIT4RESPONSE: if ( (clock( )-timel) /CLOCKS_PER_SEC>VENT_RSP_TIMEOUT) { //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often ( it would be nice if it never //did occur) . com4BfrIndx[VENTBR-D-l ] [VENTCHNL-l ) . sob - com4BfrIndx [VENTBRD-l ] [VENTCHNL-1 ) .bfrlndx; state - VENTTIMEOUT; return (VENTALQTIMEOU ) ; //Timeout has occurred . } else { //First copy data into channel buffer. com4board2.getChnlData(VENTBilD,VENTCHNL,bfrsize) ; b f r * ( c h a r *)chnlBfrPtrs[VENTBRD-1] [VENTCHN -1] ; 16 s o b s a v e s o b com4BfrIndx[VENTBRD-l] [VENTCHNL-1] -sob; sob - findlnBuffer(bfr,eob,IpszALQ) ; //Returns negative if //not found. Otherwise, //returns updated sob. if (1 (sob >- 0) ) { //Check it ventilator did not understand command //or that the value was out of range, sob " findlnBuffer(bfr,savesob,IpszHUH) ; if (sob >- 0) { //Command not understood; value out of range, com4BfrIndx[VENTBRD-l][VENTCHNL-l] .sob = sob; state - CMDNOTACCEPTED; return(VALUEOUTOFRANGE) ; > } if (sob >- 0) { //Then we have seen at least a "ALQ-". //If bfrlndx is 2 position beyond ne, then assume //we have the alarm number followed by return. d i f f com4BfrIndx[VENTBRD-l]!VENTCHNL-l] .bfrlndx - sob; if ((diff -- NE) I I ( (CHNLBFRSIZE+diff) — NE) ) { //Make the assumption that we have received ALQ-ne //response packet. //This handles wrap-around condition //and any other situation. //Copy NE. for (i-0; i<NE; i++) temp[i] - bfr[(8θb+i)%CHNLBFRSIZE); temp[i] - '\0'; //Make conversion, n » atoi(temp) ; com4Bfrlndx[VENTBRD-1][VENTCHN -1] .sob (sob+NE) %CHNLBFRSIZE; state - RESPONSERCVD; return(n) ; 17 } } break; } default: return(INVALIDVENTSTATE) ; } return(NORESP); case ALR: switch (state) { case COMMAND: if (VENTBRD «-- 1) com4boardl.cmdAL { ) ; else //ass-ume board 2 com4board2.cmdALR( ) ; state - WAIT RESPONSE; timel - clock(); return(NORESP) ; break; case WAIT4RESPONSE: if ( (clock( )-timel)/CLOCKS_PER_SEC>VENT_RSP_TIME0UT) //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-l][VENTCHNL-l].sob - com4Bfrlnd [VENTBRD-1][VENTCHNL-1) .bfrlndx; state - VENTTIMEOUT; return(VENTALRTIMEOUT) ; //Timeout has occurred. } else { //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; b f r » ( c h a r *)chnlBfrPtrs[VENTBRD-l3 [VENTCHNL-1] ; s o b — s a v e s o b = com4BfrIndx[VENTBRD-l] [VENTCHNL-1] .sob; sob - findlnBuffer(bfr,sob,lpszALR) ; //Returns negative if //not found. Otherwise, 18 //returns updated sob. if (1 {8θb ' >- 0) ) { //Check it ventilator did no understand command //or that the value was out of range, sob - findInBuffer(bfr,savesob,IpszHUH) ; if (sob > ' - 0) { //Command not .understood; value out of range, com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob - sob; state - CMDNOTACCEPTED;. return(VALUEOUTOFRANGE) ; } > if (sob >- 0) { //Then we have seen "ALRe" com4Bfrlndx[VENTBRD-1] [VENTCHNL-l) .sob - sob; state - RESPONSERCVD; return(O) ; } } break; default: return(INVALIDVENTSTATE) ; } return(NORESP) ; case MAC: //return(com boardl.cmdMAC( ) ) ; break; case MB: return(com4boardl.cmdMB( ) ) ; break; case MI: return(com4boardl.cmdMI( ) ) ; break; case MIMV: return(com4boardl.cmdMIMV( ) ) ; break; case MO: return(com4boardl.cmdM0( ) ) ; break; case MSC: return(com4boardl.cmdMSC( ) ) ; break; 19 case PMAX: switch (state) { case COMMAND: itoa(value,nn, 10) ; //Convert breath rate command to string. if (value < 10) { //need to prepend a 0 nn[2] - nn[1] ; nn[l) - nn[0); nn[0) - '0'; } if (VENTBRD — 1) com4board1.cmdPMAX(nn) ; else //ass-ume board 2 com4board2.cmdPMAX(nn) ; state - WAIT4RESPONSE; timel - clock(); return(NORESP) ; break; case WAIT RESPONSE: if ( ( clock ( ) -timel ) /CLOCKS_PER_SEOVENT_RSP_TIMEOUT) { //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob = com4Bfrlndx[VENTBRD-1] [VENTCHNL-l].bfrlndx; state - VENTTIMEOUT; return(VENTPMAXTIMEOUT) ; //Timeout has occurred. } else { //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; b f r - ( c h a r *)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l] ; s o b - s a v e s o b = com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob; //Check it ventilator did not understand command //or that the value was out of range, sob - findInBuffer(bfr,sob,lpszHUH) ; if (sob >- 0) { //Command not understood; value out of range. 20 com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob = sob; state - CMDNOTACCEPTED; return{VALUEOUTOFRANGE) ; } sob — savesob; //Otherwise, check for. appropriate response diff - .com4BfrIndx[VENTBRD-l][VENTCHNL-l].bfrlndx sob; if ((diff -= nne) | | ( (CHNLBFRSIZE+diff) -= nne) ) //Make the assumption that we have received a two digit //number followed by a OxOD. , (sob+nne) %CHNLBFRSIZE; state - RESPONSERCVD; return(n) ; } break; default: return(INVALIDVENTSTATE) ; } return(NORESP) ; case PMIN: switch (state) { case COMMAND: itoa(value,nn,10) ; //Convert breath rate command to string if (value < 10) { //need to prepend a 0 nn[2J - nn[l]; nn[l] - nn[0]; nn[0) - '0'; } if (VENTBRD — 1) com4boa dl.cmdPMIN(nn) ; else //aβs-ume board 2 com4board2.cmdPHI (nn) ; 21 state - WAIT4RESPCNSE; timel = clock( ) ; return(NORESP) ; break; case WAIT4RESP0NSE: if ( (clock()-timel) /CLOCKS_PER_SEOVENT_RSP_TIMEOUT) { //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-l] [VENTCHNL-l) .sob - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .bfrlndx; state - VENTTIMEOUT; return(VENTPMINTIMEOU ) ; //Timeout has occurred. } else { //First copy data into channel buffer. com4board2.getChnlDat (VENTBRD,VENTCHNL,bfrsize) ; bfr- (char *)chnlBfrPtrs[VENTBRD-1) [VENTCHNL-l]; s o b -' s a v e s o b - com4Bfrlndx!VENTBRD-1] [VENTCHNL-l] .sob; //Check it ventilator did not understand command //or that the value was out of range, sob - findInBuffer(bfr,sob,lp8zHUH) ; if (sob >- 0) { //Command not understood; value out of range. com4BfrInd [VENTBRD-1] [VENTCHNL-l].sob- sob; state - CMDNOTACCEPTED; return(VALUEOUTOFRANGE) ; } sob - savesob; //Otherwise, check for appropriate response diff - com4Bfrlndx[VENTBRD-1][VENTCHNL-l].bfrIndx - sob; if ((diff — nne) || ( (CHNLBFRSIZE+diff) — nne)) { //Make the assumption that we have received a two digit //number followed by a OxOD. //This handles wrap-around condition //and any other situation. //Copy next three characters into temp array. 22 for (i-0; i<nne; i++) temp[i] - bfr[ ( sob+i) %CHNLBFRSIZE] ; temp[i] = ■ , \0'; n - atoi(temp) ; com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob - ( sob+nne)%CHNLBFRSIZE; state - RESPONSERCVD; return(n) ; } } break; default: return(INVALIDVENTSTATE) ; } return(NORESP) ; case PP: switch (state) { case COMMAND: if (VENTBRD ■» 1) com4boardl.cmdPP( ) ; else //ass-ume board 2 com4board2.cmdPP( ) ; state - WAIT4RESPONSE; timel - clock( ) ; return( ORESP) ; break; case WAIT4 RESPONSE : if ( ( clock ( ) -timel ) /CLOCKS_PER_SEOVENT_RSP_TIMEOUT ) { //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrInd [VENTBRD-1] [VENTCHNL-l] .sob - com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .bfrlndx; state - VENTTIMEOUT; return(VENTPPTIMEOUT) ; //Timeout has occurred. } else { //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) 23 b f r - ( c h a r *)chnlBfrPtrβ[VENTBRD-1] [VENTCHNL-l]; β o b « β a v e s o b - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .βob; //Check it ventilator did not underβtand command //or that the value was out of range, sob - findlnBuffer(bfr,aob,lpβzHUH) ; if (sob >- 0) { //Command not understood; value out of range. com4BfrIndx[VENTBRD-l][VENTCHNL-l].sob- sob; state - CMDNOTACCEPTED; return(VALUEOUTOFRANGE) ; } sob - savesob; //Otherwise, check for appropriate response //Look for cm in 4th poβition. s o b - findInBuffer(bfr, (sob+ )%CHNLBFRSIZE,lpβzCM) ; if (sob >- 0) { //Then we have βeen "cm\r" in reeponee. //Thiβ handlββ wrap-around condition //and any other βituation. //NOTE: An optional βign may be present. It is // assumed that if it iβ not present, a space // will be preβet. for (i-0; i<βignNNN; i++) temp[i) - bfr[ (saveβob+i)%CHNLBFRSIZE) ; temp[i] - '\0'; //Make conversion, n - atoi(temp) ; com4Bfrlnd [VENTBRD-1] [VENTCHNL-l] .sob - sob; state - RESPONSERCVD; return(n) ; > break; default: return(INVALIDVENTSTATE) ; } return(NORESP) ; case RBR: return(com4boardl.cmdRBR( ) ) ; 24 break; case RIT: return(com4boardl.cmdRIT( ) ) ; break; case RST: return(com4boardl.cmdRST( ) ) ; break; case SBR: switch (state) { case COMMAND: itoa(value,nn, 10) ; //Convert breath rate command to string . if (value < 10) { //need to prepend a 0 nn[2] - nn[l) ; nn[l] - nn[0]; nn[0] « '0'; > if (VENTBRD — 1) com4boardl.cmdSBR(nn) ; else //ass-ume board 2 com4board2.cmdSBR(nn) ; state - WAIT4RESPONSE; timel - clock( ) ; return(NORESP) ; break; case WAIT4RESPONSE: if ( (clock( )-timel)/CL0CKS_PER_SEOVENT_RSP_TIME0UT) //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob = com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .bfrlndx; state - VENTTIMEOUT; return(VENTSBRTIMEOUT) ; //Timeout has occurred. } else { //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; b f r - ( c h a r *)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l]; ■ s o b - s a v e s o b = com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob; 25 //Check it ventilator did not understand command //or that the value was out of range, sob » findlnBuffer(bfr,Bθb,lpszHUH) ; if (sob >- 0) { //Command not understood; value out of range. com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob - sob; state - CMDNOTACCEPTED; return(VALUEOUTOFRANGE) ; > eob - savesob; //Otherwise, αhβαk for appropriate reeponee diff - com4BfrIndx[VENTBRD-l][VENTCHNL-l).b rlndx - soub; if ((diff — nne) | J ( (CHNLBFRSIZE+diff) — nne)) { //Make the assumption that we have received a two digit //number followed by a OxOD. // //This workB for non-wraparound situations.. ////br - atoi(&bfr[sob]); ////com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob sob+3 ////return(br) ; //This handles wrap-around condition //and any other situation. //Copy next three characters into temp array for (i β 0; i<nne; i++) temp[i] - bfr[ (sob+i)%CHNLBFRSIZE] ; temp[i] - '\0'; br - atoi(temp); com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob - (sob+nne)%CHNLBFRSIZE; state - RESPONSERCVD; return(br) ; } } break; default: return(INVALIDVENTSTATE) ; } return(NORESP) ; case SIT: switch (state) { case COMMAND: dvalue « ( (double)value)/10.0; nnptr β fcv (dvalue, l,t.dec,&Bign) ; 26 *(nnptr+2) - *{nnptr+l); *(nnptr+l) - '.'; if (VENTBRD -- 1) com4boardl.cmdSIT(nnptr) ; else //asB-ume board 2 com4board2.cmdSIT(nnptr) ; state « WAIT4RESP0NSE; timel - clock( ) ; return(NORESP) ; break; case WAIT4RESP0NSE: if ( (clock( )-timel)/CL0CKS_PER_SEOVENT_RSP_TIME0UT) { //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob - com4BfrlndxfVENTBRD-1] [VENTCHNL-l] .bfrlndx; state β VENTTIMEOUT; return(VENTSITTIMEOUT) ; //Timeout has occurred. } else { //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; b f r - ( c h a r * )chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l] ; s o b - s a v e s o b - com4BfrIndx!VENTBRD-l] [VENTCHNL-l] .sob; //Check it ventilator did not understand command //or that the value was out of range, sob - indlnBuffer(bfr,sob,IpszHUH) ; if (sob >- 0) { //Command not understood; value out of range. com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob - sob; state - CMDNOTACCEPTED; return(VALUEOUTOFRANGE) ; } sob =■ savesob; //Otherwise, check for appropriate response diff - com4Bfrlnd [VENTBRD-1][VENTCHNL-l].bfrlndx - sob; if ((diff — ndotnse) | | ( (CHNLBFRSIZE+diff) == ndotnse) ) { 27 //Make the assumption that we have received n.nse. //This handles wrap-around condition //and any other situation. //Copy next three characters into temp array, for (i-0; i<ndotn; i++) temp[i] - bfr[ (sob+i)%CHNLBFRSIZE); temp[i) - '\0'; dvalue - atof(temp); com4BfrIndx[VENTBRD-1] [VENTCHNL-l].sob - (sob+ndotnse) %CHNLBFRSIZE; state » RESPONSERCVD; n = (int) (dvalue*10.0) ; return(n) ; } } break; default: return(INVALIDVENTSTATE) ; } return(NORESP) ; default: return(l) , return(O) ; } / / ϊ 3 = BXIMB B BHB βB B B» B B B BBBBBB»JB» «BBBBB«BMMBBBBBBBBBB«BBβB«BBBBCIβ βH= t SBS- z-tnBB»Bic attB /* ventCtrlWait(cmd, value) Description : Sends ventilator commands and looks for response. Returns only after getting response or timing out. Returns : Non-negative indicates return value from ventilator Negative value indicates error code. (-1 indicates that no response was found) * / // int FAR PASCAL _export ventCtrlWait(ventCode ventCmd, unsigned int value) { static clock_t timel; 28 0588 -470- static char nn[17]; static char * nnptr; static char temp[20]; βtatic int i, sob, βavesbb, bfrsize, br, n, dec, sign, plength, rvalue; static double dvalue; ' static unsigned char . " *bfr; static int diff; int retVal; int timer; //Used to indicate .that no response from RS232 serial char bell - 0x07; //link is probably hanging system. static int llastread, lsize, aavesize, totalβize; static unsigned char tempCmd[50]; ChnlBlk *lbrdBlk; Boolean found - TRUE; //dandy.astound //cout « "ventcontrol / event - " « event « "\n"; switch (ventCmd) { case ALQ: lifdef ENABLE_TEST_MODE if (sysMode — TEST) { n - rand{)%28; . if (n > 7) return(O) ; else return(n) , } lendif ENABLE_TEST_MODE if (VENTBRD — 1) IbrdBlk - ibrdlBlks[VENTCHNL-l]; else //Assume board 2 , IbrdBlk - &brd2BlksTVENTCHNL-1); for (i-0; KVENTRETRY; i++) { //Send the command if (VENTBRD — 1) com boardl.cmdALQ() ; 29 else //ass-ume board 2 com4board2.cmdALQ() ; timel - clock(); timer - 1, //Wait for response. retVal - VENTALQTIMEOUT; while ((clock()-timel)/CLOCKS_PER_SEC<VENT_RSP_TIMEOUT) //Beep if having to wait more than usual to indicate //why the system may be hanging. if (( (clock -timel) /CLOCKS_PER_SEC) > timer) { cout « bell; timer++; } if (lbrdBlk->curBfrInfo->lastread >- 0) { //No wrap-arround //dandy. stound1 //First copy data into channel buffer. //com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; //dandy.astound1 / / b f r - ( c h a r *)chnlBfrPtrs[VENTBRD-1][VENTCHNL-l); bfr - lbrdBlk->curBfrInfo->bfr; //dandy.astound! / / s o b «■ s a v e s o b - com4BfrIndx[ VENTBRD-1 ] [VENTCHNL-l ). sob; Bob - lbrdBlk->curBfrInfo->lastread; //WAS - dandy. stoundI /* sob ■» findInBuffer(bfr,sob,lpszALQ) , //Returns negative if //not found. Otherwise, //returns updated sob. */ //Calculate length of string to match, plength - lbrdBlk->curBfrlnfo->bfrlndx - sob; 30 if ( IventFindlnBuffer( (const char *)ϋbfrfsob] , ■ plength, ventResponse[ventCmd] [0] , ventResponse[ventCmd] [1] , rvalue) ) //Check if ventilator did not understand command //or that the value was out of range. //WAS - dandy. stound //sob - findlnBuf er(bfr,savesob,IpszHUH) ; plength - strlen(IpszHUH) ; if ( entFindlnBuffer{ (const char *)&bfr[8θb], plength, lpβzHUH, NULL, rvalue) ) { //Command not understood; value out of range. //dand . stoundI //com4BfrIndx[VENTBRD-l)[VENTCHNL-l] .sob- sob; lbrdBlk->curBfrInfo->laBtread +- plength; return(VALUEOUTOFRANGE) ; ) } elβe {//Found in buffer //Then we have seen the response. lbrdBlk->curBfrInfo->lastread +- plength; return(rvalue) ; } } else { //Wrap-around situation //First get partial coππaand string in flush buffer. llastread - lbrdBlk->flushBfrlnfo->lastread; totalsize - savesize ■ lsize ■ lbrdBlk->blockSize - llastread; if (lsize > sizeof(tempCmd)) { 31 //WΘ need to increase the size of our array. lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too . small in ventCtrlWait . \n\r " ) ; 8tatuslog(statusMsg) ; endif ENABLE_FATAL_ERROR_MSGS break; > memcpy(( oid *)tempCmd, &(lbrdBlk->flushBfrlnfo->bfr[llastread] ) , lsize) ; //Now get rest of command in current buffer, if ((lsize + lbrdBlk->curBfrlnfo->bfrlndx) > sizeof(tempCmd) ){ //We need to increase the size of our array, lifdef ENABLE_FATAL_ERROR_MSGS βtrcpy(statusMsg, "Array too small in ventCtrlWait.\n\r") ; βtatuβlog(statusMsg) ; lendif ENABLE_FATAL_ERROR_MSGS break; } llastread - 0; lsize - lbrdBlk->curBfrInfo->bfrlndx; totalsize +- lsize; memcp ((void *)SitempCmd[savesize] , &(lbrdBlk->curBfrlnfo->bfr[llastread]) ,lsize) ; bfr - tempCmd; eob — 0; //WAS - dandy.astound /* sob - findlnBuffer(bfr,sob,IpszALQ) ; //Returns negative if //not found. Otherwise, //returns updated sob. */ if (!ventFindlnBuffer(bfr, totalsize, ventResponse[ventCmd] [0] , ventResponse[ entCmd] [1] , rvalue)) { 32 //Check if ventilator did not understand command //or that the value was out of range. //WAS - dandy. stoundl //sob - findInBuffer(bfr,savesob,lpszHUH) ; plength - strlen(IpszHUH) ; if (ventFindInBuffer(bfr, plength, IpszHUH, NULL, rvalue) ) { //Command not understood; value out of range. //dandy.astound! //com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob- sob; //Set the flush buffer lastread variable to -1 to indicate //that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread - -1; lbrdBlk->curBfrInfo->lastread - lsize; return(VALUEOUTOFRANGE) ; } } else {//Found in buffer //Then we have seen the response. //Set the flush buffer lastread variable to -1 to //indicate that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread - -1; lbrdBlk->curBfrInfo->lastread - lsize; return(rvalue) ; > } } //Timeout has occurred. //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should 33 //not happen too often (it would be nice if it never //did occur) . //dandy. stound1 //com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob - // com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .bfrlndx; lbrdB.l ->curBfrInfo->lastread lbrdBlk->curBf rlnf o->bf rlndx; } return(retVal) ; case ALR: lifdef ENABLE_TEST_MODE if (sysMode — TEST) return(O) ; lendif ENABLE_TEST_MODE for (i-0; i<VENTRETRY; i++) { //Send the command if (VENTBRD — 1) com board1.cmdALR( ) ; else //ass-ume board 2 com4board2.cmdAL ( ) ; timel - clock() ; timer - 1; //Wait for r aponse. retVal - VENXATHTIMEOUT; w h i l e ( ( (clockO"timel) /CLOCKS_PE _SEC)<VENT_RSP_TIMEOUT) { //Beep if having to wait more than usual to indicate //why the βyβte may be hanging. if (( (clockO-timel)/CLOCKS_PER_SEC) > timer) { cout « bell; timer++; } //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; bfr - (char *)chnlBfrPtrs[VENTBRD-l] [VENTCHNL-l] ; s o b - — s a v e s o b - com4Bfrlnd [VENTBRD-1] [VENTCHNL-l].sob; sob - findlnBuffer(bfr,sob,IpszALR) ; //Returns negative if 34 //not found, Otherwise, //returns updated sob. if (I (sob >« 0)) { //Check it ventilator did not understand command //or that the value was out of range. sob - findlnBuffer(bfr,savesob,IpszHUH) ; if (sob >- 0) { //Command not understood; value out of range. com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob- sob; return(VALUEOUTOFRANGE); } } if (eob >- 0) { //Then we have seen "ALRe". com4BfrIndx[VENTBRD-1][VENTCHNL-l].sob - sob; return(O) ; } > //Timeout has occurred. //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-l][VENTCHNL-l}.sob - com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .bfrlndx; } return(retVal) ; case MAC: for (i-0; i<VENTRETRY; i++) { itoa(value,nn,10) ; //Convert negative sense pressure if (value < 10) { //need to prepend a 0 nn[2] - nn[l]; nn[l] - nn[0]; nn[0] - '0'; } if (VENTBRD — 1) com4boardl.cmdMAC(nn) ; else //ass-ume board 2 com4board2.cmdMAC(nn) ; 35 timel - clock( ) ; timer — 1; //Wait for response. retVal - VENTMACTIMEOUT; w h i l e ( ( (clock( )-timel)/CLOCKS_PER_SEC)<VENT_RSP_TIMEOUT) { //Beep if having to wait more than usual to indicate //why the system may be hanging. if (( (clock -timel)/CLOCKS_PER_SEC) > timer) { cout « bell; timer++; } //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; bfr - (char *)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l] ; s o b - s a v e s o b - com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob; //Check it ventilator did not understand command //or that the value was out of range, sob - findlnBuffer(bfr,sob,IpszHUH) ; if (sob >- 0) { //Command not understood; value out of range. com4Bfrlndx[VENTBRD-1][VENTCHNL-l].sob - sob; return(VALUEOUTOFRANGE) ; } sob - savesob; //Otherwise, check for appropriate response diff - com4Bfrlndx[VENTBRD-1][VENTCHNL-l].bfrlndx - sob; if ((diff — AslashCdashnne) | | ( (CHNLBFRSIZE+diff) AslaβhCdashnne) ) //Make the assumption that we have received A/C-nn //number followed by a OxOD. //This handles wrap-around condition //and any other situation. //Copy nne characters into temp array. Offset by 4 //characters to account for MAC- for (i-0; i<nne; i++) temp[i] - bfr[ (βob+i+ ) %CHNLBFRSIZE] ; temp[i) - '\0'; n - atoi(temp) ; 36 com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob - (sob+nne+4)%CHNLBFRSIZE; return(ri) ; //Timeout has occurred. //Abort command - : Reset; sob to end of buffer and //start anew. This. essentially recovers from //an error in ' -commanding the ventilator. This should //not happen too * , often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob - com4Bfrlnd [VENTBRD-1] [VENTCHNL-l].bfrlndx; } return(retVal) ; case MB: return(com4boardl.cmdMB( ) ) ; break; case MI: return(com4boardl.cmdMI{ ) ) ; break; case MIMV: lifdef ENABLE_TEST_MODE if (sysMode — TEST) return(O) ; lendif ENABLE TEST MODE for (i=0; i<VENTRETRY; i++) { //Send the command if (VENTBRD — 1) com4boardl.cmdMIMV( ) ; else //aβs-ume board 2 com4board2.cmdMIMV( ) ; timel -.clockO; timer - 1; //Wait for response. retVal « VENTALRTIMEOUT; w h i l e ( ( (clock( )-timel) /CLOCKS_PER_SEC)<VENT_RSP_TIMEOUT) { //Beep if having to wait more than usual to indicate //why the system may be hanging. if ( ((clockO-timel)/CLOCKS_PER_SEC) > timer) { 37 cout « bell; timer++; } //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; bfr - (char *)chnlBfrPtrs[VENTBRD-l] [VENTCHNL-l] ; s o b - β a v e s o b - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .βob; sob - findlnBuffer(bfr,βob,lpβzIMV) ; //Returns negative if //not found, Otherwise, //returna updated sob, if M(sob >- 0)) { //Check it ventilator did not understand command //or that the value was out of range, sob - findInBuffer(bfr,savesob,IpszHUH) ; if (sob >- 0) { i //Command not understood; value out of range. com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob- sob; return(VALUEOUTOFRANGE) ; } } if (sob >- 0) { //Then we have seen "IMVe". com4BfrIndx[VENTBRD-l] [VENTCHNL-l].sob - sob; return{0) ; * } //Timeout has occurred. //Abort command - Reset βob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4Bfrlnd [VENTBRD-1] [VENTCHNL-l].sob - com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .bfrlndx; } return(retVal) ; break; 38 case MO : return(com4boardl.cmdMO( ) ) ; break; case MSC: return(com4boardl.cmdMSC( ) ) ; break; case PMAX: for (i=0; i<VENTRETRY; i++) { itoa(value,nn, 10) ; //Convert breath rate command to string if (value < 10) { //need to prepend a 0 nn[2] - nn[l] ; nn[1] « nn[0] ; nn[0] - '0'; } if (VENTBRD — 1) com4boardl.cmdPMAX(nn) else //ass-u e board 2 com4board2.cmdPMAX(nn) timel - clock( ) ; timer - 1; //Wait for response. retVal - VENTPMAXTIMEOUT; w h ( ( (clock( )-timel)/CLOCKS_PER_SEC)<VENT_RSP_TIMEOUT) { //Beep if having to wait more than usual to indicate //why the system may be hanging. if (( (clockO-timel)/CLOCKS_PER_SEC) > timer) { cout « bell; timer++; ) //First copy data into channel buffer. com board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; bfr = (char *)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l] ; s o b - s a v e s o b = com4BfrIndx[VENTBRD-l] [VENTCHNL-l].sob; //Check it ventilator did not understand command //or that the value was out of range, sob - findlnBuffer(bfr,sob,IpszHUH) ; if (sob >- 0) { //Command not understood; value out of range. com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob - sob; return(VALUEOUTOFRANGE) ; 39 } sob - savesob; //Otherwise, check for appropriate response diff « com4BfrInd [VENTBRD-1HVENTCHNL-l].bfrlndx sob; if ((diff — nne) | | ( (CHNLBFRSIZE+diff) — nne)) { //Make the assumption that we have received a two digit //number followed by a OxOD. //This handles wrap-around condition //and any other situation. //Copy next three characters into temp array. for (i-0; i<nne; i++) tempfi] - bfr[ (sob+i)%CHNLBFRSIZE] ; temp[i) - '\0'; n - atoi(temp) ; com4Bfrlndx[VENTBRD-1][VENTCHNL-l].sob - (sob+nne)%CHNLBFRSIZE; return(n) ; > } //Timeout has occurred. //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .bfrlndx; } return(retVal) ; case PMIN: for (i-0; i<VENTRETRY; i++) { itoa(value,nn,10) ; //Convert breath rate command to string, if (value < 10) { //need to prepend a 0 nn[2] - nn[l]; nn[l] - nn[0]; nn[0) - '0'; } if (VENTBRD — 1) com4boardl.cmdPMIN(nn) ; else //ass-ume board 2 com4board2.c dPMI (nn) ; 40 timel - clock( ) ; timer - 1; //Wait for response. retVal - VENTPMINTIMEOUT; w h i l e ( ( (clockO-timel) /CLOCKS_PER_SEC)<VENT_RSP_TIMEOUT) { 11 Beep if having to wait more than usual to indicate //why the system may be hanging. if (( (clockO-timel)/CLOCKS_PER_SEC) > timer) { cout « bell; timer++; } //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; bfr - (char *)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l) ; s o b - s a v e s o b - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .βob; //Check it ventilator did not understand command //or that the value was out of range. •ob - findInBtJ-Cι#r(bfr / *ob,lpβzBUH) ; if (eob >» 0) i //Command not understood; value out of range. com4Bfrlndx[VENTBRD-1][VENTCHNL-l],βob - sob; return(VALUEOUTOFRANGE) ; > sob - saveβob; //Otherwise, check for appropriate response diff - com4BfrIndx[VENTBRD-1) [VENTCHNL-l] .bfrlndx - sob; if ((diff — nne) | | ( (CHNLBFRSIZE+diff) — nne)) { //Make the assumption that we have received a two digit //number followed by a OxOD. //This handles wrap-around condition //and any other situation. //Copy next three characters into temp array. for (i-0; i<nne; i++) temp[i] - bfr[ (sob+i) %CHNLBFRSIZE] ; temp[i) - '\0'; n - atoi(temp) ; com4BfrIndx[VENTBRD-l] [VENTCHNL-l) .sob » (sob+nne)%CHNLBFRSIZE; return(n); } 41 } //Timeout has occurred. //Abort command - Reβet sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob - com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .bfrlndx; } return(retVal) ; case PP: lifdef ENABLE_TEST_MODE if (sysMode — TEST) return( (rand()%130) - 10) lendif ENABLE_TEST_MODE for (i=0; KVENTRETRY; i++) { if (VENTBRD — 1) com4boardl.cmdPP( ) ; else //asβ-ume board 2 com4board2.cmdPP( ) ; timel - clock( ) ; timer - 1; //Wait for response. retVal - VENTPPTIMEOUT; w h i l e ( ( (clockO-timel)/CLOCKS_PER_SEC)<VENT_RSP__TIMEOUT) { //Beep if having to .wait more than usual to indicate //why the system may be hanging. if (( (clock()-timel)/CLOCKS_PER_SEC) > timer) { cout « bell; timer++; } //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; bfr - (char *.)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l] ; s o b - s a v e s o b = com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob; //Check it ventilator did not understand command 42 //or that the value was out of range, sob - findlnBuffer(bfr,sob,IpszHUH) ; if (sob >» 0) { //Command not understood; value out of range. com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob - sob; return(VALUEOUTOFRANGE) ; > sob - savesob; //Otherwise, check for appropriate response //Look for cm in 4th position. sob - findlnBuffer(bfr, (sob+4) %CHNLBFRSIZE,IpszCM) ; if (sob >- 0) { //Then we have seen "cm\r" in response. //This handles wrap-around condition //and any other situation. //NOTE: An optional aign may be present. It is // assumed that if it iβ not present, a space // will be preset, for (i-0; i<signNNN; i++) temp[i) « bfr[ (savesob+i) %CHNLBFRSIZE] ; temp[i] - '\0'; //Make conversion. n - atoi(te p); com4BfrIndx[VENTBRD-l] [VENTCHNL-l).sob = sob; return(n) ; } } //Timeout has occurred. //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4Bfrlndx[VENTBRD-1] [VENTCHNL-l].sob - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .bfrlndx; } return(retVal) ; case RBR: lifdef ENABLE_TEST_MODE if (sysMode — TEST) return( (rand()%990) + 1); lendif ENABLE_TEST_MODE 43 return ( com4boardl . cmdRBR ( ) ) ; break ; case RIT: return(com4boardl.cmdRIT( ) ) ; break; case RST: return(com4boardl.cmdRST( ) ) ; break; case SBR : for (i-0; i<VENTRETRY; i++) { itoa(value,nn, 10) ; //Convert breath rate command to string. if (value < 10) { //need to prepend a 0 nn[2] - nn[l); nn[l] - nn[0]; nn[0] - '0'; } if (VENTBRD — 1) com4boardl.cmdSBR(nn) ; else //ass-ume board 2 com4board2.cmdSBR(nn) ; timel - clock( ) ; timer - 1; //Wait for response. retVal - VENTSBRTIMEOUT; w h i l e ( ( (clock( )-timel) /CLOCKS_PER_SEC)<VENT_RSP_TIMEOUT) { //Beep if having to wait more than usual to indicate //why the βystem may be hanging. if (( (clockO-timel)/CLOCKS_PER_SEC) > timer) { cout « bell; timer++; } //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; bfr - (char *)chnlBfrPtrs[VENTBRD-l] [VENTCHNL-l] ; s o b = s a v e s o b = com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob; //Check it ventilator did not understand command //or that the value was out of range. sob - findInBuffer(bfr,sob,IpszHUH) ; 44 if (sob >- 0) { //Command not understood; value out of range. com4BfrIndx[VENTBRD-1] [VENTCHNL-l].sob - sob; return(VALUEOUTOFRANGE) ; } sob - savesob; //Otherwise, check for appropriate response diff - com4BfrIndx[VENTBRD-l] [VENTCHNL-l].bfrlndx - sob ; if ((diff — nne) | | ( (CHNLBFRSIZE+diff) -- nne)) { //Make the assumption that we have received a two dL ? t //number followed by a OxOD. rray. (sob+nne)%CHNLBFRSIZE; return(br) ; } //Timeout has occurred. //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .bfrlndx; } return(retVal) ; πααn STT" for (i-0; i<VENTRETRY; i++) { itoa(value,nn,10) ; if (value < 10) { //need to prepend a "0." nn[3] - nn[l]; //'\0' nn[2] - nn[0]; nn[l] - '.'; nn[0] - '0'; } 45 else { It need to insert a decimal point. nn[3] - nn[2]; nn[2] - nn[1]; nn[l] - '.'; if (VENTBRD — 1) . com4boardl.cmdSIT(nn) ; else //asB-ume board 2 com4board2.cmdSIT(nn) ; //WAS /* dvalue = ( (double)value)/10.0; nnptr - fcvt(dvalue,l,&dec,&sign) ; *(nnptr+2) - *{nnptr+l); *(nnptr+l) - '.'; if (VENTBRD « 1) com4boardl.cmdSIT(nnptr) ; else //ass-u e board 2 com4board2.cmdSIT(nnptr) ; */ timel - clock{); timer - 1; //Wait for response. retVal - VENTSITTIMEOUT; w h i l e ( ( (clock( )-timel)/CLOCKS_PER_SEC)<VENT_RSP_TIMEOUT) { //Beep if having to wait more than usual to indicate //why the βyste may be hanging. if (( (clockO-timel)/CLOCKS_PER_SEC) > timer) { cout « bell; timer++; y //First copy data into channel buffer. com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; bfr - (char *)chnlBfrPtra[VENTBRD-1)[VBNTCHNL-1] ; s o b - s a v e s o b - om4Bfrlndx[VENTBRD-1][VENTCHNL-l].βob; //Check it ventilator did not understand command //or that the value vas out of range, sob - findlnBuffer(bfr,sob,IpszHUH) ; if (sob >- 0) { //Command not understood; value out of range. ccm4BfrInάΛ[VEΪTraRD-l][VENTCHNL-l].eob - sob; 46 7/10588 -488- return(VALUEOUTOFRANGE) ; } sob - savesob; //Otherwise, check for appropriate response diff - com4Bfrlnd [VENTBRD-1)[VENTCHNL-l].bfrlndx - sob; if ((diff — ndotnse) || ((CHNLBFRSIZE+diff) — ndotnse) ) { //Make the assumption that we have received n.nse. //This handles wrap-around condition //and any other situation. ; //Copy next three characters into temp array. for (i-0; i<ndotn; i++) temp[i] - bfr[(sob+i)%CHNLBFRSIZE]; temp[i] - '\0'; dvalue - atof(temp); com4BfrInd [VENTBRD-1][VENTCHNL-l).sob - (sob+ndotnse)%CHNLBFRSIZE; n - (int) (dvalue*10.0); return(n) ; } } //Timeout has occurred. //Abort command - Reset sob to end of buffer and //start anew. This essentially recovers from //an error in commanding the ventilator. This should //not happen too often (it would be nice if it never //did occur) . com4BfrIndx[VENTBRD-l][VENTCHNL-l].βob - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .bfrlndx; } return(retVal) ; default: return(INVALIDVENTCMD) ; } } //........-».«.-..-- S=->BlMlMK-B WΛMME— K-KW-B /* pumpControl(event, on/off) Description : Sets/Clears appropriate 10 channel of UI048 for pumping units. 47 Returns : 0 - success Non-zero error code */ // ■ // int FAR PASCAL _export pumpControl(pumpCode event, unsigned int onOff) { switch(event) { case SUCPOWER: return(uio48board.writeChannel(SUCchnl, onOff) ) ; break; case VENTPOWER: if (onOff — 1) first - TRUE; //dandy.astound return(uio48board.writeChannel(VENTchnl, onOff) ) ; break; default: return ( l ) ; } return ( 0 ) ; } / / ——————————————————————. s =s =3 =3 ϊ-S τaτx *a at n ex EX nn /* defibControl(action, on/off) Description : Sets/Clears appropriate 10 channel of UI048 for defibrillator unit. Returns : 0 - success Non-zero error code */ II- // int FAR PASCAL _export defibControl(defibCode action, unsigned int onOff) { unsigned int channel; switch (action) { case POWER: channel - DEFIB_PWRchnl; break; 48 case RESUME: channel - DEFIB_RESchnl; break; case FIRE: channel - DEFIB_EXEchnl; break; default: channel - NULLchnl; } if (channel I- NULLchnl) return(uio48board.writeChannel(channel, onOff) ) ; 10 else return(NULLchnl) ; I l¬ /* ecsControl(event, on/off) l s Description : Sets/Clears appropriate 10 channel of UI048 for ECS. Returns : 0 - success Non-zero error code 0 */ / /αan-iBiι π--ιnBπ>Bπιιa-ι-ι»κ-ι-ιaιιaBnaB-»-ι-iH-na-ι_ιa--i»a>iBa-iBiιιιsι:3i3«[i =-:=-:-ι-:-:-:==-:-J-l-ι // int FAR PASCAL _export ecsControl(int event, unsigned int onOff) { //"event" is currently not used. 5 return(uio48board.writeChannel(ECSchnl, onOff) ); } // « /* powerControl(notUsed, on/off) 0 Description : Sets/Clears appropriate 10 channel of UI048 for power (charge). Returns : 0 - success Non-zero error code */ //■»„ «. -„—-.-— 5 49 // int FAR PASCAL _export powerControl(int notUsed, unsigned int onOff) { //Not implemented return(1) ; defibSenseD(event, on/off) Description : Senses appropriate event on defib input channel. Returns : On/Off state (as reference parameter) Function Value: 0 - success Non-zero error code mciiximi // nt FAR PASCAL _export defibSenseD(defibCodθ event, int &state) { //int FAR PASCAL _export defibSensβD(int event, int &state) { unsigned int channel; state = 0; switch (event) { case POWER: channel - NULLchnl; break; case RESUME: channel - DEFIB_RDYchnl; break; case FIRE: channel - NULLchnl; break; default: channel « NULLchnl; > if (channel i- NULLchnl) { state =» readChannel(channel) ; //debug 50 //printf("Channel 9 : %x\r", state); return(0) ; } else { return(NULLchnl) ; } } -ssaaassaizls asiSM /* tempSenseA(location,temp) Description : Senses temperature at location. For prototype, an average of a sample of temperatures is calculated. Future implementation should do this sampling at the board level for increase performance. Returns : Temperature (as reference parameter) Function Value: 0 - success Non-zero error code I It int FAR PASCAL _export tempSenseA(tempCode location, unsigned int far &temp) { int retval - 0; switch (location) { case EQUIPX: equipTempSensor.readData(temp) ; break; case PATSUP: patTempSensor.readData(temp) ; break; case DISPLAY: dsplyTempSensor.readData(temp) ; break; case CPU: cpuTempSensor.readData(temp) ; break; default: retval - 1; 51 if (1retval) temp - tβmp*1.8 + 320; //cout « "Temp : " « temp « "\r"; //debug //printf("Temp « %d\r", savetemp) ; return(retval)j /* ekgSenseA( ) Description : Senses ekg voltage. Returns : */ //==========* // int FAR PASCAL _export ekgSenseA() { return(aioboard.readChannel(AI0CHNL4IUNIPLRIDFRNTL) ) ; } //= /* getrs232(chnlBfr respbuf) Description : Returns a pointer to the channel buffer of the specified I board and the start and end indices to the buffer. I It is assumed that member function getChnlData has been previously called to copy data into buffer. Returnβ Pointer to channel buffer. */ //===— === // 52 ChnlBfr * FAR PASCAL _βxport gβtr«232(int board, int chnl, int fcBob, int tβob) { linclude <mem.h> int savesob; / ♦ Removed for mod of design on 1/2296 Check for condition indicating no data to be read, if ( (sob-com4BfrIndx[board-l] [chnl-1] .sob) — (eob-com4BfrIndx[board-l] [chnl-1] .eob) ) { // sob * eob - savesob[board-l] [chnl-1] = saveeob[board-1) [chnl-1] - 0; //sob - eob - 0; return(NULL) ; } */ //Pass back start and end of buffer and save / / / / sob - savesob [ board- l ] [ chnl- l ] com4Bf rlndx [board- 1] [chnl-1 ] .sob; // / /eob - saveeob [ board- l ] [ chnl- l ) = com4BfrIndx[board-l] [chnl-1] .eob; //Update indices / / com4 B f rIndx [ board- l ] [ chnl- 1 ] . s ob com4BfrIndx[board-l] [chnl-1] .eob + 1; //if (com4Bfrlndx[board-1] [chnl-1] .bfrlndx — 0) // eob - com4Bfrlndx[board-1] [chnl-1] .eob - CHNLBFRSIZE-1; //else // eob - com4BfrIndx[board-l] [chnl-1] .eob - // com4BfrIndx[board-1] [chnl-1] .bfrlndx-1; //Check for no data available condition if ( (sob-com4BfrIndx[board-l] [chnl-1] .sob) — (com4Bfrlnd [board-1] [chnl-1] .bfrlndx) ) { eob - sob; return(NULL) ; } else { sob - com4BfrIndx[board-l] [chnl-1] .sob; eob - com4BfrIndx[board-l) [chnl-1] .sob - com4BfrIndx[board-l] [chnl-1] .bfrlndx; //savesob - com4BfrIndx[board-l] [chnl-1] .sob - // com4BfrIndx[board-l] [chnl-1] .bfrlndx; //savesob — 0 ? eob - CHNLBFRSIZE-1 : eob - savesob-1 53 //sob - com4BfrIndx[board-l] [chnl-1] .sob; If ob - com4BfrIndx[board-l] [chnl-1] .eob; • return( (ChnlBfr *) (chnlBfrPtrβ[board-l] [chnl-1] ) ) ; }? x-r-α-aEa-R a-a s-a-a-axa-a-a /* systemControl( ) Description : System control routine for periodic processing for - Ventilator initialization sequence Event - VENTINIT (Compressor turned on) State = RDYWAIT 1. Look for RDY response - Current State - RDYWAIT - Event if RDY seen o Send MO command o Next State - ONWAIT 2. Look for ON respsonse - Current State - ONWAIT - Event if ON seen o Send MIMV command o Next State = IMVWAIT 3. Look for IMV response - Current State - IMVWAIT - Event if IMV seen o Next State = IMV Returns : Array of status codes. // int FAR PASCAL _export systemControl(int sysEvent, int &ctrlState){ #include <mem.h> static int i, sob, bfrsize, llastread, lsize, savesize, rvalue, plength; static int totalsize; static unsigned char *bfr, tempCmd[50]; ChnlBlk *lbrdBlk; Boolean found - TRUE; 54 switch (sysEvent) { case CAPTUREVENT: //dandy.astound com4board2.getChnlDat (VENTBRD,VENTCHNL,bfrsize) ; break; case VENTINIT: switch (ctrlState) { case RDYWAIT : //Check for RDY on ventilator RS232 Channel. #ifdef ENABLE_TEST_MODE if (sysMode — TEST) { //Just simulate receiving the response. first - TRUE; ctrlState - ONWAIT; break; } #endif ENABLE TEST MODE if (VENTBRD — 1) IbrdBlk - ϋbrdlBlks[VENTCHNL-l] ; else //Assume board 2 IbrdBlk - &brd2Blks[VENTCHNL-l] ; if (first) { //Save time to check for timout systemTime - clock() ; first - FALSE; } e l s e i f ( ( (clockO-systemTime) /CLOCKS_PER_SEC)>VENT_INIT_TIMEOU ) { //Just give up. firβt » TRUE; ctrlState - VENTTIMEOUT; //dandy.astoundi //com4BfrIndx[VENTBRD-1) [VENTCHNL-l] .sob - // com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .bfrlndx; lbrdBlk->curBfrInfo->lastread - lbrdBlk->curBfrlnfo->bfrlnd ; return(VENTRSTTIMEOUT) ; } if (lbrdBlk->curBfrInfo->lastread >- 0) { //No wrap-arround //dandy. stound1 //First copy data into channel buffer. 55 //com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsizβ) ; //dandy.astoundI / / b f r ( c h a r *)chnlB rPtrs[VENTBRD-1] [VENTCHNL-l] ; bfr » lbrdBlk->curBfrInfo->bfr; //dandy.astoundl //sob - com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob; sob - lbrdBlk->curBfrInfo->lastread; //WAS - dandy.astoundl /* sob - findlnBuffer(bfr,sob,IpszRDY) ; //Returns negative if //not found. Otherwise, //returns updated sob. */ //Calculate length of string to match, plength - lbrdBlk->curBfrlnfo->bfrlndx - sob; if ( 1ventFindlnBuffer( (const char *)&bfr[sob], plength, ventResponse[RST] [0] , ventResponse[RST] [ 1] , rvalue) ) { //Check if ventilator did not understand command //or that the value was out of range. //WAS - dandy.astound //sob - findlnBuffe (bfr,savesob,IpszHUH) ; plength - strlen(lpszHUH) ; if (ventFindlnBuffer( (const char *) &bfr[sob] , plength, IpszHUH, NULL, rvalue) ) { //This should never happen during initialization. //There is currently no recovery from this error. //Ventilator will not initialize. 56 //Command not undβrβtood; value out of range. //dand .astoundJ //com4Bfrlndx[VENTBRD-1][VENTCHNL-l] .sob= sob; #ifdef. ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Fatal Error 1 in systemControl/RDYWAIT.\n\r") ; statuslog(statusMsg) ; #endif ENABLE_FATAL_ERROR_MSGS lbrdBlk->curBfrInfo->lastread += plength; return(VALUEOUTOFRANGE) ; } } else {//Found in buffer //Then we have seen the response. lbrdBlk->curBfrInfo->lastread +- plength; //Send MO cmd if (VENTBRD — 1) com4boardl.cmdM0( ) ; else //ass-ume VENTBRD — 2 com4board2.cmdM0( ) ; first - TRUE; ctrlState - ONWAIT; //WAS - dandy.astoundl /* if (sob >= 0) { //Found string; update sob index to index to the next //area of buffer to be read. //dandy.astoundl //com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob sob; lbrdBlk->curBfrInfo->lastread - sob; 57 //Send MO cmd if (VENTBRD — 1) com boardl.cmdMO( ) ; else //ass-umβ VENTBRD com4board2.cmdMO( ) ; first - TRUE; ctrlState - ONWAIT; */ else { //Wrap-around situation //First get partial command string in flush buffer. llastread - lbrdBlk->flushBfrInfo->lastread; totalsize = savesize - lsize =■ lbrdBlk->blockSize llastread; if (lsize > sizeof(tempCmd) ) { //We need to increase the size of our array. Iifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in systemControl. \n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_FATAL_ERROR_MSGS break; } memcpy( (void *)tempCmd, α (lbrdBlk->flushBfrInfo->bfr[llastread] ) , Isxze) //Now get rest of command in current buffer. if ((lsize + lbrdBlk->curBfrlnfo->bfrlndx) > sizeof(tempCmd) ) { //We need to increase the size of our array, lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in systemControl. \n\r" ) ; statuslog(statuBMsg) ; lendif ENABLE_FATAL_ERROR_MSGS break; } llastread - 0; lsize - lbrdBlk->curBfrInfo->bfrIndx; totalsize +- lsize; memcpy( (void *)&tempCmd[savesize] , &(lbrdBlk->curBfrlnfo->bfr[llastread] ) ,lsize) ; 58 bfr - tempCmd ; //dandy. stoundl //sob - com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob; sob - 0; //WAS - dandy.astoundl /* sob - findlnBuffer(bfr,sob,IpszRDY) ; //Returns negative if //not found. Otherwise, //returns updated sob. */ if ( lventFindInBuffer(bfr, totalsize, ventResponse[RST] [0) , ventResponse[RST] [1] , rvalue) ) { //Check if ventilator did not understand command //or that the value was out of range. //WAS - dandy.astoundl //sob - findlnBuffer(bfr,savesob,IpszHUH) ; plength - strlen(IpszHUH) ; if (ventFindlnBuffer(bfr, plength, IpszHUH, NULL, rvalue) ) { //Command not understood; value out of range. //dandy.astound1 //com4Bfrlnd [VENTBRD-1] [VENTCHNL-l] .sob= sob; //Set the flush buffer lastread variable to -1 to indicate //that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread - -1; lbrdBlk->curBfrInfo->lastread = lsize; lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, 59 "Fatal Error 2 in systemControl/RDYWAIT.\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE FATAL ERROR MSGS return(VALUEOUTOFRANGE) ; } } else {//Found in buffer //Then WΘ have seen the response. //Set the flush buffer lastread variable to -1 to //indicate that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastrβad - -1; lbrdBlk->curBfrInfo->lastrβad - lsize; //Send MO cmd if (VENTBRD — 1) com board1.cmdMO( ) ; else //ass-ume VENTBRD — 2 com4board2.cmdMO( ) ; first - TRUE; ctrlState « ONWAIT; //WAS - dandy.astound /* if (sob >- 0) { //Found string; update sob index to index to the next //area of buffer to be read. //dandy.astound1 //com4Bfrlnd [VENTBRD-1] [VENTCHNL-l] . sob sob; //Set the flush buffer lastread variable to -1 o indicate //that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread - -1; lbrdBlk->curBfrInfo->la8tread = lsize; 60 /10588 -502- II Send MO cmd if (VENTBRD — 1) com4boardl.cmdMO( ) ; else //ass-ume VENTBRD com4board2.cmdMO{ ) ; first - TRUE; ctrlState - ONWAIT; break; case ONWAIT: //Waiting for ON response from ventilator lifdef ENABLE_TEST_MODE if (sysMode ==> TEST) { //Just simulate receiving the response, first » TRUE; ctrlState - IMVWAIT; break; } lendif ENABLE_TEST_MODE if (VENTBRD — 1) IbrdBlk - &brdlBlks[VENTCHNL-l] ; else //Assume board 2 IbrdBlk - &brd2Blks[VENTCHNL-l] ; if (first) { //Save time to check for timout systemTime - clock( ) ; first - FALSE; } e l s e i f ( ( cloc O -systemTime ) /CLOCKS_PER_SEOVENT_RSP_TIMEOUT ) { //Just give up. first - TRUE ; ctrlState - VENTTIMEOUT; / /dandy . astound ! //com4BfrIndxfVENTBRD-l ] [VENTCHNL-l ] . sob - com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .bfrlndx; lbrdBlk->curBfrInfo->laBtread - lbrdBlk->curBfrlnfo->bfrlndx; return(VENTMOTIMEOUT) ; } 61 if (lbrdBlk->curBfrInfo->lastread >« 0) { //No wrap-arround //dandy.astound1 //First copy data into channel buffer. //com4board2.getChnlData(VENTBRD,VENTCHNL,bfrsize) ; //dandy.astound1 / / b f r< ( c h a r *)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l] ; bfr - lbrdBlk->curBfrInfo->bfr; //dandy.astoundI //sob - com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob; sob - lbrdBlk->curBfrInfo->lastread; //WAS - dandy.astoundl /* sob - findlnBuffer(bfr,sob,IpszON) ; //Returns negative if //not found. Otherwise, //returns updated sob. */ //Calculate length of string to match, plength - lbrdBlk->curBfrlnfo->bfrlndx - sob; if ( 1ventFindlnBuffer( (const char *)&bfr[sob], plength, ventResponse[MO] [0] , ventResponse[MO] [1] , rvalue) ) { //Check if ventilator did not understand command //or that the value was out of range. //WAS - dandy.astound //sob - findlnBuffer(bfr,βavesob,IpszHUH) ; plength - strlen(IpszHUH) ; if (ventFindlnBuffer( (const char *)&bfr[sob], plength, IpszHUH, NULL, rvalue) ) { //This should never happen during initialization. 62 //There is currently no recovery from this error. //Ventilator will not initialize. //Command not understood; value out of range. //dandy.astoundJ //com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob- sob; lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Fatal Error 1 in systemControl/ONWAIT.\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE FATAL ERROR MSGS lbrdBlk->curBfrInfo->lastread +- plength; return(VALUEOUTOFRANGE) ; > > else {//Found in buffer //Then we have seen the response. lbrdBlk->curBfrInfo->lastread +- plength; / /Send MIMV cmd iff (VENTBRD — 1) com boardl.cmdMIMV{ ) ; elβe //ass-umβ VENTBRD — com4board2.cmdMIMV{ ) ; first - TRUE; ctrlState - IMVWAIT; //WAS - dandy.astoundl /* if (sob >- 0) { //Found string; update sob index to index to the next //area of buffer to be read. //dandy.astound1 63 //com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob sob ; lbrdBlk->curBfrInfo->lastread - sob; //Send MIMV cmd if (VENTBRD == 1) com4boardl.cmdMIMV( ) ; else //ass-u e VENTBRD -= com4board2.cmdMIMV{ ) ; first = TRUE; ctrlState - IMVWAIT; } */ else { //Wrap-around situation //First get partial command string in flush buffer. llastread - lbrdBlk->flushBfrlnfo->lastread; totalsize => savesize = lsize = lbrdBlk->blockSize llastread; if (lsize > sizeof(tempCmd) ) { //We need to increase the βize of our array. lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in systemControl.\n\r" ) ; Btatuslog(statusMsg) ; lendif ENABLE_FATAL_ERROR_MSGS break; } memcpy{ (void *)tempCmd, &(lbrdBlk->flushBfrInfo->bfr[llastread] ) , lsize) ; //Now get rest of command in current buffer, if ((lsize + lbrdBlk->curBfrlnfo->bfrlndx) sizeof(tempCmd) ) { //We need to increase the size of our array, lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in systemControl. \n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_FATAL_ERROR_MSGS break; } 64 llastread = 0; lsize - lbrdBlk->curBfrInfo->bfrIndx; totalsize +- lsize; memcpy( (void *) &tempCmd[savesize] , & (lbrdBlk->curBfrlnfo->bfr[llastread]) ,lsize) ; bfr - tempCmd; //dandy.astound1 //sob = com4BfrIndx[VENTBRD-l] [VENTCHNL-l].sob; sob - 0; //WAS - dandy.astoundl /* sob - findlnBuffer(bfr,sob,IpszON) ; //Returns negative if //not found. Otherwise, //returns updated sob. */ if ( lventFindInBuffer(bfr, totalsize, ventResponsefMO] [0] , ventResponse[MO] [ 1] , rvalue) ) { //Check if ventilator did not understand command //or that the value was out of range. //WAS - dandy.astoundl //sob - findlnBuffer(bfr,savesob,IpszHUH) ; plength - strlen(lpszHUH) ; if (ventFindInBuffer(bfr, plength, IpszHUH, NULL, rvalue) ) { //Command not understood; value out of range. //dandy.astoundI //com4BfrIndx[VENTBRD-l] [VENTCHNL-l] .sob= sob; //Set the flush buffer lastread variable to -1 to indicate //that we are done looking at the buffer. 65 lbrdBlk->flushBfrlnfo->lastread «=■ -1; lbrdBlk->curBfrInfo->lastread - lsize; lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, " Fatal i Error 2 i n systemControl /ONWAIT. \n\r" ) ; statuslog(statusMsg) ; endif ENABLE_FATAL_ERROR_MSGS return(VALUEOUTOFRANGE) ; } } else {//Found in buffer //Then we have seen the response. //Set the flush buffer lastread variable to -1 to //indicate that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread - -1; lbrdBlk->curBfrlnfo->lastread - lsize; //Send MIMV cmd if (VENTBRD — 1) com4board1.cmdMIMV() ; elβe //ass-umβ VENTBRD -' com4board2.cmdMIMV( ) ; first - TRUE; ctrlState - IMVWAIT; stoundl //Found string; update Bob index to index to the next //area of buffer to be read. //dandy.astoundl //com4Bfrlndx[VENTBRD-1][VENTCHNL-l].sob sob; 66 11 Set the flush buffer lastread variable to -1 to indicate //that WΘ are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread - -1; IbrdBlk->curBfrInfo->lastread - lsize; //Send MIMV cmd if (VENTBRD «-» 1) com4boardl.cmdMIMV( ) ; else //ass-ume VENTBRD — 2 com4board2.cmdMIMV( ) ; first - TRUE; ' ctrlState - IMVWAIT; } */ break; case IMVWAIT: lifdef ENABLE_TEST_MODE if (sysMode -= TEST) { first - TRUE; ctrlState - IMVMODE; break; } lendif ENABLE_TEST_MODE if (VENTBRD ==■ 1) IbrdBlk - StbrdlBlks[VENTCHNL-l] ; else //Assume board 2 IbrdBlk - &brd2Blks[VENTCHNL-l] ; if (first) { //Save time to check for timout systemTime =■ clock(); first - FALSE; } e l s e i ( ( clock ( ) -systemTime ) /CL0CKS_PER_SEOVENT_RSP_TIME0UT ) { //Just give up . first - TRUE ; ctrlState - VENTTIMEOUT; / /dandy . stound 1 //com4Bf rlndx [VENTBRD-1 ] [VENTCHNL- l ] . sob = / / com4BfrIndx [VENTBRD-l ] [VENTCHNL-l ] . bfrlndx; lbrdBlk->curBfrInfo->lastread - 67 lbrdBlk->curBfrlnfo->bfrlndx; return(VENTMIMVTIMEOUT) ; } if (lbrdBlk->curBfrInfo->lastrβad >- 0) { //No wrap-arround //dandy.astoundl //First copy data into channel buffer. //com4board2.getChnlData(VENTBRD,VENTCHNL,bfraize); //dandy.astound1 / / b f r ( c h a r *)chnlBfrPtrs[VENTBRD-1] [VENTCHNL-l] ; bfr » lbrdBlk->curBfrInfo->bfr; //dandy. stound1 //sob - com4BfrIndx[VENTBRD-1] [VENTCHNL-l] .sob; sob - lbrdBlk->curBfrInfo->laβtread; //WAS - dandy. stoundl /* sob - findlnBuffer(bfr,sob,IpszIMV) ; //Returns negative if //not found. Otherwise, //returns updated sob. */ //Calculate length of string to match, plength ~ lbrdBlk->curBfrIπfo->bfrIndx - sob; if ( 1 entFindlnBuffer( (const char *)&bfr[sob], plength, ventReβponsefMIMV] [0] , ventResponse[MIMV] [1] , rvalue) ) { //Check if ventilator did not understand command //or that the value was out of range. //WAS - dandy.astound //sob - findlnBuffer(bfr,savesob,IpszHUH) ; plength - strlen(IpszHUH) ; if (ventFindlnBuffer( (const char *)&bfr[sob] , 68 plength, IpszHUH, NULL, rvalue) ) { //This should never happen during initialization, //There is currently no recovery from this error. //Ventilator will not initialize. //Command not understood; value out of range. //dandy.astoundl //com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob= sob; lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, " Fa t a l E rror 1 i n systemControl/IMVWAIT. \n\r " ) ; statuslog(statusMsg) ; lendif ENABLE_FATAL_ERROR_MSGS lbrdBlk->curBfrInfo->lastread +- plength; return(VALUEOUTOFRANGE) ; } } else {//Found in buffer //Then we have seen the response. lbrdBlk->curBfrInfo->lastread +- plength; first - TRUE; ctrlState - IMVMODE; stoundl //dandy. βtoundl //com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob sob; lbrdBlk->curBfrInfo->lastread - sob; 69 first - TRUE; ctrlState - IMVMODE; } } */ else { //Wrap-around situation //First get partial command string in flush buffer. llastread - lbrdBlk->flushBfrlnfo->lastread; totalsize - savesize ■ lsize - lbrdBlk->blockSize - llastread; if (lsize > sizeof(tempCmd) ) { //We need to increase the size of our array. lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in systemControl. \n\r") ; statuslog(βtatUBMsg) ; lendif ENABLE_FATAL_ERROR_MSGS break; } memcpy( (void *)tempCmd, &(lbrdBlk->flushBfrlnfo->bfr[liastread]) , lsize) ; //Now get rest of command in current buffer, if ((lsize + lbrdBlk->curBfrlnfo->bfrlndx) > sizeof(tempCmd) ) { //We need to increase the size of our array, lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, "Array too small in systemControl. \n\r") ; statuslog(statusMsg) ; lendif ENABLE_FATAL_ERROR_MSGS break; > llastread - 0; lsize - lbrdBlk->curBfrInfo->bfrlndx; totalsize +- lsize; memcpy((void *) SrtempCmd[savesize] , & (lbrdBlk->curBfrlnfo->bfr[llastread] ) ,lsize) ; bfr - tempCmd; //dandy.astoundl //sob - com4B rInd [VENTBRD-1] [VENTCHNL-l] .sob; 70 sob = 0; //WAS - dandy.astoundl /* sob - findlnBuffer(bfr,sob,IpszIMV) ; //Returns negative if //not found. Otherwise, //returns updated sob. */ if ( lventFindInBuffer(bfr, totalsize, ventResponse[MIMV] [0] , ventResponse[MIMV] [1] , rvalue) ) { //Check if ventilator did not understand command //or that the value was out of range. //WAS - dandy.astoundl //sob » findlnBuffer(bfr,savesob,IpszHUH) ; plength - strlen(IpszHUH) ; if (ventFindInBuffer(bfr, plength, IpszHUH, NULL, rvalue) ) { //Command not understood; value out of range. //dandy.astoundI //com4Bfrlndx[VENTBRD-1] [VENTCHNL-l] .sob= sob; //Set the flush buffer lastread variable to -1 to indicate //that WΘ are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread - -1; lbrdBlk->curBfrInfo->lastread » lsize; lifdef ENABLE_FATAL_ERROR_MSGS strcpy(statusMsg, " Fat a l Erro r 2 i n systemControl/IMVWAIT . \n\r " ) ; statuslog(statusMsg) ; lendif ENABLE FATAL ' ERROR MSGS 71 return(VALUEOUTOFRANGE) else {//Found in buffer //Then we have seen the response. //Set the flush buffer lastread variable to -1 to //indicate that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread » -1; lbrdBlk->curBfrInfo->lastread - lsize; first - TRUE; ctrlState - IMVMODE; //WAS - dandy.astound /* if (sob >- 0) { //Found string; update sob index to index to the next //area of buffer to be read. //dandy. stound1 //com4BfrIndx[VENTBRD-1][VENTCHNL-1].sob sob; //Set the flush buffer lastread variable to -1 to indicate //that we are done looking at the buffer. lbrdBlk->flushBfrlnfo->lastread - -1; lbrdBlk->curBfrInfo->lastread - lsize; first - TRUE; ctrlState - IMVMODE; break; 72 default: break; //dandy.astound - return error status } //switch state break; case CAPTUREFLOW: //Copies Novametrix flow data into chnl buffers. com4board2.getChnlData(NOVABRD,FLOWCHNL,bfrsize) ; break; case CAPTUREETC02: //Copies Novametrix capnostat data into chnl buffers. com4board2.getChnlData(NOVABRD,ETC02CHNL,bfrsize) ; break; case CAPTURESP02: //Copies Novametrix pulseox data into chnl buffers. com4board2.getChnlData(NOVABRD,SP02CHNL,bfrsize) ; break; case CAPTUREC2B1: //Copies channel 2 of board 1 into chnl bfrs. com4board2.getChnlData(l,2,bfrsize) ; //For testing only break; case CAPTUREC4B2: //Copies channel 4 of board 2 into chnl bfrβ. com4board2.getChnlData(2,4,bfrsize) ; //For testing only break; default: break; //dandy.astound - return error status } //switch event return(O) ; }; /* getPulsox Description : Quick and dirty way of getting 02 saturation, heart rate, and status code from SP02 novametrix board. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time. Negative value indicates error code. */ / / =3 so sα MM MSB nan man nee MM // int FAR PASCAL _export getPulsox(int &avg02, int SavgHR, int &statusCode) { 73 ChnlBlks *lbrdBlks; int lindex, i, savei; unsigned char * usebfr - NULL; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Get PulseOX data...\n\r") ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED //First Bβlect which board the novametrix sensors are on. if ( OVABRD—1) IbrdBlks - SbrdlBlks; else IbrdBlks - &brd2Blks; //Grab current index lindex - (*lbrdBlks+SP02CHNL-l)->curBfrlnfo->bfrIndx; //First check in current buffer working backward. if (lindex >= SP02SDLEN) for (i-lindex-SP02SDLEN; i>-0; i—) if ( (*lbrdBlks+SP02CHNL-l)->curBfrInfo->bfr[i) == OxFE) { u s e b f r - (*lbrdBlks+SP02CHNL-l)->curBf lnfo->bfr; savei - i; break; } //Check flush buffer if not found in current buffer, i f ( ( u s e b f r - - N U L L ) & & ( (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->bfr 1- NULL) && ( (*lbrdBlks+SP02CHNL-l)->blockSize >- SP02SDLEN) ) for (i = ( (*lbrdBlks+SP02CHNL-l)->blockSize)-SP02SDLEN; i >- 0; i—) if ((*lbrdBlks+SP02CHNL-l)->flushBfrInfo->bfr[i] « OxFE) { u s e b f r = (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->bfr; savei - i; break; } if (usebfr 1- NULL) { lavg02 - *(usebfr + savei + 2); lavgHR = *(usebfr + savei + 4); IstatusCode - *(usebfr + savei + 6); avg02 = lavg02; avgHR - lavgHR; StatusCode - IstatusCode; return( 1) ; 74 } el s e { avg02 - 0 ; avgHR - 0 ; StatusCode - 0; return ( -l ) ; /* This is the old way VVVVV Π/VVVVVVVVVVVVVVVVVVV^ wwv const int chnl3 - 3; const int board2 - 2; int sob,eob; ChnlBfr * cbufr; int i; Boolean found; //First, capture data into local buffer. systemControl(CAPTURESP02,0) ; //Copies board bfr data into chnl bfr cbufr = getrs232(board2, chnl3, sob, eob); //Sets our local pointer to //channel buffer. //Start at eob and look backwards for Oxfe (start of special data) . //At this point in the game, not going to worry about going past //start of buffer pointer. Eventually, we just need to make sure //we processing this data to avoid over-wrap of data. if (sob 1- eob) { //This check to see if we have any data. //Of course, there is a possibility that we have //a perfectly full buffer of data, but this should //never be the case if we keep up with the data flow. i - eob; found - FALSE; while ((.found) && (i >- 0)) 75 if ((*cbufr)[i] — OXFE) found - TRUE; else i~; if (liound) { //Try starting at the absolute end of the buffer to the //eob pointer, i - CHNLBFRSIZE-1; while ((lfound) && (i > eob)) if ((*cbufr)[i] — OXFE) found - TRUE; else . ' lf (lfound) { //Then we have a real problem. Return a negative status //code to indicate that no start of data was found. Set //all return paramters to zero while we are at it. avg02 - avgHR - StatusCode - 0; return(-1); } } //If we have gotten this far, i points to the start of the data block. //Grab the data and run. avg02 - (*cbufr) [ (i+2)%CHNLBFRSIZE] ; avgHR - (*cbufr) [ (i+4)%CHNLBFRSIZE] ; StatusCode - (*cbufr) [ (i+6) %CHNLBFRSIZE] ; return(O) ; } else { //Most likely, no data present. avg02 - avgHR - StatusCode - 0; return ( -1 ) ; } * / /* getPulsoxWF Description : Returns pulse oximeter waveform value. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time, Negative value indicates error code. */ 76 -518- // int FAR PASCAL _export getPulβoxWF(int &o2satWF) . { ChnlBlkβ *lbrdBlks; int lbfrSize; int lpacketSize; int lindex, i, savei, counter, retval; unsigned char * usebfr - NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; lifdef STATUS_LOG__ENABLED strcpy(statusMsg, "Get Pulsox WF...\n\r"); Btatuslog(statusMsg) ; lendif STATUS_LOG_ENABLED lifdef ENABLE_TEST_MODE if (sysMode « TEST) { o2satWF - 0; return(99) ; } lendif ENABLE TEST MODE pulseoxWF - 0; retval - -1; //First select which board the novametrix sensors are on. if (NOVABRD==l) { IbrdBlks » ϋbrdlBlks; lbfrSize - blchnlblksize[SP02CHNL-l] ; } else { IbrdBlks - &brd2Blks; lbfrSize - b2chnlblksize[SP02CHNL-l] ; > //Grab current index lindex - (*lbrdBlks+SP02CHNL-l)->curBfrInfo->bfrlndx; //Since we need to know if we are looking at special data opposed //to actual waveform, we must be at least 7 bytes from start of //buffer to be able to look backward for start byte. i - lindex; Boolean found - FALSE; while ((i >- SP02SPECDATALNGTH) && (lfound)) { //Start searching backwards for absence of start byte. //Start byte can not be 2, 4, or 6 bytes in front of //current index. If it is, then we are really looking 77 - 5 1 9- //at interleaved special data. if {( ( (*lbrdBlks+SP02CHNL-l)->curBfrInfo->bfr[i)) 1- Oxfe) & & ( ((*lbrdBlks+SP02CHNL-l)->curBfrInfo->bfr[i-2]) J- Oxfe) & S. ( ( (*lbrdBlks+SP02CHNL-l)->curBfrInfo->bfr[i-4]) 1- Oxfe) & £> (((*lbrdBlks+SP02CHNL-l)->curBfrInfo->bfr[i-6)) 1- Oxfe)) { //Then we are looking at waveform data. found - TRUE; pulseoxWF - (*lbrdBlks+SP02CHNL-l)->curBfrlnfo->bfr[i]? retval β 1; break; } i—; } //Now try flush buffer if needed. if (lfound) { i - (*lbrdBlks+SP02CHNL-l)->blockSize-l; while ((i >- SP02SPECDATALNGTH) && (lfound)) { if ( ( ( (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->bfr[i]) 1= Oxfe) &-. ( ( (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->bfr[i-2) ) 1 ' Oxfe) &S ( ( (*lbrdBlks+SP02CHNL-l)->flushBfrInfo->bfr[i-4] ) 1= OOxxffee)) &&&& ( ( (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->bfr[i-6]) 1= Oxfe)) { //Then WΘ are looking at waveform data, found - TRUE; p u l s e o x W (*lbrdBlks+SP02CHNL-l)->fluahBfrInfo->bfr[i]; retval - 1; break; } i—; } } o2satWF - pulseoxWF * 0.5; return(retval) ; } / / øvα»«V r Hβs-BaκκM M :«- B V -Ha-im-K-HM-*jM f * getPulsoxWFs Description : Returns array of pulse oxi βter waveform values, 78 Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time. Negative value indicates error code. */ //=====» // int FAR PASCAL _export getPulsoxWFs(int * &o2satWFs, int &size) { ChnlBlks *lbrdBlks; unsigned char * lcurBfr; unsigned char * lflushBfr; int lbfrSize; int llastreadc, llastreadf; int lpacketSize; int lindex, i, βavei, counter, retval; unsigned char * usebfr α NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; lifdef STATUS_LOG_ENABLED strcpy(statusMβg,"Get Pulsox WFs...\n\r") ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED lifdef ENABLE_TEST_MODE if (sysMode — TEST) { o2satWFs - NULL; return(O) ; } lendif ENABLE_TEST_MODE retval = 1; //First select which board the novametrix sensors are on. // if (NOVABRD—1) { IbrdBlks - ϋbrdlBlks; lbfrSize - blchnlblksize[SP02CHNL-l] ; } else { IbrdBlks - &brd2Blks; lbfrSize - b2chnlblksize[SP02CHNL-l]; } //Need to get local copies of pointers to hopefully avoid //having the ISR change a pointer on us in mid- stream. //It may be too late even now, but this is the best we //can do for now. lcurBfr = (*lbrdBlks+SP02CHNL-l)->curBfrInfo->bfr; lflushBfr - (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->bfr; 79 //Grab the laβt read index. llastreadc-(*lbrdBlkβ+SP02CHNL-l)->curBfrlnfo->lastread; llastre df-{*lbrdBlka+SP02CHNL-l)-> flushBfrlnfo->laβtread; // //Grab current index //lindex - (*lbrdBlks+SP02CHNL-l)->bfrlndx; lindex - (*lbrdBlks+SP02CHNL-l)->curBfrlnfo->bfrlndx; i - llastreadc; size - 0; if (llastreadc — Oxff) { //Must go back to flush buffer first for (i - llastreadf; i < lbfrSize; i++) if (seenFEcount — 0) if (lflushBfr[i] 1- Oxfe) if (size < SP02WFDATAMAX) pulseoxWFβ[size++] - lflushBfr[i] ; else { //LOBS of data will occur - major problem, retval - -1; lifdef ENABLE_DATA_LOSS_MSGS strcpy(βtatuBMsg, "Sp02 Data Loss\n\r") ; statuslog(statusMsg) ; lendif ENABLE_DATA_LOSS_MSGS break; } else {//Start of special data. seenFEcount - SP02SPECDATALNGTH-1; seenFEtogglβ — TRUE; //Do not take this value; take next. } else {// if (seenFEtoggle) //Take this value if (size < SP02WFDATAMAX) pulseoxWFs[size++) - IflushBfr[i) ; else { //Loss of data will occur - major problem. retval - -1; lifdef ENABLE_DATA_LOSS_MSGS strcpy(statusMsg, "Sp02 Data Loss\n\r"); statuslog(statusMsg) ; lendif ENABLE_DATA__LOSS_MSGS break; } //Decrement count and toggle flag seenFEtoggle - 1seenFEtoggle; seenFEcount—; } WAS //Now set lastread in flush buffer to negative value to indicate //we have looked at all the data. (*lbrdBlks+SP02CHNL-l)-> 80 flushBfrInfo->bfr[ (*lbrdBlks+SP02CHNL-l)->blockSize] -= -l; */ (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->lastread - -1; } //Now look at current buffer for data up to lindex. for (i = 0; i < lindex; i++) if (seenFEcount — 0) if (lcurBfr[i] 1- Oxfe) if (size < SP02WFDATAMAX) pulBeoxWFs[size++] - lcurBfr[i]; else { //Loss of data will occur - major problem, retval - -1; lifdef ENABLE_DATA_LOSS_MSGS strcpy(statusMsg, "Sp02 Data Loss\n\r"); statuslog(statusMsg) ; lendif ENABLE_DATA_LOSS_MSGS break; > else {//Start of special data. seenFEcount - SP02SPECDATALNGTH-1; seenFEtoggle - TRUE; //Do not take this value; take next. } else {// if (seenFEtoggle) //Take this value if (size < SP02WFDATAMAX) pulβeoxWFβ[size++] - lcurBfr[i); else { //Loss of data will occur - major problem. retval - -1; lifdef ENABLE_DATA_LOSS_MSGS strcpy(statusMsg, "Sp02 Data Loss\n\r"); statuslog(statuBMsg) ; lendif ENABLE_DATA_LOSS_MSGS break; } //Decrement count and toggle flag seenFEtoggle - 1seenFEtoggle; seenFEcount—; } (*lbrdBlks+SP02CHNL-l)->curBfrInfo->lastread - lindex; o2satWFs - pulseoxWFs; return(retval) ; //»«: — .....--.—........ /* getAHPulsox 81 Description : Returns array of pulse oximeter waveform values as well as special data. This function returns the three special data values (heart rate, oxygen saturation, and front end statue code) , an array of Sp02 waveform, the size of the array, and the starting index. Returns : Non-negative indicates normal βtatus code. 0 - indicates no data available at this time, Negative value indicates error code. * / ti¬ ll int FAR PASCAL _export gβtAllPulsox(int *S,o2Data, int * io2satWFs, int isize, int &start) { ChnlBlks *lbrdBlkβ; unsigned char * lcurBfr; unsigned char * lflushBfr; int lbfrSize; int llastreadc, llastreadf; int lpacketSize; int lindex, i, savei, counter, retval; unsigned char * usebfr - NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Get Pulsox WFs...\n\r" ) ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED lifdef ENABLE_TEST_MODE if (sysMode — TEST) { for (i-0; i<SP02SPECDATAMAX; pulseoxSpecData[i++] - i); o2Data - pulseoxSpecData; for (i-0; i<SP02WFDATAMAX; pulseoxWFs[i++) - i); o2satWFs - pulseoxWFs; size - SP02WFDATAMAX; start - 0; return(99) ; } lendif ENABLE TEST MODE retval - 1; //First select which board the novametrix sensors are on. 82 // if (NOVABRD—1) { IbrdBlks - SbrdlBlks; lbfrSize - blchnlblksize[SP02CHNL-l] ; brdBlkβ - _.brd2Blkβ; lbfrSize - b2chnlblkβize[SP02CHNL-l] ; > //Need to get local copiββ of pointer* to hopefully avoid //having the ISR change a pointer on us in mld-βtrβam. t It may be too late even no*, but thiβ iβ the best we //can do for now. lcurBfr - (*lbrdBlks+SP02CHNL-l)->curBfrInfo->bfr; lflushBfr - (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->bfr; //Grab the last read index. /*WAS llastreadc - (*lbrdBlks+SP02CHNL-l)-> curBfrlnfo->bfr[ (*lbrdBlks+SP02CHNL-l)->blockSize] ; llastreadf - (*lbrdBlks+SP02CHNL-l)-> flushBfrInfo->bfr[ (*lbrdBlks+SP02CHNL-l)->blockSize] ; */ llastreadc = (*lbrdBlks+SP02CHNL-l) ->curBfrlnfo->lastread; llastreadf - (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->lastread; // //Grab current index //lindex - (*lbrdBlks+SP02CRNL-l)->bfrlndx; lindex - (*lbrdBlks+SP02CHNL-l)->curBfrlnfo->bfrlndx; i - llastreadc; size = 0; if (llastreadc — -1) { //Must go back to flush buffer first llastreadc - 0; //This prepares us to read current buffer after flush. for (i - llastreadf; i < lbfrSize; i++) if (seenFEcount — 0) if (lflushBfrfiJ 1- 0xfe){ if (size >- SP02WFDATAMAX) {//Loss of data will occur - not good. lifdef ENABLE_DATA_LOSS_MSGS if (retval »= » 1) { strcpy(statusMsg, "Sp02 Data Loss\n\r"); statuslog(BtatusMsg) ; } lendif ENABLE_DATA_LOSS_MSGS retval - -1; 83 //Wrap data around to beginning of buffer. size - 0; pulβeoxWF«[βizβ++] - lflu»hBfr[i); pulββoxWFβ[βizβ++] - lfluβhBfr[i]; ) el-βe -(//Start of special data. βeenFEσσαπt » S r PO2SFECDATMiWG B ; -'I seenFEtoggle - TRUE; //Do not take this value; take next. eenFEtoggle) { //Waveform value (size >- SP02WFDATAMAX) {//Lose of data will occur. lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg,"Sp02 Data Loss\n\r"); statuslog(statusMsg) ; } lendif ENABLE_DATA_LOSS_MSGS retval « -1; //Wrap data around to beginning of buffer. size - 0; } pulseoxWFs[size++] - lflushBfr[i] ; } else //Special data value //Save special data. pulseoxSpecData[ (5-seenFEcount)/2] — lflushBf [i) ; //Decrement count and toggle flag seenFEtoggle - 1seenFEtoggle; seenFEcount—; } //Now set lastread in flush buffer to negative value to indicate //we have looked at all the data. /*WAS ( *lbrdBlks+SP02CHNL-l ) -> f lushBf rlnf o->bfr[ ( *lbrdBlks+SP02CHNL- l ) ->blockSize ] -0xf f ; */ (*lbrdBlks+SP02CHNL-l)->flushBfrlnfo->lastread - -1; } //Now look at current buffer for data up to lindex. for (i = llastreadc; i < lindex; i++) if (seenFEcount — 0) if (lcurBfr[i] 1- Oxfe) { if (size >- SP02WFDATAMAX) { //Loss of data will occur, lifdef ENABLE_DATA_LOSS_MSGS 84 if (retval — 0) { strcpy(statusMsg, "Sp02 Data Loss\n\r"); Btatuslog(BtatUBMsg) ; } lendif ENABLE_DATA_LOSS_MSGS retval - -1; //Wrap data around to beginning of buffer, size - 0; } pulseoxWFs[size++] - lcurBfr[i]; } else {//Start of special data. seenFEcount - SP02SPECDATALNGTH-1; seenFEtoggle ■ TRUE; //Do not take this value; take next, } else {// if (seenFEtoggle) { //Take this value if (size >« SP02WFDATAMAX) { //Loss of data will occur. lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg, "Sp02 Data Loss\n\r"); statuslog(statusMsg) ; } lendif ENABLE_DATA_LOSS_MSGS retval - -1; //Wrap data around to beginning of buffer. size - 0; } pulseoxWFs[size++] - lcurBfr[i]; } else //Save special data. pulseoxSpecData[ (5-seenFEcount) /2] - lcurBfr[i]; //Decrement count and toggle flag seenFEtoggle - 1 seenFEtoggle; seenFEcount—; } //Update last read index. WAS (*lbrdBlks+SP02CHNL-l)-> curBfrInfo->bfr[ (*lbrdBlkB+SP02CHNL-l)->blockSize] - lindex? */ (*lbrdBlks+SP02CHNL-l)->curBfrInfo->lastread - lindex; if (retval 1- 1) { //Variable size could possibly be equal to SP02WFDATAMAX if we happen 85 //to stop at the end of our waveform array before wrapping around. //Therefore, it is necessary to perform a mod to reset size to 0 //if this is the case. /*This works (3) size %- SP02WFDATAMAX; start - size; size - SP02WFDATAMAX; */ start - size%SP02WFDATAMAX; size - SP02WFDATAMAX; } else start = 0; o2Data = pulseoxSpecData; o2satWFs - pulseoxWFs; return(retval) ; } / /s= =s=:==-3=-:--=---3S-t-=ιza(^-t-=a= /* getEtC02swrev Description : Returns the software revision of the capnostat board. ASSUME NO CONTINUOUS COMMAND IS CURRENTLY ACTIVE. We will perform an internal reset for the EtC02 channel which will reset pointer and counters to an i !nitial state. Returns : Non-negative indicates normal status code. Negative value indicates error code. 7 // int FAR PASCAL _export getEtC02swrev(unsigned char far * &swrev, i n Slength) { clock_t timel; ChnlBlks *lbrdBlks; int retval; //Old way... 86 //int funcRet - com4board2.cmdC02swrev( ) ; //New way... int funcRet = com4board2.cmdC02 (C02swrev, .C02SWREVLNGTH) ; , //Expect a response with a 35 byte packet with command byte //and checksum byte. Total - 37. //First select which board the novametrix sensors are on. if (N0VABRD==1) { IbrdBlks = ϋbrdlBlks; } else { IbrdBlks - &brd2Blks; } Boolean ready = TRUE; timel - clock(); //Only wait around for a while. //This works, but let's use a little easier syntax. //while ((((* (IbrdBlks) [ETC02CHNL-1] ) .bfrlndx) < SWREVLENGTH) && // ( (clock()-timel)/CLOCKS_PER_SEC<=l ? TRUE : (ready=FALSE) ) ) ; //dandy.astound //This is a little tricky. Variable laβtread used to be initialized //to 0, but now lastread has been replaced by lastreadc (current buffer) //and lastreadf (flush buffer). Variable lastread was used here //to have a way of handling multiple non-continous commands without //reseting buffer pointers. Now since I have replaced lastread with //two other variables which are really used to keep track of the //last waveform data we have captured, we need to check if 'lastreadc //is -1 and set it to 0 if it is. This will enable this code to //work as before. /* if ( ( (*lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr[ (*lbrdBlks+SP02CHNL-l)->blockSize] )—1) (*lbrdBlks+ETC02CENL-l)-> curBfrInfo->bfr[ (*lbrdBlks+SP02CHNL-l)->blockSize) - 0; */ //First perform an internal reset. This assumes we don't care 87 //what data is in the capnostat buffers and that no continous command is //running, if (NOVABRD — 1) com4boardl.intrnlReset(NOVABRD,ETC02CHNL) ; else //Assume board 2 com4board2.intrnlReset(N0VABRD,ETC02CHNL); / ♦ This used to use lastread to enable multiple commands without intrnl reset. while ( ( ( ( (*lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx) - ( (*lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr[ (*lbrdBlks+SP02CHNL-l)->blockSize] ) ) < C02SWREVrespLNGTH) && ( (clock() -timel)/CLOCKS_PER_SEC<=l ? TRUE : (ready=FALSE) ) ) ; */ while ((({*lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx) < C02SWREVrespLNGTH)&& ((clockO-timel)/CLOCKS_PER_SEC<=l ? TRUE : (ready=FALSE) ) ) ; if (ready) //Validate the s/w revision packet. /*WAS if (validChksm( (const char *) (& (*lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ (*lbrdBlks+ETC02CHNL-l )-> curBfrInfo->bfr[ {*lbrdBlks+SP02CHNL-l)->blockSize] ] ) , C02SWREVrespLNGTH) ) { */ i f ( v a l i d C h k s m ( ( c o n s t c h a r * ) ( *lbrdBlks+ETC02CHNL-l ) ->curBf rlnf o->bf r, C02SWREVrespLNGTH) ) { //Copy the revision string to global area /*WAS memcpy(co2swrevresp,& ( ( *lbrdBlks+ETC02CHNL-1)-> curBfrInfo->bfr[ ( (*lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr[ (*lbrdBlks+SP02CHNL-l)->blockSize] )+l] ) , C02SWREVrespLNGTH-2) ; */ memcpy(co2swrevresp,&( (*lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[1] ) , C02SWREVrespLNGTH-2) ; retval = 1; } else < memcpy(co2swrevresp, "Invalid checksum detected ", C02SWREVrespLNGTH-2) ; 88 retval - -1; } else { //Timed out. memcpy(co2swrevresp, "Timeout waiting for response ", C02SWREVreBpLNGTH-2) ; retval - -1; } / ♦ WAS (*lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfr[ (*lbrdBlks+SP02CHNL-l)-> blockSize] - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; */ (*lbrdBlks+ETC02CHNL-l)->curBfrlnfo->lastread - (*lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; / ♦ Not sure if we need this now. //Note : This really does assume that we are not currently streaming data. if ( ( ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSize] )—0) (♦lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSize] - -1; ♦ / length = C02SWREVrespLNGTH-2; swrev = co2swrevresp; return(retval) ; } / /====aac=====3-3ai-iB=38Z-iar3nι.on--W —=r==— 3 =a-=α=r=—assess / ♦ getEtC02selfTest apnostat self-test. COMMAND IS CURRENTLY ACTIVE. THE CHANNEL BLOCK COMPONENTS ormal status code. error code. 89 / / int FAR PASCAL _export getEtC02self est(int..-.status) { clock_t timel; ChnlBlks ♦ IbrdBlks; int retval; //First perform an internal reset. This assumes we don't care //what data is in the capnostat buffers. if (NOVABRD — 1) com4boardl.intrnlReset(NOVABRD,ETC02CHNL) ; else //Assume board 2 com4board2.intrnlReset(NOVABRD,ETC02CHNL) ; //Old way... //int funcRet - com4board2.cmdC02swrev( ) ; //New way... int funcRet - com4board2.cmdC02(C02test, C02TESTLNGTH) ; //Expect a 3 byte response. //First select which board the novametrix sensors are on. if (NOVABRD—1) { IbrdBlks = SbrdlBlks; } else { IbrdBlks = &brd2Blks; } Boolean ready ■= TRUE; timel - clock( ) ; //Only wait around for a while. //This works, but let's use a little easier syntax. //while (((( ♦ (IbrdBlks) [ETC02CHNL-1] ) .bfrlndx) < SWREVLENGTH) && // ((clockO-timel)/CL0CKS_PER_SEC<»1 ? TRUE : (ready-FALSE))); / ♦ Not sure if we still ' need this, if ( ( ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr [ ( ♦ lbrdBlks+SP02CHNL-l ) ->blockSize ] ) — 1 ) ( ♦ lbrdBlks+ETC02CHNL-l ) -> curBfrInfo->bfr[ ( + lbrdBlks+SP02CHNL-l ) ->blockSize ] = 0 ; 90 */ / ♦ WAS while ( ( ( ( { ♦ lbrdBlks+ETC02CHNL-l )->curBfrlnfo->bfrlndx) - ( (♦lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlka+SP02CHNL-l)->blockSize] ) ) < C02TESTrespLNGTH) && ( (clock() -timel)/CLOCKS_PER_SEC<-l ? TRUE : (ready-FALSE))); */ while ((( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfrlndx) < C02TESTrespLNGTH) && ( (clock -ti el)/CLOCKS_PER_SEC<-l ? TRUE : (ready=-FALSE) ) ) ; if (ready) //Validate the β/w revision packet. / ♦ WAS if (validChksm( (const char ♦ ) (& ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSize] ] ) , C02TESTrespLNGTH) ) { ♦ / if (validChksm( (const char ♦ ) ( ♦ lbrdBlks+ETC02CHNL-l) -> curBfrlnfo->bfr, C02TESTrespLNGTH) ) { //Return second byte in response (self-test status byte) / ♦ WAS status - (♦lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ (*lbrdBlks+SP02CHNL-l)->blockSize] )+1] ; ♦ / status - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[l] ; retval « 1; } else { //Invalid checksum. status - 99; retval - -1; } else { //Timed out. status - 99; retval = -2; } //Update lastread index. / ♦ WAS 91 (♦lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfr[ (♦lbrdBlks+SP02CHNL-l)-> blockSize] - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; ♦ / ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->laβtrβad - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; / ♦ Now sure if we need this now since we reset counters/pointers upon entry. //Note : This really does asβume that we are not currently streaming data. if ( ( ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSize] )==0) ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr[ ( ♦lbrdBlks+SP02CHNL-l ) ->blockSize ]= -1 ; ♦ / return ( retval ) i/n/t FAR PASCAL _export startEtC02( ) { //This is the old way... //com4board2.cmdC02cont( ) ; lifdef ENABLE_STATUS_LOG_IN_START WF strcpy(statusMsg, "Starting EtC02 n\r" ) ; statuslog(statusMsg) ; #endif ENABLE_STATUS_LOG_IN_START_WF 92 //Now let's try the new way. com4board2.cmdC02 (C02cont,C02C0NTLNGTH) ; return(0) ; >; Btop continuous code. // int FAR PASCAL _export stopEtC02( ) { //This is the old way... //com4board2.cmdC02cont( ) ; lifdef ENABLE_STATUS_LOG_IN_STOP_WF strcpy(statusMsg, "Stopping EtC02.\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_STATUS_LOG_IN_STOP_WF //Now let's try the new way. return(com4board2.cmdC02(C02stop,C02ST0PLNGTH) ) ; }; / ♦ getCapnostat Description : Quick and dirty way of getting end tidal C02 and respiration rate from capnostat board. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time. Negative value indicates error code. / // 93 int FAR PASCAL _export getCapnostat(int far ♦ ϋcapnoParams, int Seize) { ChnlBlks ♦ IbrdBlks; int lbfrSize; int lpacketSize; int lindex, i, savei, counter; unsigned char ♦ usebfr - NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Get Capno data...\n\r" ) ; statuslog(statusMsg) ; endif STATUS_LOG_ENABLED lifdef ENABLE_TEST_MODE if (sysMode =- TEST) { for (i=0; i < C02DATACOUNT; capnoData[i] => i++); capnoParams - capnoData; size - C02DATAC0UNT; return(99) ; } lendif ENABLE TEST MODE //First select which board the novametrix sensors are on. if (NOVABRD=-l) { IbrdBlks - ..brdlBlks; lbfrSize = blchnlblksize[ETC02CHNL-l] ; > else { IbrdBlks - &brd2Blks; lbfrSize = b2chnlblksize[ETC02CHNL-l] ; } //Grab current index lindex - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; //Start searching in current buffer for all parameters associated with //the command bytes in the CO2DATAP0S array. for (i«0; i<C02DATAC0UNT; capnoData[i++] - -1) int paramCount » 0; i = lindex; while ((paramCount < C02DATAC00NT) && (i >=» 0)) { //Start searching backwards for command bytes. for (int k » 0; k < C02DATAC0UNT; k++) if ( ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[i] ) C02DATAP0S[k] ) //Found command byte. 94 //Do we have room to look at the entire packet. //WASi //if ((i+C02DATAOFFSET[k)+2) < lbfrSize) if ( (i+C02PACKBTSIZB[k]-l) < lbfrSize) //We can look at packet. if (validChkβm( ( c o n s t c h a r ♦ ) (& ( ♦ lbrdBlkβ+ETC02CHNL-l)->curBfrlnfo->bfr[i] ) , C02PACKETSIZE[k])) //We have a valid packet. //Extract data. if (capnoData! ) < 0) { //Thi β iβ the firβt time we've seen this parameter. if (C02DATALBNGTB[k] — 2) //Two byte value capnoDat [k] - ( ( ♦ lbrdBlka+ETC02CHNL-l)-> curBfrInfo->bfr[i+C02DATAOFTSET[k]])«8 | ( ♦ lbrdBlkβ+ETC02CHNL-l)-> curBfrlnfo->bfr[i+C02DATA0FFSET[k)+l] ; elβe //ASSUME a 1 byte value capnoData[ ) - ( ♦ lbrdBlkβ+ETC02CBNL-l)-> curBfrInfo->bfr[i+C02DATA0FFSET[k]]; ++paramCount; break; > i—; } //Now try fluβh buffer if needed. i - ( ♦ lbrdBlkβ+ETC02CHNL-l)->blockSize-l; while ((paramCount < C02DATACOUNT) if, (i >- 0) ) { //Start βearching backwardβ for command byteβ. for (int k - 0; k < C02DATAC0UNT; k++) if (((*lbrdBlk β +ETC02CHNL-l)->fluβhBfrlnfo->bfr[i]) — C02DATAP0S[k]) //Found command byte. //Do we have room to look at the entire packet. //WAS. //if ((i+C02DATAOFFSET[k]+2) < lbfrSize) if ( (i+C02PACKETSIZE[k)-l) < lbfrSize) //We can look at packet, if (validChkβm( ( σ o n β t c h a r ♦ ) ( -. ( ♦ lbrdBlkβ+ETC02CHNL-l ) ->f luβhBf rlnf o->bfr [ i ] ) , C02PAC ETSIZE[k] ) ) //We have a valid packet. //Extract data. if (capnoDatafk] < 0) { 95 //Thiβ is the first time we've seen this parameter. capnoData[k] - ( ( ♦ lbrdBlks+ETCθ2CHNL-l)-> 5 flushBfrlnfo->bfr[i+C02DATAOFFSET[k] ] )«8 | ( ♦ lbrdBlks+ETC02CHNL-l)-> flushBfrlnfo->bfr[i+C02DATA0FFSET[k)+l] ; ++paramCount; break; 10 > i~; } size - C02DATAC0UNT; capnoParams - capnoData; return(paramCount) ; 15 20 / ■■ ■■ ■* am w «■■■ ■■■■ ■■!-■ as WΛ m*wm^ wmΛ^WΛm*wκwmu w*wmwmwκwawΛmιxMXB ^πκΕ*wmαmmwκwκw*wmmκ*M wiWΛWκwmxExxxn x x=≠x Z 25 D i f n / t FAR PASCAL _export getCapnoESB(int &ESB1, int &ESB2, int &ESB3 { ChnlBlks ♦ IbrdBlks; int lbfrSize; int lpacketSize; int lindex, i, savei, counter; 30 unsigned char ♦ usebfr » NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Get Capno ESB... \n\r") ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED 5 lifdef ENABLE_TEST_MODE if (sysMode — TEST) { 96 ESB1 - ESB2 - ESB3 - 0; return(99) ; > lendif ENABLE_TEST_MODE //First select which board the novametrix sensors are on. if (NOVABRD—1) { IbrdBlks - SbrdlBlks; lbfrSize - blchnlblksize[ETC02CHNL-l]; } else { IbrdBlks - &brd2Blks; lbfrSize - b2chnlblksize[ETC02CHNL-l] ; } //Grab current index lindex - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; //Start searching in current buffer for 0x84 command word. i - lindex; Boolean found - FALSE; while ((i >- 0) && (lfound)) { //Start searching backwards for command byte. if ( ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[i]) — 0x84) //Found command byte. //Do we have room to look at the entire packet, if ( (i+C02X84PSIZE-l) < lbfrSize) //We can look at packet, if (validChksm( ( c o n s t c h a r *) (-.( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[i] ) , C02X84PSIZE) ) { //We have a valid packet. //Extract data. for (int k - 0; k < 3; k++) capnoESB[k] - ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[i+C02ESB0FFSET+k] ; found - TRUE; break; } i~; //Now try flush buffer if needed, if (lfound) { i - ( ♦ lbrdBlks+ETC02CHNL-l)->blockSize-l; while ((i >« 0) && (lfound)) { //Start searching backwards for command byte. if (( ( ♦ lbrdBlks+ETC02CHNL-l)->flushBfrInfo->bfr[i]) x84) 97 //Found command byte. //Do we hevβ r o to look at the entire packet, if ( (1+C02X84PSIZE-1) < lbfrSize) //We can look at packet, if (validChksm( ( c o n s t c h a r ♦ ) (&(^lbrdBlks+ETC02CHNL-l)->flushBfrInfo->bfr[i]) , C02X84PSIZE) ) { //We have a valid packet. //Extract data, for (int k » 0; k < 3; k++) capnoESBfk] - ( ♦ lbrdBlks+ETC02CHNL-l)-> flushBfrlnfo->bfr[i+C02ESBOFFSET+k] ; found - TRUE; break; } i~; } } if (found) { ESB1 = capnoESB[0]; ESB2 - capnoESBfl]; ESB3 = capnoESB[2]; return(1) ; } else { ESB1 = ESB2 - ESB3 - -1; return(-l) ; } } / / === ax=SrC===3==s=-SS=3-BS-!=-:=a-3-=-r--S-Bfl-t3Z3csxs-^ // int FAR PASCAL _export getCapnoWFssb(int Swaveform, int &ssb) { ChnlBlks ♦IbrdBlks; int lbfrSize; int lpacketSize; 98 int lindex, i, savei, counter; unsigned char ♦ usebfr - NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; lifdef STATUS_LOG_ENABLED strcpy(statusMβg, "Get Capno WF/SSB...\n\r" ) ; statUBlog(statusMsg) ; lendif STATUS_LOG_ENABLED lifdef ENABLE_TEΞT_MODE if (sysMode == TEST) { return(99) ; } lendif ENABLE_TEST_MODE //First select which board the novametrix sensors are on. if (N0VABRD==1) { IbrdBlks - ϋbrdlBlks; lbfrSize = blchnlblksize[ETC02CHNL-l] ; } else { ; IbrdBlks = &brd2Blks; lbfrSize = b2chnlblksize[ETC02CHNL-l] ; } //Grab current index lindex » ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; //Start searching in current buffer for a command byte. i = lindex; Boolean found = FALSE; while ((i >« 0) && (lfound)) { //Start searching backwards for command byte, if ( ( ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[i])-i0x80) 1= x00){ //Found command byte. //Do we have room to look at the entire packet, switch ( ( ♦ lbrdBlks+ETC02CHNL-l)->curB rInfo->bfr[i]) { case 0x80 : lpacketSize - CO2X80PSIZE; break; case 0x81 : lpacketSize - C02X81PSIZE; break; case 0x82 : lpacketSize - C02X82PSIZE; break; case 0x83 : lpacketSize - C02X83PSIZE; break; case 0x84 : lpacketSize - C02X84PSIZE; break; default : lpacketSize « lbfrSize; //Force not to look t packet. } if ( (i+lpacketSize-1) < lbfrSize) //We can look at packet. if (validChksm( 99 ( c o n s t c h a r ♦ ) (&(^lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[i]) , lpacketSize) ) { //We have a valid packet. //Extract data. capnoWF - ( ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr[i+l] )«8 | ( ♦ lbrdBlks+ETC02CHNL-1)-> curBfrInfo->bfr[i+2] ; capnoSSB - ( ♦ lbrdBlks+ETC02CHNL-1 ) -> curBfrlnfo->bfr[i+3]; : found - TRUE; break; } } i—; } //Now try flush buffer if needed. if (lfound) { i = ( ♦ lbrdBlks+ETC02CHNL-l)->blockSize-l; while ((i >= 0) && (lfound)) { //Start searching backwards for command byte. if ( ( ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[i] )&0x80) 1= 0x00) { //Found command byte. //Do we have room to look at the entire packet, switch ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[i]) { lpacketSize - CO2X80PSIZE; break; lpacketSize - C02X81PSIZE; break; lpacketSize = C02X82PSIZE; break; lpacketSize - C02X83PSIZE; break; lpacketSize =■ C02X84PSIZE; break; lpacketSize = lbfrSize; //Force not to < lbfrSize) //We can look at packet, if (validChksm( ( c o n s t c h a r *) (& (*lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfr[i] ) , lpacketSize) ) { //We have a valid packet. //Extract data. capnoWF - ( ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr[i+l])«8 | ( ♦ lbrdBlks+ETC02CHNL-1)-> curBfrInfo->bfr[i+2] ; capnoSSB - ( ♦ lbrdBlks+ETC02CHNL-l ) -> curBfrInfo->bfr[i+3] ; found = TRUE; break; 100 } } } if (found) { waveform - capnoWF; ssb «= capnoSSB; return(1) ; } else { waveform - ssb - 0; return(-1) ; } //—==. capnoAdptrO Description : Sends Start Adapter Zero to capnostat board. Returns : Non-negative indicates normal ' status code. 0 - indicates no data available at this time. Negative value indicates error code. // int FAR PASCAL _export capnoAdptrO(int &csb) { clock__t timel; ChnlBlks ♦IbrdBlks; int retval; //Old way... //int funcRet - com4board2.cmdC028wrev{ ) ; //New way... int funcRet - com4board2.cmdC02 (C02strtAdptr0 , CO2STRTADPTR0LNGTH) ; //Expect a response with a command status byte. //First select which board the novametrix sensors are on. if (NOVABRD=-l) { IbrdBlks = SbrdlBlks; 101 } else { IbrdBlks = &brd2Blks; } Boolean ready =» TRUE; timel = clock( ) ; //First perform an internal reset. This assumes we don't care //what data is in the capnostat buffers and that no continous command is //running. if (NOVABRD == 1) com4boardl.intrnlReset( OVABRD,ETC02CHNL) ; else //Assume board 2 com4board2.intrnlReset(NOVABRD,ETC02CHNL) ; //Only wait around for a while. / ♦ Now sure if we need this anymore. if ( ( (♦lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ (♦lbrdBlks+SP02CHNL-l)->blockSize] )—1) ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrInfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSize] - 0; ♦ / //This works, but let's use a little easier syntax. //while ((( ( ♦ (IbrdBlks) [ETC02CHNL-1] ) .bfrlndx) < SWREVLENGTH) // ((clockO-timel)/CLOCKS_PER_SEC<-l ? TRUE : (ready=FALSE) ) ) ; /♦WAS while ( ( ( ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx) - ( (♦lbrdBlks+ETC02CHNL?-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSizβ) ) ) < CO2STRTADPTR0LNGTH) && ( (clock() -timel)/CLOCKS_PER_SEC<=l ? TRUE : (ready=FALSE) ) ) ; */ w h i l e ( ( ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx)<CO2STRTADPTR0LNG TH) && ((clockO -timel)/CL0CKS_PER_SEC<-l ? TRUE : (ready-FALSE) ) ) ; if (ready) { //Validate the s/w revision packet. / ♦ WAS 102 if (validChksm( (const char ♦ ) (& ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ (♦lbrdBlks+SP02CHNL-l)->blockSize] ] ) , CO2ADPTR0respLNGTH) ) { */ i f ( v a l i d C h k s m ( ( c o n s t c h a r ♦ ) ( ♦ lbrdBlks+ETC02CHNL-l ) ->curBfrInfo->bfr, CO2ADPTR0respLNGTH) ) { //Copy Command Status byte into global area. / ♦ WAS capnoCSB - ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSize] )+l] ; */ capnoCSB » ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->bfr[ 1] ) ; retval - 1; > else { capnoCSB - -1; retval - capnoCSB - -1; } } else { //Timed out. capnoCSB - -1; retval - -2; } / ♦ WAS ( ♦lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)-> blockSize] - (♦lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; */ ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrInfo->lastread - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; / ♦ Now sure if WΘ need thiβ now //Note : This really does assume that we are not currently streaming data. if ((( ♦ lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSize] )~0) (*lbrdBlks+ETC02CHNL-l)-> curBfrlnfo->bfr[ ( ♦ lbrdBlks+SP02CHNL-l)->blockSize] - -1; ♦ / 103 csb - capnoCSB; return(retval) ; / ♦ getCapnostat Description : Quick and dirty way of getting end tidal C02 and respiration rate from capnostat board. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time. Negative value indicates error code. ♦ / //THIS IS THE OLDER VERSION OF getCpanostat. It has not been updated to use //the new ChnlBlks data structure. /* int FAR PASCAL _export getCapnostat(int &etC02, int SrespRate) { ChnlBlks ♦IbrdBlks; int lindex, i, savei; unsigned char ♦ usebfr - NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Get Capnostat data...\n\r" ) ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED lifdef ENABLE_TEST_MODE if (sysMode == TEST) { etC02 - 50; respRate - 12; return(99) ; } lendif ENABLE TEST MODE //First select which board the novametrix sensors are on. if (NOVABRD—1) IbrdBlks - SbrdlBlks; else IbrdBlks = &brd2Blks; 104 //Grab current index lindex » ( ♦ lbrdBlks+ETC02CHNL-l)->bfrlndx; //FirBt check for respiration rate in current buffer working backward. //Must validate with checksum. if (lindex >= ETC02RRLEN) for (i-lindex-ETC02RRLEN; i>-0; i—) if ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfr[i] — 0x82) //Validate data using checksum i f ( v a l i d C h k s m ( ( c h a r ♦)&( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfr[i]) , ETC02RRLEN) ) { usebfr- ( ♦ lbrdBlks+ETC02CHNL-l)->curBfr; savei - i; foundlnBfr - CURRENT; break; } //Check flush buffer if not found in current buffer, if ( (usebfr == NULL) && (( ♦ lbrdBlks+ETC02CHNL-l ) ->f lushBf r != NULL) && ( (♦lbrdBlks+ETC02CHNL-l)->blockSizβ >- ETC02RRLEN) ) for (i= ( ( ♦ lbrdBlks+ETC02CHNL-l)->blockSize)-ETC02RRLEN; i >= 0; i— ) if ( ( ♦ lbrdBlks+ETC02CHNL-l)->flushBfr[i] — 0x82) //Validate data using checksum i f ( va l i dC hk sm ( ( c o n s t c h a r *) (&(^lbrdBlks+ETC02CHNL-l)->f lushBf r[i)) , ETC02RRLEN)) { u s e b f r = (*lbrdBlks+ETC02CHNL-l)->f lushBf r; savei — i; foundlnBfr - FLUSH; break; } if (usebfr 1- NULL){ IrespRate - ♦(usebfr+savei+4)«8 | ♦(usebfr+savei+5) ; respRate = IrespRate; } else { //Couldn't find respiration rate. respRate - -1; //Next, we will search for end tidal C02 starting at the same //point we started searching for respiration rate. } //Now try to find end tidal C02 knowing that it should just precede the //respiration rate. The assumption being made here is that by starting 105 I lour search where we left off searching for respiration rate, we can //speed things up. But we are assuming that end tidal C02 was not //passed up during the search of the respiration rate. if (foundlnBfr == CURRENT) { //Continue searching in current buffer, //then search flush. lindex — savei; if (lindex >- ETC02ETLEN) for (i=lindex-ETC02ETLEN; i>=0; i — ) if ( ( ♦ lbrdBlks+ETC02CHNL-l)->curBfr[i] — 0x81) //Validate data using checksum if ( va 1 idC hk β m ( ( c on s t char *) (.-(♦lbrdBlks+ETC02CHNL-l)->curBfr[i] ) , ETC02ETLEN) ) { u s e b f r = ( *lbrdBlks+ETC02CHNL-l ) ->curBf r ; savei = i; break; } } //Check flush buffer if not found in current buffer. if ( (usebfr « NULL) && (( ♦ lbrdBlks+ETC02CHNL-l ) ->f lushBf r 1- NULL) && ( (♦lbrdBlks+ETC02CHNL-l)->blockSize >- ETC02ETLEN) ) for (i- ( (♦lbrdBlks+ETC02CHNL-l)->blockSize)-ETC02ETLEN; i >= 0; i~) if ( ( ♦ lbrdBlks+ETC02CHNL-l)->f lushBf r[i] — 0x81) //Validate data using checksum i f ( va l idC hk β m ( ( c o n s t c h a r *) (-.(♦lbrdBlks+ETC02CHNL-l)->f lushBf r[i]) , ETC02ETLEN)) { u s e b f r - (♦lbrdBlks+ETC02CHNL-l)->f lushBf r; savei - i; break; } if (usebfr 1- NULL) { //Returning both values. letC02 - ♦ (usebf r+savei+4)«8 | * (usebf r+savei+5 ) ; etC02 - letC02; return ( 1) ; else { 106 //Returning juβt respiration rate - could not find EtC02 value. etC02 =• -1; //Send back 0 to indicate no data found for EtC02 return(O) ; } } ♦ / void getAllinit( ) ; / / zax3S>BB-Bmssβsκx- nmxαεxxα.:α*α «xBxx«» =aa=ssasassacaxaaassrasa xa / ♦ getAllCapno Description : Quick and dirty way of getting end tidal C02 and respiration rate from capnostat board. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time. arry3type| Negative value indicates error code. */ ==3=-_=*=»a // int FAR PASCAL _export getAllCapno(int far ♦ &wf, int iwfsize, int &start. int far ♦ SpatData, int &patdsize, int &ssb. int far ♦ Sesb, int Sesbsize) { int retval - 1; wfsize - 0; ChnlBlks ♦ IbrdBlks; unsigned char ♦ lcurBfr; unsigned char ♦ lflushBfr; int lbfrSize; int llastreadc, llastreadf; int lindex, i; lifdef STATUS_LOG_ENABLED strcpy(atatuBMsg, "Get Capno WFβ...\n\r") ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED lifdef ENABLE_TEST_MODE if (sysMode — TEST) { for (i=0; i<CAPNOWFSIZE; capnowf[i++]-i) ; wf - capnowf; 107 wfsize = CAPNOWFSIZE; start - 0; for (i=0; i<CAPNODATASIZE; capnodata[i++]-i) ; patData — capnodata; patdsize = CAPNODATASIZE; ssb — 0; for (i-0; i<CAPNOESBSIZE; capnoesb[i++]-i) ; esb = capnoesb; esbsize - CAPNOESBSIZE; return(99) ; } lendif ENABLE_TEST_MODE lifdef ENABLE_JOHNS_TEST_MODE if (sysMode == TEST) { getAllinit( ) ; } lendif ENABLE JOHNS TEST MODE //First select which board the novametrix sensors are on. // if (NOVABRD==l) { IbrdBlks - &brdlBlks; lbfrSize =» blchnlblksize[ETC02CHNL-l] ; } else { IbrdBlks = &brd2Blks; lbfrSize = b2chnlblksize[ETC02CHNL-l] ; } //Need to get local copies of pointers to hopefully avoid //having the ISR change a pointer on us in mid-stream. //It may be too late even now, but this is the best we //can do for now. lcurBfr - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfr; lflushBfr = ( ♦ lbrdBlks+ETC02CHNL-l)->flushBfrlnfo->bfr; //Grab the last read index. llastreadc - ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->lastread; llastreadf - ( ♦ lbrdBlks+ETC02CHNL-l)->flushBfrlnfo->lastread; //Grab current index lindex = ( ♦ lbrdBlks+ETC02CHNL-l)->curBfrlnfo->bfrlndx; i = llastreadc; if (llastreadc — -1) { //Must go back to flush buffer first llastreadc = 0; //This prepares us to read current buffer after flush. for (i = llastreadf; i < lbfrSize; i++) 108 if ( (lflushBfr[i]&0x80) I- 0) { //Command byte switch (lflushBfr i { case case case case case default: ; Unrecogn ze command byte } indx - 0; tempbfr[indx++] - lflushBfr[i] ; } else if (cmdlen > 0) //We have seen command byte, so we know what to do. if (indx — cmdlen-l){ //Array is full after we read the next byte. tempbfr[indx++] - lfluahBfr[i] ; cmdlen - 0; if (validChksm(tempbfr,indx) ) {//Valid checksum? //Calculate wf and place in global area. if (wfsize >- CAPNOWFSIZB) { //Wrap around - data loss cond. lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg, "Capno Data statuslog(statuβMBg) ; } lendif ENABLE_DATA_LOSS_MSGS retval - -1; //To indicate data loss wfsize - 0; } capnowf[wfsize++] - (tempbfr[l) << 8) tempbfr[2]; capnossb - tempbfr[3]; switch (tempbfr[0]) { case 0x80 x break; case 0x81 : //wfhb-wflb-asb-ethb-etlb-chk //Calculate etC02 capnodata[ETC02POS] - (tempbfr[4] « 8) tempbfr[5] ; break; case 0x82 : //wfhb-wflb-βab-rrhb-rrlb-chk //Calculate Respiration Rate capnodata[RRPOS] - (tempbfr[4 ] « 8) | tempbfr[5] ; break; case 0x83 i //wbhb-wflb-sβb-inβpb-chk //Calculate inspired C02 capnodata[INSPC02P0S] - tempbfr[4]; 109 break; c a s e 0 x 8 4 : //wfhb-wf lb- S8b-esbl-eeb2-esb3 -chk //Get Exended Status bytes capnoesb [ 0 ] - tempbfr[ 4 ] ; capnoesb[ l ] - tempbfr[ 5 ] ; capnoesb[ 2 ) - tempbf r[ 6) ; break; default : ; //Unknown command } else //Invalid checksum - discard data cmdlen - indx - 0 ; f else //place data in temp buffer tempbfr[indx++) - lflushBfr[i] ; ( ♦ lbrdBlks+ETC02CHNL-l)->flushBfrlnfo->lastread - -1; } //Now look at current buffer for data up to lindex. for (i « llastreadc; i < lindex; i++) if ( (lcurBfr[i)-.0x80) 1- 0) { //Command byte switch (lcurBfrfi]) { case 0x80 : cmdlen - 5; break; caβe 0x81 : cmdlen - 7; break; case 0x82 : cmdlen - 7; break; case 0x83 : cmdlen — 6; break; case 0x84 : cmdlen - 8; break; default: ; //Unrecognized command byte } ' indx - 0; tempbfr[indx++] = lcurBfr[i]; } else if (cmdlen > 0) //WΘ have seen command byte, so we know what to do. if (indx — cmdlen-l){ //Array is full after we read the next byte. tempbfr[indx++] - lcurBfr[i]; cmdlen - 0; if (validChksm(tempbfr,indx) ) {//Valid checksum? //Calculate wf and place in global area. if (wfsize >- CAPNOWFSIZE) { //Wrap around - data loss cond, lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg, "Capno Data Loss\n\r" ) ; statuslog(statusMsg) ; } lendif ENABLE_DATA_LOSS_MSGS 110 retval -i; //To indicate data loss wfsize o; } capnowf[wfsize++] - (tempbfr[l] « 8) | tempbfr[2] ; capnossb - tempbfr[3]; switch (tempbfr[0]) { case 0x80 : break; case 0x81 : //wfhb-wflb-ssb-ethb-etlb-chk //Calculate etC02 capnodata[ETC02P0S] - (tempbfr[4] « 8) | tempbfr[5] ; break; case 0x82 : //wfhb-wflb-ssb-rrhb-rrlb-chk //Calculate Respiration Rate capnodata[RRPOS] - (tempbfr[4] « 8) | tempbfr[5] ; break; case 0x83 : //wbhb-wflb-ssb-inspb-chk //Calculate inspired C02 capnodata[INSPC02P0S] - tempbfr[4]; break; case 0x84 : //wfhb-wfIb-ssb-esbl-esb2-esb3-chk //Get Exended Status bytes capnoesb[0] - tempbfr[4]; capnoesb[l] - tempbfr[5]; capnoesb[2) - tempbfr[6]; break; default: ;//Unknown command } > else //Invalid checksum - discard data cmdlen - indx = 0; } else //place data in temp buffer tempbfr[indx++] - lcurBfr[i]; (*lbrdBlks+ETC02CHNL-l)->curBfrInfo->lastread - lindex; wf - capnowf; start - 0; patData - capnodata; patdsize - CAPNODATASIZE; ssb « capnossb; esb - capnoesb; esbsize «= CAPNOESBSIZE; if (retval 1- 1) { start - wfsize%CAPNOWFSIZE; wfsize - CAPNOWFSIZE; 111 -553- } return(retval) ; II- /♦ getFlowSWrev Description Commands the Flow board to respond with sw revision. Returns : Non-negative indicates normal status code. Negative value indicates error code. I // int FAR PASCAL _export getFlowSWrev() { com4board2 ,cmdFLOWswrev( ) ; return(1) ; >; sa=-==.==ε=asss=s==s= = a=a /♦ startFlow Description Commands the Flow board to start continuous waveform mode. Returns : Non-negative indicates normal status code. Negative value indicates error code. */ li¬ lt int FAR PASCAL __βxport startFlow() { lifdef ENABLE_STATUS_LOG_IN_START_WF strcpy(statusMsg, "Starting Flow.\n\r") ; statuslog(statusMsg) ; lendif ENABLE_STATUS_LOG_IN_START_WF com4board2.cmdFLOWwfdata( ) ; return(1) ; } ; 112 ιπrι==;-ια / ♦ stopFlow Description Commands the Flow board to βtop continuous waveform mode. Returnβ : Non-negative indicates normal status code. Negative value indicates error code. « sx act 33 -a =a = -a xα x-t =3 s-t X3 =a rx _= =r r= rr =_ 53 rs z / / int FAR PASCAL _export stopFlow( ) { lifdef ENABLE_STATUS_LOG_IN_STOP WF strcpy(statusMsg, "Stopping Flow.\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE STATUS LOG IN STOP WF com4board2.cmdFLOWwfstop( ) ; return(l) ; >; / / X3 -a 3- =9 -a xτ sat set xs x-: -3 st as xs xa xa xc 3. a. as as Ki-asiB- Bi-BxassBiBBa.Bia«aκB aBaBBBSBaBBBaBBzassiBiBi-3 Eixaι / ♦ getFlow I Description : Quick and dirty way of getting tidal volume, etc. from flow board. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time. Negative value indicates error code. ♦ / // int FAR PASCAL _export getFlow(int ♦ SflowParams, int tsize) { //int FAR PASCAL _export getFlow(int ϋtidalVol, int &expVol, int SpeakPress, // int -iavgPress, int &freq, int ϋieRatio) { ChnlBlks ♦ lbrdBlkβ; int lbfrSize; 113 int lpacketSize; int lindex, i, savei, counter; unsigned char ♦ usebfr - NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; unsigned int dpiWORD - 0; //Each bit corresponds to a requested DPI lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Get Flow data... \n\r") ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED lifdef ENABLE_TEST_MODE if (sysMode ==» TEST) { for (i-0; i < FLOWDPICOUNT; flowData[i] - i++) ; flowParams - flowData; size = FLOWDPICOUNT; return(99) ; } lendif ENABLE TEST MODE //First select which board the novametrix sensors are on. if (NOVABRD—1) { IbrdBlks - ϋbrdlBlks; lbfrSize - blchnlblksize[FLOWCHNL-l] ; } else { IbrdBlks » &brd2Blks; lbfrSize - b2chnlblksize[FLOWCHNL-l] ; } //Grab current index lindex - (*lbrdBlks+FLOWCHNL-l)->curBfrlnfo->bfrlndx; //D3 will be the command byte to look for. The format is: // D3 <* of bytes> <WF Hi> <WF Lo> <dpi> <hi> <lo> ... <chksm> //All the requested DPIs may not be in the D3 command packet //being looked at, BO multiple command packets may need to be //searched to obtain all requested patient parameters. //First check for patient parameters in the most recent buffer, the //current buffer. //Must validate data packet with checksum. for (i-0; i<FL0WDPIC0UNT; flowData[i++] - -1) ; int paramCount - 0; i - lindex; while ((paramCount < FLOWDPICOUNT) && (i >- 0)) { 114 //Start searching backwards for start of data packet. if ( ( ( ♦ lbrdBlks+FLOWCHNL-l)->curBfrInfo->bfr[i]) — 0xD3) { //Found start of packet. //Do not go beyond end of buffer. int 1 = i; if ((++1) < lbfrSize) { //Then we can look at of bytes in packet. l p a c : e t S i z e = ( ♦ IbrdBlks+FLOWCHNL-1)->curBfrlnfo->bfr[1] ; //Now we know the size of packet - will we run off end of buffer? if (1+lpacketSize < lbfrSize) //We are home free - look at packet. if (validChksm( ( c o n s t c h a r ♦ ) (& ( ♦ lbrdBlks+FLOWCHNL-1)->curBfrlnfo->bfr[i] ) , lpacketSize+2) ) { //We are finally ready to process packet. //Skip over any waveforms being transmitted. counter - FL0WWFC0UNT^2 + 1; 111 +- (FL0WWFC0UNT^2)+1; //Two bytes per waveform. 1 +=» counter; //Two bytes per waveform. while (counter < lpacketSize) { //Stop before checksum. //Search for DPI in table... for (int k-0; k<FL0WDPIC0UNT; k++) if ({ ( ♦ lbrdBlks+FLOWCHNL-l)-> curBfrlnfo->bfr[l] )-=DPIP0S[k] ) //Then we found DPI we are looking for. if (flowDatafk] < 0) { //Then enter this value. //The next two byteβ are <hi byte> <lo byte> flowData[k] - ( (*lbrdBlks+FLOWCHNL-l)->curBfrInfo->bfr[l+l] )«8 | (*lbrdBlks+FLOWCHNL-1)->curBfrlnfo->bfr[1+2] ; ++paramCount; break; } counter +- 3; //DPI, Hi, Lo bytes 1 +- 3; > } 115 f (paramCount < FLOWDPICOUNT) { //Look at flush buffer for remainder of data. i - ( ♦ lbrdBlks+FLOWCHNL-l)->blockSize-l; while ((paramCount < FLOWDPICOUNT) && (i >- 0) ) { //Start searching backwards for start of data packet. if ( ( ♦ lbrdBlks+FLOWCHNL-l)->flushBfrlnfo->bfr[i] 0xD3) { //Found start of packet. //Do not go beyond end of buffer, int 1 - i; if ((++1) < lbfrSize) { //Then we can look at of bytes in packet. l p a c e t S i z e = (♦lbrdBlks+FLOWCHNL-l)->flushBfrlnfo->bfr[l]; //Now we know the size of packet - will we run off end of buffer? if (1+lpacketSize < lbfrSize) //We are home free - look at packet. if (validChksmf (const char ♦ ) (& ( ♦ lbrdBlks+FLOWCHNL-1) -> flushBfrInfo->bfr[i] ) , lpacketSize+2) ) { //We are finally ready to process packet. //Skip over any waveforms being transmitted, counter * FL0WWFC0UNT^2 + 1; til +- (FL0WWFC0UNT*2)+1; //Two bytes per waveform. 1 += counter; //Two bytes per waveform, while (counter < lpacketSize) { //Stop before checksum. //Search for DPI in table... for (int k-0; k<FL0WDPIC0UNT; k++) i f ( ( (♦lbrdBlks+FLOWCHNL-l)->flushBfrlnfo->bfr[1] )-=■ DPIP0S[k]) //Then we found DPI we are looking for. if (flowDatafk] < 0) { //Then enter this value. //The next two bytes are <hi byte> <lo byte> flowData[k] - ( ( ♦ lbrdBlks+FLOWCHNL-1)-> flushBfrlnfo->bfr[1+1] )«8 ( ♦ IbrdBlks+FL0WCHNL-1)-> flushBfrlnfo->bfr[1+2] ; ++paramCount; break; 116 } counter +- 3; //DPI, Hi, Lo bytes 1 +- 3; } > } —i; } } size - FLOWDPICOUNT; flowPara s - flowData; return(paramCount) ; } lifdef ENABLE_AVG_GET_ALL_FLOW / / z3 -3sB -3XB OIBI IB a>B>KBIB a> B aSBI B B BIB Bi IBSX>IBra /♦ getAHFlow Description : Quick and dirty way of getting tidal volume, etc. from < flow board. THIS IS THE AVERAGING VERSION. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time. Negative value indicates error code. ♦ / // int FAR PASCAL _export getAllFlow (int ♦♦ 4-flowwfs, int ♦ ϋfwfsize, int ♦ ϋfwfstart, int ♦ -.dpis, int * &dpivalue, int {idpisize, int fcestatuβl, int &estatus2, int &estatus3) { //From flow prototype - moved to global area for now. //static int savenbf, findx; //static unsigned char flowbfr[50]; //static int overrun[FLOWWFMAX] - {0,0,0}; //Used to indicate data loss per wf int retval - 1; estatusl » estatus2 - estatus3 - 0; 117 ChnlBlks ♦ IbrdBlks; unsigned char ♦ lcurBfr; unsigned char ♦ lflushBfr; int lbfrSize; int llastreadc, llastreadf; int lpacketSize; .int lindex, i, savei, counter; unsigned char ♦ usebfr - NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; //From flow prototype - zero out size array, for (int j - 0; j < FLOWWFMAX; j++) flowWFsize[j] - 0; //Zero out over run array. for (j - 0; j < FLOWWFMAX; j++) overrun[j] - 0; //Zero out averaging array, for (j-0; j < FLOWWFMAX; j++) flowAvg[j] - 0; dpisize - 0; lifdef ENABLE_CALLING_STATUS strcpy(statusMsg, "Get Flow WFs...\n\r") statuBlog(statusMsg) ; lendif ENABLE_CALLING_STATUS lifdef ENABLE_TEST_MODE if (sysMode — TEST) { for (i-0; i<FLOWWFSIZE; i++) flowWF[i) - i; for (i-0; i<FLOWWFSIZE; i++) pressWF[i] - i; for (i-0; i<FLOWWFSIZE; i++) volWF[i] - i; flowwfβ - flowWFs; for (int i - 0; i < FLOWWFMAX; i++) flowWFsize[i] - FLOWWFSIZE; fwfsize - flowWFsize; for (i-0; i<FLOWWFMAX; i++) flowWFstart[i] - i; fwfstart - flowWFstart; i - 0; flowDPIs[i) - 22 flowDPIvalues[i++] - 0; flowDPIsfi] - 24 flowDPIvalues[i++] - 1; flowDPIs[i] - 30 flowDPIvalue8[i++] - 2; flowDPIs[i] - 31 flowDPIvalueβ[i++] - 3; flowDPIs[i] - 34 flowDPIvalues[i++] - 4; flowDPIs[i] - 35 flowDPIvalues[i++] - 5; 118 dpis - flowDPIβ; dpivalue - flowDPIvalues; dpisize - 6; eβtatusl - estatuβ2 - estatus3 - 0; return(99); } lendif ENABLE_TEST_MODB retval - 1; //First select which board the novametrix sensors are on. // if (NOVABRD—1) { IbrdBlks - ϋbrdlBlks; lbfrSize - blchnlblksize[FLOWCBNL-l] ; } else { IbrdBlks - &brd2Blks; lbfrSize - b2chnlblksize[FLOWCHNL-l] ; > //Need to get local copies of pointers to hopefully avoid //having the ISR change a pointer on us in mid-stream. //It may be too late even now, but this is the best we //can do for now. lcurBfr - ( ♦ lbrdBlks+FLOWCHNL-1)->curBfrlnfo->bfr; lflushBfr - ( ♦ lbrdBlks+FLOWCHNL-l)->flushBfrlnfo->bfr; //Grab the last read index. llastreadc - ( ♦ lbrdBlks+FLOWCHNL-1)->curBf lnfo->lastread; llastreadf - ( ♦ lbrdBlks+FLOWCHNL-1)->flushBfrlnfo->lastread; //Grab current index lindex - ( ♦ lbrdBlks+FLOWCHNL-1)->curBfrlnfo->bfrlndx; i - llastreadc; if (llastreadc — -1) { //Must go back to flush buffer first llastreadc - 0; //Thiβ prepares us to read current buffer after flush. for (i « llastreadf; i < lbfrSize; i++) if (lflushBfrfi] — 0xd3){ //Command byte cmdByteSeen - 1; findx - 0; flowbfr[findx++] - lflushBfr[i] ; } else if (cmdByteSeen) { //Get number of bytes nbf - lflushBfr[i]; 119 flowbfr[findx++) = nbf; cmdByteSeen - 0; } else if (nbf > 0) if (findx — nbf+1) { //flow buffer is full after we get next byte flowbfr[findx++] - lflushBfr[i) ; savenbf - nbf; nbf - 0; //Calculate checksum if (validChksm(flowbfr,find ) ) { //Validate checksum //For each waveform, : save in appropriate array. for (j - 0; j < FLOWWFMAX; j++) { if (flowWFsize[j] >- FLOWWFSIZE) { //Wrap around - data loss lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg, "Flow Data Loss\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_DATA__LOSS_MSGS ovβrrun[j] - 1; retval - -1; //To indicate data loss flowWFsizefj) = 0; flowAvgfj) +- ((flowbfr[(j*2)+2]«8) I flowbfr[ (j*2)+3]) ; avgcount[j]++; if (avgcount[j]>-FLOWAVGSIZE) { //Average the values. flowWFs[j] [flowWFsize[ j] ] f1owAvg[j]/FLOWAVGSIZE; flowWFsize[j]++; avgcount[j) - flowAvg[j] - 0; } } //Now get DPIs for (j - 0; j < savenbf - FLOWWFMAX^2 - 1; j+=3) if (flowbfr[FLOWWFMAX^2+2+j] — 2) { //Special case - extended status (3 bytes) estatusl - flowb r[FLOWWFMAX^2+3+j ] ; 120 estatus2 - flowbfr[FLOWWFMAX^2+4+j ) ; estatus3 = ■ flowbfr[FLOWWFMAX^2+5+j] ; j++; //Add one more for this special 3-byte dpi, } else if (dpisize < MAXDPIS) { flowDPIsfdpieize] flowbfr[FLOWWFMAX^2+2+j]; flowDPIvalues[dpisize++] - (flowbfr[FLOWWFMAX^2+3+j)«8) J flowbfr[FLOWWFMAX^2+4+j] ; > else { //Need to pre-allocate more space. lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcp (statusMsg, "Allocatemore space for DPIs.\n\r" ) statuslog(BtatusMsg) ; } lendif ENABLE_DATA_LOSL_MSGS retval » -1; } } else //Invalid checksum - discard data nbf » 0; } else //Place data in buffer. flowbfr[findx++] - lflushBfr[i] ; (♦lbrdBlks+FLOWCBNL-l)->flushBfrlnfo->lastread - -1; //Now look at current buffer for data up to lindex. for (i - llastreadc; i < lindex; i++) if (lcurBfr[i] — 0xd3){ //Command byte cmdByteSeen - 1; findx - 0; flowbfr[findx++] - lcurBfr[i]; if (cmdByteSeen) { //Get number of bytes nbf - lcurBfr[i]; flowbfr[findx++] - nbf; cmdByteSeen » 0; } else f (nbf > 0) 121 if (findx — nbf+1) { It flow buffer is full after we get next byte flowbfr[findx++] - lcurBfr[i); savenbf - nbf; nbf - 0; //Calculate checksum if (validChksm(flowbfr,findx) ) { //Validate checksum //For each waveform, save in appropriate array. for (j - 0; j < FLOWWFMAX; j++) { if (flowWFsize[ ] >- FLOWWFSIZE) { //Wrap around - data loss lifdef ENABLE_DATA LOSS_MSGS if (retval — 1) { 7/First time this has happened strcpy(statusMsg, "Flow Data Loss\n\r") ; statuslog(statusMsg) ; } lendif ENABLE_DATA_LOSS_MSGS overrun[j] - 1; retval - -1; //To indicate data loss flowWFsize[j) = 0; } flowAvg[j] += ( (flowbfr[(j Λ 2)+2]«8) | flowbfr[ (j*2)+3] ) ; avgcount[j]++; if (avgcount[j]>=FLOWAVGSIZE) { //Average the values. flowWFs [j )[ flowWFsize[ j ] ] flowAvg[j]/FLOWAVGSIZE; flowWFsize[j]++; avgcount[j] - flowAvg[j] - 0; } //Now get DPIs for (j - 0; j < savenbf - FL0WWFMAX^2 - 1; j+=3) if (flowbfr[FLOWWFMAX^2+2+j] == 2) { //Special case - extended status (3 bytes) estatusl - flowbfr[FLOWWFMAX Λ 2+3+j ] ; estatus2 = flowbfrfFLOWWFMAX^2+4+j ] ; estatus3 - flowbfr[FLOWWFMAX♦2+5+j] ; j++; //Add one more for this special 3-byte dpi. 122 } else if (dpisize < MAXDPIS) { f lowDPIβ [ dpiβize ] flowbfr[FLOWWFMAX^2+2+j]; flσwDPIvalueβ[dpisize++] - (flowbfr[FLOWWFMAX^2+3+j]«8) | f lowbf r[FLOWWFMAX Λ 2+4+j] ; } else { //Need to pre-allocate more space. lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg, "Allocatemore space for DPIs.\n\r") Btatuβlog(βtatusMsg) ; } lendif ENABLE DATA LOSS MSGS } ~ } else //Invalid checksum - discard data nbf - 0; } else //Place data in buffer. flowbfr[findx++] - lcurBfr[i]; ( ♦ lbrdBlks+FLOWCHNL-l)->curBfrInfo->lastread - lindex; //Check averaging array to determine if there are any more points //to be averaged. for (j-0; j<FLOWWFMAX; j++) if (avgcount[j] 1- 0) { //Average the value. if (flowWFsize[ ] >- FLOWWFSIZE) { //Wrap around - data loss lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg, "Flow Data LoββNnXr"); statuslog(statusMsg) ; } lendif ENABLE__DATA_LOSS_MSGS overrunfj] - 1? retval - -1; //To indicate data lose flowWFsize[j] - 0; } flowWFsf j][flowWFsize[j]] - f lowAvg[ j ] /FLOWAVGSIZE; 123 lowWFsxzefj]++; } for (int n - 0; n < FLOWWFMAX; n++) if (overrun[n]) { flowWFstartfn] » flowWFsize[n]%FLOWWFSIZE; flowWFsizefn] - FLOWWFSIZE; > else { flowWFstart[n] - 0; //flowWFsizefn] - flowWFsize[n]%FLOWWFSIZE; } flowwfs - flowWFs; fwfsize - flowWFsize; fwfstart - flowWFstart; dpis - flowDPIs; dpivalue - flowDPIvalues; dpisize %- MAXDPIS; //in case we just filled the array. } lelse etc, // int FAR PASCAL _export getAHFlow (int ♦♦ ϋflowwfs, int ♦ &fwfsize, int * &fwfstart, int ♦ Sdpiβ, int ♦ &dpivalue, int &dpisize, int Sestatusl, int &estatus2, int &estatus3) { //From flow prototype - moved to global area for now. //static int savenbf, findx; //static unsigned char flowbfr[50]; 124 //static int overrun[FLOWWFMAX] - {0,0,0}; //Used to indicate data loss per wf int retval - 1; estatusl - estatus2 - estatus3 — 0; ChnlBlks ♦IbrdBlks; unsigned char ♦ lcurBfr; unsigned char ♦ lflushBfr; int lbfrSize; int llastreadc, llastreadf; int lpacketSize; int lindex, i, savei, counter; unsigned char ♦ usebfr - NULL; enum cycle {CURRENT, FLUSH, NONE} foundlnBfr; //From flow prototype - zero out size array, for (int j - 0; j < FLOWWFMAX; j++) flowWFsize[ ] - 0; //Zero out over run array, for (j - 0; j < FLOWWFMAX; j++) overrun!j] - 0; dpisize — 0; lifdef ENABLE_CALLING_STATUS strcpy(statusMsg, "Get Flow WFs, n\r"); statuslog(statusMsg) ; lendif ENABLE CALLING STATUS lifdef ENABLE_TEST_MODE if (syBMode — TEST) { for (i-0; i<FLOWWFSIZE; i++) flowWF[i] - i; for (i-0; i<FLOWWFSIZE; i++) pressWF[i] - i; for (i-0; KFLOWWFSIZE; i++) volWF[i] - i; flowwfβ - flowWFs; for (int i - 0; i < FLOWWFMAX; i++) flowWFsizefi] « FLOWWFSIZE; fwfsize - flowWFsize; for (i-0; i<FLOWWFMAX; i++) flowWFstart[i] - i; fwfstart - flowWFstart; i - 0; flowDPIs[i] - 22; flowDPIvalues[i++] o; flowDPIs[i] - 24; flowDPIvalues[i++] i; flowDPIsfi] - 30; flowDPIvalues[i++] 2; 125 flowDPIs[i) - 31; flowDPIvalues[i++] - 3; flowDPIs[i) « 34; flowDPIvalues[i++] - 4; flowDPIs[i) - 35; flowDPIvalues[i++] - 5; dpis - flowDPIs; dpivalue - flowDPIvalues; dpisize - 6; estatusl - estatus2 - estatus3 = 0; return(99) ; } lendif ENABLE_TEST_MODE retval - 1; 10 //First select which board the novametrix sensors are on, // if (NOVABRD—1) { IbrdBlks = {.brdlBlks; lbfrSize - blchnlblksize[FLOWCHNL-l] ; > else { 15 IbrdBlks = -ibrd2Blks ; lbfrSize - b2chnlblksize [ FL0WCHNL-l ] ; > //Need to get local copies of pointers to hopefully avoid //having the ISR change a pointer on us in mid-stream. //It may be too late even now, but this is the best we //can do for now. 20 lcurBfr - (*lbrdBlks+FLOWCHNL-l)->curBfrInfo->bfr; lflushBfr - ( ♦ lbrdBlks+FLOWCHNL-l)->flushBf lnfo->bfr; //Grab the last read index. llastreadc - ( ♦ lbrdBlks+FLOWCHNL-1)->curBfrlnfo->lastread; llastreadf - ( ♦ lbrdBlks+FLOWCHNL-1)->flushBfrlnfo->lastread; 2 5 //Grab current index lindex = (*lbrdBlks+FLOWCHNL-l)->curBfrlnfo->bfrlndx; i — llastreadc; if (llastreadc — -1) { //Must go back to flush buffer first llastreadc «= 0; //This prepares us to read current buffer 30 after flush. for (i - llastreadf; i < lbfrSize; i++) if (lflushBfrfi] — 0xd3){ //Command byte cmdByteSeen — 1; findx - 0; ,,- flowbfr[findx++] « lflushBfrfi]; } 126 else if (cmdByteSeen) { //Get number of bytes nbf = lflushBfrfi]; flowbfr[findx++] - nbf; cmdByteSeen - 0; } else if (nbf > 0) if (findx == nbf+1) { //flow buffer is full after we get next byte lowbfr[findx++] - lflushBfrfi]; savenbf = nbf; nbf = 0; //Calculate checksum if (validChksm(flowbfr,findx) ) { //Validate checksum //For each waveform, save in appropriate array. for (j - 0; j < FLOWWFMAX; j++) { if (flowWFsizefj) >- FLOWWFSIZE) { //Wrap around data loss ifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { Btrcpy(statusMsg, "Flow Data Loss\n\r" ) ; statuslog(statusMsg) ; } lendif ENABLE_DATA_LOSS_MSGS overrunfj) - 1; retval - -1; //To indicate data loss flowWFsizefj] - 0; } lowWFs f j ) [ flowWFsize [ j ] ] (flowbfr[ (j^2)+2]«8) J flowbfr[(j*2)+3]; flowWFsizefj]++; //Now get DPIs for (j - 0; j < savenbf - FLOWWFMAX A 2 - 1; j+-3) if (flowbfr[FLOWWFMAX^2+2+j] — 2) { //Special case - extended status (3 bytes) estatusl - flowbfr[FLOWWFMAX Λ 2+3+j] ; estatus2 - flowbfr[FLOWWFMAX^2+4+j] ; βstatus3 - flowbfr[FLOWWFMAX^2+5+j ] ; j++; //Add one more for this special 3-byte dpi, 127 } else if ( dpisize < MAXDPIS ) { f l owDP I s f d p i B i z e ] f lowbf r [ FLOWWFMAX* 2+2+j ] ; flowDPIvaluesfdpisize++] - (flowbfr[FLOWWFMAX^2+3+j]«8) | flowbfr[FLOWWFMAX^2+4+j) ; } ': else { //Need to pre-allocate more space. lifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg, "Allocatemore space for DPIs.\n\r") ; statuslog(statusMsg) ; } lendif ENABLE_DATA_LOSS_MSGS retval - -1; } } elβe //Invalid checksum - discard data nbf - 0; } else //Place data in buffer. lowbfr[findx++] - lflushBfr[i) ; (♦lbrdBlks+FLOWCHNL-l)->flushBfrlnfo->lastread - -1; } //Now look at current buffer for data up to lindex. for (i = llastreadc; i < lindex; i++) if (lcurBfrfi] .— 0xd3) { //Command byte cmdByteSeen - 1; findx - 0; flowbfrffindx++] - lcurBfrfi]; } else if (cmdByteSeen) { //Get number of bytes nbf - lcurBfr[i]; flowbfr[findx++] - nbf; cmdByteSeen - 0; } else if (nbf > 0) if (findx — nbf+1) { //flow buffer is full after we get next byte flowbfr[findx++] = lcurBfrfi); savenbf - nbf; nbf - 0; 128 //Calculate checksum if (validChksm(flowbfr,findx) ) { //Validate checksum //For each waveform, save in appropriate array. for (j » 0; j < FLOWWFMAX; j++) { if (flowWFsizefj] >- FLOWWFSIZE) { //Wrap around - data loss lifdef ENABLE_DATA L0SS_MSGS if (retval — 1) { 7/First time this has happened strcpy(statusMsg, "Flow Data Loss\n\r" ); statuslog(statusMsg) ; } lendif ENABLE_DATA_LOSS_MSGS overrunfj] - 1; retval - -1; //To indicate data loss flowWFsizef j ] - 0; f lowWFs f j ] [flowWFsizef ] ] (flowbfrf (j*2)+-2]«8) | flowbfr[ (j*2)+3); f lowWFsize [ j]++; //Now get DPIs for (j » 0; j < savenbf - FLOWWFMAX^2 - 1; j+=3) if (flowbf [FLOWWFMAX^2+2+j] — 2) { //Special case - extended status (3 bytes ) estatusl - flowbfr[FLOWWFMAX^2+3+j] ; estatus2 - flowbfr[FLOWWFMAX ♦ 2+4+j ] ; estatus3 - flowbfr[FLOWWFMAX♦2+5+j ) ; j++; //Add one more for this special 3-byte dpi, } else if (dpisize < MAXDPIS) { flowDPIs [ dpisize ] flowbfr[FLOWWFMAX^2+2+j] ? flowDPIvaluesfdpisize++) = flowbfr[FLOWWFMAX*2+4+j]; > else { //Need to pre-allocate more space. 129 ifdef ENABLE_DATA_LOSS_MSGS if (retval — 1) { strcpy(statusMsg, "Allocatemore space for DPIs.\n\r"); statuslog(statusMsg) ; > lendif ENABLE_DATA_LOSS_MSGS } } else //Invalid checksum - discard data nbf - 0; } else //Place data in buffer. flowbfr[findx++] - lcurBfrfi); (♦lbrdBlks+FLOWCHNL-l)->curBfrInfo->lastread - lindex; for (int n - 0; n < FLOWWFMAX; n++) if (overrun[n]) { flowWFstartfn) - flowWFsizefn]%FLOWWFSIZE; flowWFsizefn] - FLOWWFSIZE; } else { flowWFstartfn] - 0; //flowWFsizefn] - flowWFsizefn]%FLOWWFSIZE; } flowwfs - flowWFs; fwfsize « flowWFsize; fwfstart - flowWFstart; dpis - flowDPIs; dpivalue - flowDPIvalues; dpisize %- MAXDPIS; //In case WΘ just filled the array, } lendif ENABLE AVG GET ALL FLOW / / χχχzχ 3 xxx χ M mx as B x x Λ x^xx mx*x* mιxw m mi*xτΛBMtaπtτxsxx3XXΕxτxxxτκ zjsixx^aΛ ΛaxτxτBxκτxxΛZzz /♦ wfPulsox Description : Returns pointer to pulsox waveform. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time, Negative value indicates error code. */ 130 // int FAR PASCAL _export wfPulsox(unsigned char far ♦ SflowWF, int &size) { if (brdlBlks[SP02CHNL-1J .flushBfrlnfo 1- NULL &S. brdlBlksfSP02CHNL-1] .curBfrlnfo->bfrlndx < (brdlBlks[SP02CHNL-1] .blockSize-100) ) { //Copy contents of flush buffer to global area and return pointer to it. memcpy(spo2wfbfr,brdlBlks[SP02CHNL-1] .flushBfrlnfo->bfr,BRD2CHNL3 BL SIZE); flowWF - spo2wfbfr; size - BRD2CHNL3BL SIZE; return(l) ; } else { flowWF - NULL; size - 0; return(-1) ; } } /♦ bpControl Description : Returns : */ ti¬ l l int FAR PASCAL export bpControl(const bpCode bpCmd, int &ctrlState, unsigned char far * ϋbpResp, int &size) { const BPWAIT 0; //Requests bpControl to look for end notice message. const BPNOWAIT - 1; //Requests bpControl to return response immediately. 131 const BPWAITING - 2; //Indicates bpControl is looking for end notice message. const BPREADY - 3; //Indicates bpControl has seen end notice message. static clock_t timel; ChnlBlk ♦ IbrdBlk; Boolean found - TRUE; static unsigned char far TESTSTRINGf] » "TEST_M0DE"; switch (ctrlState) { BPWAIT: //Send command and transition to waiting state. lifdef ENABLE_TEST_MODE if (βysMode — TEST). {. bpResp - TESTSTRING; size - strlen( ESTSTRING) ; return(l) ; > lendif ENABLE_TEST_MODE if (BPBRD « 1) IbrdBlk - &brdlBlks[BPCHNL-1] ; else //Assume board 2 IbrdBlk - _.brd2Blks[BPCHNL-1] ; switch (bpCmd) { case RESl: //Reserved //Send the command if (BPBRD — 1) com4boardl.bpcmdRESl( ) ; else //ass-ume board 2 com4board2.bpcmdRESl( ) ; break; case STRIMED: //Start measurement immediately //Send the command if (BPBRD — 1) com4boardl.bpcmdSTRIMED( ) ; else //ass-ume board 2 com board2.bpcmdSTRIMED( ) ; break; 132 case RES2: break; case TRMAUTO: break; case CYCLE1: break; case CYCLE2: break; 10 case CYCLE3: break; case CYCLE4 : break; case CYCLE5: 15 break; case CYCLElO: break; case CYCLE15: break; 20 case CYCLE30: break; case CYCLE60: break; case CYCLE90: break; 25 case BGNMANO: break; case BGNWTCH: break; 30 case RSTMOD: break; case PNEUTST: break; case RQSTDAT: break; 35 case INFLlOO: 133 break ; case INFL120: . break; case INFL140: break; case INFL160: break; case INFL180: break; case ADLT150: break; case NEO100: break; case RES3: break; case STAT: break; default: //Invalid blood pressure command return(INVALIDBPCMD) ; ctrlState - BPWAITING; return(l) ; BPNOWAIT: //Retrieve response from board immedidately after BPWAITING: //Look for end notice command. default: //Invalid bpControl State retur (INVALIDBPCTRLSTATE) ; } //——> X3zas .nsasvxx.xaci / ♦ logwf Description : Logs novametrix waveform of choice. ASSUJMING USING BOARD 2 FOR NOVAMETRIX. 134 /US97/10588 -576- Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time Negative value indicates error code. * / //. // int FAR PASCAL _export logwf(int waveform) { if (brd2Blks[waveform-l).tempBfrInfo 1- NULL && brd2Blks[waveform-1] .curBfrlnfo->bfrlndx < (brd2Blks[waveform-1] .blockSize-100) ) { lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,itoa(waveform+1,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED //Write flush buffer fwrite(brd2Blks[waveform-1) .flushBfrlnfo->bfr, brd2Blks[waveform-1] .blockSize,l,fhandlesb2fwaveform-1] ) ; //Time stamp it at the end. _dos__gettime(&timeS) ; fwrite(&starttime, 1, l.fhandlesb2[waveform-1] ) ; fwrite(ϋtimeS, sizeof(timeS) , 1, handlesb2[waveform-1] ) ; //Set tempBfr to NULL to indicate we have written flush buffer. //ISR uses temp buffer to swap current and flush buffers. and the //ISR does not set the temp buffer back to NULL. Therefore, //looking at the state of the temp buffer is the way we are //determining when to flush. brd2Blks[ aveform-1] .tempBfrlnfo - NULL; return(l); } return(O); //Did not write buffer. 135 /♦ logwaveform(waveform,command) Description : Logs novametrix waveform of choice. ASSUJMING USING BOARD 2 FOR NOVAMETRIX. Commands : 1 - start 2 - continue 3 = stop Must be called periodically at a rate fast enough to dump buffers before they fill. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time, Negative value indicates error code. I li¬ ft I* THIS VERSION DOES NOT WORK DUE TO NOT BEING ABLE TO APPEND DATA IN A // BINARY FILE. int FAR PASCAL _export logWaveForm(int waveform, int command) { static clock_t timel; Boolean ready -■ TRUE; Boolean errflag - FALSE; int lsavelndx; swxtch (command) { case STARTLOG: //Fill in time stamp and current bfrindx. ready - TRUE; timel - clock( ) ; while ( (brd2Blks[waveform-1] .curBfrlnfo->bfrlndx > (brd2Blks[waveform-1) .blockSize-BFRZONE[waveform-1) ) ) && ((clockO-timel)<-10 ? TRUE : (ready-FALSE))); if (1ready) { //May have a problem. Neet to adjust out BFRZONE value. //We will go ahead and dump buffer, but with risk, lifdef ENABLE_LOGGING_ERRORS strcpy(statusMsg, "Logging ERROR 1 on board 2, channel " ) ; strncat(statusMsg,ito (waveform+1,tempstring,10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; 136 statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; } //Set temp buffer to null so we can use it later to determine when //flush buffer is ready to be flushed. brd2Blks[waveform-1] .tempBfrlnfo - NULL; //Get ti estamp dos_gettime(fclogTi es[waveform-1] ) ; 7/Capture bfrlndx and timestamp brd2Blkβ[waveform-1] .curBfrlnfo->saveIndx - brd2Blks[waveform-1] .curBfrlnfo->bfrlndx; brd2Blks [waveform-1 ) . curBfrlnfo->timeStamp StlogTimes[waveform-1] ; break; case CONTLOG: //Check for full flush buffer and write to disk if full. if (brd2Blks[waveform-1) .tempBfrlnfo 1- NULL) { //Temmp buffer is used by the ISR to switch buffers. If it is //not NULL, then we know a awitch haa be.en performed (providing //we always set it back to NULL after we process it) . if (brd2Blkβ[wave oππ-lj .curBfrlnfo->bfrlndx > i (brd2Blks[waveform-l] .blocksize-BFRZONE[ ave orm-1] ) ) { lifdef ENABLE_LOGGING_ERRORS //We are getting dangerously close to having the flush buffer //get overwritten by incoming data. //Need to adjust buffer size or frequency of calling this routine //to avoid this scenario. Will log buffer anyway - may be //corrupted by ISR or even cause a system crash (if //crashes, then I will change thiβ code to not write this //buffer at all which means we will lose data in our //log file - better that than a crash, though) . //Remember that we can not just wait for //the current buffer to fill and switch since we are trying //to capture the flush buffer before this happens, strcpy(statusMsg, 137 "Potential logging ERROR on board 2, channel ") ; strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusHsg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; } lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); strncat(BtatusMsg,itoa(waveform,tempstring,10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE LOGGING STATUS //Open file for write/append. lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Opening file "); strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ? strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS //_fmode - 0_BINARY; f h a n d l e s b 2 [ w a v e f o r m - l ] = f open(brd2Blks [waveform-1] . fileName, "ab" ) ; if (brd2Blks[waveform-l] .flushBfrlnfo->timeStamp 1= NULL) { //Write unique byte to indicate that timestamp follows. fwrite ( (void ' * ) &starttime , 1 , 1,fhandlesb2[wave orm-1] ) ; //Write timestamp and then flush buffer. f w r i t e ( ( v o i d ♦ )brd2Blkβ[waveform-1] .fluβhB r nfo->timβStamp, sizeof (♦ (brd2Blkβ[wave orm-1] . luβhB rln o->timeStamp) ) , 1, fhandlesb2[waveform-1) ) ; //Set time stamp back to null. brd2Blks[waveform-1].flushBfrlnfo->timeStamp = NULL; //Write flush buffer starting at saved index f w r i t e ( ( v o i d ♦) &brd2Blksfwaveform-1] . lushBfrlnfo->bfr[ brd2Blks[waveform-1] .flushBfrlnfo->saveIndx] , brd2Blks[waveform-1] .blockSize - brd2Blks[waveform-1] .flushBfrlnfo->saveIndx, 138 1, fhandlesb2[waveform-1] ) ; } else //JuBt write flush buffer f w r i t e ( ( v o i d 5 ♦ )brd2Blks[waveform-1) .flushBfrlnfo->bfr, brd2Blkβ[waveform-1] .blockSize, 1,fhandlesb2[waveform-1] ) ; lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Closing file "); strncat(statusMsg,ito (waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; 0 statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS fcloβe(fhandlββb2[ ave orm-1] ) ; //Set temp buffer back to null to indicate that wβ have written //flush buffer. brd2Blks[waveform-1] .tempBfrln o - NULL; > break; case STOPLOG: //Write out flush buffer if necessary and Q current buffer. //First write out flush if temp buffer if not null. We run the risk //here of the ISR changing things on us in mid-stream, but hopefully //our buffers are big enough and our timing is good enough to //avoid problems. 5 //Open file for write/append. lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Opening file "); strncat(statusMsg,ito (wave orm,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGI G_STATUS 0 //Important: Setting _fmode to binary while not including "b" // in the format string of the open works. Including // "b" in the format string causes problems in tryxng 5 // to append to file. 139 //_ mode - 0_BINARY; f h a n d l e s b 2 f w a v e f o r m - l ] f open(brd2Blke[waveform-l] .' ileName, "ab" ) ; if (brd2Blks[waveform-l] .tempBfrlnfo 1- NULL) { //Write out flush buffer. if (brd2Blkβ[waveform-l] .f lushBfrlnf o->timeStamp 1- NULL) { //Write unique byte to indicate that ti ββtamp follows. fwrite ( (void .*.) Sstarttime, 1, 1, fhandlesb2 [ wavef orm-1] ) ; //Write timestamp f w r i t e ( ( v o i d ♦ ) brd2Blks [wavef orm-1 ] . f lushBf rlnf o->timeStamp, sizeo (♦ (brd2Blks[ waveform- 1] . f lushBf rln o->timeStamp) ) , 1, fhandlesb2 [wavef orm-1] ) ; } lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel " ) ; strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING__STATUS //Write flush buffer fwrite( (void^)brd2Blks[waveform-1] .flushBfrlnfo->bfr, brd2Blks[waveform-1] .blockSize, 1,fhandlesb2[waveform-1] ) ; //Set time stamp back to null. brd2Blks[ aveform-1] .flushBfrlnfo->timeStamp - NULL; } //If current buffer is almost full, then wait around a few ms to //allow buffer to fill completely and switch. This way, we will //hopefully have time to write buffers before data is overwritten. //Of course, just above I wrote the flush buffer assuming that //current buffer was not too close to being full, so why be so //careful here? The answer is - because I know how to be careful I there. ready =■ TRUE; 140 ti el = clock( ) ; while ( (brd2Blks[waveform-1] .curBfrInfo->bfrlndx > (brd2Blks[waveform-1] .blockSize-BFRZONE[waveform-1] ) ) && ( (clock()-timel)<= » 10 ? TRUE : (ready-FALSE))); xf ( 1ready) { lifdef ENABLE_LOGGING_ERRORS strcpy(statusMsg, "Logging ERROR 2 on board 2, channel " ) ; strncat(statusMsg,ito (waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS errflag - -1; } //Grab current index and time. //WAS //brd2Blks[waveform-1] .curBfrlnfo->saveIndx - // brd2Blks[waveform-1] .curBfrlnfo->bfrlndx; lsavelndx - brd2Blks[wavefoπn-1] .curBfrlnfo->bfrlndx; _dos_gettime(ϋlogTimes[waveform-1] ) ; //WAS //brd2Blks fwaveform-1 ) . curBf lnfo->timeStamp = SlogTimes[ ave orm-1] ; //Must check flush buffer again in case we have swapped buffers. if (brd2Blks[wave orm-1] .tempBfrlnfo 1- NULL) { if (brd2Blks[waveform-1] .flushBfrlnfo->timeStamp I- NULL) { lifdef ENABLE_LOGGING_ERRORΞ strcp (BtatusMsg, "ERROR -> Unexpected log condition\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS } lifdef ENABLEJuOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS //Just write flush buffer fwrite( .flushBfrlnfo->bfr J 141 brd2Blks[waveform-l] .blockSize, l,fhandlesb2[waveform-1] ) ; } //Now write current buffer up to index and then the timestamp. //WAS //fwrite(brd2Blks[waveform-l] .curBfrlnfo->bfr, // brd2Blksfwaveform-l] .curBfrlnfo->saveIndx, // l,fhandlesb2fwaveform-l] ) ; lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); Btrncat(statuβMβg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE LOGGING STATUS fwrite( (void ♦ )brd2Blks[waveform-l] .curBfrlnfo->bfr, lsavelndx, 1, fhandlesb2[waveform-l] ) ; //Write unique byte to indicate that timestamp follows. fwrite((void ♦ )δstarttime, 1, 1,fhandlesb2[waveform-l] ) ; //Write timestamp //WAS / / f w r i t e ( ( v o i d ♦)brd2Blks[waveform-l) .curBfrlnfo->timeStamp, sizeof(♦(brd2Blks[waveform-1] .curBfrlnfo->timeStamp) ) , // 1, fhandlesb2[waveform-l] ) ; fwrite( (void ♦ )&logTimes[waveform-l] , sizeof(logTimes[waveform-l] ) , 1, fhandlesb2[ aveform-l] ) ; lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Closing file "); strncat(statusMsg,ito (waveform,tempstring,10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS fclose(fhandleBb2fwaveform-l] ) ; break; default: lifdef ENABLE_LOGGING_ERRORS 142 -584- strcpy(statusMsg, "ERROR -> Unrecognized logging command "); strncat(statusMsg,itoa(command,tempstring, 10) ,5) ; strncat(statuβMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; } if (errflag) return(-1) ; else return(command) ; } / ♦ logwf(wavefor ,command) Description Logs novametrix waveform of choice. ASSUJMING USING BOARD 2 FOR NOVAMETRIX. Waveforms 1 - Flow 2 - Capno 3 - PulβeOx Commands : 1 - start 2 - continue 3 - stop Must be called periodically at a rate fast enough to dump buffers before they fill. Returns Non-negative indicates normal status code. 0 - indicates no data available at this time. Negative value indicates error code. I I j =3 = £-I 3Xα X-5B3 EK:3 αS< XlK{SBSS XS «X« S a XX« s:as-acιmιxHxiBε.BXix // //NOTE: THIS VERSION ASSUMES FILES ARE ALREADY OPENED. THIS VERSION ALSO // DOES NOT CLOSE FILES. /* int FAR PASCAL _export logWaveForm(int waveform, int command) { static clock_t timel; Boolean ready - TRUE; Boolean errflag = FALSE; int lsavelndx; 143 ifdef ENABLE_CALLING_STATUS strcpy(statusMsg, "Called logWaveFoπn/ waveform :"); strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, " /command : ",20); Btrncat(statusMsg,itoa(command,temp8tring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE CALLING STATUS switch (command) { case STARTLOG: //Fill in time stamp and current bfrindx. ready - TRUE; timel - clock( ) ; while ( (brd2Blks[waveform-l] .curBfrlnfo->bfrlndx > (brd2Blks[waveform-l] .blockSize-BFRZONE[waveform-l] ) ) && ((clockO-timel)<=10 ? TRUE : (ready=FALSE) ) ) ; if (1ready) { //May have a problem. Need to adjust out BFRZONE value. //We will go ahead and dump buffer, but with risk, lifdef ENABLE_LOGGING_ERRORS strcpy(statusMsg, "Logging ERROR 1 on board 2, channel " ) ; strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; } //Set temp buffer to null so we can use it later to determine when //flush buffer is ready to be flushed. brd2Blks[waveform-l) .tempBfrlnfo - NULL; //Get timestamp dos_gettime(ϋlogTimes[waveform-l] ) ; 7/Capture bfrlndx and timestamp brd2Blks[waveform-l) .curBfrlnfo->saveIndx - brd2Blks[waveform-1] .curBfrlnfo->bfrlndx; brd2Blks [waveform-l ) . curBfrlnfo->timeStamp SlogTimes[waveform-l] ; break; 144 case CONTLOG: //Check for full flush buffer and write to disk if full. if (brd2Blks[waveform-l) .tempBfrlnfo 1- NULL) { //Temmp buffer is used by the ISR to switch buffers. If it is //not NULL, then we know a switch has been performed (providing //we always set it back to NULL after WΘ process it) . if (brd2Blks[waveform-1] .curBfrlnfo->bfrlndx > (brd2Blks[waveform-l] .blockSize-BFRZONE[waveform-l) ) ) { lifdef ENABLE_LOGGING_ERRORS i //We are getting dangerously close to having the flush buffer //get overwritten by incoming data. //Need to adjust buffer size or frequency of calling this routine //to avoid this scenario. Will log buffer anyway - may be //corrupted by ISR or even cause a system crash (if system //crashes, then I will change this code to not write this //buffer at all which means we will lose data in our //log file - better that than a crash, though) . //Remember that we can not just wait for //the current buffer to fill and switch since we are trying //to capture the flush buffer before this happens, strcpy(statusMsg, "Potential logging ERROR on board 2, channel strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; 8tatuslog(statU8Msg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; > lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuBlog(statusMsg) ; lendif ENABLE_LOGGING_STATUS //Open file for write/append, //lifdef ENABLE_LOGGING_STATUS //strcpy(statusMsg, "Opening file "); //strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; 145 //strncat(statusMsg, "\n\r" ,5) ; //statuslog(statusMsg) ; //lendif ENABLE_LOGGING_STATUS //__f ode - 0_BINARY; / / f h a n d l e s b 2 [ w a v e f o r m - l ] = £open(brd2Blks [wavef orm-l] .fileName, "a"); if ( brd2Blks[ wavef orm-l] .f lushBf rlnf o->timeStamp I- NULL) { //Write unique byte to indicate that timestamp follows . fwrite ( (void ♦ ) & s t r 11 i e , 1 , 1 , fhandlesb2 [wavef orm-l )) ; //Write timestamp and then flush buffer. f w r i t e ( ( v o i d ♦ )brd2Blks[ wavef orm-l] . f lushBf rlnf o->timeStamp, sizeof(♦ (brd2Blks[waveform-l) .flushBfrlnfo->timeStamp) ) , 1, fhandlesb2[waveform-l] ) ; //Set time stamp back to null. brd2Blks[waveform-l] .flushBfrInfo->timeStamp = NULL; //Write flush buffer starting at saved index f w r i t e ( ( v o i d ♦)&brd2Blks[waveform-l] .fluβhBfrlnfo->bfr[ brd2Blks[waveform-l] .flushBfrlnfo->saveIndx] , brd2Blks[waveform-l] .blockSize - brd2Blks[waveform-l] .flushBfrlnfo->saveIndx, 1,fhandlesb2[waveform-l) ) ; } else //Just write flush buffer f w r i t e ( ( \ ♦)brd2Blks[waveform-l] .flushBfrlnfo->bfr, brd2Blks[ aveform-l] .blockSize, 1,fhandlesb2[waveform-l] ) ; //lifdef ENABLE_LOGGING_STATUS //strcpy(statusMsg, "Closing file "); //strncat(statusMsg,ito (waveform,tempstring, 10) ,5) ; //strncat(statusMsg, "\n\r" ,5) ; //Btatuslog(statusMsg) ; //lendif ENABLE_LOGGING_STATUS //fclose(fhandlesb2[waveform-l] ) ; //Set temp buffer back to null to indicate that we have written 146 //flush buffer. brd2Blksfwaveform-l) .tempBfrlnfo - NULL; } break; case STOPLOG: //Write out flush buffer if necessary and current buffer. //First write out flush if temp buffer if not null. We run the risk //here of the ISR changing things on us in mid-stream, but hopefully //our buffers are big enough and our timing is good enough to //avoid problems. //Open file for write/append, //lifdef ENABLE_LOGGING_STATUS //strcpy(statusMsg, "Opening file "); //strncat(statusMsg,itoa(wavefor ,tempstring, 10) //strncat(statusMsg, "\n\r" ,5) ; //statuslog(statusMsg) ; //lendif ENABLE LOGGING STATUS //Important: Setting _fmode to binary while not including "b" // in the format string of the open works. Including // "b" in the format string causeB problems in trying // to append to file. //_fmode - 0_BINARY; / / f h a n d l e s b 2 f w a v e f o r m - l ) = fopen (brd2Blks fwavef orm-l] .fileName, "a" ) ; if (brd2Blks fwavef orm-l] .tempBfrlnfo 1- NULL) { //Write out flush buffer. if (brd2Blks [wavef orm-l] .f lushBf lnf o->timeStamp 1- NULL) { //Write unique byte to indicate that timestamp follows. fvritβ j (void ♦ ) &starttime , 1 , 1 , f handlesb2 [wavef orm-l ] ) ; //Write timestamp f w r i t e ( ( v o i d ♦ ) brd2 ~ Iks fwavef orm-l] . f lushBfrlnf o->timeS tamp, sizeof ( ♦ (brd2Blks [wavef orm-l] . f lushBf rlnf o->timeS tamp) ) , 1, fhandlesb2 [wavef orm-l ]) ; 147 } lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; Btatuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS //Write flush buffer fwrite( (void + )brd2Blksfwaveform-l] . flushBfrlnfo->bfr, brd2Blks[waveform-l] .blockSize, 1,fhandlesb2fwaveform-l] ) ; //Set time stamp back to null. brd2Blks[waveform-l] .flushBfrlnfo->timeStamp - NULL; } //If current buffer IB almost full, then wait around a few s to //allow buffer to fill completely and switch. This way. we will //hopefully have time to write buffers before data is overwritten. //Of course, just above I wrote the flush buffer assuming that //current buffer was not too close to being full, so why be so //careful here? The answer is - because I know how to be careful //here. ready ~ TRUE; timel = cloc ( ) ; while ( (brd2Blks[waveform-l] .curBfrlnfo->bfrlndx > (brd2Blks[waveform-l] .blockSize-BFRZONE[waveform-l] ) ) && ( (cloc ()-timel)<-10 ? TRUE : (ready-FALSE))); if ( 1ready) { lifdef ENABLE_LOGGING_ERRORS strcpy(statusMsg, "Logging ERROR 2 on board 2, channel " ) ; strncat(statusMsg,ito (waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE_L0GGING_ERRORS errflag - -1; } //Grab current index and time. //WAS 148 //Blkε(waveform-l] .curBfrlnfo->saveIndx = brd2Blks[waveform-l] .curBfrlnfo->bfrlndx; lsavelndx = brd2Blksfwaveform-l] .curBfrlnfo->bfrlndx; _dos_gettime(-ilogTimesfwaveform-l] ) ; //WAS //brd2Blks fwaveform-l ] .curBfrlnfo->timeStamp &logTimes[waveform-l) ; //Must check flush buffer again in case we have swapped buffers. if (brd2Blks[waveform-l] .tempBfrlnfo 1- NULL) { if (brd2Blks[waveform-l] .flushBfrlnfo->timeStamp != NULL) { lifdef ENABLE_LOGGING_ERRORS strcpy(statusMsg, "ERROR -> Unexpected log condition\n\r" ) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS . > lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,itoa(wave orm,tempstring, 10) , 5 ) ; strncat(statusMβg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS //Just write flush buffer fwrite( (void^)brd2Blks[waveform-l] .flushBfrlnfo->bfr. brd2Blks[waveform-l] .blockSize,1,fhandlesb2[waveform-l] ) ; } //Now write current buffer up to index and then the timestamp. //WAS //fwrite(brd2Blks[waveform-1] .curBfrlnfo->bfr, // brd2Blks[waveform-l] .curBfrlnfo->saveIndx, // 1,fhandlesb2[waveform-l] ) ; lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; Btatuslog(statusMsg) ; lendif ENABLE LOGGING STATUS 149 write( (void ♦ )brd2Blks[waveform-l] .curBfrlnfo->b r, lsavelndx, 1,fhandlesb2[waveform-l] ) ; //Write unique byte to indicate that timestamp follows, fwrite((void ♦) Sstarttimβ, 1, 1,fhandlβab2[waveform-l]) ; //Write timestamp //WAS / / f w r i t e ( ( v o i d ♦ )brd2Blks[waveform-l] .curBfrlnfo->timeStamp, / / sizeof( ♦ (brd2Blks[waveform-l] .curBfrlnfo->timeStamp) ) , // 1, fhandlesb2[waveform-l] ) ; // fwrite( (void ♦ ) SlogTimes[waveform-l] , sizeo (logTi esfwaveform-l] ) , 1, fhandlesb2[waveform-l] ) ; //lifdef ENABLE_LOGGING_STATUS //strcpy(statusMsg, "Closing file "); //strncat(statusMsg,itoa(waveform,tempstring,10) ,5) ; //strncat(statusMsg, "\n\r" ,5) ; //statuslog(statusMsg) ; //lendif ENABLE_LOGGING_STATUS I If.close(fhandlesb2[waveform-l] ) ; break; def ult: lifdef ENABLE_LOGGING_ERRORS strcpy(statusMsg, "ERROR -> Unrecognized logging command ") ; strncat(statusMsg,itoa(command,tempstring, 10) ,5) ; strncat(statusMBg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; if (errflag) return(-1) ; else return(command) ; } */ //===- 150 /♦ logwf (waveform,command) Description : Logs novametrix waveform of choice. ASSUJMING USING BOARD 2 FOR NOVAMETRIX. Waveforms 1 - Flow 2 - Capno 3 - PulseOx Commands : 1 - start 2 - continue 3 - stop Muβt bθ called periodically at a rate fast enough to dump buffers before they fill. Returns : Non-negative indicates normal status code. 0 - indicates no data available at this time. Negative value indicates error code. */ / κasκ»t3x«xxχaxκx>XB κcκ3X-χjtf aMaκκ«x« XBX« // //NOTE: THIS VERSION ASSUMES FILES ARE ALREADY OPENED. THIS VERSION ALSO • // DOES NOT CLOSE FILES. THIS VERSION! USES LOCAL POINTERS TO CAPTURE // CURRENT STATE OF THE BUFFERS TO AVOID POTENTIAL CONFLICT. int FAR PASCAL _export logWaveForm(int waveform, int command) { ChnlBlks ♦IbrdBlks; unsigned char ♦ lcurBfr; unsigned char ♦ lflushBfr; static clock_t timel; Boolean ready = TRUE; Boolean errflag - FALSE; int Isavelndx; lifdef ENABLE_CALLING_STATUS strcpy(statusMsg, "Called logWavβForm/ waveform :"); strncat(statusMsg,ito (waveform,tempstring, 10) ,5) ; strncat(statusMsg, " /command : ",20); strncat(statusMsg,itoa(command,tempstring,10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE_CALLING_STATUS if (NOVABRD—1) { IbrdBlks - ϋbrdlBlks; //lbfrSize - blchnlblksize[waveform-l] ; 151 gi gα 1 IbrdBlkβ - tbrd2Blkβ; //lbfrSize - b2chnlblksize[wave orm-l] ; } lcurBfr - ( ♦ IbrdBlks+waveform-l)->curBfrlnfo->bfr; lflushBfr - ( ♦ IbrdBlks+waveform-l)->flushBfrlnfo->bfr; switch (command) { case STARTLOG: //Fill in time stamp and current bfrindx. //First check to see if we are close to filling current buffer. //If we are, then wait until we switch buffers before we start to //record. ready - TRUE; timel - clock(); while ( (brd2Blks[waveform-1] .curBfrlnfo->bfrlndx > (brd2Blks[waveform-l] .blockSize-BFRZONEfwaveform-l) ) ) && {(clockO-timel)<-10 ? TRUE : (ready-FALSE))); if ( 1ready) { //May have a problem. Need to adjust out BFRZONE value. //We will go ahead and dump buffer, but with risk, lifdef ENABLE_LOGGING_ERRORS etrcpy(statusMsg, "Logging ERROR 1 on board 2, channel ") ; strncat(statusMsg,itoa(wavefόrm,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; } //Set temp buffer to null so we can use it later to determine when //flush buffer is ready to be flushed. brd2Blks[waveform-l] .tempBfrlnfo - NULL; //Get timestamp _dos_gettime(&logTimes[waveform-l] ) ; //Capture bfrlndx and timestamp brd2Blks[waveform-l] .curBfrlnfo->saveIndx - brd2Blkβ[waveform-l] .curBfrlnfo->bfrlndx; 152 ItSet time βtamp of current buffer to the current time. This is //the time we will- use to precede the current buffer when written //to indicate when we started to record. brd2Blks [wavef orm-l ] .curBfrInfo->timeStamp = &logTimes [wavef orm-l ] ; break; case CONTLOG: //Check for full flush buffer and write to diβk if full. if (brd2Blks[waveform-l) .tempBfrlnfo 1- NULL) { //Tem p buffer is used by the ISR to switch buffers. //not NULL, then we know a switch has been performed (providing //we always set it back to NULL after we process it). if (brd2Blks[waveform-l] .curBfrlnfo->bfrlndx > (brd2Blks[waveform-l] .blockSize-BFRZONE[waveform-l] ) ) { lifdef ENABLE_LOGGING_ERRORS • //We are getting dangerously close to having the flush buffer //get overwritten by incoming data. //Need to adjust buffer size or frequency of calling this routine //to avoid this scenario. Will log buffer anyway - may be //corrupted by ISR or even cause a system crash (if system //crashes, then I will change this code to not write this //buffer at all which means we will lose data in our //log file - better that than a crash, though) . //Remember that we can not just wait for //the current buffer to fill and switch since we are trying //to capture the flush buffer before this happens. strcpy(statusMsg, "Potential logging ERROR on board 2, channel strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; } lifdef ENABLE_LOGGING_STATUS 153 strcpy(statusMsg, "Logging board 2, channel "); strncat(statUBMsg,ito (waveform,tempstring, 10) , 5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS //Open file for write/append. //lifdef ENABLE_LOGGING_STATUS //strcpy(statusMsg, "Opening file "); //strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; //strncat(statusMsg, "\n\r" ,5) ; //statuslog(statusMsg) ; //lendif ENABLE_LOGGING_STATUS //_fmode = 0_BINARY; / / f h a n d l e s b 2 [ w a v e f o r m - l ] = f open (brd2Blks[ wavef orm-l] . ileName, "a" ) ; if (brd2Blks [wavef orm-l] .f lushBf rlnf o->timeStamp 1= NULL) { //Write unique byte to indicate that timestamp follows . fwrite f (void ♦ ) &starttime , 1 , l, handle sb2[ avef orm-l] ) ; //Write timestamp and then flush buffer. f w r i t e ( ( v o i d * ) brd2Blks [wavef orm-l ] . f lushBf rlnf o->timeStamp, sizeof(* (brd2Blks[waveform-l] .flushBfrlnfo->timeStamp) ) , 1, fhandlesb2[waveform-l) ) ; //Set time stamp back to null. brd2Blks[waveform-l] .flushBfrlnfo->timeStamp - NULL; //Write flush buffer starting at saved index f w r i t e ( ( v o i d *) &brd2Blks[waveform-l] .flushBfrlnfo->bfrf brd2Blks[waveform-l] .flushBfrlnfo->saveIndx] , brd2Blks[waveform-l] .blockSize - brd2Blkε[waveform-l] .flushBfrlnfo->saveIndx, l,fhandlesb2[waveform-l] ) ; } else //Just write flush buffer f w r i t e ( ( v o i d *)brd2Blka[waveform-l] .flushBfrlnfo->bfr, brd2Blks [waveform-l] .blockSize, 1,fhandlesb2[waveform-l] ) ; //lifdef ENABLE_LOGGING_STATUS 154 //strcpy(statusMsg, "Closing file "); //strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; //strncat(statusMsg, "\n\r" ,5) ; //statuslog(statusMsg) ; //lendif ENABLE_LOGGING_STATUS ■ I Ifclose(fhandlesb2[waveform-l] ) ; //Set temp buffer back to null to indicate that we have written //fluβh buffer. brd2Blks[waveform-l] .tempBfrlnfo - NULL; > break; case STOPLOGi //Write out flush buffer if necessary and current buffer. //First write out flush if temp buffer if not null. We run the risk //here of the ISR changing things on us in mid-stream, but hopefully //our buffers are big enough and our timing is good enough to //avoid problems //Open file for write/append. //lifdef ENABLE_LOGGING_STATUS ■ //strcpy(statusMsg, "Opening file "); //strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; //strncat(statusMsg, "\n\r" ,5) ; //statuslog(statusMsg) ; //lendif ENABLE_LOGGING_STATUS //Important: Setting _f ode to binary while not including "b" // in the format string of the open works. Including // "b" in the format string causes problems in trying // to append to file. //_fmode - 0_BINARY; / / f h a n d l e s b 2 [ w a v e f o r m - l ] = fopen (brd2Blks[ waveform- 1] .fileName, "a" ) ; if (brd2Blks[waveform-l] .tempBfrlnfo 1- NULL) { //Write out flush buffer. if (brd2Blks[waveform-l] . flushBfrlnfo->timeStamp 1= NULL) { 155 //Write unique byte to indicate that timestamp follows. fwrite ( ( void ♦ ) & starttime , 1 , 1 , f handlesb2 [wavef orm-l ] ) ; //Write timestamp f w r i t e ( ( v o i d *)brd2Blks[waveform-l] . lushBfrlnfo->timeStamp, sizeof( ♦ (brd2Blks[waveform-l] .flushBfrlnfo->timeStamp) ) , 1, fhandlesb2[waveform-l] ) ; //Set time stamp back to null. brd2Blks[waveform-1] .flushBfrlnfo->timeStamp - NULL; } lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS //Write flush buffer fwrite( (void^)brd2Blks[waveform-l] .flushBfrlnfo->bfr, brd2Blks[waveform-l) .blockSize, 1,fhandlesb2[waveform-l] ) ; } //If current buffer is almost full, then wait around a few ms to //allow buffer to fill completely and switch. This way, we will //hopefully have time to write buffers before data is overwritten. //Of courβe, just above I wrote the fluβh buffer assuming that //current buffer was not too close to being full, so why be so //careful here? The answer is - because I know how to be careful //here. ready = TRUE; timel - clock( ) ; while ( (brd2Blks[waveform-1] .curBfrlnfo->bfrIndx > (brd2Blks[wave orm-l] .blockSize-BFRZONE[waveform-l] ) ) && ((clockO-timel)<-10 ? TRUE : (ready-FALSE))); if ( 1ready) { 156 Iifdef ENABLE_LOGGING_ERRORS strcpy(statusMsg, "Logging ERROR 2 on board 2, channel " ) ; strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; . lendif ENABLE_LOGGING_ERRORS errflag - -1; > //Grab current index and time. / ♦ WAS brd2Blks[waveform-l] .curBfrlnfo->save!ndx = brd2Blks[waveform-l] .curBfrlnfo->bfrlndx; ♦ / //This used to be done here, but should be done after checking //if the current buffer needs to have its start timestamp //written out to disk. If we do the following two statements //right now, we will overwrite our start timestamp. These //two statements will be moved to a point after we have //determined the status of our start timestamp. /♦WAS lsavelndx = brd2Blks[waveform-l] .curBfrlnfo->bfrlndx; dos_gettime(&logTimes[waveform-l) ) ; */ / ♦ WAS brd2 B lk s [ wave f o rm- l ] . c urB f r I n f o- >t ime S t amp &logTimes [ wavef orm- l ] ; * / //Must check flush buffer again in case we have swapped buffers, if (brd2Blks[waveform-l).tempBfrlnfo I- NULL) { if (brd2Blks[waveform-l] .flushBfrlnfo->timeStamp 1= NULL) { lifdef ENABLE_LOGGING_ERRORS strcpy ( statusMsg , "ERROR . -> Unexpected log condition\n\r " ) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS } lifdef ENABLE_LOGGING_STATUS strcpy(statuβMsg, "Logging board 2, channel "); strncat(statusMsg,ito (waveform,tempstring, 10) , 5) strncat(statusMsg, "\n\r",5) ; 157 statuslo ( statusMsg) ; lendif ENABLE_LOGGI G__STATUS if (brd2Blks [wavef orm-l) .f lushBf rlnf o->timeStamp 1= NULL) { //Write unique byte to indicate that timestamp follows fwrite ( (void ♦ ) &starttime , 1 , 1 , f handlesb2 [wavef orm-l] ) ; //Write timestamp f w r i t e ( ( v o i d * ) brd2Blks [wavef orm-l ] . f lushBf rlnf o->timeStamp, sizeof (♦(brd2Blks [wavef orm-l] .f lushBf rlnf o->timeStamp) ) , 1, fhandlesb2 [wavef orm-l] ) ; //Set time stamp back to null. brd2Blks[waveform-l] .flushBfrlnfo->timeStamp - NULL; } //Just write flush buffer f rite( {void A )brd2Blks[waveform-l] .flushBfrlnfo->bfr, brd2Blks[waveform-l) .blockSize, 1,fhandlesb2[waveform-l] ) ; } //Now write current buffer up to index and then the timestamp. / ♦ WAS fwrite(brd2Blk8[wavβform-l] .curBfrlnfo->bfr, brd2Blks(waveform-l] .curBfrlnfo->saveIndx, 1,fhandlesb2[waveform-l] ) ; */ //But first, we need to check if we are ready to write the //current buffer which is the only buffer which will be //written for this record cycle. If the timestamp is not //null, this indicates that we need to precede our block with //a timestamp. if (brd2Blks [wavef orm-l] .curBf rlnf o->timeStamp 1=» NULL) { //Write unique byte to indicate that timestamp follows. fwrite ( ( void ♦ ) & starttime , 1 , 1 , f handlesb2 [wavef orm-l] ) ; //Write timestamp f w r i t e ( ( v o i d ♦ ) brd2Blks [wavef orm- 1 ] . curBf rlnf o->timeS tamp, 158 sizeof( ♦ (brd2Blks[wavefor -.l) .curBfrlnfo->timeStamp) ) , 1, fhandlesb2 [waveform-1] ) ; It Set time stamp back to null. brd2Blks[waveform-l] .curBfrlnfo->timeStamp - NULL; //Get the end timestamp and an index to go along with it. lsavelndx - brd2Blks[waveform-l] .curBfrlnfo->bfrlndx; _dos_gettime(δlogTimes[waveform-l] ) ; //Note that we do not set the timβBtamp field to point to //logTimes structure since when we exit this part of the //switch of this case, we want all of our timestamp fields //associated with this waveform to be null to prepare for //our next, if any, record cycle. We therefore use the //address of the appropriate logTi e structure to write the //timestamp. (see below) lifdef ENABLE_LOGGING_STATUS strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_STATUS //Write the data next. fwrite( (void ♦ )brd2Blks[waveform-l] .curBfrlnfo->bfr, lsavelndx, 1, fhandlesb2[waveform-l] ) ; //Write unique byte to indicate that the end timestamp follows, f rite((void ♦) Sstarttime, 1, 1, handlesb2[waveform-l]) ; //Write timestamp / ♦ WAS fwrite( (void ♦)brd2Blks[waveform-l] .curBfrlnfo->timeStamp, sizeof(♦ (brd2Blks[waveform-l] .curBfrlnfo->timeStamp) ) , 1, fhandleβb2[waveform-l] ) ; ♦ / //Note that we are writing the timestamp using the logTimes //variable instead of the timeStamp field in the brdlBlks //structure. Now we do not have to worry about setting that 159 //pointer to null since we never set it in the first place, fwrite( (void ♦) &logTimes[waveform-l] , sizeof(logTimes[waveform-l] ) , 1, fhandlesb2[waveform-l] ) ; //lifdef ENABLE_LOGGING_STATUS //strcpy(statusMsg, "Closing file "); //strncat(statusMsg,itoa(waveform,tempstring, 10) ,5) ; //strncat(statusMsg, "\n\r",5) ; //statuslog(statusMsg) ; //lendif ENABLE_LOGGING_STATUS / Ifclose(fhandlesb2[waveform-l] ) ; break; default: lifdef ENABLE_LOGGING_ERRORS strcpy(statusMsg, "ERROR -> Unrecognized logging command strncat(statusMsg,itoa(command,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif ENABLE_LOGGING_ERRORS errflag - TRUE; if (errflag) return(-1) ; else return(command) ; /♦ statuslog Description : Writes error message to error port for debugging, Returns : 160 10588 -602- */ //' // int FAR PASCAL _export statuslog(char ♦ msg) { //Sends an error message to error port for display and/or log, //dandy.astound - Note that com4boardl is arbitrary. com4boardl.writeStatus (meg) ; } / / πxirαarHnnnc3θr3--iB=ιαi3σn«nMn«MaιnnHnH-αaMa / ♦ readChannel Description : Reads channel from UI048 board. Returns : I // int FAR PASCAL _export readChannel(int channel) { return(uio48board.readChannel(channel) ) ; } =S=:=3=33333-:3-I // int FAR PASCAL _export dummy(int &inout) { inout « 1; return(inout) ; } 161 -603- 3-QBBj=Eiασaπxι-Z3xιnaaια c-s:ns:a = :s==:-π /♦ reset518 Description : Performs reset of 518 board given board number. Returns : Return code from 518 boardReset function. r-=333-S3£33=S33333333=33£3-3XX33== // int FAR PASCAL _export reset518(int boardNo) { if (boardNo == 1) return(board518Nol.boardReset( ) ) ; else retur (board518No2.boardReset( ) ) ; ==;=::=-:-= =:r==-:=3™—=-==-==3 / ♦ readBoardTemp Description : Performs 518 Read Board Temperature command given board number. Returns : Board temperature, // int FAR PASCAL _export readBoardTem (int boardNo) { int boardTemp; if (boardNo — 1) { board518Nol.writeCommand(READ_BOARD_TEMP) ; board518Nol.readData(8, boardTemp) ; } else { board518No2.writeCommand(READ_BOARD_TEMP) ; board518No2.readData(8, boardTemp) ; } return(boardTemp) ; 162 /♦ getdllVersion Description : Returns current version number '/ / / const char ♦ FAR PASCAL _export getDllVersion( ) { if (sysMode ==■ REAL) return(DLLVERSIO ) ; else return(DLLVERSIONNH) ; } / j za :== a sa α xa xsnx= .a xs:» =5 :=:-=:---:== /♦ iodrvr4 Description : Test ventilator start up sequence logic, Returns : * / // void FAR PASCAL _export iodrvr ( ) { int sob[4], eob[4]; int Bobl[4], sob2[4], eobl[4], eob2[4]; ChnlBfr ♦ cbpl[4]; ChnlBfr ♦ cbp2[4); //C0M4 object declarations comm4 com4boardl (COM4BlCHNLS,COM4BRDlCONFIG) ; comm4 com4board2(COM4B2CHNLS,COM4BRD2CONFIG) ; //Fill both COM4 board buffers with data. for (int i - 0; i < 4000; i++) brdBfrs[0]fi] = brdBfrsf1] [i] = (i%26)+65; 163 int temp = strlen(clbl) memcpy(brdBfrPtrs[0 fO],clbl,temp) memcpy(brdBfrPtrsf0 fl],c2bl,temp) memcpy(brdBfrPtrs[0 [2] ,c3bl,temp) memcpy(brdBfrPtrsf0 [3] ,c4bl,temp) memcpy(brdBfrPtrs[ 1 [0] ,clb2,temp) memcpy(brdBfrPtrsf1 [1) ,c2b2,temp) memcpy(brdBfrPtrs[1 [2] ,c3b2,temp) memcpy(brdBfrPtrs[1 [3] ,c4b2,temp) //First get channel buffer data. Since systemControl //has not been called at this point, channel data //buffers should contain no data. //getrs232 (int board, int chnl, int &sob, int &eob) cbpl[0] » getrs232(l,l,sob[0] ,eob[0j) cbp2[0] = getrs232(2,l,sob[l) ,eob[l] ) cbp2[l] = getrs232(2,2,sob[2],eob[2)) cbp2[2) = getrs232(2,3,sob[3],eob[3] ) //Now simulate the receipt of data by updating bfrlndx. //bfrlndx is the index into the board buffer which points //to the last character received. //NOTE: This has changed. bfrlndx now points to one position // beyond the last character received. for (int j = 0; j < 2; j++){ for (int k = 0; k < 4; k++) { com4BfrIndx[j] [k] .bfrlndx - temp+1; } > //Copy data into channel buffers. systemControl(CAPTUREFLOW,0) ; systemControl(CAPTUREETC02,0) ; systemControl(CAPTURESP02,0) ; //Grab pointer to channel buffers. //getrs232 (int board, int chnl, int &sob, int Seob) cbpl[0] =■ getrs232(l, 1, sobl[0], eobl[0] ) ; cbp2[0] = getrs232(2, 1, sob2[0], eob2[0] ) ; 164 cbp2[l] - getrs232(2, 2, sob2[l], eob2[l]); cbp2f2] - getrs232(2, 3, sob2[2], eob2[2]); //Now test logic for ventilator initialization sequence, char cmdstringf20] ; char ♦ cr - "\r"; strcpy(cmdstring, "RDY" ) ; strcat(cmdstring,cr) ; strcat(cmdstring, "ON") ; strcat(cmdstring,cr) ; strcat(cmdstring, "IMV" ) ; strcat(cmdstring,cr) ; //copy cmd string into board 1 buffer at channel one allocation memcpy(brdBfrPtrsfO] [0] ,cmdstring,12) ; //Now go through venitlator sequence startup systemControl(CAPTUREVENT,0) ; //Check for data in channel buffer. cbpl[0] - getrs232(l, 1, sobl[0], eobl[0]); int state =» RDYWAIT; systemControl(VENTINIT,state) ; systemControl(VENTINIT,,state) ; systemControl (VENTINIT . ,state) ; } /♦ iodrvr5 Description : Tests set breath rate logic. Returns : * / //= // void FAR PASCAL _export iodrvr5 ( ) { clock_t timel; int i; int ventState - 0; //Turn on ventilator... pumpControl (VENTPOWE , 1) ; 165 //Now wait for ventilator start-up sequence to be performed, ventstate - RDYWAIT; Boolean ready - TRUE; timel - clock( ) ; /* while ((ventStatθ /- IMVMODE) && ( (clockO-timel) /CLOCKS_PER_SEC<-180 ? TRUE (ready-FALSE))) systemControl(VENTINIT,ventStatθ) ; ♦ / while (ventState 1- IMVMODE) systemControl(VENTINIT,ventState) ; /* if ( lready) { //Timeout has occurred. cout « "Ventilator start up sequence failed" « endl; return; } else { cout « "Ventilator initialized into IMV mode" « endl; ventState = 0; } */ ventState - 0; //Now try to query alarms ventCtrlWait(ALQ, 0); ventState - 0; //Now try to set breath rate. for (i-0; i<10; i++) ventControl(SBR, 15, ventState); //Turn off ventilator... pumpControl (VENTPOWER, 0); //ox.-.---- ™™ - ™ ™————.. ———-.--—.————- =-=-3-=.:-3.=:sιxs3-κ 3{E-;xssx /* iodrvr6 Description : General checkout of all ventilator commands. 166 int cmdOption - 1; static int ventState - 0; static int cmd - 0; static int value - 0; */ void FAR PASCAL _export iodrvr6() { const VENTON = 1; const VENTOFF - 2; const SYSTEMCONTROL - 3; conβt VENTCONTROL - 4; static int cmdOption - 1; static int ventState - 0; static int cmd - 0; static int value - 0; int goon - 1; int retval; /* //Set cmdOption in debugger while (goon) { if (cmdOption — VENTON) pumpControl(VENTPOWER, 1); else if (cmdOption « VENTOFF) pumpControl(VENTPOWER, 0); else if (cmdOption — SYSTEMCONTROL) systemControl(VENTINIT,ventState) ; else if (cmdOption « VENTCONTROL) ventControl(cmd, value, ventState); else goon - 0; } > */ 167 while (goon) { switch (cmdOption) { 111 case VENTON: //Turn on the ventilator retval - pumpControl(VENTPOWER,' 1); fanControl(COND, 1) ; break; 112 case VENTOFF: //Turn it off retval - pumpControl(VENTPOWER, 0); fanControl(COND,0) ; break; 113 cane SYSTEMCONTROL: //Perform a system control event. retval - aystemControl(VENTINIT,ventState) ; break; //4 case VENTCONTROL: //Command the ventilator retval - ventControl(cmd, value, ventState); break; //Anything else -> exit default: return; } //=============- / ♦ iodrvr7 Description : First checkout of getting data from the novametrix boards. Returns */ //= // void FAR PASCAL _export iodrvr7 ( ) { int average02, averagePulse, pulsoxStatus, funcRet, breakhere; funcRet » getPulsox(average02, averagePulse, pulsoxStatus); 168 breakhere - funcRet; //Set a break point here if you would like. / / 33=33 = 333333X333 = 333X3333333 3 33333=3338X3 S3 XSBI E- BC 333333X3 B X333 X333 S3 = 35 S3 S3 SB £3 XX B 33 S333 X S333 331 33 £333 =333 £3 £33a XX XX S3 SB 3333 / ♦ iodrvr9 Description : First checkout of getting data from the EtC02 novametrix sensor. Returns : */ //==== -.«»=:== // void FAR PASCAL _export iodrvr9 ( ) { ChnlBfr ♦ cbfr; int funcRet, breakhere, sob, eob; funcRet - com4board2.cmdC02swrev( ) ; //Copy data into channel buffers. systemControl (CAPTUREETC02, 0) ; //Grab pointer to channel buffers. //getrs232(int board, int chnl, int &sob, int &eob) cbfr - getrs232 (NOVABRD, ETC02CHNL, sob, eob); breakhere - funcRet; 1 r=:=-== / ♦ iodrvr10 Description : General checkout of all ventilator commands using ventControlWait. Returns : */ //== « 169 // void FAR PASCAL _export iodrvrl0() { const VENTON - 1; const VENTOFF - 2; const SYSTEMCONTROL - 3; const VENTCONTROL - 4; static int cmdOption - 1; static int ventState - 0; static int cmd - 0; static int value — 0; int goon - 1; int retval; while (goon) { switch (cmdOption) { 111 case VENTON: //Turn on the ventilator retval = pumpControl(VENTPOWER, 1); anControl(COND, 1) ; break; 112 case VENTOFF: //Turn it off retval = pumpControl(VENTPOWER, 0); fanControl(COND,0) ; break; 113 case SYSTEMCONTROL: //Perform a system control event, retval - systemControl(VENTINIT,ventState) ; break; //4 case VENTCONTROL: //Command the ventilator retval - ventCtrlWait(cmd, value); break; //Anything else -> exit default: return; > //—————————————-BX3BIB.BB.BIX.XX-..-.»>.<..»S / ♦ iodrvrll Description : First checkout of getting data from the FLOW and capnostat novametrix sensors. 170 Returns */ II- // void FAR PASCAL _export iodrvrll() { ChnlBfr ♦ cbfr; int funcRet, breakhere, sob, eob; lifdef STATUS_LOG_E ABLED statuslog( "Called iodrvrll to send FLOW commands... \n\r" ) ; lendif STATUS_LOG_ENABLED funcRet - com4board2.cmdFLOWswrev( ) ; funcRet - com4board2.cmdFLOWwfdata( ) ; funcRet - com4board2.cmdC02swrev( ) ; funcRet - com4board2.cmdC02con ( ) ; / ♦ This was the old way / / VVV TVVVVVVVVVVVVVVVVVVVVVV rV ^^ //Copy data into channel buffers. systemControl(CAPTUREFLOW,0) ; //Grab pointer to channel buffers. //getrs232(int board, int chnl, int &sob, int &eob) cbfr = getrs232(NOVABRD, FLOWCHNL, sob, eob); // ΛΛΛ ΛΛ A ΛΛΛΛΛΛΛ */ breakhere - funcRet; } / =====3S3SXX33BX3XXEXESSXXnS3SIXXX anzxi-insix Hs s xflKtKf H / ♦ target Description : This is part of the thruput analysis. This test driver I receives data from simulator. It is included here in I the guiif so as to have access to the various global ' variables of interest. 171 Returns : * I ============== // void FAR PASCAL _export target(int &sob, int &eob, int δbfrlndx, ChnlBfr far ♦ Scbufr) { const int chnll - 1; const int boardl - 1; //First, capture data into local buffer. //CHANNEL 1 OF BOARD 1 //Ventilator channel is channel 1 of board 1 systemControl(CAPTUREVENT, 0) ; //Copies board bfr data into chnl bfr //dandy.astound - Note that getrs232 expects board and channel to be //the actual number, not one less. It may be wise in the future to //change getrs232 to use the constants CHNLl and BOARDl defined in //one of the global header files to make it consistent with all //other calls. cbufr «= getrs232 (boardl, chnll, sob, eob); //Sets our local pointer to //channel buffer. bfrlndx = com4BfrIndx[C0M4BRDl] [CHNLl] .bfrlndx; //Determine if the block should be logged? if (nextToRead == eob) { //Probably do nothing here. Assume we are handling ports fast //enough to prevent a complete and perfect wrap-around condition. return; } if (nextToRead < eob) //Check for a complete block, while ( (eob-1)-nextToRead >= BLOCKSIZE) { //Process as many blocks as possible. //if (validateChksm(^cbufr+nextToRead, // BLOCKSIZE,handle) ) //This is where a block is written to file write(handle, (void ♦ ) ( ♦ cbufr+nextToRead) ,BLOCKSIZE+1) ; 172 //dandy.astound - beep to indicate block written /////////////////////////////////////////////////// //char bell = 0x07; //cout « bell « endl; /////////////////////////////////////////////////// //Update last read value nextToRead += (BLOCKSIZE+1) ; } else //(nextToRead > eob) - possible wrap-around condition //Check for a complete block. while (CHNLBFRSIZE-nextToRead + eob > BLOCKSIZE) { //Process as many blocks as possible. //Check for wrap-around condition if (nextToRead+BLOCKSIZE < CHNLBFRSIZE) { //No wrap write(handle, (void^) ( ♦ cbufr-fnextToRead) ,BLOCKSIZE+l) ; //dandy.astound - beep to indicate block written /////////////////////////////////////////////////// //char bell - 0x07; //cout « bell « endl; /////////////////////////////////////////////////// } else { //Wrap //Do first part write(handle, ( ♦ cbufr-fnextToRead) ,CHNLBFRSIZE-nextToRead) ; //Now do second part w r i t e ( h a n d l e , ♦ c b u f r , BLOCKSIZE-(CHNLBFRSIZE-nextToRead)+1) ; //dandy.astound - beep to indicate block written /////////////////////////////////////////////////// //char bell = 0x07; //cout « bell « endl; /////////////////////////////////////////////////// } //Update last read value nextToRead - (nextToRead + (BLOCKSIZE+1) ) %CHNLBFRSIZE; if ( 1 (nextToRead > eob)) break; 173 ) //end of logging code } //—-KB. B.B.: 1— —— BK..-. «— .... „-.—--.---.----.-. / ♦ iodrvr12 Description : First checkout of double buffering Returnβ : */ //==_ iz-xszεxasaαi las saBxxc-ssr:: // void FAR PASCAL _export iodrvrl2() { ; 111 need just one statement to break on } ' /n-mBBBBBBBBB BBBaBBBBBBBBBBBBBBBBB BBHB BBBB Ba SXXaXXBKBKBKBKBRBKBtaK iBKBK // void FAR PASCAL _export iodrvrl3() { //board 1 for (int i - 0; i < CHNLSPERBRD; i++) if (brdlBlks[i] .tempBfrlnfo 1- NULL && brdlBlks[i].curBfrInfo->bfrIndx < brdlBlks[i] .blockSize/2) ); ; 174 write(handlesblfi) ,brdlBlks[i] .flushBfrlnfo->bfr,brdlBlks[i] .bloc kSize) ; brdlBlksfi] .tempBfrlnfo - NULL; _- > b //board 2 for (i - 0; i < CHNLSPERBRD; i++) if (brd2Blks[i). tempBfrlnfo 1- NULL && brd2Blks[i]. curBf rlnf o->bf rlndx < brd2Blks[i] .blockSize/2) { lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Logging board 2, channel "); 0 strncat(statusMsg,itoa(i-fl,tempstring, 10) ,5) ; 8trncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif STATUS_LOG_ENABLED write(handlesb2[i] ,brd2Blks[i) .flushBfrlnfo->bfr,brd2Blks[i] .bloc kSize) ; brd2Blks[i] .tempBfrlnfo - NULL; 5 > } j χxxX=a»XXJ3-3EXEZX3XSXXXSSXZ3XBS S«tf =-3 -ii-xxsxxxαs«xcxαπιxαxBS«sκ / ♦ iodrvr14 Description : Tests the new getpulseox method. Returns : */ //== xst∑asxsttxsEix xxsssaE-iXrXs // void FAR PASCAL _export iodrvrl4 ( ) { //First βet both pulse ox buffers to 0. for (int i - 0; i < BRD2CHNL3BLKSIZE; i++) { brd2chnl3bfr[0)[i) - 0; brd2chnl3bfr[l][i] - 0; } //Now put special data at beginning of current buffer, brd2chnl3bfr[0)[0] - 254; //Start byte. brd2chnl3bfr[0)[2] - 98; brd2chnl3bfr[0][4] - 60; brd2chnl3bfr[0][6] - 1; 175 -617 - //Now set temp buffer to point to something other than //null to indicate flush buffer has data. brd2Blks[2] .tempBfrlnfo - &b2c3curBfrInfo; //Set buffer index to maximum brd2Blks[2] .curBfrlnfo->bfrlndx - BRD2CHNL3BLKSIZE-1; int avg02, avgHR, statusCode; //Call getPulβOx to retrieve data. getPulsox(avg02, avgHR, statusCode); //Expected: 98, 60, 1 //Now put special data in middle of buffer... brd2chnl3bfr[0][500] - 254; //Start byte. brd2chnl3bfr[0][502) - 97; brd2chnl3bfr[0][504] - 59; brd2chnl3bfr[0][506] » 0; //Call getPulsOx to retrieve data. avg02 - avgHR - statusCode -0; getPulsox(avg02, avgHR, statusCode); //Expected: 97, 59, 0 //Set index to before special data in middle of buffer. brd2Blks[2] .curBfrlnfo->bfrIndx - 499; //Call getPulsOx to retrieve data. avg02 = avgHR - statusCode- -0; getPulsox(avg02, avgHR, statusCode); //Expected: 98, 60, 1 //Now put special data at end of buffer... brd2chnl3bfr[0] [993] - 254; //Start byte. brd2chnl3bfr[0)[995] - 96; brd2chnl3bfr[0][997] - 58; brd2chnl3bfr[0][999] - -l; brd2Blks[2] .curBfrlnfo->bfr - brd2chnl3bfr[1] ; brd2Blks[2] .flushBfrlnfo->bfr - brd2chnl3bfr[0] ; brd2Blks[2] .curBfrlnfo->bfrlndx - 10; //Call getPulsOx to retrieve data. avg02 - avgHR - statusCode -0; getPulso (avg02, avgHR, statusCode); //Expected: 96, 58, -1 //Now move data up one byte brd2chnl3bfr[0][993] - 0; brd2chnl3bfr[0][994) - 254; //Start byte, brd2chnl3bfr[0][995) - 0; brd2chnl3bfr[0][996] - 96; brd2chnl3bfr[0][997] - 0; brd2chnl3bfr[0][998] - 58; brd2chnl3bfr[0][999) - 0; 176 //Call getPulβOx to retrieve data. avg02 - avgHR - statusCode -0; getPulsox(avg02, avgHR, statusCode) //Expected: 97, 59, 0 If- I* iodrvr15 Description : File 10 test. Returns : */ It- // void FAR PASCAL _export iodrvrl5() { unsigned char bfrflOO); //unsigned char a - 0; for (int i - 0; i < 100; i++) bfrfi] - i; //write(handlesb2[0],bfr,100) ; fwrite(bfr, 100, 1, fhandlesb2[0] ) ; //fclosβ(fhandlesb2[0] ) ; II- /♦ iodrvr16 Description : Logs RS232 buffers to disk using fopen/fwrite Returns : ♦ / // ■ // void FAR PASCAL ^ export iodrvrl6() { lifndef DISABLE_FILE_I0 177 //board 1 for (int i - 0; i < CHNLSPERBRD; i++) if (brdlBlks[i] .tempBfrlnfo 1- NULL && brd lBlks f i ) . curB rlnf o- >bf rlndx < (brdlBlks[i) .blockSize-100) ) { lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Logging board 1, channel "); strncat(statusMsg,itoa(i+1,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslogtstatusMsg) ; lendif STATUS_LOG_ENABLED _dos_gettime(&timeS) ; fwrite(&starttime, 1, 1,fhandlesb2[i] ) ; fwrite(&timeS, sizeof(timeS) , 1, fhandlesbl[i] ) ; fwrite(brdlBlks[i] .flushBfrlnfo->bfr, brdlBlks[i] .blockSize, 1,fhandlesbl[i] ) ; brdlBlks[i] .tempBfrlnfo - NULL; } //board 2 for (i - 0; i < CHNLSPERBRD; i++) if (brd2Blks[i].tempBfrlnfo 1- NULL &£. brd2Blks [ i ] . curBf rlnf o->bf rlndx < (brd2Blks[i].blockSize-100) ) { lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Logging board 2, channel "); strncat(statusMsg,ito (i+1,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusM8g) ; lendif STATUS_LOG_ENABLED _dθ8_gettime(&timeS) ; \ fwrite(&βtarttime, 1, 1,fhandlesb2[i] ) ; fwrite(&timeS, sizeof(timeS) , 1, fhandlesb2[i] ) ; fwrite(brd2Blks[i] .flushBfrInfo->bfr, brd2Blks[i) .blockSize, 1,fhandlesb2[i] ) ; brd2Blks[i].tempBfrlnfo - NULL; > lendif DISABLE_FILE_IO } — ———— / ♦ calcChksm Description : Calculates checksum. Returns : Returns checksum value Note : This function is duplicated in comm4.h. It is included here for test purposes. Not exported. 178 */ II- 1/ unsigned char calcChksm(unsigned char ♦ cmd, int length) { unsigned char sum - 0; int i; if (length « 0) for (i - 0; i < strlen(cmd); sum +- cmd[i++)); else for (i - 0; i < length; sum +- cmd[i++]); lifdef CALC_CBECKSUM_LOG_ENABLED strcpy(statUBMsg, "Length is "); strncat(BtatusMsg,itoa(length,tempstring,10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(atatu8Msg) ; strcpy(statusMsg, "sum is "); strncat(statusMsg,itoa(sum,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5); statuslog(8tatusMsg) ; lendif CALC_CHECKSUM_LOG_ENABLED //Calculate checksum. return( ( (-sum) + 1) & 0x7F) ; // ...... ,....—.—....... / ♦ iodrvrl7 Description : Unit test of getCapnostat Returns : */ It- tr void FAR PASCAL _export iodrvrl7() { 179 int ♦ IcapnoData, size; unsigned char vpacketf) - {0x80,0x00,0x00,0x08,0x78, // 5 6 7 8 9 10 11 0x81,0x00,0x00,0x08,0x00,0x00,0x77, // 12 13 14 15 16 17 18 0x82,0x00,0x00,0x08,0x00,0x00,0x76, // 19 20 21 22 23 24 0x83,0x00,0x00,0x08,0x00,0x75, // 25 26 27 28 29 30 31 32 0x84,0x00,0x00,0x08,0x20,0x40,0x00,0x14); unsigned char zeropacketf33] ; int etC02, respRate, retval; for (int i - 0; i < βizeof(vpacket) ; i++) zeropacket[i] - 0x00; //First set both capnostat buffers to 0. for (i » 0; i < BRD2CHNL2BLKSIZE; i++) { brd2chnl2bfrf0]fi) - 0; brd2chnl2bfr[l][i] - 0; } //Modify vpacket to contain values that we can recognized. The //initialization of this array above is using board-genrated data, //but contains too many zeros to really know when we are pulling //the correct value from the data stream. vpacketf1] - 0x01; vpacket[2] - 0x02; vpacketf ] - calcChksm(vpacket,4 ) ; vpacketf6] - 0x03; vpacket[7] - 0x04; vpacket[9] - 0x05; vpacketf 10] - 0x06; vpacketfll] - calcChksm({.vpacket[5],6) ; vpacket[13) - 0x07; vpacket[14] - 0x08; vpacketf16] - 0x09; vpacketf17] - 0x0a; vpacketf 18] - calcChksm(&vpacketf12] ,6) ; vpacket[20] - 0x0b; vpacketf21] - 0x0c; vpacket[23] - OxOd; vpacket[24] - calcChksm(&vpacket[ 19],5) ; vpacket[26] = 0X0Θ; vpacket[27] - OxOf; 180 vpacket[32] - calcChksm(&vpacketf25] ,7) ; //TEST 1 - VALID PACKET STARTING AT BYTE 0 OF THE CURRENT BUFFER. // Current buffer index at end of buffer. II 11 Set up EtC02 channel to have a valid packets //Buffer 0 defaults to current buffer; buffer 1 " is flush buffer. memcpy(brd2chnl2bfr[0] , vpacket, ' sizeof(vpacket) ) ; I I Set temp buffer to non-null value to βignal receipt of data. brd2Blks[l] .tempBfrlnfo - &b2c2curBfrlnfo; //Set buffer index to maximum brd2Blks[ 1] .curBfrlnfo->bfrIndx - BRD2CHNL2BLKSIZE-1; retval - getCapnostat(IcapnoData, size); //Expect: 0x0506,0x090A /retval-2 etC02 - IcapnoDatafO] ; //TEST 2 - VALID PACKET STARTING AT BYTE 0 OF THE CURRENT BUFFER. // Current buffer index at start of buffer. //Set buffer index to minimum brd2Blks[l) .curBfrlnfo->bfrlndx - 0; retval - getCapnostat(IcapnoData, size); //Expect: 0,0 /retval-0 //TEST 3 - VALID PACKET STARTING AT BYTE 0 OF THE CURRENT BUFFER. // Current buffer before respiration rate, but after end tidal. brd2Blks[l].curBfrlnfo->bfrlndx - 11; retval = getCapnostat(IcapnoData, size); //Expect: 0x506 /retval-1 //* /♦ iodrvrlδ Description : Unit test of getFlow Returns : 181 */ / szsaxaxss«sxxxx3xa--3sαxax3xsxxs3xαxsxxx<s«a dS-asSBtsa-αmxi // 5 void FAR PASCAL _export iddrvrl8() { int ♦ lflowData, size; II 0 1 2 3 4 5 6 7 8 u n s i g n e d c h a r v p a c k e t [ ] {0xd3, 0x07 ,0x 0,0x00, 0x02, 0x00, 0x04 ,0x00 ,0x24, 10 It 9 10 11 12 13 1 15 16 0xd3,0x06,0x40,0x00,0x16,0x00,0x00,0x51, //17 18 19 20 21 22 23 24 ! 5 0xd3,0x06,0x40,0x00,0x18,0x00,0x00,0x4f, //25 26 27 28 29 30 31 32 0xd3,0x06,0x40,0x00,Oxle,0x00,0x00,0x49, //33 34 ' 35 36 37 38 39 40 0 0xd3,0x06,0x40,0x00,0xl ,0x00,0x00,0x48, //41 42 43 44 45 46 47 48 0xd3,0x06,0x40, 0x00,0x22,0x00,0x00,0x45, //49 50 51 52 53 54 55 56 5 0xd3,0x06,0x40,0x00,0x23,0x00,0x00,0x44, //57 58 59. 60 61 0xd3,0x03,0x40,0x00,0x6a} ; unsigned char zeropacket[62] ; int etC02, respRate, retval; 0 . lifdef STATUS_LOG_ENABLED strcp (statusMsg, "Executing iodrvrlθ.. ,\n\r" ) ; statuslog(statusMsg) ; ♦endif STATUS_LOG_ENABLED . for (int i - 0; i < sizeof(vpacket) ; i++) zeropacketfi] - 0x00; 5 182 //First set both flow buffers to 0. for (i - 0; i < BRD2CHNL1BLKSIZE; i++) { brd2chnllbfr[0][i] - 0; brd2chnllbfr[l][i] - 0; > //Modify vpacket to contain values that we can recognized. The //initialization of this array above is .using board-genrated data, //but contains too many zeros to really know when we are pulling //the correct value from the data stream. vpacket[12] - 0x01; vpacketf16] - calcChksm(&vpacket[9] ,7) ; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Checksum in iodrvrlδ: "); strncat(statusMsg,itoa(vpacket[16] ,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif CALC_CHECKSUM_LOG_ENABLED vpacket[20] - 0x02; vpacket[24] - calcChksm(&vpacket[17] ,7) ; lifdef STATUS_LOG_E ABLED strcpy(statusMsg, "Checksum in iodrvrlβ: "); strncat(statusMsg,itoa(vpacket[2 ] ,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif CALC_CHECKSUM_LOG_ENABLED vpacket[28) = 0x03; vpacket[32] = calcChksm(fi,vpacket[25],7) ; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Checksum in iodrvrlδ: "); strncat(statusMsg,ito (vpacket[32] ,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif CALC CHECKSUM LOG ENABLED vpacket[36) - 0x04; vpacket[40] - calcChksm(&vpacket[33] ,7) ; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Checksum in iodrvrlδ: "); strncat(statusMsg,itoa(vpacket[40] ,tempstring,10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif CALC_CHECKSUM_LOG_ENABLED vpacket[44] = 0x05; 183 vpacket[48] - calcChksm(&vpacket[41] ,7) ; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Checksum in iodrvrlδ: "); strncat(statusMsg,itoa(vpacket[48] ,tempstring, 10) ,5) ; strncat(statusMsg, "\n\r" ,5) ; statuslog(statusMsg) ; lendif CALC_CHECKSUM_LOG_ENABLED vpacket[52] = 0x06; vpacket[56) - calcChksm(&vpacket[49] ,7) ; lifdef STATUS_LOG_ENABLED strcpy(statusMsg, "Checksum in iodrvr18: "); strncat(statusMsg,itoa(vpacket[56] ,tempstring,10) ,5) ; strncat(statusMsg, "\n\r",5) ; statuslog(statusMsg) ; lendif CALC_CHECKSUM_LOG_ENABLED //TEST 1 - VALID PACKET STARTING AT BYTE 0 OF THE CURRENT BUFFER. // Current buffer index at end of buffer. // //Set up Flow channel to have a valid packets //Buffer 0 defaults to current buffer; buffer 1 is flush buffer. memcpy(brd2chnllbfr[0] , vpacket, sizeof(vpacket)) ; //Set temp buffer to non-null value to signal receipt of data. brd2Blks[0] .tempBfrlnfo = &b2clcurBfrlnfo; //Set buffer index to maximum brd2Blks[0] .curBfrlnfo->bfrlndx = BRD2CHNL1BLKSIZE-1; retval = getFlow(lflowData, size); //Expect: //TEST 2 - VALID PACKET STARTING AT BYTE 0 OF THE CURRENT BUFFER. // Current buffer index at start of buffer. //Set buffer index to minimum brd2Blks[0] .curBfrlnfo->bfrlndx - 0; retval = getFlow(lflowData, size); //Expect: //TEST 3 - VALID PACKET STARTING AT BYTE 0 OF THE CURRENT BUFFER. // Set buffer index to somewhere in the middle of data. //Set buffer index to minimum brd2Blks[0] .curBfrlnfo->bfrlndx - 30; 184 retval - ge tFlow ( l f lowData , s iz e ) ; / /Expect : } //———: :. II void FAR PASCAL _export iodrvr19(int event) { if (event — 0) { //Get and store time if (timeindx == 0) filehndl-fopen("f:\\lstatio2\\buildl\\data\\iodrvrl9.dat", ■ wb") ; _dos gettime(-f (timeSs[timeindx] ) ) ; timeindx-f+; } else { fwrite(timeSs,sizeof(timeSs) ,timeindx,filehndl) ; fclose(filehndl) ; ■'■"' timeindx « 0; } } If- / ♦ iodrvr20 Description : Test Capnostat functions by starting waveform, then 185 halting waveform to enable other functions to be called which access the 10 buffers. Returns : ♦ / // • // void FAR PASCAL _export iodrvr20() { int ♦ IcapnoData; int lsize, lesbl, lesb2, lesb3, lwf, lssb; int lresult; int lcsb; int retval; int lstatus; //First, be sure the board is not streaming data at us. stopEtC02() ; //Perform Self-Test and reset internal buffer pointers, etc. retval = getEtC02selfTest(lstatus) ; //This starts an adpater zero on Capnostat board capnoAdptrO(lcsb) ; //First start waveform. startEtC02() ; //Now halt waveform. Put break here and allow to collect data //for a period of time. stopEtC02( ) ; //Call capnostat routines... // //This gets interleaved data getCapnostat{IcapnoData, lsize); //This gets the extended statue bytes. getCapnoESB(lesbl, lesb2, lesb3); //This get last waveform point and short " status byte getCapnoWFssb(lwf, lssb); //This does a self-test of the board, but more importantly, //reset indices associated with the capnostat channel buffers //to their initial values. retval - getEtC02selfTest(lresult) ; 186 } //- — - / ♦ iodrvr21 Description More testing of the pulsox board. Returns : * / It- It void FAR PASCAL _export iodrvr21( ) { int wfvalue; int retval = getPulsoxWF(wfvalue) ; } / / ^^sxzΛX3tx mτ*taτx^^ιxτ3zxxxxΛrΛ∑a.Bcτmxι**τ3**Bim**κx*κ*τaκιmιwxι / ♦ iodrvr22 Description : Even more testing of the pulsox board. Returns : */ //»-. — _. .... .. ...... // void FAR PASCAL _export iodrvr22() { int ♦ lo2data, ♦lo2satWFs, lsize, Istart; int retval - getAllPulsox(lo2data, lo2satWFs, lsize, Istart); } / / B-=-3sπnαs Bxxtιια--3a=iBtxfSiπκs.--. -τxMtBKXΛMtmK^m τxmmtnimi nmmmtτMmimπtmtmVΛ mtmtxxKx^∑iztz: / ♦ iodrvr23 Description : Kind of a collection of a bunch of stuff. 187 Returns : ♦ / //...-......... .................................. . ..... // void FAR PASCAL _export iodrvr23() { unsigned char ♦ lswrev; int llength; int retval - getEtC02swrev(lswrev, llength); int lstatus; retval » getEtC02selfTest(lstatus) ; int lcsb; retval - capnoAdptrO(lcsb) ; retval - startEtC02( ) ; retval « stopEtC02 ( ) ; retval - getFlowSWrev( ) ; retval - startFlow( ) ; retval - stopFlow( ) ; retval - startEtC02( ) ; retval - startFlow(); } / ♦ iodrvr24 Description : Start ventilator and then commands novametrix boards to I send continuous waveform. Buffers are then written J to disk to be used to test parsing routines on dev. station. Returns : 188 ♦ / //• // void FAR PASCAL _export iodrvr24( ) { clock_t timel; FILE ♦ capnohandle, ♦ flowhandle, ♦ pulsoxhandle; . . . int i; int ventState - 0; //Turn on ventilator... pumpControl(VEWTPOWER, 1); //Now wait for ventilator start-up sequence to be performed. ventState - RDYWAIT; Boolean ready - TRUE; timel = clock(); / ♦ while ((ventState /- IMVMODE) && ((clockO-timel)/CLOCKS_PER_SEC<=180 ? TRUE (ready=FALSE) ) ) systemControl(VENTINIT,ventState) ; */ while (ventState 1- IMVMODE) systemControl(VENTINIT,ventState) ; int retval = startEtC02 ( ) ; retval = startFlow(); retval - stopEtC02 ( ) ; retval - stopFlow( ) ; //Turn off ventilator... pumpControl(VENTPOWER, 0); flowhandle - fopen("c:Wflowno.dat" , "wb"); capnohandle = fopen("c:Wcapno.dat", "wb"); pulsoxhandle « fopen( "c: Wpulsno.dat", "wb"); //Write all structures and buffers to disk. 189 fwrite brd2Blks[OJ .curBfrlnfo->bfr,BRD2CHNLlBLKSIZE, 1,flowhandle) ; fwrite & (brd2Blks[0] .curBfrlnfo->bfrlndx) ,sizeof(int) , 1,flowhandl e); fwrite & (brd2Blks[0] .curBfrlnfo->lastread) ,sizeof(int) , l,flowhand le); fwrite brd2Blks[0] .flushBfrlnfo->bfr,BRD2CHNL1BLKSIZE, 1,flowhandl e); fwrite & (brd2Blks[0] .flushBfrlnfo->bfrlndx) ,sizeof(int) , 1,flowhan die); fwrite &(brd2Blks[0] .flushBfrlnfo->lastread) ,sizeof(int) , l,flowha ndle) ; fwrite brd2Blks[1] .curBfrlnfo->bf ,BRD2CHNL2BLKSIZE, 1,capnohandle) ; fwrite & (brd2Blks[1] .curBfrlnfo->bfrlndx) ,sizeof(int) ,l,capnohand le); fwrite & (brd2Blks[ 1] .curBfrlnfo->lastread) ,sizeof(int) , l,capnohan die); fwrite brd2Blks[1] .flushBfrlnfo->bfr,BRD2CHNL2BLKSIZE, 1,capnohand le); fwrite £> (brd2Blks[ 1] .flushBfrlnfo->bfrlndx) ,sizeof(int) , l,capnoha ndle) ; fwrite & (brd2Blks[ 1] .flushBfrlnfo->lastread) ,sizeof(int) , l,capnoh andle) fwrite brd2Blks[2] .curBfrInfo->bfr,BRD2CHNL3BLKSIZE, l,pulsoxhandl e); fwrite & (brd2Blks[2] .curBfrlnfo->bfrlndx) ,sizeof(int) , 1,pulsoxhan die); fwrite &(brd2Blks[2] .curBfrInfo->lastread) ,sizeof(int) , l,pulsoxha ndle) ; fwrite (brd2Blks[2 ] .flushBfrlnfo->bfr,BRD2CHUL3BLKSIZE, 1,pulsoxhan die); 190 fwrite(& (brd2Blks[2] .fluehBfrlnfo->bfrlndx) ,sizeof (int) , l,pulsoxh andle) ; fwrite(& (brd2Blks[2] .flushBfrlnfo->lastread) ,sizeof(int) , 1,pulsox handle) ; fclose(flowhandle) ; fclose(capnohandle) ; fclose(pulsoxhandle) ; } / ♦ iodrvr25 Description : Uses data collected in iodrvr24 and runs tests on etAll functions. Returns : / II void FAR PASCAL _export iodrvr25() { FILE ♦ capnohandle, ♦ flowhandle, ♦ pulsoxhandle; //NOTE : Files should be in specified directory, //flowhandle = fopen( "c: \\sled\\run4\\flowno.dat" , "rb"); //capnohandle - fopen( "c: WsledWrun4Wcapno.dat" , "rb"); //pulsoxhandle - fopen("c:\\sled\\run5\\pulsno.dat" , "rb"); flowhandle - fopen("c:Wflowno.dat" , "rb"); capnohandle - fopen( "c:\\capno.dat" , "rb"); pulsoxhandle - fopen("c:Wpulsno.dat", "rb"); //Write all structures and buffers to disk. fread(brd2Blks[0] .curBfrlnfo->bfr,BRD2CHNL1BLKSIZE, 1,flowhandle) ; fread(&(brd2Blks[0] .curBfrlnfo->bfrlndx) ,sizeof(int) ,1,flowhandle) ; fread)& (brd2Blks[0] .curBfrlnfo->lastread) ,sizeof(int) , 1,flowhandl e); fread(brd2Blks[0] .flushBfrlnfo->bfr,BRD2CHNL1BLKSIZE,1,flowhandle) 191 fread(i(brd2Blka(0 . . luβhBfrlnfo->bfrlndx) ,βi2βo (int) ,l,flowhand le); fread(& (brd2Blkβ[0] .flushBfrlnfo->lastread) ,βizeof(int) , l,f owhan die); fread(brd2Blka[ 1] .curBfrlnfo->bfr,BRD2CHNL2BLKSIZE, l,capnohandle) ; fread(&(brd2Blkβ[l] .curBfrInfo->bfrlndx) ,sizeof(int) , l,capnohandl e); fread(& (brd2Blks[ 1] .curBfrlnfo->laatread) ,βizeof(int) , l,capnohand le); fread(brd2Blkβ[ 1] .flushBfrlnfo->bfr,BRD2CHNL2BLKSIZE, l,capnohandl e)? fread(& (brd2Blks[ 1] .flushBfrlnfo->bfrlndx) ,sizeof(int) , l,capnohan die); fread(&(brd2Blks[ 1] .fluβhBfrlnfo->lastread) ,sizeof(int) , l,capnoha ndle) ; fread(brd2BlkB[2].curBfrInfo->bfr,BRD2CHNL3BLKSIZE,l,pulsoxhandle) ; fread(& (brd2Blks[2] .curBfrInfo->bfrlndx) ,sizeof(int) , l,pulsoxhand le); fread(& (brd2Blke(2) .curBfrlnfo->laβtread) ,sizeof(int) , 1,pulsoxhan die); fread(brd2Blks[2].flU8hBfrInfo->bfr,BRD2CHNL3BIrKSIZE,l,pulsoxhand le); fread(& (brd2Blks[2] .flushBfrlnfo->bfrlndx) ,aizβof(int) , l,pulsoxha ndle) ; fread(&(brd2Blks[2] .flushBfrlnfo->laatread) ,βizeof(int) , l,pulsoxh andle) ; fclose(flowhandle) ; fclose(capnohandle) ; fcloβe(pulsoxhandle) ; //Pulso Ox int ♦lo2data, ♦loΣaatWFs, lsize, lβtart; 192 int goon - 1; while (goon) int retval - getAllPulaox(lo2data, lo2satWFs, lsize, Istart); //Capnostat int *lwf, lwfsize, *lpatData, lpatdsize, lssb, *lesb, lesbsize; goon - 1; while (goon) int retval - getAllCapno(lwf, lwfsize, Istart, lpatData, lpatdβize, lssb, lesb, lesbsize); //Flow int **lflowwfø, *lfwføize, *lfwfstart, *ldpiβ, *ldpivalue, ldpisize; int lestatusl, lestatus2, lestatus3; goon - 1; while (goon) int retval - getAllFlow(lfloww s, lfwfsize, lfwfstart, ldpis, ldpivalue, ldpisize, lestatusl, lestatus2, lestatus3); } II- / ♦ getAllinit Description : Almoβt the same as iodrvr25 except this is used internally I by getAllCanpo and getAllFlow to check out GUI interface. Returns : */ It- // void getAllinit( ) { FILE *capnohandle, ♦ flowhandle, *pulsoxhandle; //NOTE : Files should be in specified directory, flowhandle - fopen("c:\\sled\\run4\\flowno.dat", "rb"); capnohandle - fopen( "c:\\sled\\run4\\capno.dat", "rb"); pulsoxhandle - fopen( "c:\\sled\\run5\\pulsno.dat", "rb"); 193 //Write all structures and buffers to disk, fread(brd2Blks[0] .curBfrlnfo->bfr,BRD2CHNL1BLKSIZE, 1,flowhandle) ; fread(&(brd2Blks[0J .curBfrlnfo->bfrlndx) ,sizeof(int) ,l,flowhandle) ; fread(&(brd2Blks[0] .curBfrlnfo->lastread) ,sizeof(int) , 1,flowhandl e); fread(brd2Blks[0] . lushBfrlnfo->bfr,BRD2CHNL1BLKSIZE,1,flowhandle) ; fread(& (brd2Blks[0] .flushBfrlnfo->bfrlndx) ,sizeof(int) ,l, lowhand le); fread(& (brd2Blks[0] .flushBfrlnfo->lastread) ,sizeof(int) , l,flowhan die); fread(brd2Blks[1] .curBfrlnfo->bfr,BRD2CHNL2BLKSIZE, 1,capnohandle) ; fread(&(brd2Blks[ 1] .curBfrlnfo->bfrlndx) ,sizeof(int) , l,capnohandl e); fread(& (brd2Blks[ 1] .curBfrlnfo->lastread) ,sizeof(int) ,l,capnohand le); fread(brd2Blks[l] .flushBfrInfo->bfr,BRD2CHNL2BLKSIZE, l,capnohandl e); fread(& (brd2Blks[l] .flushBfrlnfo->bfrlndx) ,sizeof(int) , l,capnohan die); fread(& (brd2Blks[l] .flushBfrlnfo->lastread) ,sizeof(int) , l,capnoha ndle); fread(brd2Blks[2] .curBfrlnfo->bfr,BRD2CHNL3BLKSIZE, 1,pulsoxhandle) ; fread(& (brd2Blks[2J .curBfrlnfo->bfrlndx) ,sizeof(int) , l,pulsoxhand le); fread(&(brd2Blks[2] .curBfrlnfo->lastread) ,sizeof(int) , 1,pulsoxhan die); fread(brd2Blks[2] .flushBfrlnfo->bfr,BRD2CHNL3BLKSIZE, 1,pulsoxhand le); 194 fread) & (brd2Blkβ[2] .flushBfrlnfo->bfrlndx) ,sizeof(int) , l,pulsoxha ndle) ; fread(& (brd2Blks[2] .flushBfrlnfo->lastread) ,sizeof(int) , l,pulsoxh andle) ; fclose(flowhandle) ; fclose(capnohandle) ; fclose(pulsoxhandle) ; //Pulso Ox int ♦ lo2data, ♦ lo2satWFs, lsize, Istart; //int retval - getAllPulsox(lo2data, lo2satWFs, lsize, Istart); //Capnostat int ^lwf, lwfsize, ♦ lpatData, lpatdsize, lssb, ♦lesb, lesbsize; //retval = getAllCapno(lwf, lwfsize, Istart, // lpatData, lpatdsize, lssb, // lesb, lesbsize) ; //Flow //int ♦♦ lflowwfs, ♦ lfwfsize, ♦ lfwfstart, ♦ ldpis, ♦ ldpivalue, ldpisize; //int lestatusl, lestatus2, lestatus3; //retval = getAllFlow(lflowwfs, lfwfβize, lfwfstart, // ldpis, ldpivalue, ldpisize, // lestatusl, lestatus2, lestatus3); //= tsss-ict: /♦ iodrvr26 Description : Checks out data logging using new and improved hopefully) logWaveForm function. Returns : ♦ / //• // void FAR PASCAL _export iodrvr26() { clock_t timel; 195 int i; int ventState - 0; //Turn on ventilator... pumpControl(VENTPOWER, 1) ; //Now wait for ventilator start-up sequence to be performed. ventState - RDYWAIT; Boolean ready - TRUE; timel — clock(); / ♦ while ((ventState /= IMVMODE) && ( ( clock O -timel ) /CLOCKS_PER_SEC<=180 ? TRUE ( ready-FALSE ) ) ) systemControl(VENTINIT,ventState) ; ♦ / while (ventState i= IMVMODE) systemControl(VENTINIT,ventState) ; //Ventilator initialization complete. //Now start waveforms int retval = startEtC02() ; retval = startFlow(); logWaveForm(l, 1) ; //Start flow logging. logWaveForm(2, 1) ; //Start capnostat logging logWaveForm(3, 1) ; //Start pulsox loggin //Now call logging routine at a periodic rate for 60 seconds timel - clock( ) ; for (i=0; i<60; i++){ timel = clock( ) ; while ( (clockO-timel)/CLOCKS_PER_SEC<-l) ? logWaveForm(l,2) ; //Continue flow logging. logWaveForm(2,2) ; //Continue capnostat logging logWaveForm(3,2) ; //Continue pulsox logging > //Stop logging. logWaveForm(l,3) ; //Start flow logging. logWaveForm(2,3) ; //Start capnostat logging logWaveForm(3,3) ; //Start pulsox loggin initControl(CLOSE) ; retval = stopEtC02(); 196 retval - stopFlow( ) ; //Turn off ventilator.. ' . pumpControl(VENTPOWER, 0) ; //==== / ♦ iodrvr27 Description Driver to test new ventFindlnBuffer Bcheme for systemControl and ALQ command. Returns : ♦ / // void FAR PASCAL _export iodrvr27() { int state - RDYWAIT; enum {WRAP, NOWRAP} testCondition WRAP; //Even though hardware may not be present, set system mode to REAL since 11 we want to test real code. sysMode = REAL; //Set test condition. NOTE: For WRAP condition, set buffer size in //lOTYPES.H for ventilator to something small (βay, 5). switch (testCondition) .{ case NOWRAP: //Firβt, non-wrap condition will be tested... //Waiting for RDY response from ventilator. // /PPuutt eexxppeecctteedd rreessppoonnssee iinn bbuuffffeerr aanndd uuppddaattee bbuuffffeerr index. sttrrccppyy((bbrrddllcchhnnllllbbffrr[[ Λ 0"]' , ven *t-"R°esponse m [RS^T-] i m [0 i ] *) .; bbrrdd llBBllkkss [[ 00 ]] . c u r B f r l n f o - > b f r I n d strlen(vent tRReesspnoonnssee[ TRRSSTT]1 [ f00] 1 )) ; : 197 systemControl (VENTINIT, state); //Waiting for ON response from ventilator. / / =ΛSzss^=s∑xxtuιs=X3a^K3mtSΛmzτactsxnΛXΛZxsam sx3asι^tsΛtaxxst^Λx i st*mmtxτat //Put expected response in buffer and update buffer index, strcpy (brdlchnllbf r[0]+brdlBlks [0] .curBfrlnf o->bf rlndx, ventResponse [MO] [0] ) ; brdlBlks [ 0 ) . curBf rlnf o->bf rlndx + « strlen(ventResponse[MO] [ 0] ) ; systemControl (VENTINIT, state); . //Put expected response in buffer and update buffer index, strcpy(brdlchnllbfr[0]+brdlBlks[0] .curBfrlnfo->bfrlndx, ventResponse[MIMV] [0] ) ; brdlBlks [ 0 ] . curBf rlnf o->bf rlndx + - strlen(ventResponse[MIMV] [0] ) ; systemControl(VENTINIT, state); break; case WRAP: //Second, wrap-around condition tested... //Assume buffer length is 5. //Waiting for RDY response from ventilator. / / T3a ^^ XXXmajXWtmt tmtmτmκmt m mtMiaΛatm X*m ΕKmt tmtXmXt t tmτBm m*W m* 11 Put expected response in buffer and update buffer index. //Put "RD" at the end of buffer. memcpy( (void * ) ( brdlchnl lbf r [ 0 ] + 3 ) , (void ♦ ) (ventResponse [RST] [0] ) , 2); //PUT "Y\r" at beginning of other buffer memcpy( (void ♦ ) ( brd lchnl lbf r [ 1 ] ) , (void ♦) (ventResponse[RST][0]+2) , 2); //Update other buffer information to conform to wrap-around condition. brdlBlks[0] .curBfrlnfo->lastread - 3; 198 brdlBlks[0] .curBfrlnfo->bfrIndx - 0; brdlBlks[0] . flushB rlnfo->bfrlndx - 2; //Switch buffers to simulate wrap-around condition. brdlBlks[0] .tempBfrlnfo - brdlBlks[0] .curBfrlnfo; brdlBlks[0] .curBfrlnfo - brdlBlks[0] .flushBfrlnfo; brdlBlks[0].flushBfrlnfo - brdlBlks[0] .tempBfrlnfo; systemControl(VENTINIT, state); //Waiting for ON response from ventilator. //Put expected response in buffer and update buffer index. //Put "0N\r" at the end of current buffer now containing "Y\r H . memcpy( (void ♦ ) ( brdlchnllbfr [ 1 ] +2 ) , (void ♦) (ventResponse[M0] [0]) , 3); //Update other buffer information to conform to wrap-around condition. brdlBlks[0] .curBfrlnfo->bfrlndx - 0; //Switch buffers to simulate wrap-around condition. brdlBlks[0] .tempBfrlnfo = brdlBlks[0] .curBfrlnfo; brdlBlks[0] .curBfrlnfo - brdlBlks[0] .flushBfrlnfo; brdlBlks[0] .fluehBfrlnfo = brdlBlks[0] .tempBfrlnfo; systemControl(VENTINIT, state); //Waiting for IMV response from ventilator. / /7===:_=:- 3 =x:=:s=.=x=xr3=-ι=3B.3-e.........».«»........... //Put expected response in buffer and update buffer index. strcpy(brdlchnllbfr[0]+brdlBlks[0] .curBfrlnfo->bfrlndx, ventResponse[MIMV] [0] ) ; brdlBlks [ 0 ] . curBf rlnf o->bf rlndx + « strlen(ventResponse[MIMV] [0] ) ; systemControl(VENTINIT, state); break; default: ; 199 / /— r-: rasa as ..as rasa sar==-=s.-a. t3 -a.....x- , = . — —— =>—— — — — .................. assa ..... sa / ♦ writeval Description : An entry point to test if two delphi applications running I simultaneously sharing the same dll have there own data area. Returns */ // void FAR PASCAL _export writeval(int val) { //Just set a global static variable, testvar =■ val; } / j— — -a t ca ox ss ss ss sx S3 . 33 s X3 xs =s ta xs xs ss cc xs sx xs sa sa XΛx t tm Λ t tMt Λs mxs wΛmtmtSΛm mtm tΛXΛKzatat tmtVΛiassssiS.'^TXSSSzsa I* readval Description : An entry point to test if two delphi applications running I simultaneously sharing the same dll have there own data area. Returns */ It' // unβigned int FAR PASCAL _export readval( ) { //Just set a global static variable, //return(testvar) ; //return(brdlBlks[0] .bfrlndx) ; return(brd2Blks[1] .curBfrlnfo->bfrlnd ) ; 200

Claims: WHAT IS CLAIMED IS: 1. A self-contained transportable life support system for resuscitation, stabilization, and transport of a patient, the system comprising: a) an environmentally controlled housing for receiving and supporting a patient; b) a plurality of medical devices disposed within the housing; and c) a control circuit attached to the housing, at least a portion of the control circuit extending to an external surface of the housing, for regulating operation of the medical devices and environmental conditions within the housing in response to monitored life support conditions of the patient. 2. The self-contained transportable life support system as recited in Claim 1, wherein the control circuit is programmably controllable to regulate operation of the medical devices and life support conditions of the patient independent of operator intervention. 3. The self-contained transportable life support system as recited in Claim 1, wherein the control circuit is programmably controllable to regulate environmental support conditions within the housing independent of operator intervention. 4. The self-contained transportable life support system as recited in Claim 1, wherein the plurality of medical devices comprises: a) a ventilator; b) a suction device; c) a fluid infusion device; d) a defibrillator; e) an oxygen enricher/generator; f) an electrocardiograph; g) a blood pressure monitor; h) a temperature sensor; i) a respiration volume and rate monitor; j) a ventilator gas monitor for monitoring p0 2 and pC0 2 ; k) an 0 2 saturation monitor; 1) a cardiac rate, cardiac output, and local blood flow monitor; ) a device for performing blood chemistry analysis; and n) an electroencephalograph. 5. The self-contained transportable life support system as recited in Claim 1, further comprising at least one environmental control device disposed within the housing, and in electrical communication with the control circuit, for regulating environmental conditions within the housing. 6. The self-contained transportable life support system as recited in Claim 5, wherein the environmental control device comprises a heater for heating an interior portion of the housing so as to maintain the interior portion above a predetermined minimum temperature. 7. The self-contained transportable life support system as recited in Claim 5, wherein the environmental control device comprises a cooler for cooling an interior portion of the housing so as to maintain the interior portion below a predetermined maximum temperature. 8. The self-contained transportabl life support system as recited in Claim 5, wherein the environmental control device comprises air filtration system for filtering air within the housing to deplete chemical and bacterial contamination within the housing. 9. The self-contained transportable life support system as recited in Claim 1, wherein the medical devices comprise: a) at least one medical monitoring device for monitoring at least one life support condition of the patient; and b) at least one medical treatment device for providing medical treatment to the patient, the treatment device providing treatment being regulatable by the control circuit in response to signals from the medical monitoring device. 10. The self-contained transportable life support system as recited in Claim 1, wherein the control system comprises a closed-loop control system. 11. The self-contained transportable life support system as recited in Claim 1, further comprising a communication circuit attached to the housing for communicating between the control circuit and a remote station. 12. The self-contained transportable life support system as recited in Claim 9, wherein the communication system comprises: a) a transmitter for transmitting information representative of patient life support conditions; b) a receiver for receiving externally generated remote control signals; and c) the control circuit being responsive to regulate operation of the medical devices and environmental conditions within the housing in response to the remote control signals. 13. The self-contained transportable life support system as recited in Claim 1, wherein the control circuit comprises: a) a general purpose microprocessor; and b) a data storage device for storing patient data, medical device data, environmental data, and system data. 14. The self-contained transportable life support system as recited in Claim 1, wherein the housing having an interior portion is configured to receive and engage a stretcher, and also having an exterior portion configured to receive and engage vehicular mounted stretcher supports. 15. The self-contained transportable life support system as recited in Claim 1, wherein the housing co prises four stretcher retention members disposed within the housing for receiving and engaging a stretcher within the housing. 16. The self-contained transportable life support system as recited m Claim 13, wherein each of the stretcher retention members comprise a stretcher engagement mechanism operative to provide locking engagement to the stretcher solely in response to placement of the stretcher upon the stretcher engagement mechanism. 17. The self-contained transportable life support system as recited in Claim 1, wherein the control circuit comprises: a) first and second battery sections; and b) a charging circuit for selectively charging either one of the first and second battery sections; c) the control circuit being operative to alternately charge the first battery section from an external power source while maintaininσ the second battery section ready to power the medical devices during an interruption of external power, and then charge the second battery section from the external power source while maintaining the first battery section ready to power the medical devices during an interruption of external power. 18. The self-contained transportable life support system as recited in Claim 1, wherein the medical devices comprise: a) a temperature monitoring device connectable to a patient for monitoring a body temperature of the patient; and b) a temperature control device connectable to the patient for controlling the body temperature of the patient. 19. The self-contained transportable life support system as recited in Claim 16, wherein the temperature control device comprises an extracorporeal blood temperature controller for regulating blood temperature of the patient in response to the temperature monitoring system. 20. The self-contained transportable life support system as recited in Claim 16, wherein the temperature control device further comprises a temperature controlled water jacket. 21. The self-contained transportable life support system as recited in Claim 16, wherein the temperature monitoring device comprises at least one of: a) an indwelling rectal temperature probe; b) an infrared eardrum temperature sensor; c) an axillary temperature sensor; and d) an intra-esophageal temperature sensor. 22. The self-contained transportable life support system as recited in Claim 16, wherein the temperature control device directs temperature controlled air about the patient in response to the temperature monitoring device, so as to maintain the temperature of the patient within a desired range. 23. The self-contained transportable life support system as recited in Claim 1, wherein the housing is sealable to isolate the patient therein from chemical and biological conditions external to the housing. 24. The self-contained transportable life support system as recited in Claim 1, further comprising a pressure regulating device disposed within the housing, in electrical communication with the control circuit, for regulating pressure within the housing. 25. The self-contained transportable life support system as recited in Claim 1, wherein the control circuit comprises an audio/visual device, at least a portion of which being disposed external to the housing and in electrical communication with the control circuit, for communicating information representative of patient life support conditions. 26. The self-contained transportable life support system as recited in Claim 23, wherein the audio/visual device displays treatment instructions in response to operating conditions of the medical devices. 27. The self-contained transportable life support system as recited in Claim 1, wherein the control circuit comprises a power regulation circuit for regulating application of electrical power to the medical devices in accordance with an assigned priority status of the medical devices. 28. The self-contained transportable life support system as recited in Claim 25, wherein the control circuit is operative to modify the assigned priority status of medical devices in response to the patient life support conditions. 29. The self-contained transportable life support system as recited in Claim 1, wherein the control circuit is operative to simulate a plurality of life support conditions, to monitor an operator's utilization of the medical devices in response to the simulated life support conditions, and to evaluate the effectiveness of the operator's utilization of the medical devices. 30. The self-contained transportable life support system as recited in Claim 1, wherein the housing comprises at least one of a hyperbaric chamber and a hypobaric chamber. 31. The self-contained transportable life support system as recited in Claim 28, wherein the hyperbaric chamber comprises a polymer material. 32. The self-contained transportable life support system as recited in Claim 1, wherein the control circuit comprises a medical data reader for receiving medical data from a medical data storage device, the control circuit being operative to regulate operation of the medical devices in response to the received medical data. 33. The self-contained transportable life support system as recited in Claim 30, wherein the medical data storage device is selected from the group consisting of: a) a dog tag having medical data stored 5 therein; b) an identification card having medical data stored therein; and c) a storage device implanted beneath a patient 's skin. 0 34. A method for transporting a patient while providing life support therefor, the method comprising the steps of: a) controlling an environment within a transportable housing configured to receive and 5 support the patient; b) providing a plurality of medical devices within the housing to facilitate resuscitation and stabilization of the patient; and c; regulating operation of the medical 0 devices and environmental conditions within the housing in response to monitored life support conditions of the patient. 35. The method as recited in Claim 32, further comprising the step of programmably controlling the D control circuit so as to regulate operation of the medical devices and life support conditions of the patient independent of simultaneous operator intervention. 36. The method as recited in Claim 32, wherein the 0 step of providing a plurality of medical devices comprises providing: a) a ventilator; b) a suction device; c) a fluid infusion device; 5 d) a defibrillator; e) an oxygen enricher/generator; f) an electrocardiograph; g) a blood pressure monitor; h) a temperature sensor; l) a respiration volume and rate monitor: j) a ventilator gas monitor for monitoring p0 2 and pC0 2 ; k) an 0 2 saturation monitor; and 1) a cardiac rate, cardiac output, and local blood flow monitor; m) a device for performing blood chemistry analysis; and n) an electroencephalograph. 37. The method as recited in Claim 32, further comprising the step of heating an interior portion of the housing so as to maintain the interior portion above a predetermined minimum temperature. 38. The method as recited in Claim 32, further comprising the step of cooling an interior portion of the housing so as to maintain the interior portion below a predetermined maximum temperature. 39. The method as recited in Claim 32, further comprising the step of filtering the air within the housing. 40. The method as recited in Claim 32, wherein the step of providing a plurality of medical devices comprises providing at least one medical monitoring device for monitoring at least one life support condition of the patient and providing at least one medical treatment device for providing medical treatment to the patient, the treatment device being regulatable by the control circuit m response to signals from the medical monitoring device. 41. The method as recited in Claim 32, wherein the step of regulating operation of the medical devices comprises regulating operation of the medical devices via a closed-loop control system. 42. The method as recited in Claim 32, further comprising the step of communicating between the control circuit and a remote location. 43. The method as recited in Claim 40, wherein the step of communicating comprises: a) transmitting information representative of patient life support conditions; b) receiving externally generated remote control signals; and c) the control circuit responding to the remote control signals, such that patient life support conditions are regulatable in response to the remote control signals. 44. The method as recited in Claim 32, wherein the step of regulating operation of the medical devices comprises regulating operation of the medical devices with a general purpose microprocessor. 45. The method as recited in Claim 32, further comprising the steps of receiving and engaging a stretcher within the housing and engaging the housing with vehicle mounted stretcher supports. 46. The method as recited in Claim 32, further comprising the steps of receiving and engaging a stretcher within the housing. 47. The method as recited in Claim 44, wherein the step of engaging a stretcher comprises providing locking engagement of the housing to the stretcher solely in response to placement of the stretcher upon a stretcher engagement mechanism. 48. The method as recited in Claim 32, wherein the step of regulating the operation of the medical devices comprises: a) providing power to the medical devices via first and second battery sections; and b) selectively charging either one of the first or second battery sections; c) alternately charging the first battery section from an external power source while maintaining the second battery section ready to power the medical devices during an interruption of external power, and then charging the second battery section from the external power source while drawing power from the first battery section ready to power the medical devices during an interruption of medical power. 49. The method as recited in Claim 32, further comprising the steps of: a) monitoring a body temperature of the patient; and b) controlling the body temperature of the patient . 50. The method as recited in Claim 47, wherein the step of controlling the body temperature of the patient comprises controlling the body temperature of the patient via an extracorporeal blood temperature controller for regulating blood temperature of the patient in response to the temperature monitoring system. 51. The method as recited in Claim 47, wherein the step of controlling the body temperature of the patient comprises controlling the body temperature of the patient via a temperature controlled water jacket. 52. The method as recited in Claim 47, wherein the step of monitoring the body temperature of the patient comprises at least one of: a) monitoring the body temperature of the patient via a rectal temperature probe; b; monitoring the body temperature of the patient via an infrared eardrum temperature sensor; c) monitoring the body temperature of the patient via an axillary temperature sensor; and d) monitoring the body temperature of the patient via an intra-esophageal temperature sensor. 53. The method as recited in Claim 47, wherein the step of controlling the body temperature of the patient comprises directing temperature controlled air about the patient in response to the temperature monitoring system, so as to maintain the temperature of the patient within a desired range. 54. The method as recited in Claim 32, further comprising the step of sealing the housing so as to isolate the patient therein from chemical and biological conditions external to the housing. 55. The method as recited in Claim 32, further comprising the step of regulating the pressure within the housing. 56. The method as recited in Claim 32, further comprising the step of displaying patient life support conditions. 57. The method as recited in Claim 54, further comprising the step of displaying treatment instructions in response to patient life support conditions. 58. The method as recited in Claim 32, wherein the step of regulating operation of the medical devices comprises regulating application of electric power to the medical devices in accordance with an assigned priority status of the medical devices. 59. The method as recited in Claim 56, further comprising the step of modifying the assigned priority status of the medical devices in response to patient life support conditions. 60. The method as recited in Claim 32, further comprising the step of simulating a plurality of life support conditions via the control circuit and monitoring an operator's utilization of the medical devices in response to the simulated life support conditions to evaluate the effectiveness of the operator's utilization of the medical devices. 61. The method as recited in Claim 32, wherein the step of receiving the patient within an environmentally controlled housing comprises receiving the patient within one of a hyperbaric chamber and a hypobaric chamber. 62. The method as recited in Claim 59, wherein the step of receiving the patient within a hyperbaric chamber 5 comprises receiving the patient within a hyperbaric chamber comprised of a polymer material. 63. The method as recited in Claim 32, further comprising the step of receiving medical data from a medical data storage device via a medical data reader, 0 the control circuit being operative to regulate operation of the medical devices in response to the received medical data. 64. The method as recited in Claim 61, wherein the step of receiving medical data from a medical storage 'j device comprises receiving medical data from a medical storage device selected from the group consisting of: a) a dog tag having medical data stored therein; b) an identification card having medical data 0 stored therein; and c) a storage device implanted beneath a patient's skin.

Inventors: BERRY MARK L, BRAYTON JOHN R, CLARK WALTER D, GARCIA ROBERT M, HANKS DONALD, HOOD DAVID D, KNEALE TODD D, MOORE GENE B, SHERILL DAVID, SHULTZ DOUGLAS E, SOBKO WILLIAM R, STANLEY DAVID M, TOTH LOUIS S, BERRY, MARK, L., BRAYTON, JOHN, R., CLARK, WALTER, D., GARCIA, ROBERT, M., HANKS, DONALD, HOOD, DAVID, D., KNEALE, TODD, D., MOORE, GENE, B., SHERILL, DAVID, SHULTZ, DOUGLAS, E., SOBKO, WILLIAM, R., STANLEY, DAVID, M., TOTH, LOUIS, S.
Applicants: NORTHROP GRUMMAN CORP, NORTHROP GRUMMAN CORPORATION
Application year: 1997
Main classification: A61F5
IPC codes: A61G1, A61G10, A61M16