Advertisement
Guest User

Untitled

a guest
Sep 2nd, 2012
295
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // based on http://www.open.com.au/mikem/bcm2835/
  2.  
  3. // test it:
  4. // gcc -o blink blink.c;sudo ./blink
  5.  
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <errno.h>
  11. #include <stdint.h>
  12. #include <fcntl.h>
  13. #include <sys/mman.h>
  14.  
  15. static volatile uint32_t *i2c0 = MAP_FAILED;
  16.  
  17. // Physical addresses for various peripheral regiser sets
  18. /// Base Physical Address of the BCM 2835 peripheral registers
  19. #define BCM2835_PERI_BASE 0x20000000
  20. // i2c base
  21. #define BCM2835_I2C0_BASE (BCM2835_PERI_BASE + 0x205000)
  22.  
  23. /// Size of memory page on RPi
  24. #define BCM2835_PAGE_SIZE (4*1024)
  25. /// Size of memory block on RPi
  26. #define BCM2835_BLOCK_SIZE (4*1024)
  27.  
  28.  
  29. static int fd = -1;
  30. static uint8_t *i2c0Mem = NULL;
  31. static debug = 0;
  32.  
  33. // safe read from peripheral
  34. uint32_t bcm2835_peri_read(volatile uint32_t* paddr)
  35. {
  36. if (debug)
  37. {
  38. printf("bcm2835_peri_read paddr %08X\n", paddr);
  39. return 0;
  40. }
  41. else
  42. {
  43. // Make sure we dont return the _last_ read which might get lost
  44. // if subsequent code changes to a differnt peripheral
  45. uint32_t ret = *paddr;
  46. uint32_t dummy = *paddr;
  47. return ret;
  48. }
  49. }
  50.  
  51. // safe write to peripheral
  52. void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value)
  53. {
  54. if (debug)
  55. {
  56. printf("bcm2835_peri_write paddr %08X, value %08X\n", paddr, value);
  57. }
  58. else
  59. {
  60. // Make sure we dont rely on the firs write, which may get
  61. // list if the previous access was to a different peripheral.
  62. *paddr = value;
  63. *paddr = value;
  64. }
  65. }
  66.  
  67. uint32_t bcm2835_read_i2c(uint8_t offset)
  68. {
  69. volatile uint32_t* paddr = i2c0 + offset/4;
  70. return bcm2835_peri_read(paddr);
  71. }
  72.  
  73. void bcm2835_i2c_setClockDivider(uint16_t divider)
  74. {
  75. volatile uint32_t* paddr = i2c0 + 0x14/4;
  76. bcm2835_peri_write(paddr, divider);
  77. }
  78.  
  79. void bcm2835_i2c_setClockStretch(uint16_t stretch)
  80. {
  81. volatile uint32_t* paddr = i2c0 + 0x1c/4;
  82. bcm2835_peri_write(paddr, stretch);
  83. }
  84.  
  85. void bcm2835_i2c_setEdgeDelay(uint32_t stretch)
  86. {
  87. volatile uint32_t* paddr = i2c0 + 0x18/4;
  88. bcm2835_peri_write(paddr, stretch);
  89. }
  90.  
  91.  
  92.  
  93.  
  94. int main(int argc, char **argv)
  95. {
  96. printf("initialising.. \n");
  97.  
  98. uint8_t *mapaddr;
  99. if ((fd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0)
  100. {
  101. fprintf(stderr, "bcm2835_init: Unable to open /dev/mem: %s\n", strerror(errno)) ;
  102. return 0;
  103. }
  104.  
  105. if ((i2c0Mem = malloc(BCM2835_BLOCK_SIZE + (BCM2835_PAGE_SIZE - 1))) == NULL)
  106. {
  107. fprintf(stderr, "bcm2835_init: i2c0mem malloc failed: %s\n", strerror(errno)) ;
  108. return 0;
  109. }
  110.  
  111. mapaddr = i2c0Mem;
  112. if (((uint32_t)mapaddr % BCM2835_PAGE_SIZE) != 0)
  113. mapaddr += BCM2835_PAGE_SIZE - ((uint32_t)mapaddr % BCM2835_PAGE_SIZE) ;
  114.  
  115. i2c0 = (uint32_t *)mmap(mapaddr, BCM2835_BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, BCM2835_I2C0_BASE) ;
  116.  
  117. if ((int32_t)i2c0 < 0)
  118. {
  119. fprintf(stderr, "bcm2835_init: mmap failed (i2c0): %s\n", strerror(errno)) ;
  120. return 0;
  121. }
  122.  
  123.  
  124. printf("done \n");
  125.  
  126. // bcm2835_i2c_setClockDivider(10000);
  127. // bcm2835_i2c_setClockStretch(0x200);
  128. // bcm2835_i2c_setEdgeDelay(0x1600160);
  129.  
  130. uint32_t CLKT_register = bcm2835_read_i2c(0x1c);
  131. uint32_t DIV_register = bcm2835_read_i2c(0x14);
  132. uint32_t DEL_register = bcm2835_read_i2c(0x18);
  133.  
  134.  
  135. printf("raw read i2c clock stretch: %x\n", CLKT_register);
  136. printf("raw read i2c clock div: %d %x\n", DIV_register, DIV_register);
  137. printf("raw read i2c edge delay: %x\n", DEL_register, DEL_register);
  138. printf("i2c clock: %d kHz\n", 150000/DIV_register);
  139.  
  140.  
  141. return 0;
  142. }
Advertisement
RAW Paste Data Copied
Advertisement