Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * spiio.c - Very simple SPI I/O example
- *
- * Written 2011 by Werner Almesberger
- * Copyright 2011 Werner Almesberger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
- #include <stdint.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- enum {
- VDD_OFF = 1 << 2, /* VDD disable, PD02 */
- MMC_CMD = 1 << 8, /* CMD, PD08 */
- MMC_CLK = 1 << 9, /* CLK, PD09 */
- MMC_DAT0 = 1 << 10, /* DAT0, PD10 */
- MMC_DAT1 = 1 << 11, /* DAT1, PD11 */
- MMC_DAT2 = 1 << 12, /* DAT2, PD12 */
- MMC_DAT3 = 1 << 13, /* DAT3/CD, PD13 */
- };
- #define MOSI MMC_DAT0
- #define MISO MMC_CMD
- #define SCLK MMC_DAT3
- #define nSEL MMC_DAT2
- #define SOC_BASE 0x10000000
- #define REG(n) (*(volatile uint32_t *) (mem+(n)))
- #define GPIO(n) REG(0x10000+(n))
- #define PDPIN GPIO(0x300) /* port D pin level */
- #define PDDATS GPIO(0x314) /* port D data set */
- #define PDDATC GPIO(0x318) /* port D data clear */
- #define PDFUNS GPIO(0x344) /* port D function set */
- #define PDFUNC GPIO(0x348) /* port D function clear */
- #define PDDIRS GPIO(0x364) /* port D direction set */
- #define PDDIRC GPIO(0x368) /* port D direction clear */
- #define PAGE_SIZE 4096
- static void *mem;
- /* ----- Low-level SPI operations ------------------------------------------ */
- static void spi_begin(void)
- {
- PDDATC = nSEL;
- }
- static void spi_end(void)
- {
- PDDATS = nSEL;
- }
- static void spi_send(uint8_t v)
- {
- uint8_t mask;
- for (mask = 0x80; mask; mask >>= 1) {
- if (v & mask)
- PDDATS = MOSI;
- else
- PDDATC = MOSI;
- PDDATS = SCLK;
- PDDATC = SCLK;
- }
- }
- static uint8_t spi_recv(void)
- {
- uint8_t res = 0;
- uint8_t mask;
- for (mask = 0x80; mask; mask >>= 1) {
- if (PDPIN & MISO)
- res |= mask;
- PDDATS = SCLK;
- PDDATC = SCLK;
- }
- return res;
- }
- static uint8_t spi_bidir(uint8_t v)
- {
- uint8_t res = 0;
- uint8_t mask;
- for (mask = 0x80; mask; mask >>= 1) {
- if (PDPIN & MISO)
- res |= mask;
- if (v & mask)
- PDDATS = MOSI;
- else
- PDDATC = MOSI;
- PDDATS = SCLK;
- PDDATC = SCLK;
- }
- return res;
- }
- /* ---- High-level -------------------------------------------------------- */
- static void spi_io(const int order, const int value)
- {
- uint8_t ch;
- spi_begin();
- ch = spi_bidir(order);
- if (strchr("\t\n\r", ch) || (ch >= ' ' && ch <= '~'))
- putchar(ch);
- else
- putchar('?');
- ch = spi_bidir(value);
- if (strchr("\t\n\r", ch) || (ch >= ' ' && ch <= '~'))
- putchar(ch);
- else
- putchar('?');
- ch = spi_bidir(0x00);
- if (strchr("\t\n\r", ch) || (ch >= ' ' && ch <= '~'))
- putchar(ch);
- else
- putchar('?');
- spi_end();
- putchar('\n');
- }
- int main(int argc, char **argv)
- {
- int fd, i;
- fd = open("/dev/mem", O_RDWR | O_SYNC);
- if (fd < 0) {
- perror("/dev/mem");
- exit(1);
- }
- mem = mmap(NULL, PAGE_SIZE*3*16, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, SOC_BASE);
- if (mem == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
- /* set the output levels */
- PDDATS = nSEL | VDD_OFF;
- PDDATC = SCLK;
- PDFUNC = MOSI | MISO | SCLK | nSEL;
- /* set the pin directions */
- PDDIRC = MISO;
- PDDIRS = MOSI | SCLK | nSEL;
- spi_io(atoi(argv[1]),atoi(argv[2]));
- /* make all MMC pins inputs */
- PDDIRC = MOSI | MISO | SCLK | nSEL;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement