/****************************************************************************** * * Copyright 1999 NetBurner ALL RIGHTS RESERVED * Permission is hereby granted to purchasers of NetBurner Hardware * to use or modify this computer program for any use as long as the * resultant program is only executed on NetBurner provided hardware. * * No other rights to use this program or it's derivitives in part or * in whole are granted. * * It may be possible to license this or other NetBurner software for * use on non NetBurner Hardware. * Please contact Licensing@Netburner.com for more infomation. * * NetBurner makes no representation or warranties * with respect to the performance of this computer program, and * specifically disclaims any responsibility for any damages, * special or consequential, connected with the use of this program. * *--------------------------------------------------------------------- * * information available at: http://www.netburner.com * E-Mail info@netburner.com * * Support is availible: E-Mail support@netburner.com * *****************************************************************************/ /*------------------------------------------------------------------- Application Example Driver for NetBurner General Purpose I/O card Revision 1.0 Jan 15, 1999 This software module contains low level drivers to operate the digital I/O, DAC, and ADC of the NetBurner General Purpose I/O application example hardware. -------------------------------------------------------------------*/ #include "predef.h" #include "Sim5206.h" #include #include #include #include //----- Chip select defines ----- // R/W, A3, and A4 are used by a 3 to 8 line decoder to create 8 chip selects // from a single chip select of the ColdFire. #define IO_BASE 0x50000000 // value of ColdFire chip select address register #define IO_DIG_WR IO_BASE // write digital outputs (r/w=0, A3=0, A4=0) #define IO_DIG_RD IO_BASE // read digital inputs (r/w=1, A3=0, A4=0) #define IO_ADC_WR (IO_BASE + 0x08) // write to ADC (r/w=0, A3=1, A4=0) #define IO_ADC_RD (IO_BASE + 0x08) // read ADC (r/w=1, A3=1, A4=0) #define IO_DAC_WR_LM (IO_BASE + 0x10) // write DAC low and middle nibble (r/w=0, A3=0, A4=1) #define IO_DAC_WR_H (IO_BASE + 0x16) // write DAC high nibble (r/w=0, A3=0, A4=1) also uses A1,A2 #define IO_DAC_LD (IO_BASE + 0x10) // load DAC (r/w=1, A3=0, A4=1) #define IO_DIG_WREN (IO_BASE + 0x18) // enable digital outputs (r/w=0, A3=1, A4=1) //----- ADC defines ----- #define ADC_INT_CLK_MODE 0x40 // Internal clock mode #define ADC_EXT_CLK_MODE 0x00 // External clock mode #define ADC_ACQMOD_INT 0x00 // Internally controlled acquisition #define ADC_ACQMOD_EXT 0x20 // Externally controlled acquisition #define ADC_RANGE_0_5 0x00 // Input range #define ADC_RANGE_0_10 0x10 // Input range #define ADC_CHANNEL_0 0x00 // Input channel #define ADC_CHANNEL_1 0x01 // Input channel #define ADC_CHANNEL_2 0x02 // Input channel #define ADC_CHANNEL_3 0x03 // Input channel #define ADC_CHANNEL_4 0x04 // Input channel #define ADC_CHANNEL_5 0x05 // Input channel //----- Function Prototypes ----- void EnableDOut(unsigned short n); void WriteDOut(volatile unsigned short data); unsigned short ReadDIn(); void WriteDac(volatile unsigned short data); unsigned short ReadAdc(unsigned short channel); void SetupChipSelects(); /*------------------------------------------------------------------- Executes a DAC ramp until a char is received -------------------------------------------------------------------*/ void DacRampTest() { volatile unsigned short data; data = 0; while (! charavail()) { WriteDac(data); data += 5; data &= 0x3ff; } } /*------------------------------------------------------------------- Enable upper an/or lower 8 bits of digital output. n = 1 for lower 8 bits n = 2 for upper 8 bits n = 3 for upper and lower 8 bits -------------------------------------------------------------------*/ void EnableDOut(volatile unsigned short n) { *(unsigned short *)(IO_DIG_WREN) = n; printf("Wrote %d to enable dig out\r\n", n); } /*------------------------------------------------------------------- Writes a 16-bit hex value to the digital output latches. -------------------------------------------------------------------*/ void WriteDOut(volatile unsigned short data) { *(unsigned short *)(IO_DIG_WR) = data; } /*------------------------------------------------------------------- Read a 16-bit hex value from the digital inputs. -------------------------------------------------------------------*/ unsigned short ReadDIn() { return *(unsigned short *)(IO_DIG_RD); } /*------------------------------------------------------------------- Write a 10-bit value to the dac. The Max503 has an 8-bit parallel interface, and writes data as low, middle, and high nibbles. This function will preform 2 write operations (8+4): the low and middle nibbles, followed by the high nibble. The final operation will load the data register into the DAC. 12-bit are written, but S0 and S1 must always be 0 Low Nibble = S0(D6), S1(D7), D0, D1 Middle Nibble = D2, D3, D4, D5 High Nibble = D6, D7, D8(D0), D9(D1) -------------------------------------------------------------------*/ void WriteDac(volatile unsigned short data) { volatile unsigned short *pDacLoad = (unsigned short *)(IO_DAC_LD); volatile unsigned short *pDacWriteLM = (unsigned short *)(IO_DAC_WR_LM); volatile unsigned short *pDacWriteH = (unsigned short *)(IO_DAC_WR_H); // Write lower and middle nibble. Shift past S0 and S1 per the Max503 data // sheet, and write data bits 0 - 5. *pDacWriteLM = (data & 0x003f) << 2; // Write upper nibble. We want bits 6, 7, 8, & 9, in the lower nibble of the // upper byte, so shift up by 2. *pDacWriteH = (data & 0x03C0) >> 6; // load new value into dac output data = *pDacLoad; } /*------------------------------------------------------------------- Start a conversion and return an A/D value. This function uses a 50ms delay to wait for a conversion to comeplete. The conversion time is 12 clock cycles, which is 7.7us when using the internal clock of the Max196. The chip is wired to use IRQ4, which will be the subject of a future application note. -------------------------------------------------------------------*/ unsigned short ReadAdc(unsigned short channel) { volatile unsigned short *pAdcWrite = (unsigned short *)(IO_ADC_WR); volatile unsigned short *pAdcRead = (unsigned short *)(IO_ADC_RD); volatile unsigned short data; if (channel > 5) channel = 5; *pAdcWrite = (ADC_INT_CLK_MODE | ADC_ACQMOD_INT | ADC_RANGE_0_5 | channel); // start a conversion OSTimeDly(1); // There are 20 ticks/sec, so this delay is 50ms. // We only need 7.7us to do a conversion. return *pAdcRead; // Read data } /*------------------------------------------------------------------- SetupChipSelects Set up chip select for I/O board (to HCT138) -------------------------------------------------------------------*/ void SetupChipSelects() { sim.cs[1].csar = (unsigned short)(IO_BASE >> 16); // chip select address resigter (CSAR1) sim.cs[1].csmr = 0x00000000; // chip select mask register sim.cs[1].cscr = 0x03DC3; // 0011 1101 1100 0011 chip select control register } /*------------------------------------------------------------------- UserMain The following program will output a voltage ramp using the DAC, while reading the DAC output with channel 0 of the ADC. The DAC output must be jumpered to ADC channel 0. -------------------------------------------------------------------*/ void UserMain(void * pd) { unsigned short DacOut, AdcVal; printf("Starting Program\n"); SetupChipSelects(); DacOut = 0; while (1) { WriteDac(DacOut); // program dac output AdcVal = ReadAdc(0); // read A/D channel 0 WriteDOut(AdcVal); // write binary data to digital output pins printf("%04X\r\n", AdcVal); DacOut += 10; // increment output value DacOut &= 0x03ff; // scale to 10 bits } // end main while loop } // end user main