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

📄 mcc4.txt

📁 CCS FAT file system access
💻 TXT
📖 第 1 页 / 共 2 页
字号:
#include <linux/delay.h>
#include <linux/timer.h>

#include <linux/module.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/blkpg.h>
#include <linux/hdreg.h>
#include <linux/major.h>
#include <asm/uaccess.h>
#include <asm/io.h>

#define DEVICE_NAME "mmc"
#define DEVICE_NR(device) (MINOR(device))
#define DEVICE_ON(device)
#define DEVICE_OFF(device)
#define MAJOR_NR 121

#include <linux/blk.h>

MODULE_AUTHOR("Madsuk/Rohde modified for WAP54G V31 by Jan Panteltje");
MODULE_DESCRIPTION("Driver MMC/SD-Cards");
MODULE_SUPPORTED_DEVICE("WAP54G V31");
MODULE_LICENSE("GPL");


/* all we have on the WAP54G V31 */
#define RESET_BUTTON   (1)
#define SES_BUTTON      (1<<14)
#define YELLOW_LED      (1<<6)
#define WHITE_LED      (1<<12)

#ifdef OLD_CODE
#define SD_DI 0x20
#define SD_DO 0x10
#define SD_CLK 0x08
#define SD_CS 0x80
#endif // OLD_CODE


#define SD_CS   RESET_BUTTON
#define SD_DO   SES_BUTTON
#define SD_CLK   WHITE_LED
#define SD_DI   YELLOW_LED


/* we have only one device */
static int hd_sizes[1<<6];
static int hd_blocksizes[1<<6];
static int hd_hardsectsizes[1<<6];
static int hd_maxsect[1<<6];
static struct hd_struct hd[1<<6];

static struct timer_list mmc_timer;
static int mmc_media_detect = 0;
static int mmc_media_changed = 1;

typedef unsigned int uint32;

static unsigned int port_state = 0x0;
static volatile uint32 *gpioaddr_input = (uint32 *)0xb8000060;
static volatile uint32 *gpioaddr_output = (uint32 *)0xb8000064;
static volatile uint32 *gpioaddr_enable = (uint32 *)0xb8000068;
static volatile uint32 *gpioaddr_control = (uint32 *)0xb800006c;


//#define AQ1
#ifdef AQ1
static void delay(int loops)
{
int a, i;

for(i = 0; i < loops; i++)
   {
   a += 1;
   }

} /* end function delay */
#endif // AQ1


static void mmc_spi_cs_low(void)
{

port_state &= ~(SD_CS);
*gpioaddr_output = port_state;

//delay(100);
}


static void mmc_spi_cs_high(void)
{

port_state |= SD_CS;
*gpioaddr_output = port_state;

//delay(100);
}


static unsigned char mmc_spi_io(unsigned char data_out)
{
int i;
unsigned char result = 0;
unsigned int tmp_data = 0;
  
for(i = 0; i < 8; i++)
   {
   if(data_out & (0x01 << (7 - i)))  port_state |= SD_DI;
   else port_state &= ~SD_DI;
    
   *gpioaddr_output = port_state;
   port_state |= SD_CLK;
   *gpioaddr_output = port_state;

//delay(100);    
   tmp_data = *gpioaddr_input;

//delay(100);
    
   port_state &= ~SD_CLK;
   *gpioaddr_output = port_state;

//delay(100);    

   result <<= 1;
    
   if(tmp_data & SD_DO) result |= 1;
   }
  
return(result);
} /* end function mmc_spi_io */


static int mmc_write_block(unsigned int dest_addr, unsigned char *data)
{
   unsigned int address;
   unsigned char r = 0;
   unsigned char ab0, ab1, ab2, ab3;
   int i;

   address = dest_addr;

   ab3 = 0xff & (address >> 24);
   ab2 = 0xff & (address >> 16);
   ab1 = 0xff & (address >> 8);
   ab0 = 0xff & address;
   mmc_spi_cs_low();
   for (i = 0; i < 4; i++) mmc_spi_io(0xff);
   mmc_spi_io(0x58);
   mmc_spi_io(ab3); /* msb */
   mmc_spi_io(ab2);
   mmc_spi_io(ab1);
   mmc_spi_io(ab0); /* lsb */
   mmc_spi_io(0xff);
   for (i = 0; i < 8; i++)
   {
      r = mmc_spi_io(0xff);
      if (r == 0x00) break;
   }
   if (r != 0x00)
   {
      mmc_spi_cs_high();
      mmc_spi_io(0xff);
      return(1);
   }

   mmc_spi_io(0xfe);
   for (i = 0; i < 512; i++) mmc_spi_io(data[i]);
   for (i = 0; i < 2; i++) mmc_spi_io(0xff);

   for (i = 0; i < 1000000; i++)
   {
      r = mmc_spi_io(0xff);
      if (r == 0xff) break;
   }
   if (r != 0xff)
   {
      mmc_spi_cs_high();
      mmc_spi_io(0xff);
      return(3);
   }
   mmc_spi_cs_high();
   mmc_spi_io(0xff);
   return(0);
}


static int mmc_read_block(unsigned char *data, unsigned int src_addr)
{
unsigned int address;
unsigned char r = 0;
unsigned char ab0, ab1, ab2, ab3;
int i;

address = src_addr;


ab3 = 0xff & (address >> 24);
ab2 = 0xff & (address >> 16);
ab1 = 0xff & (address >> 8);
ab0 = 0xff & address;

mmc_spi_cs_low();

for (i = 0; i < 4; i++) mmc_spi_io(0xff);

/* send command 17 */
mmc_spi_io(0x51);
mmc_spi_io(ab3); /* msb */
mmc_spi_io(ab2);
mmc_spi_io(ab1);
mmc_spi_io(ab0); /* lsb */

/* send 7 bits fake checksum and 1 stop bit */
mmc_spi_io(0xff);

//printk("WAS a=%d\n", address);

/* get command respose 0 (no error) */
for (i = 0; i < 8; i++)
   {
   r = mmc_spi_io(0xff);
   if (r == 0x00) break;
   }
if (r != 0x00)
   {
   mmc_spi_cs_high();
   mmc_spi_io(0xff);
   return 1;
   }

/* get start block sign */
for (i = 0; i < 100000; i++)
   {
   r = mmc_spi_io(0xff);
   if (r == 0xfe) break;
   }
if (r != 0xfe)
   {
   mmc_spi_cs_high();
   mmc_spi_io(0xff);
   return 2;
   }

/* read sector data block */
for (i = 0; i < 512; i++)
   {
   r = mmc_spi_io(0xff);
   data[i] = r;
   }

/* get and ignore CRC bytes */
for (i = 0; i < 2; i++)
   {
   r = mmc_spi_io(0xff);
   }

mmc_spi_cs_high();
mmc_spi_io(0xff);

return 0;
} /* end function mmc_read_block */



#ifdef NEW_BLOCK_READ
static int mmc_read_block(unsigned char *data, unsigned int src_addr)
{
unsigned int address;
unsigned char r = 0;
unsigned char ab0, ab1, ab2, ab3;
int i;

address = src_addr;

address = 317;

ab3 = 0xff & (address >> 24);
ab2 = 0xff & (address >> 16);
ab1 = 0xff & (address >> 8);
ab0 = 0xff & address;

mmc_spi_cs_low();

//delay(100);

//for (i = 0; i < 4; i++) mmc_spi_io(0xff);

/* block read command */
mmc_spi_out(0x51); // command 17   //  8

/* sector address 32 bits */
mmc_spi_out(ab3); /* msb */      // 16   
mmc_spi_out(ab2);            // 24
mmc_spi_out(ab1);            // 32
mmc_spi_out(ab0); /* lsb */      // 40

/* fake CRC (7 bits) and set 'end bit' */
mmc_spi_out(0xff);            // 48

//delay(100);

/*
expect response code R1 

0 x x x x x x x
  | | | | | | |in idle state
  | | | | | |erase reset
  | | | | |illegal command
  | | | |com CRC error
  | | |erase sequence error
  | |address error
  |parameter error

*/

/*
r = mmc_spi_in();
if(r != 0x00)
   {
   printk("read_block: command response=%02x\n", r);

   mmc_spi_cs_high();
   mmc_spi_out(0xff);

   return 1;
   }
*/


   for (i = 0; i < 8; i++)
   {
      r = mmc_spi_in();
      if (r == 0x00) break;
   }
   if (r != 0x00)
   {
      mmc_spi_cs_high();
      mmc_spi_out(0xff);
      return(1);
   }

printk("WAS past1\n");

/*
expect start block token
11111110
*/

/*
r = mmc_spi_in();
if(r != 0xfe)
   {
   printk("read_block: start token=%02x\n", r);

   mmc_spi_cs_high();
   mmc_spi_out(0xff);

   return 2;
   }
*/

   for (i = 0; i < 100000; i++)
   {
      r = mmc_spi_in();
      if (r == 0xfe) break;
   }
   if (r != 0xfe)
   {
      mmc_spi_cs_high();
      mmc_spi_out(0xff);
      return(2);
   }

printk("WAS past2\n");


/* read sector data */
for(i = 0; i < 512; i++)
   {
   r = mmc_spi_in();
   data[i] = r;

printk("%02x ", r);
   }

printk("\n");

/* read and ignore CRC 2 bytes */
for(i = 0; i < 2; i++)
   {
   mmc_spi_in();
   }

mmc_spi_cs_high();
mmc_spi_out(0xff);

return 0;
} /* end function mmc_read_block */

#endif // NEW_BLOCK_READ


static void mmc_request(request_queue_t *q)
{
   unsigned int mmc_address;
   unsigned char *buffer_address;
   int nr_sectors;
   int i;
   int cmd;
   int rc, code;
   
   (void)q;
   while (1)
   {
      code = 1; // Default is success
      INIT_REQUEST;
      mmc_address = (CURRENT->sector + hd[MINOR(CURRENT->rq_dev)].start_sect) * hd_hardsectsizes[0];
      buffer_address = CURRENT->buffer;
      nr_sectors = CURRENT->current_nr_sectors;
      cmd = CURRENT->cmd;
      if (((CURRENT->sector + CURRENT->current_nr_sectors + hd[MINOR(CURRENT->rq_dev)].start_sect) > hd[0].nr_sects) || (mmc_media_detect == 0))
      {
         code = 0;
      }
      else if (cmd == READ)
      {
         spin_unlock_irq(&io_request_lock);
         for (i = 0; i < nr_sectors; i++)
         {
            rc = mmc_read_block(buffer_address, mmc_address);
            if (rc != 0)
            {
               printk("mmc: error in mmc_read_block (%d)\n", rc);
               code = 0;
               break;
            }
            else
            {
               mmc_address += hd_hardsectsizes[0];
               buffer_address += hd_hardsectsizes[0];
            }
         }
         spin_lock_irq(&io_request_lock);
      }
      else if (cmd == WRITE)
      {
         spin_unlock_irq(&io_request_lock);
         for (i = 0; i < nr_sectors; i++)
         {
            rc = mmc_write_block(mmc_address, buffer_address);
            if (rc != 0)
            {
               printk("mmc: error in mmc_write_block (%d)\n", rc);

⌨️ 快捷键说明

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