Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // based on http://www.open.com.au/mikem/bcm2835/
- // test it:
- // gcc -o blink blink.c;sudo ./blink
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <stdint.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- static volatile uint32_t *i2c0 = MAP_FAILED;
- // Physical addresses for various peripheral regiser sets
- /// Base Physical Address of the BCM 2835 peripheral registers
- #define BCM2835_PERI_BASE 0x20000000
- // i2c base
- #define BCM2835_I2C0_BASE (BCM2835_PERI_BASE + 0x205000)
- /// Size of memory page on RPi
- #define BCM2835_PAGE_SIZE (4*1024)
- /// Size of memory block on RPi
- #define BCM2835_BLOCK_SIZE (4*1024)
- static int fd = -1;
- static uint8_t *i2c0Mem = NULL;
- static debug = 0;
- // safe read from peripheral
- uint32_t bcm2835_peri_read(volatile uint32_t* paddr)
- {
- if (debug)
- {
- printf("bcm2835_peri_read paddr %08X\n", paddr);
- return 0;
- }
- else
- {
- // Make sure we dont return the _last_ read which might get lost
- // if subsequent code changes to a differnt peripheral
- uint32_t ret = *paddr;
- uint32_t dummy = *paddr;
- return ret;
- }
- }
- // safe write to peripheral
- void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value)
- {
- if (debug)
- {
- printf("bcm2835_peri_write paddr %08X, value %08X\n", paddr, value);
- }
- else
- {
- // Make sure we dont rely on the firs write, which may get
- // list if the previous access was to a different peripheral.
- *paddr = value;
- *paddr = value;
- }
- }
- uint32_t bcm2835_read_i2c(uint8_t offset)
- {
- volatile uint32_t* paddr = i2c0 + offset/4;
- return bcm2835_peri_read(paddr);
- }
- void bcm2835_i2c_setClockDivider(uint16_t divider)
- {
- volatile uint32_t* paddr = i2c0 + 0x14/4;
- bcm2835_peri_write(paddr, divider);
- }
- void bcm2835_i2c_setClockStretch(uint16_t stretch)
- {
- volatile uint32_t* paddr = i2c0 + 0x1c/4;
- bcm2835_peri_write(paddr, stretch);
- }
- void bcm2835_i2c_setEdgeDelay(uint32_t stretch)
- {
- volatile uint32_t* paddr = i2c0 + 0x18/4;
- bcm2835_peri_write(paddr, stretch);
- }
- int main(int argc, char **argv)
- {
- printf("initialising.. \n");
- uint8_t *mapaddr;
- if ((fd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0)
- {
- fprintf(stderr, "bcm2835_init: Unable to open /dev/mem: %s\n", strerror(errno)) ;
- return 0;
- }
- if ((i2c0Mem = malloc(BCM2835_BLOCK_SIZE + (BCM2835_PAGE_SIZE - 1))) == NULL)
- {
- fprintf(stderr, "bcm2835_init: i2c0mem malloc failed: %s\n", strerror(errno)) ;
- return 0;
- }
- mapaddr = i2c0Mem;
- if (((uint32_t)mapaddr % BCM2835_PAGE_SIZE) != 0)
- mapaddr += BCM2835_PAGE_SIZE - ((uint32_t)mapaddr % BCM2835_PAGE_SIZE) ;
- i2c0 = (uint32_t *)mmap(mapaddr, BCM2835_BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, BCM2835_I2C0_BASE) ;
- if ((int32_t)i2c0 < 0)
- {
- fprintf(stderr, "bcm2835_init: mmap failed (i2c0): %s\n", strerror(errno)) ;
- return 0;
- }
- printf("done \n");
- // bcm2835_i2c_setClockDivider(10000);
- // bcm2835_i2c_setClockStretch(0x200);
- // bcm2835_i2c_setEdgeDelay(0x1600160);
- uint32_t CLKT_register = bcm2835_read_i2c(0x1c);
- uint32_t DIV_register = bcm2835_read_i2c(0x14);
- uint32_t DEL_register = bcm2835_read_i2c(0x18);
- printf("raw read i2c clock stretch: %x\n", CLKT_register);
- printf("raw read i2c clock div: %d %x\n", DIV_register, DIV_register);
- printf("raw read i2c edge delay: %x\n", DEL_register, DEL_register);
- printf("i2c clock: %d kHz\n", 150000/DIV_register);
- return 0;
- }
Advertisement
RAW Paste Data
Copied
Advertisement