/* Real Time Devices, Inc. Box 906 State College, PA 16804 Voice: 814-234-8087 FAX: 814-234-5218 Board: DM5406 Compiler: Turbo C (r) version 1.0, 1.5, 2.0 Turbo C++ (r) version 1.0 Borland C++ (r) version 2.0 Last update: 9/4/93 This file contains procedure and functions used by the sample programs provided with your DM5406 The procedures are well documented and should be helpful in learning how to program your DM5406 */ #include #define ENABLED 1 #define DISABLED 0 #define INPUT 1 #define OUTPUT 0 #define TRUE 1 #define FALSE 0 unsigned BaseAddress; float VoltageRange, DACSlope, ConversionFactor, Baseline ; int DACOffset; /************************** InitializeBoardSettings The InitializeBoardSettings procedure is used to set the Base address variable and calculate the conversion factor for converting between digital values and volts. Since the base address variable is not set until this procedure is called, make certain that you call this procedure before any others in this file. *******************/ void InitializeBoardSettings(unsigned BA, float Range) { BaseAddress = BA; VoltageRange = Range; ConversionFactor = VoltageRange / 4096.0; Baseline = 0; } /*********** The Function DigitalToReal converts a digitized value to a real world value. In these sample programs the conversion factor and baseline correspond to converting between digitized values and volts. ***********/ float DigitalToReal(int DigitalValue) { return(DigitalValue * ConversionFactor + Baseline); } /******************* ResetBoard The ResetBoard procedure is used to reset the DM5406. The 8255 PPI is configured so that ports A and C are input and port B is output, a dummy A-D conversion is performed and then the clear board command is sent. *******************/ void ResetBoard(void) { outportb(BaseAddress + PPI_CTRL, 0x99); /* Set PPI Port B for output */ outportb(BaseAddress + PPI_B, 0); /* Channel 0, Gain 1, Ext Trig = Disabled, IRQ = Disabled */ outportb(BaseAddress + SCAN_BURST_SLCT, 0); outportb(BaseAddress + CLEAR_BOARD, 0); outportb(BaseAddress + START_CONVERSION, 0); /* Start a Dummy conversion */ delay(5); outportb(BaseAddress + CLEAR_BOARD, 0); /* Any value will do */ } /******************* ClearBoard The clear board procedure writes to the CLEAR BOARD port on the DM5406. *******************/ void ClearBoard(void) { outportb(BaseAddress + CLEAR_BOARD, 0); /* Any value will do */ } /******************* ClearIrqStatus The ClearIrqStat procedure reads from the CLEAR_IRQ_STAT port on the DM5406. *******************/ void ClearIrqStat(void) { inportb(BaseAddress + CLEAR_IRQ_STAT); } /******************* ClearDmaDone The ClearDmaDone procedure reads from the CLEAR_DMA_ONE port on the DM5406. *******************/ void ClearDmaDone(void) { inportb(BaseAddress + CLEAR_DMA_DONE); } /******************* SetChannel The SetChannel procedure is used to set the channel bits, B0..B3, in the CHANNEL SELECT register (BA + 5). Note how this procedure sets only the channel select bits; it does not change the other bits in this register. This is important because if you unintentionally clear the other bits it can cause unexpected behavior of the DM5406. *******************/ void SetChannel(unsigned char ChannelNumber) { unsigned char B; B = inportb(BaseAddress + CHANNEL_SLCT); /* read current byte */ B = B & 240; /* clear B0 - B3 */ B = B | (ChannelNumber - 1); /* set channel bits */ outportb(BaseAddress + CHANNEL_SLCT, B); /* write new byte */ } /******************* SetGain The SetGain procedure is used to set the Gain bits on the DM5406. Note how this procedure sets only the channel select bits; it does not change the other bits in this register. This is important because if you unintentionally clear the other bits it can cause unexpected behavior of the DM5406. *******************/ void SetGain(unsigned char Gain) { unsigned char B; switch (Gain) { case 1 : Gain = 0; break; case 2 : Gain = 1; break; case 4 : Gain = 2; break; case 8 : Gain = 3; break; default : Gain = 0; break; } B = inportb(BaseAddress + GAIN_SLCT); /* read current byte */ B = B & 207; /* clear B4,B5*/ B = B | (Gain * 16); /* set gain bits */ outportb(BaseAddress + GAIN_SLCT, B); /* write new byte */ } /******************* SetIRQStatus The SetIRQStatus procedure is used to set or clear the IRQ Enable bit on the DM5406. A value of 1 passed to this procedure enables interrupts a value of 0 disables interrupts. *******************/ void SetIRQStatus(char IRQStatus) { unsigned char B; B = inportb(BaseAddress + IRQ_ENABLE); /* read current byte */ B = B & 127; /* clear B5 */ B = B | IRQStatus * 128; /* set IRQ select bit */ outportb(BaseAddress + IRQ_ENABLE, B); /* write new byte */ } /******************* SetExternalTrigger The SetExternalTrigger routine is used to set the external trigger bit on the DM5406. A value of 1 passed to this procedure enables the external trigger, a value of 0 disables the external trigger. *******************/ void SetExternalTrigger(unsigned char TriggerStatus) { unsigned char B; B = inportb(BaseAddress + EXT_TRIG_ENABLE); /* read current byte */ B = B & 191; /* clear B6 */ B = B | TriggerStatus * 64; /* set Trigger bit */ outportb(BaseAddress + EXT_TRIG_ENABLE, B); /* write new byte */ } /******************* SetInterruptSource The SetInterruptSource procedure determines the source used for generating interrupts for the DM5406. Passing SOURCE_AD_START selects the A/D start convert; passing SOURCE_DMA_DONE selects DMA done; passing SOURCE_TRIGGER selects the trigger; finally, passing SOURCE_PACER_CLOCK to this procedure selects the pacer clock. *******************/ void SetInterruptSource(unsigned char Source) { unsigned char B; B = inportb(BaseAddress + SCAN_BURST_SLCT); /*read current byte*/ B = B & 207; /*clear bits 4 and 5*/ B = B | Source * 16; /*set new bits*/ outportb(BaseAddress + SCAN_BURST_SLCT, B); /*write new byte*/ } /****************** ScanBurstEnable The ScanBurstEnable procedure allows the user to enable either scan mode or burst mode. A value of 0 passed to this procedure disables both modes; a value of 1 enables scan mode; a value of 2 enables burst mode. ******************/ void ScanBurstEnable(unsigned char Enable) { unsigned char B; switch (Enable) { case DISABLE_BOTH: Enable = 0; break; case SCAN_ENABLE: Enable = 2; break; case BURST_ENABLE: Enable = 3; break; default: Enable = 0; } B = inportb(BaseAddress + SCAN_BURST_SLCT); /*read current byte*/ B = B & 63; /*clear bits 6 and 7*/ B = B | Enable * 64; /*set new bits*/ outportb(BaseAddress + SCAN_BURST_SLCT, B); /*write new byte*/ } /****************** SetScanChannels The SetScanChannels procedure determines how many channels are scanned or bursted while in the appropriate mode, selected using ScanBurstEnable. The parameter passed in this procedure is simply the number of channels the user wishes to include. ******************/ void SetScanChannels(int NumChannels) { unsigned char B; B = inportb(BaseAddress + SCAN_BURST_SLCT); /*read current byte*/ B = B & 240; /*clear bits 0 through 3*/ B = B | (NumChannels - 1); /*set new bits*/ outportb(BaseAddress + SCAN_BURST_SLCT, B); /*write new byte*/ } /******************* StartConversion The StartConversion procedure is used to start conversions. *******************/ void StartConversion(void) { outportb(BaseAddress + START_CONVERSION, 0); } /******************* ConversionDone The ConversionDone function returns TRUE if a conversion is complete, FALSE if a conversion is in progress. *******************/ char ConversionDone(void) { unsigned char Status; Status = inportb(BaseAddress + STATUS_BYTE); /* read board status */ if ( (Status & 1) == 1) return(TRUE); /* if B0 is set return TRUE */ else return(FALSE); /* if B0 is not set return FALSE */ } /******************* ReadData The ReadData function retrieves two bytes from the converter and combines them into an integer value. *******************/ int ReadData(void) { unsigned char MSB, LSB; int DigitalValue; MSB = inportb(BaseAddress + READ_DATA); LSB = inportb(BaseAddress + READ_DATA); DigitalValue = (MSB * 256 + LSB); return(DigitalValue); } /******************* ClockMode The ClockMode procedure is used to set the mode of a designated counter on the 8254 programmable interval timer (PIT). *******************/ void ClockMode(unsigned char Clock, unsigned char Mode) { unsigned char StatusByte; StatusByte = (Clock * 64) + (Mode * 2) + 48; outportb(BaseAddress + TIMER_CTRL, StatusByte); } /******************* ClockDivisor The ClockDivisor procedure is used to set the divisor of a designated counter on the 8254 programmable interval timer (PIT). This procedure assumes that the counter has already been set to receive the least significant byte (LSB) of the divisor followed by the most significant byte (MSB). *******************/ void ClockDivisor(unsigned char Clock, unsigned int Divisor) { unsigned char MSB, LSB; unsigned int PortID; PortID = BaseAddress + TIMER_A + Clock; LSB = Divisor % 256; MSB = Divisor / 256; outportb(PortID, LSB); outportb(PortID, MSB); } /*********** SetUserClock The SetUserClock procedure is used to set the programmable interval timer (PIT) on the DM5406 such that the output of counter 2 goes high at the specified rate. The maximum attainable rate this procedure, as written, is 250,000 Hz although you can easily change this by adjusting the divisors accordingly. ***********/ void SetUserClock(float Rate) { ClockMode(0, 2); ClockDivisor(0, 8); ClockMode(1, 2); ClockDivisor(1, (500000.0 / Rate)); ClockMode(2, 2); ClockDivisor(2, 2); } /*********** SetPacerClock The SetPacerClock procedure is used to set the programmable interval timer (PIT) on the DM5406 such that the output of counter 1 goes high at the specified rate. The maximum attainable rate this procedure, as written, is 250,000 Hz although you can easily change this by adjusting the divisors accordingly. Note that the Pacer and User clocks are really the same device and cannot be used independently. ***********/ void SetPacerClock(float Rate) { ClockMode(0, 2); ClockDivisor(0, 16); ClockMode(1, 2); ClockDivisor(1, (500000.0 / Rate)); } /******************* ClockDone *******************/ char ClockDone(unsigned char Timer) { unsigned int CounterValue; unsigned char LSB, MSB; LSB = inportb(BaseAddress + TIMER_A + Timer); MSB = inportb(BaseAddress + TIMER_A + Timer); CounterValue = (MSB * 256) + LSB; if (CounterValue > 1) return(FALSE); else return(TRUE); } /*********** Read DigitalIO The ReadDigitalIO function returns the value of the specified digital input port. Each digital input line is represented by a bit of the return value. Digital in 0 is bit 0, digital in 1 is bit 1, and so on. ***********/ unsigned char ReadDigitalIO(unsigned char InputPort) { return(inportb(BaseAddress + PPI_A + InputPort)); } /*********** WriteDigitalIO The WriteDigitalIO function sets the value of the digital output port to equal the value passed as parameter v. Each digital output line is represented by a bit of v. Digital out 0 is bit 0, digital out 1 is bit 1, and so on. ***********/ void WriteDigitalIO(unsigned char OutputPort, unsigned char v) { outportb(BaseAddress + PPI_A + OutputPort, v); } /***************** ConfigureIOPorts The ConfigureIOPorts procedure is used to configure the ports A and C on the 8255 PPI for either input or output. A value of 1 means input, a value of 0 is for output. It is advisable to use the INPUT and OUTPUT constants defined in this file. Port B remains set for output. *****************/ void ConfigureIOPorts(unsigned char PortA, unsigned char PortC) { unsigned char ControlByte; ControlByte = 128 + (PortA * 16) + (PortC * 9); outportb(BaseAddress+PPI_CTRL, ControlByte); } /***************** UpdateDAC The UpdateDAC procedure outputs the specified voltage to the specifed DAC. The DACSlope and DACOffset variables must be set to the values required for the output range of the DACs. *****************/ void UpdateDAC(unsigned char DAC, float Volts) { int Value; Value = (int) (Volts * DACSlope) + DACOffset; outportb(BaseAddress + DAC1_LSB + (DAC - 1) * 2, Value % 256); outportb(BaseAddress + DAC1_MSB + (DAC - 1) * 2, Value / 256); outportb(BaseAddress + DAC_UPDATE, 0); }