source: multiio/pcmmio/original/mio_io.c @ 352ac8d

Last change on this file since 352ac8d was 352ac8d, checked in by Joel Sherrill <joel.sherrill@…>, on 06/08/09 at 18:40:06

2009-06-08 Joel Sherrill <joel.sherrill@…>

  • Makefile, mio_io.c, mio_io.h: Linux code split to porting file.
  • mio_io_linux.c: New file.
  • Property mode set to 100644
File size: 33.6 KB
Line 
1/* mio_io.c WinSystems support module file for the  PCM-MIO Linux driver */
2/*
3*  $Header$
4*
5*  $Id$
6*
7*  $Log$
8*  Revision 1.2  2009/06/08 18:21:56  joel
9*  2009-06-08   Joel Sherrill <joel.sherrill@oarcorp.com>
10*
11*       * Makefile, kbhit.c, mio_io.c, mio_io.h: First successful compilation
12*       under RTEMS. Added some Linux ifdef's.
13*       * rtems_config.c: New file.
14*
15*  Revision 1.1.1.1  2009/06/08 14:52:43  joel
16*  Initial import.
17*
18*
19*  This file implements all of the supported 'C' language functions. Where necessary
20*  call are made into a porting layer to access the actual hardware.
21*/
22
23#define LIB_DEFINED
24
25/* #define DEBUG 1 */
26
27#include "mio_io.h"   
28
29#include <stdio.h>
30
31/* These image variable help out where a register is not
32   capable of a read/modify/write operation
33*/
34
35unsigned char dio_port_images[8];
36unsigned char adc1_port_image =0;
37unsigned char adc2_port_image =0;
38unsigned char dac1_port_image =0;
39unsigned char dac2_port_image =0;
40
41
42/* The channel selects on the ADC are non contigous. In order to avoid shifting and such
43   with each channel select, we simple bild an array for selection.
44*/
45
46unsigned char adc_channel_select[16] = {ADC_CH0_SELECT, ADC_CH1_SELECT, ADC_CH2_SELECT,
47        ADC_CH3_SELECT, ADC_CH4_SELECT, ADC_CH5_SELECT, ADC_CH6_SELECT, ADC_CH7_SELECT,
48        ADC_CH0_SELECT, ADC_CH1_SELECT, ADC_CH2_SELECT, ADC_CH3_SELECT, ADC_CH4_SELECT,
49        ADC_CH5_SELECT, ADC_CH6_SELECT, ADC_CH7_SELECT };
50
51/* Mode selection can also be time consuming and we'd also like the mode to "Stick" from
52   call to call. This array will eventually hold the actual command byte to send to the
53   ADC controller for each channel according to the mode set with adc_set_channel_mode
54*/
55
56unsigned char adc_channel_mode[16] = {ADC_CH0_SELECT, ADC_CH1_SELECT, ADC_CH2_SELECT,
57        ADC_CH3_SELECT, ADC_CH4_SELECT, ADC_CH5_SELECT, ADC_CH6_SELECT, ADC_CH7_SELECT,
58        ADC_CH0_SELECT, ADC_CH1_SELECT, ADC_CH2_SELECT, ADC_CH3_SELECT, ADC_CH4_SELECT,
59        ADC_CH5_SELECT, ADC_CH6_SELECT, ADC_CH7_SELECT };
60
61
62/* This array and the index value are used internally for the adc_convert_all_channels
63  and for the adc_buffered_conversion routines.
64*/
65unsigned char adc_channel_buff[18] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,0xff,0xff};
66unsigned char *adc_input_buffer;
67unsigned short *adc_user_buffer;
68
69/* Becaues of the nature of the ADC beast. It's necessary to keep track of the last
70  channel and the previous channel in order to retrieve the data amd know who it belongs to
71*/
72
73int adc_last_channel, adc_current_channel;
74
75/* Various index pointers for the above arrays and misc globals */
76
77int adc_ch_index =0;
78int adc_out_index=0;
79int adc_repeat_channel;
80int adc_repeat_count;
81
82
83
84
85
86///////////////////////////////////////////////////////////////////////////////
87//
88//              DISABLE_DIO_INTERRUPT
89//
90//////////////////////////////////////////////////////////////////////////////
91
92int disable_dio_interrupt(void)
93{
94        mio_error_code = MIO_SUCCESS;
95
96        if(check_handle())   /* Check for chip available */
97                return -1;
98
99        adc1_port_image = adc1_port_image | 0x10;
100        mio_write_reg(0x03, adc1_port_image);   // Access the int enable register
101        mio_write_reg(0x02, 0);
102        adc1_port_image = adc1_port_image & 0xef;
103        mio_write_reg(0x03,adc1_port_image );   // Disable the interrupt
104       
105        return(0);
106}
107
108
109///////////////////////////////////////////////////////////////////////////////
110//
111//              ENABLE_DIO_INTERRUPT
112//
113//////////////////////////////////////////////////////////////////////////////
114
115int enable_dio_interrupt(void)
116{
117unsigned char vector;
118
119        mio_error_code = MIO_SUCCESS;
120
121        if(check_handle())   /* Check for chip available */
122                return -1;
123
124        /* We read the assign IRQ from the driver, so we can program the hardware to
125           match,  but only if an aaplication desires such.
126    */
127
128        vector = mio_read_irq_assigned();
129
130        if(vector == 0)
131        {
132                mio_error_code = MIO_MISSING_IRQ;
133                sprintf(mio_error_string,"MIO(DIO) : enable_dio_interrupt - No IRQ assigned");
134                return(1);
135        }
136
137        adc1_port_image = adc1_port_image | 0x10;
138        mio_write_reg(0x03, adc1_port_image);   // Access the int enable register
139        mio_write_reg(0x02, vector);
140        adc1_port_image = adc1_port_image & 0xef;
141        mio_write_reg(0x03, adc1_port_image);   // Enable the interrupt
142
143        return(0);
144}
145
146
147///////////////////////////////////////////////////////////////////////////////
148//
149//              DISABLE_DAC_INTERRUPT
150//
151//////////////////////////////////////////////////////////////////////////////
152
153int disable_dac_interrupt(int dac_num)
154{
155        mio_error_code = MIO_SUCCESS;
156
157        if(check_handle())   /* Check for chip available */
158                return -1;
159
160        if(dac_num)
161        {
162                dac2_port_image = dac2_port_image & 0xfe;
163                dac2_port_image = dac2_port_image | 0x08;
164                mio_write_reg(0x0f, dac2_port_image);   // Access the int enable register
165                mio_write_reg(0x0e, 0);
166                dac2_port_image = dac2_port_image & 0xf7;
167                mio_write_reg(0x0f, dac2_port_image);   // Disable the interrupt
168        }
169        else
170        {
171                dac1_port_image = dac1_port_image & 0xfe;
172                dac1_port_image = dac1_port_image | 0x08;
173                mio_write_reg(0x0b, dac1_port_image);   // Access the int enable register
174       
175                mio_write_reg(0x0a, 0);
176
177                dac1_port_image = dac1_port_image & 0xf7;
178                mio_write_reg(0x0b, dac1_port_image);   // Disable the interrupt
179        }
180        return(0);
181}
182
183///////////////////////////////////////////////////////////////////////////////
184//
185//              ENABLE_DAC_INTERRUPT
186//
187//////////////////////////////////////////////////////////////////////////////
188
189int enable_dac_interrupt(int dac_num)
190{
191unsigned char vector;
192
193
194        mio_error_code = MIO_SUCCESS;
195
196        if(check_handle())   /* Check for chip available */
197                return -1;
198
199        /* We read the assign IRQ from the driver, so we can program the hardware to
200           match,  but only if an aaplication desires such.
201    */
202
203        vector = mio_read_irq_assigned();
204
205        if(vector == 0)
206        {
207                mio_error_code = MIO_MISSING_IRQ;
208                sprintf(mio_error_string,"MIO(DAC) : enable_dac_interrupt - No IRQ assigned");
209                return(1);
210        }
211
212
213        if(dac_num)
214        {
215                dac2_port_image = dac2_port_image & 0xfe;
216                dac2_port_image = dac2_port_image | 0x08;
217                mio_write_reg(0x0f, dac2_port_image);   // Access the int enable register
218
219                mio_write_reg(0x0e, vector);
220
221                dac2_port_image = dac2_port_image & 0xf7;
222                dac2_port_image = dac2_port_image | 0x01;
223                mio_write_reg(0x0f, dac2_port_image);   // Enable the interrupt
224        }
225        else
226        {
227                dac1_port_image = dac1_port_image & 0xfe;
228                dac1_port_image = dac1_port_image | 0x08;
229                mio_write_reg(0x0b, dac1_port_image);   // Access the int enable register
230
231                mio_write_reg(0x0a, vector);
232
233                dac1_port_image = dac1_port_image & 0xf7;
234                dac1_port_image = dac1_port_image | 0x01;
235                mio_write_reg(0x0b, dac1_port_image);   // Enable the interrupt
236        }
237        return(0);
238}
239
240
241
242///////////////////////////////////////////////////////////////////////////////
243//
244//              DISABLE_ADC_INTERRUPT
245//
246//////////////////////////////////////////////////////////////////////////////
247
248int disable_adc_interrupt(int adc_num)
249{
250
251        mio_error_code = MIO_SUCCESS;
252
253        if(check_handle())   /* Check for chip available */
254                return -1;
255
256        if(adc_num)
257        {
258                adc2_port_image = adc2_port_image & 0xfe;
259                adc2_port_image = adc2_port_image | 0x08;
260                mio_write_reg(0x07, adc2_port_image);   // Access the int enable register
261
262                mio_write_reg(0x06, 0);
263
264                adc2_port_image = adc2_port_image & 0xf7;
265                mio_write_reg(0x07, adc2_port_image);   // Disable the interrupt
266        }
267        else
268        {
269                adc1_port_image = adc1_port_image & 0xfe;
270                adc1_port_image = adc1_port_image | 0x08;
271                mio_write_reg(0x03, adc1_port_image);   // Access the int enable register
272
273                mio_write_reg(0x02, 0);
274
275                adc1_port_image = adc1_port_image & 0xf7;
276                mio_write_reg(0x03, adc1_port_image);   // Disable the interrupt
277        }
278        return(0);
279}
280
281
282///////////////////////////////////////////////////////////////////////////////
283//
284//              ENABLE_ADC_INTERRUPT
285//
286//////////////////////////////////////////////////////////////////////////////
287
288int enable_adc_interrupt(int adc_num)
289{
290unsigned char vector;
291
292
293        mio_error_code = MIO_SUCCESS;
294
295        if(check_handle())   /* Check for chip available */
296                return -1;
297
298        /* We read the assign IRQ from the driver, so we can program the hardware to
299           match,  but only if an aaplication desires such.
300    */
301
302        vector = mio_read_irq_assigned();
303
304        if(vector == 0)
305        {
306                mio_error_code = MIO_MISSING_IRQ;
307                sprintf(mio_error_string,"MIO(ADC) : enable_adc_interrupt - No IRQ assigned");
308
309                return(1);
310        }
311
312        if(adc_num)
313        {
314                adc2_port_image = adc2_port_image & 0xfe;
315                adc2_port_image = adc2_port_image | 0x08;
316                mio_write_reg(0x07, adc2_port_image);   // Access the int enable register
317
318                mio_write_reg(0x06, vector);
319
320                adc2_port_image = adc2_port_image & 0xf7;
321                adc2_port_image = adc2_port_image | 0x01;
322                mio_write_reg(0x07, adc2_port_image);   // Enable the interrupt
323        }
324        else
325        {
326                adc1_port_image = adc1_port_image & 0xfe;
327                adc1_port_image = adc1_port_image | 0x08;
328                mio_write_reg(0x03, adc1_port_image);   // Access the int enable register
329
330                mio_write_reg(0x02, vector);
331
332                adc1_port_image = adc1_port_image & 0xf7;
333                adc1_port_image = adc1_port_image | 0x01;
334                mio_write_reg(0x03, adc1_port_image);   // Enable the interrupt
335        }
336        return(0);
337}
338
339
340///////////////////////////////////////////////////////////////////////////////
341//
342//              SET_DAC_SPAN
343//
344//////////////////////////////////////////////////////////////////////////////
345
346int set_dac_span(int channel, unsigned char span_value)
347{
348unsigned char select_val;
349
350        mio_error_code = MIO_SUCCESS;
351
352        if(check_handle())   /* Check for chip available */
353                return -1;
354
355        if((channel < 0) || (channel > 7))
356        {
357                mio_error_code = MIO_BAD_CHANNEL_NUMBER;
358                sprintf(mio_error_string,"MIO(DAC) : Set_dac_span - bad channel number %d",channel);
359                return(1);
360        }
361
362
363        /* This function sets up the output range for the DAC channel */
364
365        select_val = (channel % 4) << 1;
366
367        write_dac_data(channel / 4, span_value);
368        if(mio_error_code)
369                return 1;
370
371        write_dac_command(channel / 4, 0x60 | select_val);
372        if(mio_error_code)
373                return(1);
374
375        if(wait_dac_ready(channel))
376                return 1;
377
378        return 0;
379}
380
381///////////////////////////////////////////////////////////////////////////////
382//
383//              WAIT_DAC_READY
384//
385//////////////////////////////////////////////////////////////////////////////
386
387int wait_dac_ready(int channel)
388{
389unsigned long retry;
390
391        retry = 100000L;
392
393        /* This may seem like an absurd way to handle waiting and violates the
394        "no busy waiting" policy. The fact is that the hardware is normally so fast that we
395        usually only need one time through the loop anyway. The longer timeout is for rare
396        occasions and for detecting non-existant hardware.
397        */
398
399        while(retry--)
400        {
401                if(dac_read_status(channel / 4) & DAC_BUSY)
402                        return 0;
403
404        }
405        return 1;
406
407}
408
409
410///////////////////////////////////////////////////////////////////////////////
411//
412//              SET_DAC_OUTPUT
413//
414//////////////////////////////////////////////////////////////////////////////
415
416int set_dac_output(int channel, unsigned short dac_value)
417{
418unsigned char select_val;
419
420        mio_error_code = MIO_SUCCESS;
421
422        if(check_handle())   /* Check for chip available */
423                return -1;
424
425        select_val = (channel % 4) << 1;
426        write_dac_data(channel / 4, dac_value);
427        if(mio_error_code)
428                return(1);
429        write_dac_command(channel / 4, 0x70 | select_val);
430        if(mio_error_code)
431                return(1);
432
433        if(wait_dac_ready(channel))
434                return 1;
435
436        return 0;
437}
438
439///////////////////////////////////////////////////////////////////////////////
440//
441//              SET_DAC_VOLTAGE
442//
443//////////////////////////////////////////////////////////////////////////////
444
445int set_dac_voltage(int channel, float voltage)
446{
447unsigned short  value = 0;
448float bit_val;
449
450        mio_error_code = MIO_SUCCESS;
451
452        if(check_handle())   /* Check for chip available */
453                return -1;
454
455        /* This output function is auto-ranging in that it picks the span that will
456        give the most precision for the voltage specified. This has one side-effect that
457        may be objectionable to some applications. When call to set_dac_span completes the
458        new range is set and the output will respond immediately using whatever value was last
459        in the output registers. This may cause a spike (up or down) in the DAC output until the
460        new output value is sent to the controller.
461        */
462
463        if((voltage < -10.0) || (voltage > 10.0))
464        {
465                mio_error_code = MIO_ILLEGAL_VOLTAGE;
466                sprintf(mio_error_string,"MIO(DAC) :Set DAC Voltage - Illegal Voltage %9.5f",voltage);
467                return 1;
468        }
469
470        if((voltage >= 0.0) && (voltage < 5.0))
471        {
472                set_dac_span(channel,DAC_SPAN_UNI5);
473                if(mio_error_code)
474                        return(1);
475                bit_val = 5.0 / 65536;
476                value = (unsigned short) (voltage / bit_val);
477        }
478
479        if(voltage >= 5.0)
480        {
481                set_dac_span(channel,DAC_SPAN_UNI10);
482                if(mio_error_code)
483                        return(1);
484                bit_val = 10.0 / 65536;
485                value = (unsigned short) (voltage / bit_val);
486        }
487
488        if((voltage < 0.0) && (voltage > -5.0))
489        {
490                set_dac_span(channel, DAC_SPAN_BI5);
491                if(mio_error_code)
492                        return(1);
493                bit_val = 10.0 / 65536;
494                value = (unsigned short) ((voltage + 5.0) / bit_val);
495        }
496
497        if(voltage <= -5.0)
498        {
499                set_dac_span(channel, DAC_SPAN_BI10);
500                if(mio_error_code)
501                        return(1);
502                bit_val = 20.0 / 65536;
503                value  = (unsigned short) ((voltage + 10.0) / bit_val);
504        }
505
506        if(wait_dac_ready(channel))
507                return 1;
508
509        set_dac_output(channel,value);
510        if(mio_error_code)
511                return(1);
512
513        return 0;
514}
515
516///////////////////////////////////////////////////////////////////////////////
517//
518//              ADC_START_CONVERSION
519//
520//////////////////////////////////////////////////////////////////////////////
521
522int adc_start_conversion(int channel)
523{
524        mio_error_code = MIO_SUCCESS;
525
526        if((channel <0) || (channel > 15))
527        {
528                mio_error_code = MIO_BAD_CHANNEL_NUMBER;
529                sprintf(mio_error_string,"MIO(ADC) : Start conversion bad channel number %d",channel);
530                return(1);
531        }
532
533        adc_last_channel = adc_current_channel;
534        adc_current_channel = channel;
535
536        write_adc_command(channel / 8,adc_channel_mode[channel]);
537       
538        if(mio_error_code)
539                return(1);
540
541        return 0;
542}
543
544///////////////////////////////////////////////////////////////////////////////
545//
546//              ADC_GET_CHANNEL_VOLTAGE
547//
548//////////////////////////////////////////////////////////////////////////////
549
550float adc_get_channel_voltage(int channel)
551{
552unsigned short value;
553float result;
554
555        mio_error_code = MIO_SUCCESS;
556
557        // Start two conversions so that we can have current data
558
559        adc_start_conversion(channel);
560        if(mio_error_code)
561                return(0.0);
562
563        adc_wait_ready(channel);
564        if(mio_error_code)
565                return(0.0);
566
567        adc_start_conversion(channel);
568        if(mio_error_code)
569                return(0.0);
570
571        adc_wait_ready(channel);
572        if(mio_error_code)
573                return(0.0);
574
575        // Read out the conversion's raw data
576
577        value = adc_read_conversion_data(channel);
578        if(mio_error_code)
579                return(0.0);
580
581        // Convert the raw data to a voltage
582
583        value = value + adc_adjust[channel];
584        result = value * adc_bitval[channel];
585        result = result + adc_offset[channel];
586
587        return(result);
588}
589
590///////////////////////////////////////////////////////////////////////////////
591//
592//              ADC_CONVERT_ALL_CHANNELS
593//
594//////////////////////////////////////////////////////////////////////////////
595
596int adc_convert_all_channels(unsigned short *buffer)
597{
598int x;
599
600        mio_error_code = MIO_SUCCESS;
601
602        if(check_handle())   /* Check for chip available */
603                return -1;
604
605        // Initialize global variables including transferinng the
606        // address of the user's ouput buffer to an internal buffer pointer
607
608        adc_user_buffer = buffer;
609        adc_input_buffer = adc_channel_buff;
610        adc_ch_index =0;
611        adc_out_index = 0;
612
613        adc_start_conversion(0);
614        if(mio_error_code)
615                return(1);
616
617        adc_wait_ready(0);
618        if(mio_error_code)
619                return(1);
620
621        // This is old data throw it out
622
623        adc_read_conversion_data(0);
624        if(mio_error_code)
625                return(1);
626
627        // Finish the rest of the channels
628
629        for(x=1; x<8; x++)
630        {
631                adc_start_conversion(x);
632                if(mio_error_code)
633                        return(1);
634
635                adc_wait_ready(x);
636                if(mio_error_code)
637                        return(1);
638
639                // Store the results in the user's buffer
640
641                adc_user_buffer[adc_out_index++] = adc_read_conversion_data(x);
642                if(mio_error_code)
643                        return(1);
644        }
645
646        // A final dummy conversion is required to get out the last data
647
648        adc_start_conversion(7);
649        if(mio_error_code)
650                return(1);
651
652        adc_wait_ready(7);
653        if(mio_error_code)
654                return(1);
655
656        adc_user_buffer[adc_out_index++] = adc_read_conversion_data(7);
657        if(mio_error_code)
658                return(1);
659
660        // Now start on the second controller
661
662        adc_start_conversion(8);
663        if(mio_error_code)
664                return(1);
665
666        adc_wait_ready(8);
667        if(mio_error_code)
668                return(1);
669
670        // This data is old - Throw it out
671
672        adc_read_conversion_data(8);
673        if(mio_error_code)
674                return(1);
675
676        for(x=9; x<16; x++)
677        {
678                adc_start_conversion(x);
679                if(mio_error_code)
680                        return(1);
681
682                adc_wait_ready(x);
683                if(mio_error_code)
684                        return(1);
685
686                adc_user_buffer[adc_out_index++] = adc_read_conversion_data(x);
687                if(mio_error_code)
688                        return(1);
689        }
690
691        // A final dummy conversion is required to get the last data
692
693        adc_start_conversion(15);
694        if(mio_error_code)
695                return(1);
696
697        adc_wait_ready(15);
698        if(mio_error_code)
699                return(1);
700
701        adc_user_buffer[adc_out_index++] = adc_read_conversion_data(15);
702        if(mio_error_code)
703                return(1);
704
705        return 0;
706}
707
708///////////////////////////////////////////////////////////////////////////////
709//
710//              ADC_CONVERT_TO_VOLTS
711//
712//////////////////////////////////////////////////////////////////////////////
713
714float adc_convert_to_volts(int channel, unsigned short value)
715{
716float result;
717
718                if((channel < 0) || (channel > 15))
719                        return(0.0);
720
721                value = value + adc_adjust[channel];
722                result = value * adc_bitval[channel];
723                result = result + adc_offset[channel];
724                return result;
725}
726
727
728///////////////////////////////////////////////////////////////////////////////
729//
730//              ADC_CONVERT_SINGLE_REPEATED
731//
732//////////////////////////////////////////////////////////////////////////////
733
734int adc_convert_single_repeated(int channel, unsigned short count, unsigned short *buffer)
735{
736        int x;
737
738        mio_error_code = MIO_SUCCESS;
739
740        if(check_handle())   /* Check for chip available */
741                return -1;
742
743        // Setup global variables including transferring the address of the
744        // user's output buffer to a global variable the ISR knows about.
745
746        adc_user_buffer = buffer;
747        adc_out_index = 0;
748        adc_repeat_channel = channel;
749        adc_repeat_count = count;
750
751        adc_start_conversion(adc_repeat_channel);
752        if(mio_error_code)
753                return(1);
754
755        adc_wait_ready(adc_repeat_channel);
756        if(mio_error_code)
757                return(1);
758
759        // This data is old, we don't want it
760
761        adc_read_conversion_data(adc_repeat_channel);
762        if(mio_error_code)
763                return(1);
764
765        // Perform the requested number of conversions. Place the results into
766        // the user's buffer.
767
768        for(x=0; x<=adc_repeat_count; x++)
769        {
770                adc_start_conversion(adc_repeat_channel);
771                if(mio_error_code)
772                        return(1);
773
774                adc_wait_ready(adc_repeat_channel);
775                if(mio_error_code)
776                        return(1);
777
778                adc_user_buffer[adc_out_index++] = adc_read_conversion_data(adc_repeat_channel);
779                if(mio_error_code)
780                        return(1);
781        }
782
783        // One last dummy conversion to retrieve our last data
784
785        adc_start_conversion(adc_repeat_channel);
786        if(mio_error_code)
787                return(1);
788
789        adc_wait_ready(adc_repeat_channel);
790        if(mio_error_code)
791                return(1);
792
793        adc_user_buffer[adc_out_index++] = adc_read_conversion_data(adc_repeat_channel);
794        if(mio_error_code)
795                return(1);
796
797        return 0;
798}
799
800///////////////////////////////////////////////////////////////////////////////
801//
802//              ADC_BUFFERED_CHANNEL_CONVERSIONS
803//
804//////////////////////////////////////////////////////////////////////////////
805
806int adc_buffered_channel_conversions(unsigned char *input_channel_buffer,unsigned short *buffer)
807{
808int adc_next_channel;
809
810        mio_error_code = MIO_SUCCESS;
811
812        if(check_handle())   /* Check for chip available */
813                return -1;
814
815
816        adc_ch_index = 0;
817        adc_out_index = 0;
818       
819        adc_user_buffer = buffer;
820        adc_input_buffer = input_channel_buffer;
821
822        // Reset all of the array index pointers
823
824        adc_start_conversion(adc_input_buffer[adc_ch_index]);
825
826        if(mio_error_code)
827                return(1);
828
829        adc_wait_ready(adc_input_buffer[adc_ch_index++]);
830
831        if(mio_error_code)
832                return(1);
833
834        // While there are channel numbers in the buffer (1= 0xff)
835        // convert the requested channel and place the result in the
836        // user's output buffer
837
838        while(adc_input_buffer[adc_ch_index] != 0xff)
839        {
840                adc_next_channel = adc_input_buffer[adc_ch_index];
841
842
843                /* This function is particularly tricky because of the
844                fact that the data is delayed by one conversion and if
845                we switch back and forth between the two controllers
846                we'll need to run an extra conversion in order to get the
847                last data offering from the previous controller. The
848                conditional code in the next several lines handles the
849                switches from one controller to the other.
850                */
851
852                if(adc_current_channel < 8 && adc_next_channel > 7)
853                {
854                        adc_start_conversion(adc_current_channel);
855                        if(mio_error_code)
856                                return(1);
857
858                        adc_wait_ready(adc_current_channel);
859                        if(mio_error_code)
860                                return(1);
861
862                        adc_user_buffer[adc_out_index++] = adc_read_conversion_data(adc_current_channel);
863                        if(mio_error_code)
864                                return(1);
865
866                        adc_start_conversion(adc_input_buffer[adc_ch_index]);
867                        if(mio_error_code)
868                                return(1);
869
870                        adc_wait_ready(adc_input_buffer[adc_ch_index++]);
871                        if(mio_error_code)
872                                return(1);
873                }
874                else if(adc_current_channel > 7 && adc_next_channel < 8)
875                {
876                        adc_start_conversion(adc_current_channel);
877                        if(mio_error_code)
878                                return(1);
879
880                        adc_wait_ready(adc_current_channel);
881                        if(mio_error_code)
882                                return(1);
883
884                        adc_user_buffer[adc_out_index++] = adc_read_conversion_data(adc_current_channel);
885                        if(mio_error_code)
886                                return(1);
887
888                        adc_start_conversion(adc_input_buffer[adc_ch_index]);
889                        if(mio_error_code)
890                                return(1);
891
892                        adc_wait_ready(adc_input_buffer[adc_ch_index++]);
893                        if(mio_error_code)
894                                return(1);
895                }
896                adc_start_conversion(adc_input_buffer[adc_ch_index]);
897                if(mio_error_code)
898                        return(1);
899
900                adc_wait_ready(adc_input_buffer[adc_ch_index++]);
901                if(mio_error_code)
902                        return(1);
903
904                adc_user_buffer[adc_out_index++] = adc_read_conversion_data(adc_current_channel);
905                if(mio_error_code)
906                        return(1);
907        }
908
909        // One last conversion allows us to retrieve our real last data
910
911        adc_start_conversion(adc_input_buffer[--adc_ch_index]);
912        if(mio_error_code)
913                return(1);
914        adc_wait_ready(adc_input_buffer[adc_ch_index]);
915        if(mio_error_code)
916                return(1);
917
918        adc_user_buffer[adc_out_index++] = adc_read_conversion_data(adc_last_channel);
919        if(mio_error_code)
920                return(1);
921
922        return 0;
923}
924
925///////////////////////////////////////////////////////////////////////////////
926//
927//              ADC_WAIT_READY
928//
929//////////////////////////////////////////////////////////////////////////////
930
931int adc_wait_ready(int channel)
932{
933long retry;
934       
935        mio_error_code = MIO_SUCCESS;
936        retry = 100000l;
937
938        /* Like with the DAC timeout routine, under normal circumstances we'll
939        barely make it through the loop one time beacuse the hadrware is plenty
940        fast. We have the delay for the rare occasion and when the hadrware is not
941        responding properly.
942        */
943
944        while(retry--)
945        {
946                if(adc_read_status(channel / 8) & 0x80)
947                        return 0;
948        }
949
950        mio_error_code = MIO_TIMEOUT_ERROR;
951        sprintf(mio_error_string,"MIO(ADC) : Wait ready - Device timeout error");
952        return(1);
953}
954
955///////////////////////////////////////////////////////////////////////////////
956//
957//              BUFFERED_DAC_OUTPUT
958//
959//////////////////////////////////////////////////////////////////////////////
960
961int buffered_dac_output(unsigned char *cmd_buff,unsigned short *data_buff)
962{
963int x= 0;
964
965        mio_error_code = MIO_SUCCESS;
966
967        if(check_handle())   /* Check for chip available */
968                return -1;
969
970        while(1)
971        {
972                if(cmd_buff[x] == 0xff)
973                        return 0;
974
975                if(set_dac_output(cmd_buff[x], data_buff[x]))
976                        return 1;
977
978                x++;
979        }
980}
981
982///////////////////////////////////////////////////////////////////////////////
983//
984//              ADC_SET_CHANNEL_MODE
985//
986//////////////////////////////////////////////////////////////////////////////
987
988int adc_set_channel_mode(int channel, int input_mode,int duplex,int range)
989{
990unsigned char command_byte;
991
992        mio_error_code = MIO_SUCCESS;
993
994        if(channel < 0 || channel > 15)
995        {
996                mio_error_code = MIO_BAD_CHANNEL_NUMBER;
997                sprintf(mio_error_string,"MIO(ADC) : Set Channel Mode - Bad Channel Number %d",channel);
998                return(1);
999        }
1000
1001        // Check for illegal modes
1002
1003        if((input_mode != ADC_SINGLE_ENDED) && (input_mode != ADC_DIFFERENTIAL))
1004        {
1005                mio_error_code = MIO_BAD_MODE_NUMBER;
1006                sprintf(mio_error_string,"MIO(ADC) : Set Channel Mode - Bad Mode Number");
1007                return(1);
1008        }
1009
1010        if((duplex != ADC_UNIPOLAR) && (duplex != ADC_BIPOLAR))
1011        {
1012                mio_error_code = MIO_BAD_MODE_NUMBER;
1013                sprintf(mio_error_string,"MIO(ADC) : Set Channel Mode - Bad Mode Number");
1014                return(1);
1015        }
1016
1017        if((range != ADC_TOP_5V) && (range != ADC_TOP_10V))
1018        {
1019                mio_error_code = MIO_BAD_RANGE;
1020                sprintf(mio_error_string,"MIO(ADC) : Set Channel Mode - Bad Range Value");
1021                return(1);
1022        }
1023
1024        command_byte = adc_channel_select[channel];
1025        command_byte = command_byte | input_mode | duplex | range;
1026
1027        /* Building these four arrays at mode set time is critical for speed
1028           as we don't need to calculate anything when we want to start an ADC
1029           conversion. WE simply retrieve the command byte from the array
1030           and send it to the controller.
1031
1032           Likewise, when doing conversion from raw 16-bit values to a voltage
1033           the mode controls the worth of each individual bit as well as binary
1034           bias and offset values.
1035   */
1036
1037        adc_channel_mode[channel] = command_byte;
1038
1039        /* Calculate bit values, offset, and adjustment values */
1040
1041        if((range == ADC_TOP_5V) && (duplex == ADC_UNIPOLAR))
1042        {
1043                adc_bitval[channel] = 5.00 / 65536.0;
1044                adc_adjust[channel] = 0;
1045                adc_offset[channel] = 0.0;
1046        }
1047
1048        if((range == ADC_TOP_5V) && (duplex == ADC_BIPOLAR))
1049        {
1050                adc_bitval[channel] = 10.0 / 65536.0;
1051                adc_adjust[channel] = 0x8000;
1052                adc_offset[channel] = -5.000;
1053        }
1054
1055        if((range == ADC_TOP_10V) && (duplex == ADC_UNIPOLAR))
1056        {
1057                adc_bitval[channel] = 10.0 / 65536.0;
1058                adc_adjust[channel] = 0;
1059                adc_offset[channel] = 0.0;
1060        }
1061
1062        if((range == ADC_TOP_10V) && (duplex == ADC_BIPOLAR))
1063        {
1064                adc_bitval[channel] = 20.0 / 65536.0;
1065                adc_adjust[channel] = 0x8000;
1066                adc_offset[channel] = -10.0;
1067        }
1068
1069        return 0;
1070}
1071
1072////////////////////////////////////////////////////////////////////////////////
1073//
1074//
1075//              ADC_AUTO_GET_CHANNEL_VOLTAGE
1076//
1077//
1078/////////////////////////////////////////////////////////////////////////////////
1079
1080float adc_auto_get_channel_voltage(int channel)
1081{
1082unsigned short value;
1083float result;
1084
1085        mio_error_code = MIO_SUCCESS;
1086
1087        if(check_handle())   /* Check for chip available */
1088                return -1;
1089
1090        // Start out on a +/-10 Volt scale
1091
1092        adc_set_channel_mode(channel,ADC_SINGLE_ENDED,ADC_BIPOLAR,ADC_TOP_10V);
1093        if(mio_error_code)
1094                return(0.0);
1095
1096        adc_start_conversion(channel);
1097        if(mio_error_code)
1098                return(0.0);
1099
1100        adc_wait_ready(channel);
1101        if(mio_error_code)
1102                return(0.0);
1103
1104        adc_start_conversion(channel);
1105        if(mio_error_code)
1106                return(0.0);
1107
1108        adc_wait_ready(channel);
1109        if(mio_error_code)
1110                return(0.0);
1111
1112        value = adc_read_conversion_data(channel);
1113        if(mio_error_code)
1114                return(0.0);
1115
1116        // Convert the raw data to voltage
1117
1118        value = value + adc_adjust[channel];
1119        result = value * adc_bitval[channel];
1120        result = result + adc_offset[channel];
1121
1122#ifdef DEBUG
1123        printf("auto_get_channel_voltage : Raw = %04x, adjust = %d, bitval = %9.5f, offset = %9.5f,  result = %9.5f\n",
1124                                                value - adc_adjust[channel],adc_adjust[channel],adc_bitval[channel],adc_offset[channel],result);
1125#endif
1126
1127        // If the voltage is less than -5.00 volts, we're as precise as we can get
1128
1129        if(result <= -5.00)
1130                return(result);
1131
1132        // If the result is between -4.99 and 0.0 we can  to the +/- 5V scale.
1133
1134        if(result < 0.0)
1135                adc_set_channel_mode(channel,ADC_SINGLE_ENDED,ADC_BIPOLAR,ADC_TOP_5V);
1136
1137        if(mio_error_code)
1138                return(0.0);
1139
1140        // If the result is above 5 volts a 0 - 10V range will work best
1141
1142        if(result >= 5.00)
1143                adc_set_channel_mode(channel,ADC_SINGLE_ENDED,ADC_UNIPOLAR,ADC_TOP_10V);
1144
1145        if(mio_error_code)
1146                return(0.0);
1147
1148        // Lastly if we're greater than 0 and less than 5 volts the 0-5V scale is best
1149
1150        if((result >= 0.0) && (result < 5.00))
1151                adc_set_channel_mode(channel, ADC_SINGLE_ENDED, ADC_UNIPOLAR,ADC_TOP_5V);
1152
1153        if(mio_error_code)
1154                return(0.0);
1155
1156        // Now that the values is properly ranged, we take two more samples
1157        // to get a current reading at the new scale.
1158
1159        adc_start_conversion(channel);
1160
1161        if(mio_error_code)
1162                return(0.0);
1163
1164        adc_wait_ready(channel);
1165
1166        if(mio_error_code)
1167                return(0.0);
1168
1169        adc_start_conversion(channel);
1170
1171        if(mio_error_code)
1172                return(0.0);
1173
1174        adc_wait_ready(channel);
1175
1176        if(mio_error_code)
1177                return(0.0);
1178
1179        value = adc_read_conversion_data(channel);
1180        if(mio_error_code)
1181                return(0.0);
1182
1183        // Convert the raw data to voltage
1184
1185        value = value + adc_adjust[channel];
1186        result = value * adc_bitval[channel];
1187        result = result + adc_offset[channel];
1188
1189#ifdef DEBUG
1190        printf("auto_get_channel_voltage : Raw = %04x, adjust = %d, bitval = %9.5f, offset = %9.5f,  result = %9.5f\n",
1191                                                value - adc_adjust[channel],adc_adjust[channel],adc_bitval[channel],adc_offset[channel],result);
1192#endif
1193
1194        return(result);
1195}
1196
1197////////////////////////////////////////////////////////////////////////////////
1198//
1199//
1200//              DIO_READ_BIT
1201//
1202//
1203/////////////////////////////////////////////////////////////////////////////////
1204
1205int dio_read_bit(int bit_number)
1206{
1207unsigned char port;
1208int val;
1209
1210        mio_error_code = MIO_SUCCESS;
1211
1212        if(check_handle())   /* Check for chip available */
1213                return -1;
1214
1215        // Adjust for 0 - 47 bit numbering
1216
1217        --bit_number;
1218
1219        port = bit_number / 8;
1220
1221        val = read_dio_byte(port);
1222
1223        // Get just the bit we specified
1224
1225        val = val & (1 << (bit_number % 8));
1226
1227        // adjust the return for a 0 or 1 value
1228
1229        if(val)
1230                return 1;
1231
1232        return 0;
1233}
1234
1235////////////////////////////////////////////////////////////////////////////////
1236//
1237//
1238//              DIO_WRITE_BIT
1239//
1240//
1241/////////////////////////////////////////////////////////////////////////////////
1242
1243int dio_write_bit(int bit_number, int val)
1244{
1245unsigned char port;
1246unsigned char temp;
1247unsigned char mask;
1248
1249        mio_error_code = MIO_SUCCESS;
1250
1251        if(check_handle())   /* Check for chip available */
1252                return -1;
1253
1254        // Adjust bit numbering for 0 based numbering
1255
1256        --bit_number;
1257
1258        // Calculate the address of the port based on bit number
1259
1260        port = bit_number / 8;
1261
1262        // Use the image value to avoid having to read from the port first
1263
1264        temp = dio_port_images[bit_number / 8];
1265
1266        // Calculate the bit mask for the specifed bit
1267
1268        mask = (1 << (bit_number %8));
1269
1270        // Check whether the request was to set or clear the bit
1271
1272        if(val)
1273                temp = temp | mask;
1274        else
1275                temp = temp & ~mask;
1276
1277        // Update the image value with the value we're about to write
1278
1279        dio_port_images[bit_number / 8] = temp;
1280
1281        write_dio_byte(port, temp);
1282
1283        return 0;
1284}
1285
1286
1287////////////////////////////////////////////////////////////////////////////////
1288//
1289//
1290//              DIO_SET_BIT
1291//
1292//
1293/////////////////////////////////////////////////////////////////////////////////
1294
1295int dio_set_bit(int bit_number)
1296{
1297        mio_error_code = MIO_SUCCESS;
1298
1299        if(check_handle())   /* Check for chip available */
1300                return -1;
1301
1302        dio_write_bit(bit_number,1);
1303
1304        return 0;
1305}
1306
1307////////////////////////////////////////////////////////////////////////////////
1308//
1309//
1310//              DIO_CLR_BIT
1311//
1312//
1313/////////////////////////////////////////////////////////////////////////////////
1314
1315int dio_clr_bit(int bit_number)
1316{
1317        mio_error_code = MIO_SUCCESS;
1318
1319        if(check_handle())   /* Check for chip available */
1320                return -1;
1321
1322        dio_write_bit(bit_number,0);
1323
1324        return 0;
1325}
1326
1327////////////////////////////////////////////////////////////////////////////////
1328//
1329//
1330//              DIO_ENAB_BIT_INT
1331//
1332//
1333/////////////////////////////////////////////////////////////////////////////////
1334
1335int dio_enab_bit_int(int bit_number, int polarity)
1336{
1337unsigned char port;
1338unsigned char temp;
1339unsigned char mask;
1340
1341
1342        mio_error_code = MIO_SUCCESS;
1343
1344        if(check_handle())   /* Check for chip available */
1345                return -1;
1346
1347        // Adjust the bit number for 0 based numbering
1348
1349        --bit_number;
1350
1351        // Calculate the offset for the enable port
1352
1353        port = (bit_number / 8) + 8;
1354
1355        // Calculate the proper bit mask for this bit number
1356
1357        mask = (1 << (bit_number % 8));
1358
1359        // Turn on access to page 2 registers
1360
1361        write_dio_byte(0x07,0x80);
1362
1363        // Get the current state of the enable register
1364
1365        temp = read_dio_byte(port);
1366
1367        // Set the enable bit for our bit number
1368
1369        temp = temp | mask;
1370
1371        // Now update the interrupt enable register
1372
1373        write_dio_byte(port, temp);
1374
1375        // Turn on access to page 1 for polarity control
1376
1377        write_dio_byte(0x07,0x40);
1378
1379        temp = read_dio_byte(port);
1380
1381        // Set the polarity according to the argument value
1382
1383        if(polarity)
1384                temp = temp | mask;
1385        else
1386                temp = temp & ~mask;
1387
1388        write_dio_byte(port, temp);
1389
1390        // Set access back to page 0
1391
1392        write_dio_byte(0x07,0);
1393
1394        return 0;
1395}
1396
1397
1398////////////////////////////////////////////////////////////////////////////////
1399//
1400//
1401//              DIO_DISAB_BIT_INT
1402//
1403//
1404/////////////////////////////////////////////////////////////////////////////////
1405
1406int dio_disab_bit_int(int bit_number)
1407{
1408unsigned char port;
1409unsigned char temp;
1410unsigned char mask;
1411
1412        mio_error_code = MIO_SUCCESS;
1413
1414        if(check_handle())   /* Check for chip available */
1415                return -1;
1416
1417        // Adjust the bit number for 0 based numbering
1418
1419        --bit_number;
1420
1421        // Calculate the offset for the enable port
1422
1423        port = (bit_number / 8) + 8;
1424
1425        // Calculate the proper bit mask for this bit number
1426
1427        mask = (1 << (bit_number % 8));
1428
1429        // Turn on access to page 2 registers
1430
1431        write_dio_byte(0x07,0x80);
1432
1433        // Get the current state of the enable register
1434
1435        temp = read_dio_byte(port);
1436
1437        // Clear the enable bit for the our bit
1438
1439        temp = temp & ~mask;
1440
1441        // Update the enable register with the new data
1442
1443        write_dio_byte(port,temp);
1444
1445        // Set access back to page 0
1446
1447        write_dio_byte(0x07,0);
1448
1449        return 0;
1450}
1451
1452
1453////////////////////////////////////////////////////////////////////////////////
1454//
1455//
1456//              DIO_CLR_INT
1457//
1458//
1459/////////////////////////////////////////////////////////////////////////////////
1460
1461int dio_clr_int(int bit_number)
1462{
1463unsigned short port;
1464unsigned short temp;
1465unsigned short mask;
1466
1467        // Adjust for 0 based numbering
1468        mio_error_code = MIO_SUCCESS;
1469
1470        if(check_handle())   /* Check for chip available */
1471                return -1;
1472
1473        --bit_number;
1474
1475        // Calculate the correct offset for our enable register
1476
1477        port = (bit_number / 8) + 8;
1478
1479        // Calculate the bit mask for this bit
1480
1481        mask = (1 << (bit_number % 8));
1482
1483        // Set access to page 2 for the enable register
1484
1485        write_dio_byte(0x07,0x80);
1486
1487        // Get the current state of the register
1488
1489        temp = read_dio_byte(port);
1490
1491        // Temporarily clear only our enable. This clears the interrupt
1492
1493        temp = temp & ~mask;
1494
1495        // Write out the temporary value
1496
1497        write_dio_byte(port, temp);
1498
1499        temp = temp | mask;
1500
1501        write_dio_byte(port, temp);
1502
1503        // Set access back to page 0
1504
1505        write_dio_byte(0x07,0);
1506
1507        return 0;
1508}
1509
Note: See TracBrowser for help on using the repository browser.