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

📄 pcc850.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 2 页
字号:

/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS inc, 1996
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
   Last change:  DZ   22 Feb 2000    5:21 pm
*/

#if (defined(ERTFS_SA))
#include "pcdisk.h"
#else
/* load RTIP configuration settings */
#include "xnconf.h"
#include "drvconf.h"

#include "rtip.h"
#endif

#if (INCLUDE_PCMCIA)
#include "pcmcia.h"

#if (defined(ERTFS_SA))
void hook_pcmcia_interrupt(int irq);
void pcmcia_irq_isr(void);                          
int map_slot_to_controller[2] = {-1,-1};
#endif

    /*
     * Configure PCMCIA Option Register 0 -- Configure as Read/Write
     *
     * ATA Card Memory Access Time:  300ns
     * Assume: System Clock Frequency of 48MHz
     * Settings Estimated According to Table 17-2, Section 17.4.1 U/M
     *
     * Bank Size         = 64 megabytes (PCMCIA_BASE+0x0..0xf)
     * Strobe Hold Time  = 15 clocks
     * Strobe Setup Time = 15 clocks
     * Strobe Length     = 30 clocks
     * Port Size         = 16 bit
     * Region Select     = Common Memory Space
     * Slot Identifier   = Slot B
     * Write Protect     = Off
     * PCMCIA Valid Bit  = Valid
     */

/* 860 otion register definitions
   + These constants are to be combined as is required using bitwise OR. */


/* EBS define PCMCIA bank addresses beginning at 0x100000.  I'm not so sure this is
   right for us.  i am going to try to use a really high address. */

#define PCMCIA_BASE           0x10000000      // Base address for PCMCIA common memory accesses.

#define PCM8_BANKSIZE         0xB8000000      // 64 Megabyte banks
#define PCM8_STRBHOLD         0x000F0000      // 15  clocks
#define PCM8_STRBSETUP        0x0000F000      // 15  clocks
#define PCM8_STRBLENGTH       0x00000F00      // 30  clocks
#define PCM8_STROBE           (PCM8_STRBHOLD|PCM8_STRBSETUP|PCM8_STRBLENGTH)
#define PCM8_PPS16            0x00000040      // 16 Bit window
#define PCM8_PPS8             0x00000000      // 8 Bit window

#define PCM8_MTYPE_COMMON     0
#define PCM8_MTYPE_ATTRIBUTE  0x10
#define PCM8_MTYPE_IO         0x18

#define PCM8_SLOTB            0x00000004      // Window mapped to slot B
#define PCM8_SLOTA            0x00000000      // Window mapped to slot A
#define PCM8_WP               0x00000002      // Write protected
#define PCM8_PV               0x00000001      // Base and options are valid


dword pcmcia_bank_address[7] = 
                              {
                              PCMCIA_BASE,
                              0x20000000,
                              0x30000000,
                              0x40000000,
                              0x50000000,
                              0x60000000,
                              0x70000000
                               };

/* encoded bank size values */
dword pcmcia_bank_size[7] = 
                           {
                           PCM8_BANKSIZE,
                           PCM8_BANKSIZE,
                           PCM8_BANKSIZE,
                           PCM8_BANKSIZE,
                           PCM8_BANKSIZE,
                           PCM8_BANKSIZE,
                           PCM8_BANKSIZE
                           };

#if (FADS860 || ADS860)
#if (FADS860 )

#define PCCEN      (0x00800000)    /* Enable PCMCIA on FADS860 */
#define PCMCIA_0V  (0x00410000)    /* 0V Setting -- Clear PCCVCC[0,1] */
#define PCMCIA_5V  (0x00400000)    /* 5 Volt VCC Setting -- Clear PCCVCC[0] */
#define PCMCIA_3V  (0x00010000)    /* 3 Volt VCC Setting -- Clear PCCVCC[1] */
/* Setup VPP Voltage Settings */
#define PCMCIA_0VPP  (0x00300000)  /* 0V Setting -- Clear PCCVPP[0,1] */
#define PCMCIA_5VPP  (0x00200000)  /* 5V Setting -- Clear PCCVPP[0] */
#define PCMCIA_12VPP (0x00100000)  /* 12 Volt Setting -- Clear PCCVPP[1] */
#define PCMCIA_HIZPP (0x00300000)  /* High Impedence Setting */

#elif (ADS860)

#define PCCEN     (0x00800000)     /* Enable PCMCIA on MPC821ADS */
#define PCCVCCON  (0x00400000)     /* Apply 5 Volt Vcc to PCMCIA Socket */
/* Setup VPP Voltage Settings */
#define PCMCIA_0VPP  (0x00300000)  /* 0V Setting -- Clear PCCVPP[0,1] */
#define PCMCIA_5VPP  (0x00200000)  /* 5V Setting -- Clear PCCVPP[0] */
#define PCMCIA_12VPP (0x00100000)  /* 12 Volt Setting -- Clear PCCVPP[1] */
#define PCMCIA_HIZPP (0x00300000)  /* High Impedence Setting */

#endif

/* Define bit combinations for interrupt sense and clear */
#define PCMCIA_ALL_AMGMT (PSCR_CAVS1_C|PSCR_CAVS2_C|PSCR_CAWP_C|PSCR_CACD2_C| \
                          PSCR_CACD1_C|PSCR_CABVD2_C|PSCR_CABVD1_C)

#define PCMCIA_ALL_AIRQ  (PSCR_CARDY_L|PSCR_CARDY_H|PSCR_CARDY_R|PSCR_CARDY_F)

#define PCMCIA_ALL_BMGMT (PSCR_CBVS1_C|PSCR_CBVS2_C|PSCR_CBWP_C|PSCR_CBCD2_C| \
                          PSCR_CBCD1_C|PSCR_CBBVD2_C|PSCR_CBBVD1_C)

#define PCMCIA_ALL_BIRQ  (PSCR_CBRDY_L|PSCR_CBRDY_H|PSCR_CBRDY_R|PSCR_CBRDY_F)

dword *at_bcsr1(void)
{
   struct bcsr {
      dword bcsr0;
      dword bcsr1;
      dword bcsr2;
      dword bcsr3;
   } *csr;

   csr = (struct bcsr *) (IMMR->memc_br1 & 0xffff8000);

	return(&csr->bcsr1);
}
#endif


/* Sets VCC voltage via board specific power control registers */
/* NOTE: Must Turn OFF VPP power supply. Not used in this ATA Flash devices.
   This is done in  pcmctrl_init. Provide pcm860_socket_vpppower function for
   devices which need VPP */
void pcm860_socket_vccpower(int socket, int voltage /* 0,3 or 5 */)
{

#if (FADS860)
/* Ignore socket arg, we only have one control */
	dword *bcsr1 = at_bcsr1();
      *bcsr1 |= PCMCIA_0V; /* 0V default Voltage Level */

	if (voltage == 0)
        *bcsr1 &= ~PCMCIA_0V; /* 0 Volt Setting */
	if (voltage == 3)
        *bcsr1 &= ~PCMCIA_3V; /* 3 Volt Setting */
	if (voltage == 5)
        *bcsr1 &= ~PCMCIA_5V; /* 5 Volt Setting */

#elif (ADS860)
/* Ignore socket arg, we only have one control */
	dword *bcsr1 = at_bcsr1();
      *bcsr1 |= PCCVCCON; /* 0V default Voltage Level */

	if (voltage == 3)
        *bcsr1 &= ~PCCVCCON; /* 5 Volt Setting (no 3v on ADDS, use 5V) */
	if (voltage == 5)
        *bcsr1 &= ~PCCVCCON; /* 5 Volt Setting */

#elif(MPC860)
   struct bcsr {
    byte  bcsr1; /* Board Control and Status Register */
    byte  bcsr2;
   } *csr;

   csr = (struct bcsr *) ((IMMR->memc_br4 & 0xffff8000) | 0x00100000);
	if (voltage == 0)
		csr->bcsr2 = 0x30|0x0e;   /* VPP same as VCC VCC = HIZ E is all leds off */
	elseif (voltage == 3)
		csr->bcsr2 = 0xb0;   	  /* 10110000 VPP same as VCC VCC = 3 */
	elseif (voltage == 5)
		csr->bcsr2 = 0x60|0x04;   /* 01100000 VPP same as VCC VCC = 5 4 is led 0 & 2 on */
#else
#error - Implement power for unknown board
#endif
	   /* Delay 10 msecs for Power supply settling */
	if (voltage > 0)
	   ks_sleep((word)(1+(10 + ks_msec_p_tick())/ks_msec_p_tick()));
}

/* Sets VPP voltage via board specific power control registers */
void pcm860_socket_vpppower(int socket, int voltage /* 0,5,12 or HiZ (not 0,3,5) */)
{

#if (FADS860 || ADS860)
/* Ignore socket arg, we only have one control */
	dword *bcsr1 = at_bcsr1();

      *bcsr1 |= PCMCIA_HIZPP; /* High Impedence default Voltage Level */
	if (voltage == 0)
        *bcsr1 &= ~PCMCIA_0VPP; /* 0 Volt Setting */
	if (voltage == 5)
        *bcsr1 &= ~PCMCIA_5VPP; /* 5 Volt Setting */
	if (voltage == 12)
        *bcsr1 &= ~PCMCIA_12VPP; /* 12 Volt Setting */

#elif(MPC860)
   struct bcsr {
    byte  bcsr1; /* Board Control and Status Register */
    byte  bcsr2;
   } *csr;

   csr = (struct bcsr *) ((IMMR->memc_br4 & 0xffff8000) | 0x00100000);
	if (voltage == 0)
		csr->bcsr2 = 0x30|0x0e;   /* VPP same as VCC VCC = HIZ E is all leds off */
	elseif (voltage == 3)
		csr->bcsr2 = 0xb0;   	  /* 10110000 VPP same as VCC VCC = 3 */
	elseif (voltage == 5)
		csr->bcsr2 = 0x60|0x04;   /* 01100000 VPP same as VCC VCC = 5 4 is led 0 & 2 on */
#else
#error - Implement power for unknown board
#endif
	   /* Delay 10 msecs for Power supply settling */
	if (voltage > 0)
	   ks_sleep((word)(1+(10 + ks_msec_p_tick())/ks_msec_p_tick()));
}

/* Returns an index into pcmcia_bank_address & pcmcia_bank_size arrays which
   are defined near the top of this file. */
int pcm860_socket_to_bank(int socket, int mem_type)
{
	int bank;

	if ( mem_type == PCM8_MTYPE_COMMON)
		bank = 0;
	else if ( mem_type == PCM8_MTYPE_ATTRIBUTE)
		bank = 1;
	else if ( mem_type == PCM8_MTYPE_IO)
		bank = 2;
	else
		bank = 0; // This is an error

	if (socket)
		bank += 3;
	return(bank);
}

void pcm860_wr_gcr(int socket, dword l)
{
	if (socket == 0)
		IMMR->pcmcia_pgcra = l;
	else
		IMMR->pcmcia_pgcrb = l;
}
dword pcm860_rd_gcr(int socket)
{
dword l;
	if (socket == 0)
		l = IMMR->pcmcia_pgcra;
	else
		l = IMMR->pcmcia_pgcrb;
	return(l);
}

void pcm860_wr_option_reg(int reg, dword val)
{
	switch (reg) {
		case 0:
 		IMMR->pcmcia_por0 = val;
		break;
		case 1:
 		IMMR->pcmcia_por1 = val;
		break;
		case 2:
 		IMMR->pcmcia_por2 = val;
		break;
		case 3:
 		IMMR->pcmcia_por3 = val;
		break;
		case 4:
 		IMMR->pcmcia_por4 = val;
		break;
		case 5:
 		IMMR->pcmcia_por5 = val;
		break;
		case 6:
 		IMMR->pcmcia_por6 = val;
		break;
		case 7:
 		IMMR->pcmcia_por7 = val;
		break;
	}		
}
void pcm860_wr_address_reg(int reg, dword val)
{
	switch (reg) {
		case 0:
 		IMMR->pcmcia_pbr0 = val;
		break;
		case 1:
 		IMMR->pcmcia_pbr1 = val;
		break;
		case 2:
 		IMMR->pcmcia_pbr2 = val;
		break;
		case 3:
 		IMMR->pcmcia_pbr3 = val;
		break;
		case 4:
 		IMMR->pcmcia_pbr4 = val;
		break;
		case 5:
 		IMMR->pcmcia_pbr5 = val;
		break;
		case 6:
 		IMMR->pcmcia_pbr6 = val;
		break;
		case 7:
 		IMMR->pcmcia_pbr7 = val;
		break;
	}		
}

PFBYTE pcm860_map_window(int socket, int is_16, int mem_type)
{
dword cfg_word;
int window;
PFBYTE p;
	window = pcm860_socket_to_bank(socket, mem_type);

	cfg_word = pcmcia_bank_size[window];
	cfg_word |= PCM8_STROBE;
	if (is_16)
		cfg_word |= PCM8_PPS16;
	if (socket)
		cfg_word |= PCM8_SLOTB;
   cfg_word |= mem_type;

	cfg_word |= PCM8_PV;
	pcm860_wr_address_reg(window, pcmcia_bank_address[window]);
	pcm860_wr_option_reg(window,  cfg_word);
	p = (PFBYTE) pcmcia_bank_address[window];
	return(p);

}

#if (defined(ERTFS_SA))
void hook_pcmcia_interrupt(int irq);
#endif

BOOLEAN pcmctrl_initted;
BOOLEAN card_is_powered[NSOCKET];
int card_device_type[NSOCKET];

void ertfs_card_down(int slot)
{
#if (INCLUDE_ERTFS)
int j;
DDRIVE *pdr;

    for (j = 0; j < NDRIVES; j++)
    {
        pdr = pc_drno_to_drive_struct(j);
        if (pdr &&
            pdr->drive_flags & DRIVE_FLAGS_PCMCIA &&
            pdr->drive_flags & DRIVE_FLAGS_VALID  &&
            pdr->pcmcia_slot_number == slot &&
            pdr->pcmcia_controller_number == 0)
			{
	            pdr->dev_table_perform_device_ioctl(
    	                pdr->driveno, 
        	            DEVCTL_REPORT_REMOVE, (PFVOID) 0);
				map_slot_to_controller[slot] = -1;
			}
    }
#endif
}

void  KS_FAR mgmt_isr(int arg)                          /*__fn__*/
{
   dword xx;

   xx = IMMR->pcmcia_pscr;

  /* Card detect 1 or card detect 2 for Card A has changed ... */
   if ( (xx & PSCR_CACD2_C) || (xx & PSCR_CACD1_C))
   {
	  ertfs_card_down(0);
      pcmctrl_card_down(0);
	}

   /* Card detect 1 or card detect 2 for Card B has changed ... */
   if ( (xx & PSCR_CBCD2_C) || (xx & PSCR_CBCD1_C))
   {
	  ertfs_card_down(1);
      pcmctrl_card_down(1);
	}
   /* Clear all mgmt interrupts for slot A and B */
//   IMMR->pcmcia_pscr  = (PSCR_CACD2_C|PSCR_CACD1_C|PSCR_CBCD2_C|PSCR_CBCD1_C);
   IMMR->pcmcia_pscr  = PCMCIA_ALL_AMGMT|PCMCIA_ALL_BMGMT;
}

void pcmcia_irq_isr(void)
{
   dword xx;

   xx = IMMR->pcmcia_pscr;

  /* IRQ for slot A/Card A has changed ... */
   if ( xx & PCMCIA_ALL_AIRQ  )
   {
     if( map_slot_to_controller[0] >= 0)
       ide_isr(map_slot_to_controller[0]);
     IMMR->pcmcia_pscr  = PCMCIA_ALL_AIRQ;
   }
  /* IRQ for slot B/Card B has changed ... */
   if ( xx & PCMCIA_ALL_BIRQ  )
   {
     if( map_slot_to_controller[1] >= 0)
       ide_isr(map_slot_to_controller[1]);
     IMMR->pcmcia_pscr  = PCMCIA_ALL_BIRQ;
   }
}
                         

BOOLEAN pcmctrl_init(void)  /* __fn__ */
{
int           i;
byte          mask;
dword         l;

   if ( pcmctrl_initted )
      return(TRUE);

   ks_disable();

   /* Make sure power is down on all sockets */
#if (FADS860)
{
dword *bcsr1 = at_bcsr1();

    *bcsr1 |= PCMCIA_0V;     /*  0  Level vcc */
    *bcsr1 |= PCMCIA_HIZPP;  /* High Impedence Voltage Level vpp */
    /* Enable FADS PCMCIA Channel */
    *bcsr1 &= ~PCCEN;
}
#elif (ADS860)

⌨️ 快捷键说明

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