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

📄 user_qspi.c

📁 mmc_qspi.tar.gz mmc block driver code for uClinux
💻 C
字号:
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <fcntl.h>#include <unistd.h>#include "qspi_cmd.h"#define STDOUT 1#define BLOCK_SIZE 512#define MMC_BLOCK_NB 16 * 1024 * 2#define MAX_FILENAME_SIZE 80#define READ_FLAG 0#define WRITE_FLAG 1unsigned char mmc_cmd0[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95};unsigned char mmc_cmd1[] = {0x41, 0x00, 0x00, 0x00, 0x00, 0xff};unsigned char mmc_cmd17[] = {0x51, 0x00, 0x00, 0x00, 0x00, 0xff};unsigned char mmc_cmd18[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xff};int set_chip_select (int , int);unsigned char read_answer (int);int read_block (int, unsigned char, unsigned char, unsigned char, unsigned char, char *);int write_block (int, unsigned char, unsigned char, unsigned char, unsigned char, char *);unsigned char send_cmd (int, unsigned char *);int dummy_write (int);int init_mmc (int);void read_mmc (int, int);void write_mmc (int, int);	struct param{	unsigned char flag;	unsigned char filename[MAX_FILENAME_SIZE];};struct param user_choice;int parse_args (int argc, char **argv){        int opt;	/* read the MMC content is the default choice */	user_choice.flag = READ_FLAG;        while ((opt = getopt (argc, argv, "r:w:")) != -1)        {                switch (opt)                {                        case 'r' :				user_choice.flag = READ_FLAG;				strcpy (user_choice.filename, optarg);                                break;                        case 'w' :				user_choice.flag = WRITE_FLAG;				strcpy (user_choice.filename, optarg);                                break;                        default:                                fprintf (stderr, "ERROR : unknown option\n\n");                                return (-1);                                break;                }        }        return (0);}int set_chip_select (int desc, int request){	if ((ioctl (desc, request)) == -1)        {                perror ("ioctl ()");                return (-1);        }	return (0);}unsigned char read_answer (int desc){	unsigned char answer;	unsigned int count = 10;	do	{		if ((read (desc, &answer, 			sizeof (unsigned char))) == -1)		{			perror ("read ()");			return (-1);		}	} 	while ((answer == 0xff) && (count--));	if (!count)		return (0xff);	return (answer);		}int read_block (int desc, unsigned char a1, unsigned char a2, unsigned char a3, unsigned char a4, char *block){	unsigned char answer;	unsigned short checksum;	int count = 10;	unsigned int nb_read = 0;	if (!block)	{		perror ("malloc ()");		return (-1);	}	memset (block, 0, BLOCK_SIZE);		mmc_cmd17[1] = a1;	mmc_cmd17[2] = a2;	mmc_cmd17[3] = a3;	mmc_cmd17[4] = a4;	/* send the single read block command */	answer = send_cmd (desc, mmc_cmd17);		while (((answer & 0xff) != 0xfe) && (count--))	{//		fprintf (stderr, "CMD51 - answer = 0x%x\n", answer);		answer = read_answer (desc);	} /*	fprintf (stderr, "CMD51 - answer = 0x%x\n", answer);	fflush (stderr);*/	if (answer != 0xfe)	{		fprintf (stderr, "CMD_17 => failure\n");		return (-1);	}//	fprintf (stderr, "=> success\n");	if ((nb_read = read (desc, block, 			BLOCK_SIZE * sizeof (char))) == -1)	{		perror ("read ()");		return (-1);	}	if (nb_read != BLOCK_SIZE)	{		fprintf (stderr, "only %d bytes read instead of %d\n", 				nb_read, BLOCK_SIZE);	}	/*  read the checksum two bytes */	if ((read (desc, &checksum, 			sizeof (unsigned short))) == -1)	{		perror ("read ()");		return (-1);	}		return (nb_read);}int write_block (int desc, unsigned char a1, unsigned char a2, unsigned char a3, unsigned char a4, char *block){	int nb_write;	int count = 10;	unsigned char answer;	char init_transfer = 0xfe;	unsigned short checksum = 0xffff;	if (!block)	{		fprintf (stderr, "block is a NULL pointer\n");		return (-1);	}	/* must lock the mmc cmd array */	mmc_cmd18[1] = a1;	mmc_cmd18[2] = a2;	mmc_cmd18[3] = a3;	mmc_cmd18[4] = a4;	answer = send_cmd (desc, mmc_cmd18);		while (((answer & 0xff) != 0x00) && (count--))	{		fprintf (stderr, "CMD_18 - answer = 0x%x\n", answer);		answer = read_answer (desc);	} 	if (answer != 0x00)	{		fprintf (stderr, "CMD_18 faillure\n");		return (-1);	}	dummy_write (desc);//	fprintf (stderr, "CMD_18 success\n");		/* send 0xfe to initiate block transfer  */	if ((write (desc, &init_transfer, 			sizeof (char))) == -1)	{		perror ("write (init_transfer)");		return (-1);	}	if ((nb_write = write (desc, block, 			BLOCK_SIZE * sizeof (char))) == -1)	{		perror ("write ()");		return (-1);	}	if (nb_write != BLOCK_SIZE)	{		fprintf (stderr, "only %d bytes read instead of %d\n", 				nb_write, BLOCK_SIZE);		return (-1);	}		/* send the checksum to the MMC */	if ((write (desc, &checksum, 			sizeof (unsigned short))) == -1)	{		perror ("write (checksum)");		return (-1);	}	count = 10;	do	{		answer = read_answer (desc);//		fprintf (stderr, "write block answer : 0x%x\n", answer);	} 	while (((answer & 0xff) != 0xff) && (count--));		if (answer != 0xff)	{		fprintf (stderr, "write block faillure\n");		return (-1);	}		dummy_write (desc);//	fprintf (stderr, "write block success\n");	return (nb_write);}unsigned char send_cmd (int desc, unsigned char *cmd){	if ((write (desc, cmd, 6)) == -1)	{		perror ("write ()");		return (-1);	}	return (read_answer (desc));		}/* dummy write */int dummy_write (int desc){	unsigned char dummy_char = 0xff;		if (set_chip_select (desc, CMD_CS0_HIGHT))		return (-1);			if ((write (desc, &dummy_char, sizeof (unsigned char))) == -1)	{		perror ("write ()");		return (-1);	}			if (set_chip_select (desc, CMD_CS0_LOW))		return (-1);	return (0);}int init_mmc (int desc){	int count = 10;	unsigned char answer;		/* send the CMD0 to set the MMC in qspi mode 	 * as the MMC is in MMC mode during the CMD0 sending, 	 * CMD0 must have a valid checksum */	answer = send_cmd (desc, mmc_cmd0);	fprintf (stderr, "answer CMD0 : 0x%x\n", (answer & 0xff));	if (answer != 0x01)	{		fprintf (stderr, "=> failure\n");	//	return (-1);	}	else	{		fprintf (stderr, "=> success\n");	}	do	{		dummy_write (desc);		answer = send_cmd (desc, mmc_cmd1);	} 	while ((count--) && ((answer & 0xff) != 0x00));		dummy_write (desc);		fprintf (stderr, "answer CMD1 : 0x%x\n", (answer & 0xff));		if (answer != 0x00)	{		fprintf (stderr, "=> faillure\n");		return (-1);	}	fprintf (stderr, "=> success\n");	return (0);}void read_mmc (int qspi_desc, int file_desc){	int i, nb_write, nb_read, size = 0;	unsigned char *block_addr_ptr;	char buffer[BLOCK_SIZE];	unsigned long block_addr;	for (i = 0; i < MMC_BLOCK_NB; i++)	{		block_addr = i * BLOCK_SIZE;		block_addr_ptr = (unsigned char *) &block_addr;/*		fprintf (stderr, "block size %d %d\n", block_addr , 				block_addr_ptr[1]);*/				nb_read = read_block (qspi_desc, block_addr_ptr[0], 				block_addr_ptr[1], block_addr_ptr[2], 				block_addr_ptr[3], buffer);		if (nb_read == -1)		{			fprintf (stderr, "error read_block [%d.%d.%d.%d] :(\n", 				block_addr_ptr[0], block_addr_ptr[1], 				block_addr_ptr [2], block_addr_ptr[3]);		//	return (-1);			continue;		}		if (nb_read < BLOCK_SIZE)		{			fprintf (stderr, "read (MMC) : %d bytes read instead of %d\n", 					nb_read, BLOCK_SIZE);		}		if ((i%50) == 0)		{			if (i != 0)				size += 50;			fprintf (stderr, "%dko already read\n", size);		}/*		fprintf (stderr, "success read_block [%d.%d.%d.%d] :)\n", 				block_addr_ptr[0], block_addr_ptr[1], 				block_addr_ptr [2], block_addr_ptr[3]);*/		if ((nb_write = write (file_desc, buffer, BLOCK_SIZE)) == -1)		{			perror ("write ()");			break;		}	}	return;}void write_mmc (int qspi_desc, int file_desc){	int i, nb_write, nb_read, size = 0;	unsigned char *block_addr_ptr;	char buffer[BLOCK_SIZE];	unsigned long block_addr;	for (i = 0; i < MMC_BLOCK_NB; i++)	{		block_addr = i * BLOCK_SIZE;		block_addr_ptr = (unsigned char *) &block_addr;/*		fprintf (stderr, "block size %d %d\n", block_addr , 				block_addr_ptr[1]);*/				memset (buffer, 0, BLOCK_SIZE);		nb_read = read (file_desc, buffer, BLOCK_SIZE);		if (nb_read == -1)		{			perror ("read (file)");			return;		}		if (nb_read == 0)		{			fprintf (stderr, "read (file) : EOF\n");			return;		}		nb_write = write_block (qspi_desc, block_addr_ptr[0], 				block_addr_ptr[1], block_addr_ptr[2], 				block_addr_ptr[3], buffer);		if (nb_write == -1)		{			fprintf (stderr, "write_block () error\n");			return;		}		if ((i%50) == 0)		{			if (i != 0)				size += 50;			fprintf (stderr, "%dko already write\n", size);		}/*		fprintf (stderr, "success read_block [%d.%d.%d.%d] :)\n", 				block_addr_ptr[0], block_addr_ptr[1], 				block_addr_ptr [2], block_addr_ptr[3]);*/	}	fprintf (stderr, "MMC is empty\n");	return;}int main (int argc, char **argv){	int qspi_desc, file_desc, i, flag = 0;	unsigned char buffer[10];	if (parse_args (argc, argv) == -1)		return (-1);		if (user_choice.flag == READ_FLAG)	{		flag = O_WRONLY | O_CREAT;	}	if (user_choice.flag == WRITE_FLAG)	{		flag = O_RDONLY;	}	/* open the file */	file_desc = open (user_choice.filename, flag); 	if (file_desc == -1)        {                perror ("open (file)");                return (-1);        }		/* open the qspi device */	if ((qspi_desc = open ("/dev/ppp", O_RDWR, 0777)) == -1)        {                perror ("open (qspi)");                return (-1);        }		/* put the chip select 0 hight during the 	 * initialization */	if (set_chip_select (qspi_desc, CMD_CS0_HIGHT))		return (-1);	/* generate 80 clock cycle to initialize the	 * MMC card */	for (i = 0; i < 10; i++)	{		buffer[i] = 0xff;	}	if ((write (qspi_desc, buffer, 10 * sizeof (unsigned char))) == -1)	{		perror ("write ()");		return (-1);	}	/* put the chip select 0 low during the transfer */	if (set_chip_select (qspi_desc, CMD_CS0_LOW))		return (-1);	if ((init_mmc (qspi_desc)) == -1)	{		fprintf (stderr, "sorry... can't init MMC card :(\n");		return (-1);	}	fprintf (stderr, "init complete :)\n");		ioctl (qspi_desc, CMD_CLK, 0x02);  // modif jmfriedt	switch (user_choice.flag)	{		case READ_FLAG :			read_mmc (qspi_desc, file_desc);			break;		case WRITE_FLAG :			write_mmc (qspi_desc, file_desc);			break;					default :			break;	}	fprintf (stderr, "exit user_qspi\n");	return (0);}

⌨️ 快捷键说明

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