⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcc850.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 2 页
字号:
{
dword *bcsr1 = at_bcsr1();

    *bcsr1 |= PCCVCCON; /*  0  Level vcc */
    *bcsr1 |= PCMCIA_HIZPP; /* High Impedence Voltage Level vpp */
    /* Enable ADS PCMCIA Channel */
    *bcsr1 &= ~PCCEN;
}
#elif (MPC860)
/*
{
dword *bcsr1 = at_bcsr1();

    *bcsr1 |= PCMCIA_HIZ; /*  0  Level vcc */
    *bcsr1 |= PCMCIA_HIZPP; /* High Impedence Voltage Level vpp */
    /* Enable ADS PCMCIA Channel */
    *bcsr1 &= ~PCCEN;
}
*/
#error define power down in pcmctrl_init for mpc860
#endif

/* Initialize the PCMCIA control registers.
   Clear pending interrupts and disable all interrupts. */

   for (i = 0; i < NSOCKET; i++)
   {
	pcm860_wr_gcr(i, 0);
      pcmctrl_card_down(i);
   }
   IMMR->pcmcia_per   = 0x00000000; /* disable all interrupts */
   IMMR->pcmcia_pscr  = PCMCIA_ALL_AMGMT|PCMCIA_ALL_AIRQ|PCMCIA_ALL_BMGMT|PCMCIA_ALL_BIRQ;

   for (i = 0; i < 7; i++)
   {
      pcm860_wr_option_reg(i, 0);
      pcm860_wr_address_reg(i, 0);
   }

    l =   pcm860_rd_gcr(0);
    l &= ~PGCRA_CASCHLVL;
    l |= ((1<<(7-PCMCIA_MGMT_INTERRUPT_LEVEL))<<16);
    pcm860_wr_gcr(0, l);
 
   if (NSOCKET > 1)
   {
	   l =   pcm860_rd_gcr(1);
	   l &= ~PGCRB_CBSCHLVL;
	   l |= ((1<<(7-PCMCIA_MGMT_INTERRUPT_LEVEL))<<16);
	   pcm860_wr_gcr(1, l);
   }
   IMMR->siu_simask |= PCMCIA_MGMT_INTERRUPT_MASK|PCMCIA_IRQ_INTERRUPT_MASK;

#if (defined(ERTFS_SA))
    hook_pcmcia_interrupt(MGMT_INTERRUPT);
#else
    ks_hook_interrupt(MGMT_INTERRUPT, (PFVOID) 0, mgmt_isr, (RTIPINTFN_POINTER) 0, 0);
#endif

   /* Enable card detect change for slot 0 and 1 */
   IMMR->pcmcia_per   |= (PSCR_CACD2_C|PSCR_CACD1_C);
   IMMR->pcmcia_per   |= (PSCR_CBCD2_C|PSCR_CBCD1_C);

   pcmctrl_initted = TRUE;
   ks_enable();

   return(TRUE);
   }

void pcmctrl_close(void)        /* __fn__ */
{
}

static void pcmctrl_enable_interrupt(int socket, int irq, BOOLEAN on_off)
{
   dword l;
   /* Set the IRQ level in 4 steps:-
      (1) Read in contents of general control register.
      (2) Clear the most significant 8 bits.
      (3) Set one bit of the MSB to indicate the level of the interrupt.
      (4) Write the updated contents of the GCR back to the GCR. */

	   l =   pcm860_rd_gcr(socket);
	   if (socket == 0)
		l &= ~PGCRA_CAIREQLVL;
	   else
            l &= ~PGCRB_CBIRQLVL;
	   l |= ((1<<(7-PCMCIA_IRQ_INTERRUPT_LEVEL))<<24);
	   pcm860_wr_gcr(socket, l);

	   /* Enable/disable interrupts:
      (1) Read contents of PCMCIA interface enable register.
      (2) If interupts are to be turned of then clear the CB_ERDY_R bit, else set it.
      (3) Update the PCMCIA interface enable register. */

	   l = IMMR->pcmcia_per;
	   if ( on_off )
   	  {
	   if (socket == 0)
#if (0)
	      l |= PER_CA_ERDY_R;
		else
	      l |= PER_CB_ERDY_R;
#endif
	      l |= PER_CA_ERDY_L;
		else
	      l |= PER_CB_ERDY_L;
      }
	   else
      {
	   if (socket == 0)
#if (0)
    	  l &= ~PER_CA_ERDY_R;
		else
    	  l &= ~PER_CB_ERDY_R;
#endif
    	  l &= ~PER_CA_ERDY_L;
		else
    	  l &= ~PER_CB_ERDY_L;
       }
	   IMMR->pcmcia_per   = l;
}

void pcmctrl_map_ata_regs(int socket, IOADDRESS ioaddr, int interrupt_number)
{
int j;
DDRIVE *pdr;
   pcm860_map_window(socket, 1 /* 16 bit */, PCM8_MTYPE_IO);

    if (interrupt_number >= 0)
	{
	    for (j = 0; j < NDRIVES; j++)
	    {
    	    pdr = pc_drno_to_drive_struct(j);
	        if (pdr && (pdr->pcmcia_slot_number == socket) && (pdr->drive_flags && DRIVE_FLAGS_PCMCIA_ATA))
			{
//				map_slot_to_controller[socket] = pdr->pcmcia_controller_number;
				map_slot_to_controller[socket] = pdr->controller_number;
				break;
			}
		}
        pcmctrl_enable_interrupt(socket, interrupt_number, TRUE);
	}
   /* Apply Vpp and Vcc power  */
   pcmctrl_device_power_up(socket);
}

/*  pcmctrl_card_is_installed(int socket, BOOLEAN apply_power) - Check if a socket has a card installed */
/* */
/*  Check the pcmcia interface at logical socket 'socket' for the presence of  */
/*  a card. */
/* */
/*  Inputs: */
/*      Logical socket number */
/*  */
/*  Returns: */
/*      TRUE        - if a card is installed */
/*      FALSE           - if the socket is empty */

BOOLEAN pcmctrl_card_is_installed(int socket, BOOLEAN apply_power)          /*__fn__*/
{
   dword l;

   /* Now read the interface status. Look for a card */
   l = IMMR->pcmcia_pipr;

   if ( (socket == 1 && (l & (PIPR_CBCD2|PIPR_CBCD1)) == 0) ||
        (socket == 0 && (l & (PIPR_CACD2|PIPR_CACD1)) == 0) )
   {
      if (apply_power && !card_is_powered[socket])
      {
         if (pcmctrl_card_power_up(socket))
            return(TRUE);
         else
         {
            pcmctrl_card_down(socket);
            return(FALSE);
         }

      }
      else
         return(TRUE);
   }
   return(FALSE);
}


/*  pcmctrl_card_installed(int socket) - Check if a socket has a card */
/*  and apply power installed */
/* */
/*  Check the pcmcia interface at logical socket 'socket' for the presence of  */
/*  a card. If found apply power and return TRUE. Otherwise return FALSE. */
/*  If the card is found and powered this routine must set the vriable */
/*  BOOLEAN card_is_powered[socket] to TRUE. */
/*  */
/* */
/*  Inputs: */
/*      Logical socket number */
/*  */
/*  Returns: */
/*      TRUE        - if a card is installed */
/*      FALSE           - if the socket is empty */

BOOLEAN pcmctrl_card_installed(int socket)          /*__fn__*/
{
    return(pcmctrl_card_is_installed(socket, TRUE));
}

/*  pcmctrl_power_up(int socket) - Enable power to a card. */
/* */
/*  This function clears the reset bit and enables power to a card. */
/*   */
/* Notes:  */
/*  1. The card is assumed to be in the slot (see card_is_installed(int socket)) */
/*  2. The power setting is 5.0 volts applied automatically when the card is */
/*  inserted. Other power options should be added as required. */
/*  Inputs: */
/*      Logical socket number */
/*  */
/*  Returns: */

BOOLEAN pcmctrl_card_power_up(int socket)                       /*__fn__*/
{
dword l;
dword xx;
word i;
int is_ready;

    /* Set the reset bit and card output enable */
	l =	pcm860_rd_gcr(socket);
	if (socket == 0)
		xx = (PGCRA_CAOE|PGCRA_CARESET);
	else
		xx = (PGCRB_CBOE|PGCRB_CBRESET);
	l |= xx;	
	pcm860_wr_gcr(socket, l);

	/* power off and settle */
	pcm860_socket_vccpower(socket, 0);
	pcm860_socket_vpppower(socket, -1); /* Set to HiZ */
	ks_sleep((word)(1+(50 + ks_msec_p_tick())/ks_msec_p_tick()));

	/* power on 3.3 or 5 volts  */
	/* Need to look in PIPR for 3V vs's 5v card. VS1 indicates 3.3 volt. VS2 is reserved
         for a secondary voltage and is not tested here */
	l = IMMR->pcmcia_pipr;
	if (socket == 0)
      {
        if ((l & PIPR_CAVS1) == 0)
             pcm860_socket_vccpower(socket, 5);
        else
             pcm860_socket_vccpower(socket, 3);
      }
	else
      {
        if ((l & PIPR_CBVS1) == 0)
             pcm860_socket_vccpower(socket, 5);
        else
             pcm860_socket_vccpower(socket, 3);
      }

   ks_sleep((word)((300 + ks_msec_p_tick())/ks_msec_p_tick()));

#if(0)
    /* Toggle reset */
	l =	pcm860_rd_gcr(socket);
	if (socket == 0)
		xx = PGCRA_CARESET;
	else
		xx = PGCRB_CBRESET;
	l |= xx;	
	pcm860_wr_gcr(socket, l);

    /* Sleep 10 msecs */
    ks_sleep((word)(1+(10 + ks_msec_p_tick())/ks_msec_p_tick()));   
#endif

    /* Clear the reset bit */
	l =	pcm860_rd_gcr(socket);
	if (socket == 0)
		xx = ~PGCRA_CARESET;
	else
		xx = ~PGCRB_CBRESET;
	l &= xx;	
	pcm860_wr_gcr(socket, l);

    /* Sleep 10 msecs */
    ks_sleep((word)(1+(10 + ks_msec_p_tick())/ks_msec_p_tick()));   

    /* Clear output enable */
	l =	pcm860_rd_gcr(socket);
	if (socket == 0)
		xx = ~PGCRA_CAOE;
	else
		xx = ~PGCRB_CBOE;
	l &= xx;	
	pcm860_wr_gcr(socket, l);

    /* Sleep 20 msecs */
    ks_sleep((word)(1+(20 + ks_msec_p_tick())/ks_msec_p_tick()));   

    /* Wait for pcmcia ready. wait up to 1 seconds. */
    is_ready = 0;
    for (i = 0; i < ks_ticks_p_sec(); i = (word)(i+2))
    {
		l = IMMR->pcmcia_pipr;
		if (socket == 0)
		{
			if (l & PIPR_CARDY) // check ready slot a
			{
				is_ready = 1;
	            break;
			}
		}
		else
		{
			if (l & PIPR_CBRDY) // check ready slot b
			{
				is_ready = 1;
	            break;
			}
		}
        ks_sleep(2);    
    }
    if (!is_ready)
        return(FALSE);

    card_device_type[socket] = PCMCIA_NO_DEVICE;
    card_is_powered[socket] = TRUE;
    return(TRUE);
}


void pcmctrl_device_power_up(int socket)                        /*__fn__*/
{
}

static void pcmctrl_enable_io_mode(int socket)
{
}

/*  pcmctrl_card_power_down(int socket) - Turn off power to a card. */
/*  This function turns off power and clears the reset bit */
/*  Returns: nothing */

static void pcmctrl_card_power_down(int socket)                     /*__fn__*/
{
dword l;
dword xx;

    /* Set the reset bit and card output enable */
	l =	pcm860_rd_gcr(socket);
	if (socket == 0)
		xx = (PGCRA_CAOE|PGCRA_CARESET);
	else
		xx = (PGCRB_CBOE|PGCRB_CBRESET);
	l |= xx;	
	pcm860_wr_gcr(socket, l);

   /* Make sure power to the card is off through external power controller */
   pcm860_socket_vccpower(socket, 0);
   pcm860_socket_vpppower(socket, -1); /* Set to HiZ */

   card_is_powered[socket] = FALSE;
   card_device_type[socket] = PCMCIA_NO_DEVICE;
}

/*  pcmctrl_card_down(int socket) - Card down */
/* */
/*  The upper layers detected that the disk is not valid or is not  */
/*  installed. This routine is called so the slot is put in a known */
/*  state for re-insertion for pcmcia this is power down, for */
/*  True IDE this should probably assert -OE. */
/*   */
/*  */
/*  Returns: */


void pcmctrl_card_down(int socket)                      /*__fn__*/
{
   int i;

   /* Make sure interrupts are disabled */
   pcmctrl_enable_interrupt(socket, 0, FALSE);
   /* Power it down */
   pcmctrl_card_power_down(socket);
}


byte pcmctrl_get_cis_byte(int socket, dword offset) /* __fn__ */
{
   byte  c;
   byte *p;

   c = 0;
   // Try Common (Bank zero) first
   p = pcm860_map_window( socket, 1 /* is_16 */, PCM8_MTYPE_COMMON);

   p = pcm860_map_window( socket, 1 /* is_16 */, PCM8_MTYPE_ATTRIBUTE);
   if (p)
      p += ( offset * 2 ); // CIS is byt twos

   if (p)
      c = *p;

   return (c);
}

void pcmctrl_put_cis_byte(int socket, dword offset, byte c) /*__fn__*/
{
   byte KS_FAR *p;

   p = pcm860_map_window(socket, 1 /* is_16 */, PCM8_MTYPE_ATTRIBUTE);
   if (p)
      p += ( offset * 2 ); // CIS is byt twos

   if (p)
      *p = c;
}

#if (0)
BROKEN
void pcmctrl_map_3com(int socket, int irq, int iobase)  /* __fn__ */
{
    pcmctrl_enable_io_mode(socket);
    /* Set up io windows */
    /* chip 0, Socket 0, window 0, size 16, isa_add = iobase pcmcia addr = iobase */
    /* Allow bus lines (CS16) to determine transfer size */
    pd67xx_map_io(socket, IO_WINDOW_0, 16, (word)iobase, 
                  (word)(IO_CTL_AUTO|IO_CTL_16BIT|IO_CTL_TR1));
    pcmctrl_enable_interrupt(socket, irq, TRUE);

}

void pcmctrl_map_linksys_regs(int socket, int irq, int iobase)  /*__fn__*/
{
    /* enable IO mode. */
    pcmctrl_enable_io_mode(socket);

    /* Set up io windows */
    /* chip 0, Socket 0, window 0, size 16, isa_add = 0x170 pcmcia addr = 0x170 */
    /* Allow bus lines (CS16) to determine transfer size */
    pd67xx_map_io(socket, IO_WINDOW_0, 32, (word)iobase, (byte)(IO_CTL_AUTO|IO_CTL_16BIT|IO_CTL_TR1));

    /* Turn on interrupts */
    pcmctrl_enable_interrupt(socket, irq, TRUE);
    /* Apply Vpp power (does nothing since we use auto Vpp) */
    pcmctrl_device_power_up(socket);

}
#endif


#endif /* INCLUDE_PCMCIA */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -