Logo Search packages:      
Sourcecode: yepp version File versions  Download package

ieee1284.c

#include <asm/io.h>
#include "port_signal.h"
#include "project.h"

#define WAITLOOP        50000
#define WAITTIME        8
#define LWAITTIME       4

int ecp = 0;

int write_data(int value)
{
   outb_p(value, DATA);

   return value;
}

int read_dsr()
{
   return inb_p(DSR);
}

int set_dcr(int signal)
{
   int current = inb_p(DCR);

   current |= signal;

   outb_p(current, DCR);

   return current;
}

int reset_dcr(int signal) 
{
   int current = inb_p(DCR);

   current &= ~signal;

   outb_p(current, DCR);

   return current;
}

int timeup (int t, struct timeval *then)
{
   struct timeval now, diff;

   gettimeofday (&now, NULL);

   timersub (&now, then, &diff);

   if (diff.tv_sec >= t)
      return SUCCESS;

   return FAIL;
}


int wait_dsr(int time, int wait_high, int wait_low)
{
   struct timeval start;
   int i = 0;

   gettimeofday (&start, NULL);

   while ((inb_p (DSR) & wait_high) != wait_high)
   {
      if (i > WAITLOOP)
      {
         if (timeup (time, &start))
            return FAIL;
         i = 0;
      }
      i++;
   }

   while ((inb_p (DSR) & wait_low))
   {
       if (i > WAITLOOP)
       {
          if (timeup (time, &start))
          return FAIL;
          i = 0;
       }
       i++;
   }

   return SUCCESS;
}


int ieee1284_rtof (void)
{
   set_dcr(DCR_NINIT);
   DIRWAIT;
   
   if (!wait_dsr (WAITTIME, DSR_PE | DSR_NBUSY | DSR_NACK, NONE))
      return FAIL;

   reset_dcr(DCR_DIRECTION);
  
   return SUCCESS;
}

int ieee1284_ftor(void)
{
   set_dcr(DCR_DIRECTION);
   set_dcr(DCR_NAUTOFEED);
   DIRWAIT;
   
   reset_dcr(DCR_NINIT);
   if (!wait_dsr (LWAITTIME, NONE, DSR_PE))
   {
      // printf("ieee1284_ftor: failed\n");
      return FAIL;
   }
   
   return SUCCESS;
}

int ieee1284_term(void)
{
   reset_dcr(DCR_NAUTOFEED);
   set_dcr(DCR_NSELECTIN);

   if (!wait_dsr (WAITTIME, DSR_PE, 0))
      return FAIL;

   set_dcr(DCR_NAUTOFEED | DCR_NINIT);

   return SUCCESS;
}

int negotiate(int i)
{
   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_EPP, ECR);
   outb_p(i, DATA);

   set_dcr(DCR_NAUTOFEED);

   reset_dcr(DCR_NSELECTIN);

   if (!wait_dsr (WAITTIME, DSR_PE | DSR_SELECT | DSR_NERROR, DSR_NACK))
      return FAIL;

   set_dcr(DCR_NSTROBE);
   reset_dcr(DCR_NSTROBE | DCR_NAUTOFEED);

   if (!wait_dsr (WAITTIME, DSR_NBUSY | DSR_SELECT, DSR_PE))
      return FAIL;

   if (!wait_dsr (WAITTIME, DSR_NACK, 0))
      return FAIL;

   set_dcr (DCR_NAUTOFEED);

   if (!wait_dsr (WAITTIME, DSR_PE, 0))
       return FAIL;

   return SUCCESS;
}

int ieee1284_probe(int base)
{
   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_EPP, ECR);
   reset_dcr(DCR_DIRECTION);
   
   write_data(0x55);
   if(inb_p(DATA) != 0x55)
      return FAIL;

   write_data(0xaa);
   if(inb_p(DATA) != 0xaa)
      return FAIL;

   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_EPP, ECR);

   set_dcr(DCR_DIRECTION);
   write_data(0x55);

   if(inb_p(DATA) == 0x55)
   {
      reset_dcr(DCR_DIRECTION);
      return FAIL;
   }

   reset_dcr(DCR_DIRECTION);
   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_ECP, ECR);

   if((inb_p(ECR) & 0xe0) != 0x60)
      return SUCCESS;

   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_EPP, ECR);

   if((inb_p(ECR) & 0xe0) != 0x20)
      return SUCCESS;

   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_SPP, ECR);

   if((inb_p(ECR) & 0xe0) != 0x00)
      return SUCCESS;

   ecp++;
   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_EPP, ECR);
   return SUCCESS;
}

void foo()
{
   outb_p(0xc, DCR);
}

int phase1(void)
{
   foo ();
   if(!negotiate(0x10))
      return FAIL;

   return SUCCESS;
}

int phase2(void)
{
    if(!ieee1284_ftor())
       return FAIL;

    return SUCCESS;
}

int phase3(void)
{
    if(!ieee1284_rtof())
       return FAIL;
    
    return SUCCESS;
}

void phase4(void)
{
    ieee1284_term();

    reset_dcr (DCR_NAUTOFEED);
}

int time_diff(struct timeval start)
{
   struct timeval current;
   long start_usec, current_usec;

   gettimeofday(&current, NULL);
   
   start_usec = start.tv_sec * 1000000 + start.tv_usec;
   current_usec = current.tv_sec * 1000000 + current.tv_usec;
   
   return (current_usec - start_usec);
}

int not1284_setup(void)
{
   reset_dcr(DCR_NAUTOFEED);
   set_dcr(DCR_NINIT);
   
   if (!wait_dsr (WAITTIME, DSR_PE | DSR_NERROR, 0))
      return FAIL;

   reset_dcr(DCR_DIRECTION);
   set_dcr(DCR_NSELECTIN | DCR_NINIT);

   if (!wait_dsr (WAITTIME, DSR_PE | DSR_NERROR, 0))
      return FAIL;

   set_dcr(DCR_NAUTOFEED);

   if (!wait_dsr (WAITTIME, DSR_NACK | DSR_SELECT, DSR_PE))
      return FAIL;

   reset_dcr(DCR_NAUTOFEED);

   if (!wait_dsr (WAITTIME, DSR_NBUSY, 0))
      return FAIL;

   return SUCCESS;
}
                   
int ieee1284_writebyte(unsigned char b)
{
   if (!wait_dsr (WAITTIME, DSR_NBUSY, 0))
   {
      // printf("1284_BUSY\n");
      return FAIL;
   }

   outb_p(b, DATA);

   set_dcr(DCR_NSTROBE);

   if (!wait_dsr (WAITTIME, 0, DSR_NBUSY))
   {
      // printf("ieee1284_writebyte 1: failed\n");
      return FAIL;
   }

   reset_dcr(DCR_NSTROBE | DCR_NAUTOFEED);

   if (!wait_dsr (WAITTIME, DSR_NBUSY, 0))
   {
      // printf("ieee1284_writebyte 2: failed\n");
      return FAIL;
   }

   set_dcr(DCR_NAUTOFEED);

   return SUCCESS;
}

int ieee1284_readbyte(unsigned char *buf)
{
   set_dcr(DCR_NAUTOFEED);
   
   if (!wait_dsr (LWAITTIME, NONE, DSR_NACK))
   {
      return FAIL;
   }
   
   *buf = inb_p(DATA);
   reset_dcr(DCR_NAUTOFEED);

   if (!wait_dsr (LWAITTIME, DSR_NACK, NONE))
   {
      return FAIL;
   }
   
   set_dcr(DCR_NAUTOFEED);

   return SUCCESS;
}

int wait_ecr(int t, int a, int d)
{
   int i;
   struct timeval start;

   gettimeofday(&start, NULL);

   i = 0;
   while((inb_p (ECR) & a) != a)
   {
      if (i > WAITLOOP)
      {
         if (timeup (t, &start))
         {
            return 0;
         }
         i = 0;
      }
      i++;
   }

   while ((inb_p (ECR) & d))
   {
      if (i > WAITLOOP)
      {
         if (timeup (t, &start))
         {
            return 0;
         }
         i = 0;
      }
      i++;
   }

   return 1;
}

int yepp_ecp_write(char *buf, int i)
{
   int red;

   red = 0;

   if(!wait_dsr(WAITTIME, DSR_NBUSY, 0))
      return red;

   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_ECP, ECR);

   reset_dcr(DCR_NAUTOFEED);

   while(i--)
   {
      if(!wait_ecr(WAITTIME, 0, ECR_FULL))
      {
         set_dcr (DCR_NAUTOFEED);
         outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_EPP, ECR);
         return red;
      }

      outb(*buf, ECPDFIFO);

      red++;
      buf++;
   }

   wait_ecr(WAITTIME, ECR_EMPTY, 0);

   set_dcr(DCR_NAUTOFEED);
   outb_p(ECR_NERRINTREN | ECR_SERVICEINTR | ECR_MODE_EPP, ECR);

   return red;
}

int yepp_write(char *buf, int i)
{
   int red = 0;

   if(ecp)
      return yepp_ecp_write(buf, i);
          
   while(i--)
   {
      if(!ieee1284_writebyte(*buf))
         return red;
      red++;
      buf++; 
   }

   return red;
}

Generated by  Doxygen 1.6.0   Back to index