| | |
| | | /********************************************************************************* |
| | | * Copyright: (C) 2023 LingYun IoT System Studio. All Rights Reserved. |
| | | * Copyright: (C) 2023 LingYun IoT System Studio |
| | | * All rights reserved. |
| | | * |
| | | * Filename: at24c.c |
| | | * Description: This file is AT24Cxx EEPROM code |
| | | * |
| | | * Version: 1.0.0(10/08/23) |
| | | * Author: Guo Wenxue <guowenxue@gmail.com> |
| | | * ChangeLog: 1, Release initial version on "10/08/23 17:52:00" |
| | | * |
| | | * Description: This file is W25Qxx SPI Norflash driver on RaspberryPi 40Pin. |
| | | * Pin connection: |
| | | * W25QXX Raspberry Pi 40Pin |
| | | * VCC <---> Pin#1 (3.3V) |
| | | * CS <---> Pin#24(CS) |
| | | * DO <---> Pin#21(MISO) |
| | | * GND <---> Pin#9 (GND) |
| | | * CLK <---> Pin#23(SCLK) |
| | | * DI <---> Pin#19(MOSI) |
| | | * |
| | | * W25QXX RaspberryPi 40Pin |
| | | * VCC <---> 3.3V(Pin#1) |
| | | * CS <---> CS(Pin#24) |
| | | * DO <---> MISO(Pin#21) |
| | | * GND <---> GND(Pin#9) |
| | | * CLK <---> SCLK(Pin#23) |
| | | * DI <---> MOSI(Pin#19) |
| | | * /boot/config.txt: |
| | | * dtparam=spi=on |
| | | * |
| | | ********************************************************************************/ |
| | | |
| | |
| | | #include <stdlib.h> |
| | | #include <string.h> |
| | | #include <errno.h> |
| | | #include <libgen.h> |
| | | #include <getopt.h> |
| | | #include <fcntl.h> |
| | | #include <time.h> |
| | |
| | | *| Entry Functions | |
| | | *+-----------------------+*/ |
| | | |
| | | void dump_buf(const char *prompt, char *buf, size_t len); |
| | | void dump_buf(const char *prompt, char *buffer, size_t length); |
| | | |
| | | static inline void banner(const char *progname) |
| | | { |
| | | printf("%s program Version v1.0.0\n", progname); |
| | | printf("Copyright (C) 2023 Avnet.\n"); |
| | | } |
| | | |
| | | static void program_usage(const char *progname) |
| | | { |
| | | |
| | | printf("Usage: %s [OPTION]...\n", progname); |
| | | printf(" %s is W25Q SPI Norflash test program. \n", progname); |
| | | |
| | | printf(" -d[device ] Specify SPI device, such as /dev/spidevX.Y\n"); |
| | | printf(" -h[help ] Display this help information\n"); |
| | | printf(" -v[version ] Display the program version\n"); |
| | | |
| | | printf("\n"); |
| | | banner(progname); |
| | | return; |
| | | } |
| | | |
| | | char *dev="/dev/spidev0.0"; /* SPI device 0 */ |
| | | |
| | | int main (int argc, char **argv) |
| | | { |
| | | int rv; |
| | | char *progname=NULL; |
| | | struct option long_options[] = { |
| | | {"device", required_argument, NULL, 'd'}, |
| | | {"version", no_argument, NULL, 'v'}, |
| | | {"help", no_argument, NULL, 'h'}, |
| | | {NULL, 0, NULL, 0} |
| | | }; |
| | | |
| | | progname = basename(argv[0]); |
| | | |
| | | /* Parser the command line parameters */ |
| | | while ((rv = getopt_long(argc, argv, "d:m:vh", long_options, NULL)) != -1) |
| | | { |
| | | switch (rv) |
| | | { |
| | | case 'd': /* Set SPI device path: /dev/spidev0.0 */ |
| | | dev = optarg; |
| | | break; |
| | | |
| | | case 'v': /* Get software version */ |
| | | banner(progname); |
| | | return EXIT_SUCCESS; |
| | | |
| | | case 'h': /* Get help information */ |
| | | program_usage(progname); |
| | | return 0; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | spinor_test(); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | /*+-----------------------+ |
| | | *| SPI API Functions | |
| | | *+-----------------------+*/ |
| | | |
| | | #define SPI_DEV "/dev/spidev0.0" |
| | | #define SPI_BITS 8 |
| | | #define SPI_MODE 0//(SPI_CPHA|SPI_CPOL) |
| | | #define SPI_SPEED 500000 |
| | |
| | | uint32_t request; |
| | | int ret; |
| | | |
| | | spi->hspi = open(SPI_DEV, O_RDWR); |
| | | spi->hspi = open(dev, O_RDWR); |
| | | if (spi->hspi < 0) |
| | | { |
| | | spinor_print("ERROR: open device %s failure: %s\r\n", SPI_DEV, strerror(errno)); |
| | | spinor_print("ERROR: open device %s failure: %s\r\n", dev, strerror(errno)); |
| | | return ; |
| | | } |
| | | |
| | |
| | | } while ((buf[1] & 0x01) == 0x01); |
| | | } |
| | | |
| | | /*+----------------+ |
| | | *| dump_buf | |
| | | *+----------------+*/ |
| | | /*+----------------------+ |
| | | *| Misc functions | |
| | | *+----------------------+*/ |
| | | |
| | | void print_buf(const char *prompt, uint8_t *buf, int size) |
| | | { |
| | |
| | | return ; |
| | | } |
| | | |
| | | #define LINELEN 81 |
| | | #define CHARS_PER_LINE 16 |
| | | static char *print_char = |
| | | " " |
| | | " " |
| | | " !\"#$%&'()*+,-./" |
| | | "0123456789:;<=>?" |
| | | "@ABCDEFGHIJKLMNO" |
| | | "PQRSTUVWXYZ[\\]^_" |
| | | "`abcdefghijklmno" |
| | | "pqrstuvwxyz{|}~ " |
| | | " " |
| | | " " |
| | | " ???????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????" |
| | | "????????????????"; |
| | | |
| | | void dump_buf(const char *prompt, char *buf, size_t len) |
| | | void dump_buf(const char *prompt, char *buffer, size_t length) |
| | | { |
| | | int rc; |
| | | int idx; |
| | | char prn[LINELEN]; |
| | | char lit[CHARS_PER_LINE + 2]; |
| | | char hc[4]; |
| | | short line_done = 1; |
| | | size_t i, j; |
| | | |
| | | if( prompt ) |
| | | printf("%s", prompt); |
| | | |
| | | rc = len; |
| | | idx = 0; |
| | | lit[CHARS_PER_LINE] = '\0'; |
| | | |
| | | while (rc > 0) |
| | | if (prompt) |
| | | { |
| | | if (line_done) |
| | | snprintf(prn, LINELEN, "%08X: ", idx); |
| | | |
| | | do |
| | | { |
| | | unsigned char c = buf[idx]; |
| | | snprintf(hc, 4, "%02X ", c); |
| | | strncat(prn, hc, LINELEN); |
| | | |
| | | lit[idx % CHARS_PER_LINE] = print_char[c]; |
| | | } |
| | | while (--rc > 0 && (++idx % CHARS_PER_LINE != 0)); |
| | | |
| | | line_done = (idx % CHARS_PER_LINE) == 0; |
| | | if (line_done) |
| | | { |
| | | printf("%s %s\r\n", prn, lit); |
| | | } |
| | | printf("%s\n", prompt); |
| | | } |
| | | |
| | | if (!line_done) |
| | | for (i = 0; i < length; i += 16) |
| | | { |
| | | int ldx = idx % CHARS_PER_LINE; |
| | | lit[ldx++] = print_char[(int)buf[idx]]; |
| | | lit[ldx] = '\0'; |
| | | printf("%08zx: ", i); |
| | | |
| | | while ((++idx % CHARS_PER_LINE) != 0) |
| | | strncat(prn, " ", sizeof(prn)-strlen(prn)); |
| | | for (j = 0; j < 16; j++) |
| | | { |
| | | if (i + j < length) |
| | | { |
| | | printf("%02x ", buffer[i + j]); |
| | | } |
| | | else |
| | | { |
| | | printf(" "); |
| | | } |
| | | } |
| | | |
| | | printf("%s %s\r\n", prn, lit); |
| | | printf(" "); |
| | | |
| | | for (j = 0; j < 16; j++) |
| | | { |
| | | if (i + j < length) |
| | | { |
| | | unsigned char c = buffer[i + j]; |
| | | printf("%c", (c >= 32 && c <= 126) ? c : '.'); |
| | | } |
| | | else |
| | | { |
| | | printf(" "); |
| | | } |
| | | } |
| | | |
| | | printf("\n"); |
| | | } |
| | | } |
| | | |