// adc.c ... device driver for A/D and D/A boards: // A/D boards: CONTEC AD12-16(PCI), AD12-64(PCI) // D/A boards: CONTEC DA12-16(PCI), CONTEC DA12-8(PCI), CONTEC DA12-4(PCI) #include #include #include "adc.h" int init_adc(void) { unsigned int Clock_Data = SAMPLING_CLOCK / 250 - 1; outb_p(0x0, ADC_BASE_ADDR + 0x08); /* AD initialization */ outb_p(0x01, ADC_BASE_ADDR + 0x08); /* mode set command */ // outb_p(SINGLE_END | SINGLE | INTERNAL_CLOCK | SOFTWARE_COMMAND, ADC_BASE_ADDR + 0x0c); outb_p(SINGLE_END | MULTI | INTERNAL_CLOCK | SOFTWARE_COMMAND, ADC_BASE_ADDR + 0x0c); // input range setting outb_p(0x02, ADC_BASE_ADDR + 0x08); outb_p(0x00, ADC_BASE_ADDR + 0x0c); // 0x0 : CH0 ; 0x1 : CH1, ... outb_p(0x01, ADC_BASE_ADDR + 0x0d); // 0x0 : +- 10V(default); // 0x1 : +- 5V // 0x2 : +- 2.5V // 0x3 : +- 1.25V // 0x4 : 0 to 10V // 0x5 : 0 to 5V // 0x6 : 0 to 2.5V // 0x7 : 0 to 1.25V outb_p(0x01, ADC_BASE_ADDR + 0x0c); // CH1 outb_p(0x01, ADC_BASE_ADDR + 0x0d); // +- 5V outb_p(0x02, ADC_BASE_ADDR + 0x0c); // CH2 outb_p(0x01, ADC_BASE_ADDR + 0x0d); // +- 5V // internal sampling clock setting outb_p(0x03, ADC_BASE_ADDR + 0x08); outb_p(Clock_Data & 0x000000ff, ADC_BASE_ADDR + 0x0c); outb_p(Clock_Data >> 8 & 0x000000ff, ADC_BASE_ADDR + 0x0d); outb_p(Clock_Data >> 16 & 0x000000ff, ADC_BASE_ADDR + 0x0e); outb_p(Clock_Data >> 24 & 0x000000ff, ADC_BASE_ADDR + 0x0f); return 0; } void cleanup_adc(void) { // outb_p(0x04, ADC_BASE_ADDR + 0x06); // sampling stop } int ad_conv(double *y) { int i = 0; unsigned short Status; int AiData; int WaitTime = 0; // outb_p(BUF_CLR, ADC_BASE_ADDR + 0x06); // Card Buffer Clear outb_p(CH, ADC_BASE_ADDR + 0x04); // Conversion Start do{ Status = inb_p(ADC_BASE_ADDR + 0x06); if(++WaitTime >= 0xf5000) return -1; }while((Status & DRE) == 0); // Data in Buffer ? #ifdef MULTI_CHANNEL_MODE for(i = 0; i <= CH; i++){ AiData = inw_p(ADC_BASE_ADDR); // read the converted digital data // translate digital data to real voltage // y[i] = (double)(AiData & 0x0fff)*20./4096. - 10.; // for +- 10V range // y[i] = (double)(AiData & 0x0fff)*2.5/4096. - 1.25; // for +- 1.25V range y[i] = (double)(AiData & 0x0fff)*10./4096. - 5.; // for +- 5V range } #else AiData = inw_p(ADC_BASE_ADDR); *y = (double)(AiData & 0x0fff)*20./4096. - 10.; // for +- 10V range #endif return 0; } int ad_conv_raw(int *y) { int i = 0; unsigned short Status; int WaitTime = 0; // outb_p(BUF_CLR, ADC_BASE_ADDR + 0x06); /* Card Buffer Clear */ outb_p(CH, ADC_BASE_ADDR + 0x04); /* Conversion Start */ do{ Status = inb_p(ADC_BASE_ADDR + 0x06); if(++WaitTime >= 0xf5000) return -1; }while((Status & DRE) == 0); /* Data in Buffer ? */ #ifdef MULTI_CHANNEL_MODE for(i = 0; i <= CH; i++){ y[i] = inw_p(ADC_BASE_ADDR); } #else *y = inw_p(ADC_BASE_ADDR); #endif return 0; } int init_dac(void) { outb_p(0x0, DAC_BASE_ADDR + 0x08); /* DA initialization */ outb_p(0x01, DAC_BASE_ADDR + 0x08); /* sampling cond. */ outb_p(0x0, DAC_BASE_ADDR + 0x0c); /* output range setting */ outb_p(0x02, DAC_BASE_ADDR + 0x08); outb_p(0x00, DAC_BASE_ADDR + 0x0c); /* channel 0 */ outb_p(0x01, DAC_BASE_ADDR + 0x0d); /* +- 5V */ // outb_p(0x02, DAC_BASE_ADDR + 0x08); outb_p(0x01, DAC_BASE_ADDR + 0x0c); /* channel 1 */ outb_p(0x01, DAC_BASE_ADDR + 0x0d); /* +- 5V */ outb_p(0x02, DAC_BASE_ADDR + 0x0c); /* channel 2 */ outb_p(0x01, DAC_BASE_ADDR + 0x0d); /* +- 5V */ outb_p(0x03, DAC_BASE_ADDR + 0x0c); /* channel 3 */ outb_p(0x01, DAC_BASE_ADDR + 0x0d); /* +- 5V */ return 0; } void cleanup_dac(void) { // outb_p(0x04, DAC_BASE_ADDR + 0x06); /* sampling stop */ } int da_conv(double v, unsigned char ch) { unsigned short val; if(ch != 0 && ch != 1 && ch != 2 && ch != 3){ return -1; } if(v > V_MAX) v = V_MAX; else if(v < V_MIN) v = V_MIN; val = (v + 5.) * 4096 / 10.; outb_p(ch, DAC_BASE_ADDR + 0x04); /* conversion start */ outw_p(val & 0x0fff, DAC_BASE_ADDR); /* 12 bits */ return 0; } int da_conv_pic(double v, unsigned char ch) { unsigned short val; if(ch != 0 && ch != 1 && ch != 2 && ch != 3){ return -1; } if(v > 1.25) v = 1.25; else if(v < -1.25) v = -1.25; val = (v + 5.) * 4096 / 10.; outb_p(ch, DAC_BASE_ADDR + 0x04); /* conversion start */ outw_p(val & 0x0ffc, DAC_BASE_ADDR); /* 10 bits */ return 0; }