📄 user_qspi.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 + -