Subversion Repositories shark

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*****************************************************************************
2
* Filename:    pci6025e.c                                                    *
3
* Author:      Ziglioli Marco                                                *
4
* Date:        15/03/2001                                                    *
5
* Description: Collection of routines to find on PCI bus and configure Natio-*
6
*              nal Instruments PCI6025E multifunction board. This board has  *
7
*              - One ADC 12 bit flash with 16 input lines (multiplexed)      *
8
*              - Two DACs 12 bit                                             *
9
*              - Eight Digital lines drived through NI DAQ-STC IC            *
10
*              - Twentyfour Digital lines drived through OKI MSM82C55A       *
11
*              - Two General purpose 24-bit counters/timers                  *
12
*              - Timing module for analog input (AITM)                       *
13
*              - Timing module for analog output (AOTM)                      *
14
*              - 10 Programmable Function pins (PFI)                         *
15
*              - RTSI bus for connection with other National Board           *
16
*              - Timing module which can provide frequency from 20MHz to     *
17
*                6,25 KHz                                                    *
18
*              - Two shared interrupt groups to manage up than 20 different  *
19
*                interrupt events                                            *
20
* For more information please refer to National Web site: www.ni.com         *
21
*----------------------------------------------------------------------------*
22
* Notes:       Based on National C Routines                                  *
23
*****************************************************************************/
24
 
25
/* This file is part of the S.Ha.R.K. Project - http://shark.sssup.it
26
 *
27
 * Copyright (C) 2001 Marco Ziglioli
28
 *
29
 * This program is free software; you can redistribute it and/or modify
30
 * it under the terms of the GNU General Public License as published by
31
 * the Free Software Foundation; either version 2 of the License, or
32
 * (at your option) any later version.
33
 *
34
 * This program is distributed in the hope that it will be useful,
35
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37
 * GNU General Public License for more details.
38
 *
39
 * You should have received a copy of the GNU General Public License
40
 * along with this program; if not, write to the Free Software
41
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
42
 *
43
 */
44
 
45
#include <drivers/pci6025e/pci6025e.h>
46
 
47
//Software copy of importan register
48
static WORD interrupt_control;
49
 
50
// PJ: Global data
51
struct pci6025e_deviceinfo NIDevice_info[10];
52
DWORD *IntLinestructptr;
53
DWORD *BAR0structptr;
54
DWORD *RevID;
55
DWORD STC_Base_Address, MITE_Base_Address;
56
 
57
//Software copy of STC general registers
58
WORD joint_reset, interrupt_a_enable, interrupt_a_ack,
59
     interrupt_b_enable, interrupt_b_ack, clock_and_fout;
60
 
61
/*****************************************************************************
62
*                    Usefull(???) Functions                                  *
63
*****************************************************************************/
64
 
65
/*****************************************************************************
66
*  Print value of each bit contained in value                                *
67
*****************************************************************************/
68
void bitfield(BYTE dim, DWORD value)
69
{
70
   int   i;
71
 
72
   for(i=(dim*8)-1; i>=0; i--)
73
      cprintf("%ld",(value>>i)%2);
74
   cprintf("\n");
75
}
76
 
77
/*****************************************************************************
78
* Print custom string (str) before printing the bitfield                     *
79
*****************************************************************************/
80
void  TEST_bitfield(BYTE dim, DWORD value, char *str)
81
{
82
   cprintf("%s", str);
83
   bitfield(dim, value);
84
}
85
 
86
/*****************************************************************************
87
*  Low Level Functions to write in windowed mode into DAQ STC                *
88
*****************************************************************************/
89
void DAQ_STC_Windowed_Mode_Write(WORD addr, WORD Value)
90
{
91
   kern_cli();
92
   *((WORD *)(STC_Base_Address + WIN_ADDR_REG)) = addr;
93
   *((WORD *)(STC_Base_Address + WIN_DATA_WR_REG)) = Value;
94
   kern_sti();
95
}
96
 
97
WORD DAQ_STC_Windowed_Mode_Read(WORD addr)
98
{
99
   WORD value = 0;
100
 
101
   kern_cli();
102
   *((WORD *)(STC_Base_Address + WIN_ADDR_REG)) = addr;
103
   value = *((WORD *)(STC_Base_Address + WIN_DATA_RD_REG));
104
   kern_sti();
105
   return (value);
106
}
107
 
108
/*****************************************************************************
109
*  Detect all NI Devices on PCI bus                                          *
110
*****************************************************************************/
111
BYTE find_NI_Device(void)
112
{
113
   WORD     devNumFunNum = 0;
114
   WORD     busNum, i = 0;
115
   DWORD    value, temp, Device_ID;
116
   BYTE     hdr, Device_Count;
117
   int      present;
118
 
119
   Device_Count = 0;
120
   BAR0structptr     = &NIDevice_info[0].BAR0Value;
121
   IntLinestructptr  = &NIDevice_info[0].IntLineRegValue;
122
   RevID             = &NIDevice_info[0].RevisionID;
123
 
124
   for(busNum = 0; busNum <= 0; busNum++){
125
      for(devNumFunNum = 0; devNumFunNum <= 0xFF; devNumFunNum += 0x08){
126
         present = 0;
127
         if((devNumFunNum & 0x07) == 0){
128
            present = pcibios_read_config_byte((BYTE)busNum,
129
                                   (BYTE)devNumFunNum, 0x0E, &hdr);
130
            if(hdr & 0x80)
131
               present = 1;
132
            if(present){
133
               if(pcibios_read_config_dword((BYTE)busNum, (BYTE)devNumFunNum,
134
                                  0x00, &value) && (value != 0xffffffff)){
135
                  if((value & 0xffffL) == NI_CODE){
136
                     Device_ID = value;
137
                     Device_ID &= 0xFFFF0000;
138
                     Device_ID = Device_ID >> 16;
139
 
140
                     NIDevice_info[i].DEVID = (WORD)temp;
141
                     NIDevice_info[i].DevFunction = (BYTE)devNumFunNum;
142
                     NIDevice_info[i].BusNumber = (BYTE)busNum;
143
                     pcibios_read_config_dword((BYTE)busNum, (BYTE)devNumFunNum, 0x10, (DWORD *)BAR0structptr);
144
                     pcibios_read_config_dword((BYTE)busNum, (BYTE)devNumFunNum, 0x3C, (DWORD *)IntLinestructptr);
145
                     pcibios_read_config_dword((BYTE)busNum, (BYTE)devNumFunNum, 0x08, (DWORD *)RevID);
146
                     NIDevice_info[i].InterruptLevel = (BYTE)NIDevice_info[i].IntLineRegValue;
147
                     i++;
148
                     BAR0structptr++;
149
                     IntLinestructptr++;
150
                     RevID++;
151
                     Device_Count++;
152
                  }
153
               }
154
            }
155
         }
156
      }
157
   }
158
   return Device_Count;
159
}
160
 
161
/*****************************************************************************
162
*  Remap Base address of STC and MITE registers presents on NI boards        *
163
*  Note: If there's over than one NI Board on bus only the first device is   *
164
*        remapped                                                            *
165
*****************************************************************************/
166
BYTE reMap(void)
167
{
168
   //DWORD       Mite_Data;
169
   //DWORD       Value;
170
 
171
   if(!find_NI_Device()){
172
      return 0;
173
   }
174
 
175
 /*
176
   // ***************************************************************
177
   // This is usefull to remap board in another memory zone
178
   // Enable this and choose memory zone setting BAR0 and BAR1 values
179
   // on PCI6025E.H
180
   // ***************************************************************
181
   // Set Up MITE
182
   Value = BAR0;
183
   pcibios_write_config_dword((BYTE)NIDevice_info[0].BusNumber,
184
         NIDevice_info[0].DevFunction, 0x10, Value);
185
   Mite_Data = 0xAEAE;
186
   lmempoked(BAR0 + 0x0340, Mite_Data);
187
 
188
   // Set Up Board
189
   Value = BAR1;
190
   pcibios_write_config_dword((BYTE)NIDevice_info[0].BusNumber,
191
         NIDevice_info[0].DevFunction, 0x14, Value);
192
   Mite_Data = (BAR1 & 0xFFFFFF00) | 0x80;
193
   lmempoked(BAR0 + 0xC0, Mite_Data);
194
 */
195
 
196
 
197
   //Setting up Base Address
198
   pcibios_read_config_dword((BYTE)NIDevice_info[0].BusNumber,
199
         (BYTE)NIDevice_info[0].DevFunction, 0x14, &STC_Base_Address);
200
   STC_Base_Address = (STC_Base_Address & 0xFFFFFF00) | 0x80;
201
   pcibios_read_config_dword((BYTE)NIDevice_info[0].BusNumber,
202
         (BYTE)NIDevice_info[0].DevFunction, 0x10, &MITE_Base_Address);
203
   //MITE_Base_Address &= 0xFFFFFF00;
204
 
205
   *((DWORD *)MITE_Base_Address) = 0xAEAE;
206
   *((DWORD *)(MITE_Base_Address + 0xC0)) = STC_Base_Address;
207
 
208
   return 1;
209
}
210
 
211
/*****************************************************************************
212
*  Sets up the internal timebase clock and enable Frequency Out (FOUT).      *
213
*  Signal is available on pin 50                                             *
214
*----------------------------------------------------------------------------*
215
*  tbs      ->    if 0 then 20 Mhz freq; if 1 then 200 Khz freq              *
216
*  divBy2   ->    if 1 divides output frequency by two else if 0 doesn't     *
217
*                 divide it                                                  *
218
*  divider  ->    if 0 divides frequency by 16                               *
219
*                 if between 1 and 15 divides frequency by specified value   *
220
*****************************************************************************/
221
BYTE setIntClock(BYTE tbs, BYTE divBy2, BYTE divider)
222
{
223
   clr(clock_and_fout, 15);
224
   DAQ_STC_Windowed_Mode_Write(CLOCK_AND_FOUT, clock_and_fout);
225
 
226
   switch(tbs){
227
      case 0:
228
         clr(clock_and_fout, 14);   //IN_TIMEBASE
229
         break;
230
      case 1:
231
         set(clock_and_fout, 11);   //Enable IN_TIMEBASE2
232
         set(clock_and_fout, 14);   //Select IN_TIMEBASE2
233
         break;
234
      default:
235
         return 0;
236
         break;
237
   }
238
 
239
   switch(divBy2){
240
      case 0: clr(clock_and_fout, 12); break;   //Not divided by two
241
      case 1: set(clock_and_fout, 12); break;   //Divided by two
242
      default: return 0; break;
243
   }
244
 
245
   //if((divider < 0) || (divider > 15))
246
   if(divider > 15)  // PJ: byte has only positive values!!!
247
      return 0;      //Addictional frequency division wrong
248
 
249
   if(divider & 0x01)
250
      set(clock_and_fout, 0);
251
   else
252
      clr(clock_and_fout, 0);
253
 
254
   if(divider & 0x02)
255
      set(clock_and_fout, 1);
256
   else
257
      clr(clock_and_fout, 1);
258
 
259
   if(divider & 0x04)
260
      set(clock_and_fout, 2);
261
   else
262
      clr(clock_and_fout, 2);
263
 
264
   if(divider & 0x08)
265
      set(clock_and_fout, 3);
266
   else
267
      clr(clock_and_fout, 3);
268
 
269
   //Write in register
270
   DAQ_STC_Windowed_Mode_Write(CLOCK_AND_FOUT, clock_and_fout);
271
 
272
   //Enable internal clock
273
   set(clock_and_fout, 15);
274
   DAQ_STC_Windowed_Mode_Write(CLOCK_AND_FOUT, clock_and_fout);
275
 
276
   return 1;
277
}
278
 
279
/*****************************************************************************
280
*                 void PFIprogramming(WORD pfi)                              *
281
*----------------------------------------------------------------------------*
282
* Use this function to program the direction of the ten available PFI lines  *
283
* Parameter: pfi     bit 0 through 9: 0 releted PFI line configured as input *
284
*                                     1 releted PFI line configured as output*
285
*                    10..15   NOT USED                                       *
286
*****************************************************************************/
287
void PFIprogramming(WORD pfi)
288
{
289
   DAQ_STC_Windowed_Mode_Write(IO_BIDIRECTION_PIN, (pfi & 0x03FF));
290
}
291
 
292
/*****************************************************************************
293
*                 Interrupt manage module                                    *
294
*****************************************************************************/
295
/*****************************************************************************
296
*                 void INT_personalize(BYTE personal)                        *
297
*----------------------------------------------------------------------------*
298
* Use this function to select the logic level will indicate an interrupt     *
299
* condition on IRQ_OUT pins and to enable or disable the possibility of      *
300
* duplicate selected interrupt to IRQ_OUT<0..1> pins                         *
301
* Parameter:   personal:   bit 0: enable(1) or disable(0) signal duplication *
302
*                          bit 1: polarity: (0)active high (1)active low     *
303
*                          bit 2..7 NOT USED                                 *
304
*****************************************************************************/
305
void INT_personalize(BYTE personal)
306
{
307
   if( (personal & 0x02) )       set(interrupt_control, 0);
308
   else                          clr(interrupt_control, 0);
309
 
310
   if( (personal & 0x01) )       set(interrupt_control, 1);
311
   else                          clr(interrupt_control, 1);
312
 
313
   DAQ_STC_Windowed_Mode_Write(INTERRUPT_CONTROL, interrupt_control);
314
}
315
 
316
/*****************************************************************************
317
*                 void INT_setup(BYTE ga, BYTE gb)                           *
318
*----------------------------------------------------------------------------*
319
* Use this function to enable interrupt groups and to indicate which pin     *
320
* indicate interrupt condition.                                              *
321
* Parameter: ga: group A manages AITM, IRQ_IN0, Counter0                     *
322
*            gb: group B manages AOTM, IRQ_IN1, Counter1                     *
323
* Both parameters have first 3 bits (0..2) to indicate IRQ_OUT pin that will *
324
* indicate interrupt condition and the fourth bit (3) to enable the          *
325
* interrupts group.                                                          *
326
* Upper 4 bits of each BYTE are NOT USED                                     *
327
*****************************************************************************/
328
void INT_setup(BYTE ga, BYTE gb)
329
{
330
   if( (ga & 0x08) )
331
      interrupt_control = (interrupt_control & 0xF0FF) |
332
                          ((ga & 0x0F) << 8);
333
   else
334
      clr(interrupt_control, 11);
335
 
336
   if( (gb & 0x08) )
337
      interrupt_control = (interrupt_control & 0x0FFF) |
338
                          ((gb & 0x0F) << 12);
339
   else
340
      clr(interrupt_control, 15);
341
 
342
   DAQ_STC_Windowed_Mode_Write(INTERRUPT_CONTROL, interrupt_control);
343
}
344
/*End of file: pci6025e.c*/