source: multiio/pcmmio/mio_io.c @ 396c143

Last change on this file since 396c143 was 396c143, checked in by Joel Sherrill <joel.sherrill@…>, on 10/05/11 at 18:03:32

2011-10-05 Cindy Cicalese <cicalese@…>

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