Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2011
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.58 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement