This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Sep 23rd, 2011  |  syntax: None  |  size: 3.58 KB  |  views: 43  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*
  2.  * spiio.c - Very simple SPI I/O example
  3.  *
  4.  * Written 2011 by Werner Almesberger
  5.  * Copyright 2011 Werner Almesberger
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation; either version 2 of the License, or
  10.  * (at your option) any later version.
  11.  */
  12.  
  13.  
  14. #include <stdint.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <unistd.h>
  18. #include <string.h>
  19. #include <fcntl.h>
  20. #include <sys/mman.h>
  21.  
  22.  
  23. enum {
  24.         VDD_OFF         = 1 << 2,       /* VDD disable, PD02 */
  25.         MMC_CMD         = 1 << 8,       /* CMD, PD08 */
  26.         MMC_CLK         = 1 << 9,       /* CLK, PD09 */
  27.         MMC_DAT0        = 1 << 10,      /* DAT0, PD10 */
  28.         MMC_DAT1        = 1 << 11,      /* DAT1, PD11 */
  29.         MMC_DAT2        = 1 << 12,      /* DAT2, PD12 */
  30.         MMC_DAT3        = 1 << 13,      /* DAT3/CD, PD13 */
  31. };
  32.  
  33. #define MOSI    MMC_DAT0
  34. #define MISO    MMC_CMD
  35. #define SCLK    MMC_DAT3
  36. #define nSEL    MMC_DAT2
  37.  
  38.  
  39. #define SOC_BASE        0x10000000
  40.  
  41. #define REG(n)  (*(volatile uint32_t *) (mem+(n)))
  42.  
  43. #define GPIO(n) REG(0x10000+(n))
  44.  
  45. #define PDPIN   GPIO(0x300)     /* port D pin level */
  46. #define PDDATS  GPIO(0x314)     /* port D data set */
  47. #define PDDATC  GPIO(0x318)     /* port D data clear */
  48. #define PDFUNS  GPIO(0x344)     /* port D function set */
  49. #define PDFUNC  GPIO(0x348)     /* port D function clear */
  50. #define PDDIRS  GPIO(0x364)     /* port D direction set */
  51. #define PDDIRC  GPIO(0x368)     /* port D direction clear */
  52.  
  53. #define PAGE_SIZE       4096
  54.  
  55.  
  56. static void *mem;
  57.  
  58.  
  59. /* ----- Low-level SPI operations ------------------------------------------ */
  60.  
  61.  
  62. static void spi_begin(void)
  63. {
  64.         PDDATC = nSEL;
  65. }
  66.  
  67.  
  68. static void spi_end(void)
  69. {
  70.         PDDATS = nSEL;
  71. }
  72.  
  73.  
  74. static void spi_send(uint8_t v)
  75. {
  76.         uint8_t mask;
  77.  
  78.         for (mask = 0x80; mask; mask >>= 1) {
  79.                 if (v & mask)
  80.                         PDDATS = MOSI;
  81.                 else
  82.                         PDDATC = MOSI;
  83.                 PDDATS = SCLK;
  84.                 PDDATC = SCLK;
  85.         }
  86. }
  87.  
  88.  
  89. static uint8_t spi_recv(void)
  90. {
  91.         uint8_t res = 0;
  92.         uint8_t mask;
  93.  
  94.         for (mask = 0x80; mask; mask >>= 1) {
  95.                 if (PDPIN & MISO)
  96.                         res |= mask;
  97.                 PDDATS = SCLK;
  98.                 PDDATC = SCLK;
  99.         }
  100.         return res;
  101. }
  102.  
  103.  
  104. static uint8_t spi_bidir(uint8_t v)
  105. {
  106.         uint8_t res = 0;
  107.         uint8_t mask;
  108.  
  109.         for (mask = 0x80; mask; mask >>= 1) {
  110.                 if (PDPIN & MISO)
  111.                         res |= mask;
  112.                 if (v & mask)
  113.                         PDDATS = MOSI;
  114.                 else
  115.                         PDDATC = MOSI;
  116.                 PDDATS = SCLK;
  117.                 PDDATC = SCLK;
  118.         }
  119.         return res;
  120. }
  121.  
  122.  
  123. /* ----  High-level -------------------------------------------------------- */
  124.  
  125.  
  126. static void spi_io(const int order, const int value)
  127. {
  128.         uint8_t ch;
  129.  
  130.         spi_begin();
  131.        
  132.                 ch = spi_bidir(order);
  133.  
  134.                 if (strchr("\t\n\r", ch) || (ch >= ' ' && ch <= '~'))
  135.                         putchar(ch);
  136.                 else
  137.                         putchar('?');
  138.                 ch = spi_bidir(value);
  139.  
  140.                 if (strchr("\t\n\r", ch) || (ch >= ' ' && ch <= '~'))
  141.                         putchar(ch);
  142.                 else
  143.                         putchar('?');  
  144.                        
  145.                 ch = spi_bidir(0x00);
  146.  
  147.                 if (strchr("\t\n\r", ch) || (ch >= ' ' && ch <= '~'))
  148.                         putchar(ch);
  149.                 else
  150.                         putchar('?');  
  151.        
  152.         spi_end();
  153.         putchar('\n');
  154. }
  155.  
  156.  
  157. int main(int argc, char **argv)
  158. {
  159.         int fd, i;
  160.  
  161.         fd = open("/dev/mem", O_RDWR | O_SYNC);
  162.         if (fd < 0) {
  163.                 perror("/dev/mem");
  164.                 exit(1);
  165.         }
  166.         mem = mmap(NULL, PAGE_SIZE*3*16, PROT_READ | PROT_WRITE,
  167.             MAP_SHARED, fd, SOC_BASE);
  168.         if (mem == MAP_FAILED) {
  169.                 perror("mmap");
  170.                 exit(1);
  171.         }
  172.  
  173.         /* set the output levels */
  174.         PDDATS = nSEL | VDD_OFF;
  175.         PDDATC = SCLK;
  176.  
  177.         PDFUNC = MOSI | MISO | SCLK | nSEL;
  178.  
  179.         /* set the pin directions */
  180.         PDDIRC = MISO;
  181.         PDDIRS = MOSI | SCLK | nSEL;
  182.  
  183.                 spi_io(atoi(argv[1]),atoi(argv[2]));
  184.  
  185.  
  186.         /* make all MMC pins inputs */
  187.         PDDIRC = MOSI | MISO | SCLK | nSEL;
  188.  
  189.         return 0;
  190. }
clone this paste RAW Paste Data