From: Alex J. <ale...@us...> - 2005-08-14 11:13:49
|
Update of /cvsroot/emc/emc2/src/hal/drivers In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26244 Modified Files: hal_stg.c Log Message: various bugfixes. moved some functions around for better reading. DIO is tested and works, rest needs further testing Index: hal_stg.c =================================================================== RCS file: /cvsroot/emc/emc2/src/hal/drivers/hal_stg.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** hal_stg.c 7 Aug 2005 23:29:23 -0000 1.5 --- hal_stg.c 14 Aug 2005 11:13:40 -0000 1.6 *************** *** 68,87 **** Digital In: Pins: ! /totest bit stg.in-<pinnum> ! /totest bit stg.in-<pinnum>-not Functions: ! /totest void stg.digital_in_read Digital Out: Parameters: ! /totest bit stg.out-<pinnum>-invert Pins: ! /totest bit stg.out-<pinnum> Functions: ! /totest void stg.digital_out_write */ --- 68,87 ---- Digital In: Pins: ! bit stg.in-<pinnum> ! bit stg.in-<pinnum>-not Functions: ! void stg.digital_in_read Digital Out: Parameters: ! bit stg.out-<pinnum>-invert Pins: ! bit stg.out-<pinnum> Functions: ! void stg.digital_out_write */ *************** *** 145,149 **** MODULE_LICENSE("GPL"); #endif /* MODULE_LICENSE */ ! static int base = 0x000; /* board base address, 0 means autodetect */ MODULE_PARM(base, "i"); MODULE_PARM_DESC(base, "board base address, don't use for autodetect"); --- 145,149 ---- MODULE_LICENSE("GPL"); #endif /* MODULE_LICENSE */ ! static int base = 0x00; /* board base address, 0 means autodetect */ MODULE_PARM(base, "i"); MODULE_PARM_DESC(base, "board base address, don't use for autodetect"); *************** *** 200,207 **** static int outpinnum=0, inputpinnum=0; ! #define DATA(x) (base + (2 * x) - (x % 2)) /* Address of Data register 0 ! */ ! #define CTRL(x) (base + (2 * (x+1)) - (x % 2)) /* Address of Control ! register 0 */ /*********************************************************************** --- 200,205 ---- static int outpinnum=0, inputpinnum=0; ! #define DATA(x) (base + (2 * x) - (x % 2)) /* Address of Data register 0 */ ! #define CTRL(x) (base + (2 * (x+1)) - (x % 2)) /* Address of Control register 0 */ /*********************************************************************** *************** *** 220,223 **** --- 218,223 ---- /* initializes the STG, takes care of autodetection, all initialisations */ static int stg_init_card(void); + /* sets up interrupt to be used */ + static int stg_set_interrupt(short interrupt); /* scans possible addresses for STG cards */ static unsigned short stg_autodetect(void); *************** *** 479,483 **** /* stg_dacs_write() - writes all dac's to the board - calls stg_dac_write() */ - static void stg_dacs_write(void *arg, long period) { --- 479,482 ---- *************** *** 628,678 **** if ( (stg->dir_bits & 0x01) != 0) { // if port A is set as output, write the bits val = build_output(&(stg->port[0][0]), 8); ! outb(base + DIO_A, val); } if ( (stg->dir_bits & 0x02) != 0) { // if port B is set as output, write the bits val = build_output(&(stg->port[1][0]), 8); ! outb(base + DIO_B, val); } if ( (stg->dir_bits & 0x04) != 0) { // if port C is set as output, write the bits val = build_output(&(stg->port[2][0]), 8); ! outb(base + DIO_C, val); } if ( (stg->dir_bits & 0x08) != 0) { // if port D is set as output, write the bits val = build_output(&(stg->port[3][0]), 8); ! outb(base + DIO_D, val); } - } /*********************************************************************** * BOARD SPECIFIC FUNCTIONS * ************************************************************************/ /* stg_counter_init() - Initializes the channel */ - static int stg_counter_init(int ch) { /* Set Counter Command Register - Master Control, Master Reset (MRST), */ /* and Reset address pointer (RADR). */ ! outb(CTRL(ch), 0x23); /* Set Counter Command Register - Input Control, OL Load (P3), */ /* and Enable Inputs A and B (INA/B). */ ! outb(CTRL(ch), 0x68); /* Set Counter Command Register - Output Control */ ! outb(CTRL(ch), 0x80); /* Set Counter Command Register - Quadrature */ ! outb(CTRL(ch), 0xC3); return 0; } - /* stg_dac_init() - Initializes the dac channel */ - static int stg_dac_init(int ch) { --- 627,680 ---- if ( (stg->dir_bits & 0x01) != 0) { // if port A is set as output, write the bits val = build_output(&(stg->port[0][0]), 8); ! outb(val, base + DIO_A); } if ( (stg->dir_bits & 0x02) != 0) { // if port B is set as output, write the bits val = build_output(&(stg->port[1][0]), 8); ! outb(val, base + DIO_B); } if ( (stg->dir_bits & 0x04) != 0) { // if port C is set as output, write the bits val = build_output(&(stg->port[2][0]), 8); ! outb(val, base + DIO_C); } if ( (stg->dir_bits & 0x08) != 0) { // if port D is set as output, write the bits val = build_output(&(stg->port[3][0]), 8); ! outb(val, base + DIO_D); } } /*********************************************************************** * BOARD SPECIFIC FUNCTIONS * + * execute board related things (write/read to/from the stg) * ************************************************************************/ + + + /*********************************************************************** + * INIT FUNCTIONS * + ************************************************************************/ + /* stg_counter_init() - Initializes the channel */ static int stg_counter_init(int ch) { /* Set Counter Command Register - Master Control, Master Reset (MRST), */ /* and Reset address pointer (RADR). */ ! outb(0x23, CTRL(ch)); /* Set Counter Command Register - Input Control, OL Load (P3), */ /* and Enable Inputs A and B (INA/B). */ ! outb(0x68, CTRL(ch)); /* Set Counter Command Register - Output Control */ ! outb(0x80, CTRL(ch)); /* Set Counter Command Register - Quadrature */ ! outb(0xC3, CTRL(ch)); return 0; } /* stg_dac_init() - Initializes the dac channel */ static int stg_dac_init(int ch) { *************** *** 688,703 **** /* ! stg_dac_write() - writes a dac channel */ - static int stg_dac_write(int ch, short value) - { ! /* write the DAC */ ! outb (base + DAC_0 + (ch << 1), value); return 0; } /* stg_counter_read() - reads one channel --- 690,752 ---- /* ! stg_adc_init() - Initializes the adc channel */ + static int stg_adc_init(int ch) + { + /* not much to setup for the ADC's */ + /* only select the mode of operation we will work with AutoZero */ + outb(0x0f, base + MIO_2); // the second 82C55 is already configured (by running stg_dio_init) + // we only set bit 8 (AZ) to 1 to enable it + return 0; + } ! /* ! stg_dio_init() - Initializes the dio's ! */ ! static int stg_dio_init(stg_struct *addr) ! { ! /* we will select the directions of each port */ ! unsigned char control, tempINTC, tempIMR; + control = 0x80; //set up |1|0|0|A|CH|0|B|CL| + if ( (addr->dir_bits & 0x01) == 0) // if port A is set as input, set bit accordingly + control |= 0x10; + if ( (addr->dir_bits & 0x02) == 0) // if port B is set as input, set bit accordingly + control |= 0x02; + if ( (addr->dir_bits & 0x04) == 0) // if port C is set as input, set bits accordingly + control |= 0x09; + + // write the computed control to MIO_1 + outb(control, base+MIO_1); + + tempINTC = inb(base + INTC); + + // next compute the directions for port D, located on the second 82C55 + control = 0x82; + + if ( (addr->dir_bits & 0x08) == 0)// if port D is set as input, set bits accordingly + control = 0x92; + + tempIMR = inb(base + IMR); // get the current interrupt mask + + outb(0xff, base + OCW1); //mask off all interrupts + + // write the computed control to MIO_2 + outb(control, base+MIO_2); + + outb(tempINTC, base + INTC); //restore interrupt control reg. + + outb(tempIMR, base+ OCW1); //restore int mask + return 0; } + + /*********************************************************************** + * ACTION FUNCTIONS * + * these do the actual data exchange with the board * + ************************************************************************/ + /* stg_counter_read() - reads one channel *************** *** 715,719 **** } pos; ! outb(CTRL(i), 0x03); pos.byte.b0 = inb(DATA(i)); pos.byte.b1 = inb(DATA(i)); --- 764,768 ---- } pos; ! outb(0x03, CTRL(i)); pos.byte.b0 = inb(DATA(i)); pos.byte.b1 = inb(DATA(i)); *************** *** 727,743 **** } /* ! stg_adc_init() - Initializes the dac channel */ - static int stg_adc_init(int ch) - { - /* not much to setup for the ADC's */ - /* only select the mode of operation we will work with AutoZero */ - outb(base + MIO_2, 0x01); // the second 82C55 is already configured (by running stg_dio_init) - // we only set bit 0 (AZ) to 1 to enable it return 0; } int stg_adc_start(unsigned short wAxis) { --- 776,793 ---- } + /* ! stg_dac_write() - writes a dac channel */ + static int stg_dac_write(int ch, short value) + { + /* write the DAC */ + outb (value, base + DAC_0 + (ch << 1)); return 0; } + + int stg_adc_start(unsigned short wAxis) { *************** *** 748,758 **** /* wait 4 uS for settling time on the multiplexer and ADC. You probably shouldn't really have a delay in a driver */ ! outb(0x80, 0); ! outb(0x80, 0); ! outb(0x80, 0); ! outb(0x80, 0); /* now start conversion */ ! outw(base + ADC_0 + (wAxis << 1), 0); return 0; --- 798,808 ---- /* wait 4 uS for settling time on the multiplexer and ADC. You probably shouldn't really have a delay in a driver */ ! outb(0, 0x80); ! outb(0, 0x80); ! outb(0, 0x80); ! outb(0, 0x80); /* now start conversion */ ! outw(0, base + ADC_0 + (wAxis << 1)); return 0; *************** *** 787,828 **** }; ! /* ! stg_dio_init() - Initializes the dio's ! */ ! ! static int stg_dio_init(stg_struct *addr) { ! /* we will select the directions of each port */ ! unsigned char control; ! ! control = 0x80; //set up |1|0|0|A|CH|0|B|CL| ! if ( (addr->dir_bits & 0x01) == 0) // if port A is set as input, set bit accordingly ! control |= 0x10; ! if ( (addr->dir_bits & 0x02) == 0) // if port B is set as input, set bit accordingly ! control |= 0x02; ! if ( (addr->dir_bits & 0x04) == 0) // if port C is set as input, set bits accordingly ! control |= 0x09; ! ! // write the computed control to MIO_1 ! outb(base+MIO_1, control); ! // next compute the directions for port D, located on the second 82C55 ! control = 0x82; ! if ( (addr->dir_bits & 0x08) == 0)// if port C is set as input, set bits accordingly ! control |= 0x10; ! ! // write the computed control to MIO_2 ! outb(base+MIO_2, control); return 0; } /*********************************************************************** * LOCAL FUNCTION DEFINITIONS * ************************************************************************/ - static int export_counter(int num, stg_struct *addr) { --- 837,929 ---- }; + /*********************************************************************** + * BOARD INIT FUNCTIONS * + * functions for autodetec, irq init * + ************************************************************************/ ! static int stg_set_interrupt(short interrupt) { ! unsigned char tempINTC=0x80; ! switch (interrupt) { ! case 3: break; ! case 5: tempINTC |= 4;break; ! case 7: tempINTC |= 2;break; ! case 9: tempINTC |= 6;break; ! case 10: tempINTC |= 5;break; ! case 11: tempINTC |= 7;break; ! case 12: tempINTC |= 3;break; ! case 15: tempINTC |= 1;break; ! default: tempINTC |= 4;break; ! } ! outb(tempINTC, base + INTC); ! return 0; ! } ! ! static int stg_init_card() ! { ! if (base == 0x00) { ! base = stg_autodetect(); ! } ! if (base == 0x00) { ! rtapi_print_msg(RTAPI_MSG_ERR, "STG: ERROR: no STG card found\n"); ! return -1; ! } ! outb(0x92, base + MIO_2); ! stg_set_interrupt(5); // initialize it to smthg, we won't use it anyways + outb(0x1a, base + ICW1); // initialize the 82C59 as single chip (STG docs say so:) + outb(0x00, base + ICW2); // ICW2 not used, must init it to 0 + outb(0xff, base + OCW1); // mask off all interrupts + + // all ok return 0; } + /* scans possible addresses for STG cards */ + unsigned short stg_autodetect() + { + + short i, j, k, ofs; + unsigned short address; + + /* search all possible addresses */ + for (i = 15; i >= 0; i--) { + address = i * 0x20 + 0x200; + + /* does jumper = i? */ + if ((inb(address + BRDTST) & 0x0f) == i) { + k = 0; // var for getting the serial + for (j = 0; j < 8; j++) { + ofs = (inb(address + BRDTST) >> 4); + + if (ofs & 8) { /* is SER set? */ + ofs = ofs & 7; /* mask for Q2,Q1,Q0 */ + k += (1 << ofs); /* shift bit into position specified + by Q2, Q1, Q0 */ + } + } + if (k == 0x75) { + rtapi_print_msg(RTAPI_MSG_INFO, + "STG: found card at address %x\n", address); + return address; /* SER sequence is 01110101 */ + } + if (k == 0x74) { + rtapi_print_msg(RTAPI_MSG_ERR, + "STG: ERROR: found version 2 card, not suported by this driver\n"); + /* \todo TODO extend the driver to support a type II STG board */ + hal_exit(comp_id); + return -1; + } + } + } + return (0); + } /*********************************************************************** * LOCAL FUNCTION DEFINITIONS * + * these are functions used for exporting various HAL pins/prams * ************************************************************************/ static int export_counter(int num, stg_struct *addr) { *************** *** 996,1049 **** return retval; } - - - static int stg_init_card() - { - if (base == 0x00) { - base = stg_autodetect(); - } - if (base == 0x00) { - rtapi_print_msg(RTAPI_MSG_ERR, "STG: ERROR: no STG card found\n"); - return -1; - } - // FIXME - further init will happen here - - // all ok - return 0; - } - - /* scans possible addresses for STG cards */ - unsigned short stg_autodetect() - { - - short i, j, k, ofs; - unsigned short address; - - /* search all possible addresses */ - for (i = 15; i >= 0; i--) { - address = i * 0x20 + 0x200; - - /* does jumper = i? */ - if ((inb(address + BRDTST) & 0x0f) == i) { - k = 0; // var for getting the serial - for (j = 0; j < 8; j++) { - ofs = (inb(address + BRDTST) >> 4); - - if (ofs & 8) { /* is SER set? */ - ofs = ofs & 7; /* mask for Q2,Q1,Q0 */ - k += (1 << ofs); /* shift bit into position specified - by Q2, Q1, Q0 */ - } - } - if (k == 0x75) - return address; /* SER sequence is 01110101 */ - if (k == 0x74) { - rtapi_print_msg(RTAPI_MSG_ERR, - "STG: ERROR: found version 2 card, not suported by this driver\n"); - hal_exit(comp_id); - return -1; - } - } - } - return (0); - } --- 1097,1098 ---- |