Raspberry Pi C# Mono GPIO


SUBMITTED BY: Guest

DATE: Nov. 11, 2013, 9:03 p.m.

FORMAT: Text only

SIZE: 7.3 kB

HITS: 1627

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Runtime.InteropServices;
  5. using System.Threading;
  6. namespace ConsoleApplication9
  7. {
  8. internal class Program
  9. {
  10. private static void Main()
  11. {
  12. int g, rep;
  13. // Set up gpi pointer for direct register access
  14. // Switch GPIO 7..11 to output mode
  15. /************************************************************************\
  16. * You are about to change the GPIO settings of your computer. *
  17. * Mess this up and it will stop working! *
  18. * It might be a good idea to 'sync' before running this program *
  19. * so at least you still have your code changes written to the SD-card! *
  20. \************************************************************************/
  21. // Set GPIO pins 7-11 to output
  22. for (g = 7; g <= 11; g++)
  23. {
  24. Console.WriteLine("Setting up pi {0}",g);
  25. IO.INP_GPIO((uint)g); // must use INP_GPIO before we can use OUT_GPIO
  26. IO.OUT_GPIO((uint)g);
  27. }
  28. for (rep = 0; rep < 10; rep++)
  29. {
  30. Console.WriteLine("Cycle {0} of 10",rep);
  31. for (g = 7; g <= 11; g++)
  32. {
  33. Console.WriteLine("Setting up pin {0}",g);
  34. IO.GPIO_SET = (uint)(1 << g);
  35. Thread.Sleep(333);
  36. }
  37. for (g = 7; g <= 11; g++)
  38. {
  39. Console.WriteLine("Resetting pin {0}",g);
  40. IO.GPIO_CLR = (uint)(1 << g);
  41. Thread.Sleep(333);
  42. }
  43. }
  44. //dont try it
  45. /*Console.WriteLine("Testing max frequency");
  46. var sw = new Stopwatch();
  47. sw.Start();
  48. int cyclesCount = 100000;
  49. for(int i=0;i<cyclesCount;i++)
  50. {
  51. IO.GPIO_SET = (uint)(0x100);
  52. IO.GPIO_CLR = (uint)(0x100);
  53. }
  54. sw.Stop();
  55. Console.WriteLine("Emitted {0} cycles in {1}. Frequency {2}KHz",cyclesCount,sw.Elapsed,cyclesCount/sw.ElapsedMilliseconds);*/
  56. }
  57. }
  58. public static unsafe class IO
  59. {
  60. private const uint BCM2708_PERI_BASE = 0x20000000;
  61. private const uint GPIO_BASE = BCM2708_PERI_BASE + 0x200000; /* GPIO controller */
  62. private const uint PAGE_SIZE = (4 * 1024);
  63. private const uint BLOCK_SIZE = (4 * 1024);
  64. private static int mem_fd;
  65. private static byte* gpio_mem;
  66. private static byte* gpio_map;
  67. private static byte* spi0_mem;
  68. private static byte* spi0_map;
  69. // I/O access
  70. private static volatile uint* gpio;
  71. private static readonly void* NULL = (void*)0;
  72. //TODO: Find constants for libc open
  73. private const int O_RDWR = 02;
  74. private const int O_SYNC = 010000;
  75. //TODO: Find constants for mmap
  76. private const int PROT_READ = 0x1 /* page can be read */;
  77. private const int PROT_WRITE = 0x2 /* page can be written */;
  78. /*
  79. #define PROT_EXEC 0x4 // page can be executed
  80. #define PROT_NONE 0x0 // page can not be accessed
  81. */
  82. private static int MAP_SHARED = 0x01 /* Share changes */;
  83. private static int MAP_FIXED = 0x10 /* Interpret addr exactly */;
  84. /*
  85. #define MAP_PRIVATE 0x02 // Changes are private
  86. #define MAP_TYPE 0x0f // Mask for type of mapping
  87. #define MAP_FIXED 0x10 // Interpret addr exactly
  88. #define MAP_ANONYMOUS 0x20 // don't use a file
  89. */
  90. // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
  91. public static void INP_GPIO(uint g)
  92. {
  93. *(gpio + ((g) / 10)) &= ~(7u << (int)(((g) % 10) * 3));
  94. }
  95. public static void OUT_GPIO(uint g)
  96. {
  97. *(gpio + ((g) / 10)) |= 1u << (int)(((g) % 10) * 3);
  98. }
  99. private static void SET_GPIO_ALT(uint g, uint a)
  100. {
  101. *(gpio + (((g) / 10))) |= (((a) <= 3 ? (a) + 4 : (a) == 4 ? 3u : 2) << (int)(((g) % 10) * 3));
  102. }
  103. /// <summary>
  104. /// sets bits which are 1 ignores bits which are 0
  105. /// </summary>
  106. public static uint GPIO_SET
  107. {
  108. set { *(gpio + 7) = value; }
  109. }
  110. /// <summary>
  111. /// clears bits which are 1 ignores bits which are 0
  112. /// </summary>
  113. public static uint GPIO_CLR
  114. {
  115. set { *(gpio + 10) = value; }
  116. }
  117. /// <summary>
  118. /// Get data
  119. /// </summary>
  120. public static uint GPIO_IN0 { get { return *(gpio + 13); } }
  121. static IO()
  122. {
  123. setup_io();
  124. }
  125. /// <summary>
  126. /// Set up a memory regions to access GPIO
  127. /// </summary>
  128. private static void setup_io()
  129. {
  130. /* open /dev/mem */
  131. if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
  132. {
  133. Console.WriteLine("can't open /dev/mem");
  134. throw new Exception();
  135. }
  136. /* mmap GPIO */
  137. // Allocate MAP block
  138. if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE - 1))) == NULL)
  139. {
  140. Console.WriteLine("allocation error");
  141. throw new Exception();
  142. }
  143. // Make sure pointer is on 4K boundary
  144. if ((ulong)gpio_mem % PAGE_SIZE != 0)
  145. gpio_mem += PAGE_SIZE - ((ulong)gpio_mem % PAGE_SIZE);
  146. // Now map it
  147. gpio_map = (byte*)mmap(
  148. gpio_mem,
  149. BLOCK_SIZE,
  150. PROT_READ | PROT_WRITE,
  151. MAP_SHARED | MAP_FIXED,
  152. mem_fd,
  153. GPIO_BASE
  154. );
  155. if ((long)gpio_map < 0)
  156. {
  157. Console.WriteLine("mmap error {0}", (int)gpio_map);
  158. throw new Exception();
  159. }
  160. // Always use volatile pointer!
  161. gpio = (uint*)gpio_map;
  162. }
  163. // setup_io
  164. [DllImport("libc.so.6")]
  165. static extern void* mmap(void* addr, uint length, int prot, int flags,
  166. int fd, uint offset);
  167. [DllImport("libc.so.6")]
  168. static extern int open(string file, int mode /*, int permissions */);
  169. [DllImport("libc.so.6")]
  170. static extern byte* malloc(uint size);
  171. }
  172. }

comments powered by Disqus