Simple Embedded Code Example : I/O Driver Functions

I/O Driver Functions

The following code sample is taken from a working driver file implemented to support the ONYX-MM-DIO I/O card from Diamond Systems Corp.

Example Code:

 
#include <vxWorks.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslib.h>
#include "types.h"
#include "symbols.h"
#include "string.h"
 
#define DIO_1A 0
#define DIO_1B 1
 
#define DIO_1C 2
#define DIO_1CR 3
 
#define DIO_2A 4
#define DIO_2B 5
#define DIO_2C 6
#define DIO_2CR 7
 
int onyx_base_addr; /* The card base address , converted into int format */
 
/* -- generic card initializer for both input and output mapping */
void onyx_init(card_desc_p card_p)
{ int addr;
sscanf(card_p->base_addr,"%x",&onyx_base_addr);
printf ("base_addr = 0x%x\n",onyx_base_addr);
sysOutByte(onyx_base_addr+ DIO_2A,0x00); /* Reset of output registers before setting of 2A port
to be output */
sysDelay();
addr = onyx_base_addr+DIO_1CR; /* control register 1CR address */
/* Port 1A , 1B and 1C set to OUTPUT/MODE 0 */
sysOutByte(addr, 0x80);
printf ("Ports 1A , 1B and 1C set to OUTPUT/MODE 0\n");
sysDelay();
 
addr = onyx_base_addr + DIO_2CR; /* control register 2CR address */
sysOutByte(addr,0x9B); /* Port 2A , 2B and 2C set to INPUT/MODE 0 */
printf ("Ports 2A , 2B and 2C set to INPUT/MODE 0\n");
 
}
 
/* -- generic card driver for both input and output mapping */
void onyx_in(report_link elem)
{
genptr new_value = (genptr)elem->received_val;
int b, offset;
sscanf(elem->pin_offset,"%d",&offset);
b = sysInByte(onyx_base_addr+offset); /* input from 2A port */
 
switch(elem->elem_type) {
case el_integer:
case el_enumer:
case el_bit_array:
*(int*)new_value = b;
break;
case el_condition:
case el_event:
*(char *)new_value = b;
break;
case el_real:
*(double*)new_value = b;
break;
default:
*(int*)new_value = 0;
break;
}
}
 
#define OUTPUT_BUF_SIZE 16
double output_buf;
 
void onyx_out(report_link elem)
{
void *actual_val = (void*) &output_buf;
int offset;
sscanf(elem->pin_offset,"%d",&offset);
switch(elem->elem_type) {
case el_integer:
case el_enumer:
case el_bit:
case el_bit_array:
if (elem->pin_inverse)
(*(int*)actual_val) = ~(*(int*)elem->elem_value);
else
(*(int*)actual_val) = (*(int*)elem->elem_value);
sysOutByte(onyx_base_addr+ offset, *(char*)actual_val); /* a=> output to 1A port */
break;
case el_real:
(*(double*)actual_val) = (*(double*)elem->elem_value);
break;
case el_condition:
case el_event:
if (elem->pin_inverse)
(*(char*)actual_val) = ~(*(char*)elem->elem_value);
else
(*(char*)actual_val) = (*(char*)elem->elem_value);
sysOutByte(onyx_base_addr+ offset,*(char*)actual_val);
break;
default:
break;
}
}
 
void onyx_driver(report_link elem, int map_mode)
{
if (map_mode == STM_OUT_MAP) {
onyx_out(elem);
}
else if (map_mode == STM_IN_MAP) {
onyx_in(elem);
}
}
 
/* -- generic card closing function */
 
void onyx_close(card_desc_p card_p)
{
/* Some RESET calls for I/O card */
printf("Card has been closed\n");
}