Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
RF24
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
RF24
Commits
f06ca7cb
Commit
f06ca7cb
authored
Feb 12, 2015
by
TMRh20
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #72 from mannkind/Updates
Potential RPi 2 support via updated bcm2835.c (version 1.39)
parents
e7deb684
25d379c1
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
307 additions
and
246 deletions
+307
-246
RPi/bcm2835.c
RPi/bcm2835.c
+183
-155
RPi/bcm2835.h
RPi/bcm2835.h
+124
-91
No files found.
RPi/bcm2835.c
View file @
f06ca7cb
...
@@ -40,16 +40,23 @@
...
@@ -40,16 +40,23 @@
// By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected.
// By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected.
// #define I2C_V1
// #define I2C_V1
// Pointers to the hardware register bases
// Physical address and size of the peripherals block
volatile
uint32_t
*
bcm2835_gpio
=
(
volatile
uint32_t
*
)
MAP_FAILED
;
// May be overridden on RPi2
volatile
uint32_t
*
bcm2835_pwm
=
(
volatile
uint32_t
*
)
MAP_FAILED
;
uint32_t
*
bcm2835_peripherals_base
=
(
uint32_t
*
)
BCM2835_PERI_BASE
;
volatile
uint32_t
*
bcm2835_clk
=
(
volatile
uint32_t
*
)
MAP_FAILED
;
uint32_t
bcm2835_peripherals_size
=
BCM2835_PERI_SIZE
;
volatile
uint32_t
*
bcm2835_pads
=
(
volatile
uint32_t
*
)
MAP_FAILED
;
volatile
uint32_t
*
bcm2835_spi0
=
(
volatile
uint32_t
*
)
MAP_FAILED
;
// Virtual memory address of the mapped peripherals block
volatile
uint32_t
*
bcm2835_bsc0
=
(
volatile
uint32_t
*
)
MAP_FAILED
;
void
*
bcm2835_peripherals
=
(
uint32_t
*
)
MAP_FAILED
;
volatile
uint32_t
*
bcm2835_bsc1
=
(
volatile
uint32_t
*
)
MAP_FAILED
;
volatile
uint32_t
*
bcm2835_st
=
(
volatile
uint32_t
*
)
MAP_FAILED
;
// And the register bases within the peripherals block
uint32_t
*
bcm2835_gpio
=
(
uint32_t
*
)
MAP_FAILED
;
uint32_t
*
bcm2835_pwm
=
(
uint32_t
*
)
MAP_FAILED
;
uint32_t
*
bcm2835_clk
=
(
uint32_t
*
)
MAP_FAILED
;
uint32_t
*
bcm2835_pads
=
(
uint32_t
*
)
MAP_FAILED
;
uint32_t
*
bcm2835_spi0
=
(
uint32_t
*
)
MAP_FAILED
;
uint32_t
*
bcm2835_bsc0
=
(
uint32_t
*
)
MAP_FAILED
;
uint32_t
*
bcm2835_bsc1
=
(
uint32_t
*
)
MAP_FAILED
;
uint32_t
*
bcm2835_st
=
(
uint32_t
*
)
MAP_FAILED
;
// This variable allows us to test on hardware other than RPi.
// This variable allows us to test on hardware other than RPi.
// It prevents access to the kernel memory, and does not do any peripheral access
// It prevents access to the kernel memory, and does not do any peripheral access
...
@@ -66,13 +73,38 @@ static unsigned long long epoch ;
...
@@ -66,13 +73,38 @@ static unsigned long long epoch ;
// Low level register access functions
// Low level register access functions
//
//
// Function to return the pointers to the hardware register bases
uint32_t
*
bcm2835_regbase
(
uint8_t
regbase
)
{
switch
(
regbase
)
{
case
BCM2835_REGBASE_ST
:
return
(
uint32_t
*
)
bcm2835_st
;
case
BCM2835_REGBASE_GPIO
:
return
(
uint32_t
*
)
bcm2835_gpio
;
case
BCM2835_REGBASE_PWM
:
return
(
uint32_t
*
)
bcm2835_pwm
;
case
BCM2835_REGBASE_CLK
:
return
(
uint32_t
*
)
bcm2835_clk
;
case
BCM2835_REGBASE_PADS
:
return
(
uint32_t
*
)
bcm2835_pads
;
case
BCM2835_REGBASE_SPI0
:
return
(
uint32_t
*
)
bcm2835_spi0
;
case
BCM2835_REGBASE_BSC0
:
return
(
uint32_t
*
)
bcm2835_bsc0
;
case
BCM2835_REGBASE_BSC1
:
return
(
uint32_t
*
)
bcm2835_st
;
}
return
(
uint32_t
*
)
MAP_FAILED
;
}
void
bcm2835_set_debug
(
uint8_t
d
)
void
bcm2835_set_debug
(
uint8_t
d
)
{
{
debug
=
d
;
debug
=
d
;
}
}
// safe read from peripheral
// safe read from peripheral
uint32_t
bcm2835_peri_read
(
volatile
uint32_t
*
paddr
)
uint32_t
bcm2835_peri_read
(
uint32_t
*
paddr
)
{
{
if
(
debug
)
if
(
debug
)
{
{
...
@@ -90,7 +122,7 @@ uint32_t bcm2835_peri_read(volatile uint32_t* paddr)
...
@@ -90,7 +122,7 @@ uint32_t bcm2835_peri_read(volatile uint32_t* paddr)
}
}
// read from peripheral without the read barrier
// read from peripheral without the read barrier
uint32_t
bcm2835_peri_read_nb
(
volatile
uint32_t
*
paddr
)
uint32_t
bcm2835_peri_read_nb
(
uint32_t
*
paddr
)
{
{
if
(
debug
)
if
(
debug
)
{
{
...
@@ -104,7 +136,7 @@ uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr)
...
@@ -104,7 +136,7 @@ uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr)
}
}
// safe write to peripheral
// safe write to peripheral
void
bcm2835_peri_write
(
volatile
uint32_t
*
paddr
,
uint32_t
value
)
void
bcm2835_peri_write
(
uint32_t
*
paddr
,
uint32_t
value
)
{
{
if
(
debug
)
if
(
debug
)
{
{
...
@@ -120,7 +152,7 @@ void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value)
...
@@ -120,7 +152,7 @@ void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value)
}
}
// write to peripheral without the write barrier
// write to peripheral without the write barrier
void
bcm2835_peri_write_nb
(
volatile
uint32_t
*
paddr
,
uint32_t
value
)
void
bcm2835_peri_write_nb
(
uint32_t
*
paddr
,
uint32_t
value
)
{
{
if
(
debug
)
if
(
debug
)
{
{
...
@@ -134,7 +166,7 @@ void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value)
...
@@ -134,7 +166,7 @@ void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value)
}
}
// Set/clear only the bits in value covered by the mask
// Set/clear only the bits in value covered by the mask
void
bcm2835_peri_set_bits
(
volatile
uint32_t
*
paddr
,
uint32_t
value
,
uint32_t
mask
)
void
bcm2835_peri_set_bits
(
uint32_t
*
paddr
,
uint32_t
value
,
uint32_t
mask
)
{
{
uint32_t
v
=
bcm2835_peri_read
(
paddr
);
uint32_t
v
=
bcm2835_peri_read
(
paddr
);
v
=
(
v
&
~
mask
)
|
(
value
&
mask
);
v
=
(
v
&
~
mask
)
|
(
value
&
mask
);
...
@@ -165,7 +197,7 @@ void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t ma
...
@@ -165,7 +197,7 @@ void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t ma
void
bcm2835_gpio_fsel
(
uint8_t
pin
,
uint8_t
mode
)
void
bcm2835_gpio_fsel
(
uint8_t
pin
,
uint8_t
mode
)
{
{
// Function selects are 10 pins per 32 bit word, 3 bits per pin
// Function selects are 10 pins per 32 bit word, 3 bits per pin
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPFSEL0
/
4
+
(
pin
/
10
);
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPFSEL0
/
4
+
(
pin
/
10
);
uint8_t
shift
=
(
pin
%
10
)
*
3
;
uint8_t
shift
=
(
pin
%
10
)
*
3
;
uint32_t
mask
=
BCM2835_GPIO_FSEL_MASK
<<
shift
;
uint32_t
mask
=
BCM2835_GPIO_FSEL_MASK
<<
shift
;
uint32_t
value
=
mode
<<
shift
;
uint32_t
value
=
mode
<<
shift
;
...
@@ -175,7 +207,7 @@ void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode)
...
@@ -175,7 +207,7 @@ void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode)
// Set output pin
// Set output pin
void
bcm2835_gpio_set
(
uint8_t
pin
)
void
bcm2835_gpio_set
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPSET0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPSET0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
bcm2835_peri_write
(
paddr
,
1
<<
shift
);
bcm2835_peri_write
(
paddr
,
1
<<
shift
);
}
}
...
@@ -183,7 +215,7 @@ void bcm2835_gpio_set(uint8_t pin)
...
@@ -183,7 +215,7 @@ void bcm2835_gpio_set(uint8_t pin)
// Clear output pin
// Clear output pin
void
bcm2835_gpio_clr
(
uint8_t
pin
)
void
bcm2835_gpio_clr
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPCLR0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPCLR0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
bcm2835_peri_write
(
paddr
,
1
<<
shift
);
bcm2835_peri_write
(
paddr
,
1
<<
shift
);
}
}
...
@@ -191,21 +223,21 @@ void bcm2835_gpio_clr(uint8_t pin)
...
@@ -191,21 +223,21 @@ void bcm2835_gpio_clr(uint8_t pin)
// Set all output pins in the mask
// Set all output pins in the mask
void
bcm2835_gpio_set_multi
(
uint32_t
mask
)
void
bcm2835_gpio_set_multi
(
uint32_t
mask
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPSET0
/
4
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPSET0
/
4
;
bcm2835_peri_write
(
paddr
,
mask
);
bcm2835_peri_write
(
paddr
,
mask
);
}
}
// Clear all output pins in the mask
// Clear all output pins in the mask
void
bcm2835_gpio_clr_multi
(
uint32_t
mask
)
void
bcm2835_gpio_clr_multi
(
uint32_t
mask
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPCLR0
/
4
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPCLR0
/
4
;
bcm2835_peri_write
(
paddr
,
mask
);
bcm2835_peri_write
(
paddr
,
mask
);
}
}
// Read input pin
// Read input pin
uint8_t
bcm2835_gpio_lev
(
uint8_t
pin
)
uint8_t
bcm2835_gpio_lev
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPLEV0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPLEV0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
bcm2835_peri_read
(
paddr
);
uint32_t
value
=
bcm2835_peri_read
(
paddr
);
return
(
value
&
(
1
<<
shift
))
?
HIGH
:
LOW
;
return
(
value
&
(
1
<<
shift
))
?
HIGH
:
LOW
;
...
@@ -215,7 +247,7 @@ uint8_t bcm2835_gpio_lev(uint8_t pin)
...
@@ -215,7 +247,7 @@ uint8_t bcm2835_gpio_lev(uint8_t pin)
// Sigh cant support interrupts yet
// Sigh cant support interrupts yet
uint8_t
bcm2835_gpio_eds
(
uint8_t
pin
)
uint8_t
bcm2835_gpio_eds
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPEDS0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPEDS0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
bcm2835_peri_read
(
paddr
);
uint32_t
value
=
bcm2835_peri_read
(
paddr
);
return
(
value
&
(
1
<<
shift
))
?
HIGH
:
LOW
;
return
(
value
&
(
1
<<
shift
))
?
HIGH
:
LOW
;
...
@@ -224,7 +256,7 @@ uint8_t bcm2835_gpio_eds(uint8_t pin)
...
@@ -224,7 +256,7 @@ uint8_t bcm2835_gpio_eds(uint8_t pin)
// Write a 1 to clear the bit in EDS
// Write a 1 to clear the bit in EDS
void
bcm2835_gpio_set_eds
(
uint8_t
pin
)
void
bcm2835_gpio_set_eds
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPEDS0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPEDS0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_write
(
paddr
,
value
);
bcm2835_peri_write
(
paddr
,
value
);
...
@@ -233,14 +265,14 @@ void bcm2835_gpio_set_eds(uint8_t pin)
...
@@ -233,14 +265,14 @@ void bcm2835_gpio_set_eds(uint8_t pin)
// Rising edge detect enable
// Rising edge detect enable
void
bcm2835_gpio_ren
(
uint8_t
pin
)
void
bcm2835_gpio_ren
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPREN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPREN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
}
}
void
bcm2835_gpio_clr_ren
(
uint8_t
pin
)
void
bcm2835_gpio_clr_ren
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPREN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPREN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
...
@@ -249,14 +281,14 @@ void bcm2835_gpio_clr_ren(uint8_t pin)
...
@@ -249,14 +281,14 @@ void bcm2835_gpio_clr_ren(uint8_t pin)
// Falling edge detect enable
// Falling edge detect enable
void
bcm2835_gpio_fen
(
uint8_t
pin
)
void
bcm2835_gpio_fen
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPFEN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPFEN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
}
}
void
bcm2835_gpio_clr_fen
(
uint8_t
pin
)
void
bcm2835_gpio_clr_fen
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPFEN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPFEN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
...
@@ -265,14 +297,14 @@ void bcm2835_gpio_clr_fen(uint8_t pin)
...
@@ -265,14 +297,14 @@ void bcm2835_gpio_clr_fen(uint8_t pin)
// High detect enable
// High detect enable
void
bcm2835_gpio_hen
(
uint8_t
pin
)
void
bcm2835_gpio_hen
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPHEN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPHEN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
}
}
void
bcm2835_gpio_clr_hen
(
uint8_t
pin
)
void
bcm2835_gpio_clr_hen
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPHEN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPHEN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
...
@@ -281,14 +313,14 @@ void bcm2835_gpio_clr_hen(uint8_t pin)
...
@@ -281,14 +313,14 @@ void bcm2835_gpio_clr_hen(uint8_t pin)
// Low detect enable
// Low detect enable
void
bcm2835_gpio_len
(
uint8_t
pin
)
void
bcm2835_gpio_len
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPLEN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPLEN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
}
}
void
bcm2835_gpio_clr_len
(
uint8_t
pin
)
void
bcm2835_gpio_clr_len
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPLEN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPLEN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
...
@@ -297,14 +329,14 @@ void bcm2835_gpio_clr_len(uint8_t pin)
...
@@ -297,14 +329,14 @@ void bcm2835_gpio_clr_len(uint8_t pin)
// Async rising edge detect enable
// Async rising edge detect enable
void
bcm2835_gpio_aren
(
uint8_t
pin
)
void
bcm2835_gpio_aren
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPAREN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPAREN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
}
}
void
bcm2835_gpio_clr_aren
(
uint8_t
pin
)
void
bcm2835_gpio_clr_aren
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPAREN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPAREN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
...
@@ -313,14 +345,14 @@ void bcm2835_gpio_clr_aren(uint8_t pin)
...
@@ -313,14 +345,14 @@ void bcm2835_gpio_clr_aren(uint8_t pin)
// Async falling edge detect enable
// Async falling edge detect enable
void
bcm2835_gpio_afen
(
uint8_t
pin
)
void
bcm2835_gpio_afen
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPAFEN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPAFEN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
bcm2835_peri_set_bits
(
paddr
,
value
,
value
);
}
}
void
bcm2835_gpio_clr_afen
(
uint8_t
pin
)
void
bcm2835_gpio_clr_afen
(
uint8_t
pin
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPAFEN0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPAFEN0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
uint32_t
value
=
1
<<
shift
;
uint32_t
value
=
1
<<
shift
;
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
bcm2835_peri_set_bits
(
paddr
,
0
,
value
);
...
@@ -329,7 +361,7 @@ void bcm2835_gpio_clr_afen(uint8_t pin)
...
@@ -329,7 +361,7 @@ void bcm2835_gpio_clr_afen(uint8_t pin)
// Set pullup/down
// Set pullup/down
void
bcm2835_gpio_pud
(
uint8_t
pud
)
void
bcm2835_gpio_pud
(
uint8_t
pud
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPPUD
/
4
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPPUD
/
4
;
bcm2835_peri_write
(
paddr
,
pud
);
bcm2835_peri_write
(
paddr
,
pud
);
}
}
...
@@ -337,7 +369,7 @@ void bcm2835_gpio_pud(uint8_t pud)
...
@@ -337,7 +369,7 @@ void bcm2835_gpio_pud(uint8_t pud)
// Clocks the value of pud into the GPIO pin
// Clocks the value of pud into the GPIO pin
void
bcm2835_gpio_pudclk
(
uint8_t
pin
,
uint8_t
on
)
void
bcm2835_gpio_pudclk
(
uint8_t
pin
,
uint8_t
on
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPPUDCLK0
/
4
+
pin
/
32
;
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPPUDCLK0
/
4
+
pin
/
32
;
uint8_t
shift
=
pin
%
32
;
uint8_t
shift
=
pin
%
32
;
bcm2835_peri_write
(
paddr
,
(
on
?
1
:
0
)
<<
shift
);
bcm2835_peri_write
(
paddr
,
(
on
?
1
:
0
)
<<
shift
);
}
}
...
@@ -345,7 +377,7 @@ void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on)
...
@@ -345,7 +377,7 @@ void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on)
// Read GPIO pad behaviour for groups of GPIOs
// Read GPIO pad behaviour for groups of GPIOs
uint32_t
bcm2835_gpio_pad
(
uint8_t
group
)
uint32_t
bcm2835_gpio_pad
(
uint8_t
group
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_pads
+
BCM2835_PADS_GPIO_0_27
/
4
+
group
*
2
;
uint32_t
*
paddr
=
bcm2835_pads
+
BCM2835_PADS_GPIO_0_27
/
4
+
group
*
2
;
return
bcm2835_peri_read
(
paddr
);
return
bcm2835_peri_read
(
paddr
);
}
}
...
@@ -354,7 +386,7 @@ uint32_t bcm2835_gpio_pad(uint8_t group)
...
@@ -354,7 +386,7 @@ uint32_t bcm2835_gpio_pad(uint8_t group)
// BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA
// BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA
void
bcm2835_gpio_set_pad
(
uint8_t
group
,
uint32_t
control
)
void
bcm2835_gpio_set_pad
(
uint8_t
group
,
uint32_t
control
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_pads
+
BCM2835_PADS_GPIO_0_27
/
4
+
group
*
2
;
uint32_t
*
paddr
=
bcm2835_pads
+
BCM2835_PADS_GPIO_0_27
/
4
+
group
*
2
;
bcm2835_peri_write
(
paddr
,
control
|
BCM2835_PAD_PASSWRD
);
bcm2835_peri_write
(
paddr
,
control
|
BCM2835_PAD_PASSWRD
);
}
}
...
@@ -461,18 +493,14 @@ void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud)
...
@@ -461,18 +493,14 @@ void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud)
void
bcm2835_spi_begin
(
void
)
void
bcm2835_spi_begin
(
void
)
{
{
// Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them
// Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them
//bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); // CE1
bcm2835_gpio_fsel
(
RPI_GPIO_P1_26
,
BCM2835_GPIO_FSEL_ALT0
);
// CE1
// Enable CE0 by default, will be disabled if bcm2835_chipSelect() is called using another pin
bcm2835_gpio_fsel
(
RPI_GPIO_P1_24
,
BCM2835_GPIO_FSEL_ALT0
);
// CE0
bcm2835_gpio_fsel
(
RPI_GPIO_P1_24
,
BCM2835_GPIO_FSEL_ALT0
);
// CE0
bcm2835_gpio_fsel
(
RPI_GPIO_P1_21
,
BCM2835_GPIO_FSEL_ALT0
);
// MISO
bcm2835_gpio_fsel
(
RPI_GPIO_P1_21
,
BCM2835_GPIO_FSEL_ALT0
);
// MISO
bcm2835_gpio_fsel
(
RPI_GPIO_P1_19
,
BCM2835_GPIO_FSEL_ALT0
);
// MOSI
bcm2835_gpio_fsel
(
RPI_GPIO_P1_19
,
BCM2835_GPIO_FSEL_ALT0
);
// MOSI
bcm2835_gpio_fsel
(
RPI_GPIO_P1_23
,
BCM2835_GPIO_FSEL_ALT0
);
// CLK
bcm2835_gpio_fsel
(
RPI_GPIO_P1_23
,
BCM2835_GPIO_FSEL_ALT0
);
// CLK
// Set the SPI CS register to the some sensible defaults
// Set the SPI CS register to the some sensible defaults
volatile
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
bcm2835_peri_write
(
paddr
,
0
);
// All 0s
bcm2835_peri_write
(
paddr
,
0
);
// All 0s
// Clear TX and RX fifos
// Clear TX and RX fifos
...
@@ -500,13 +528,13 @@ void bcm2835_spi_setBitOrder(uint8_t order)
...
@@ -500,13 +528,13 @@ void bcm2835_spi_setBitOrder(uint8_t order)
// of the APB clock
// of the APB clock
void
bcm2835_spi_setClockDivider
(
uint16_t
divider
)
void
bcm2835_spi_setClockDivider
(
uint16_t
divider
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CLK
/
4
;
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CLK
/
4
;
bcm2835_peri_write
(
paddr
,
divider
);
bcm2835_peri_write
(
paddr
,
divider
);
}
}
void
bcm2835_spi_setDataMode
(
uint8_t
mode
)
void
bcm2835_spi_setDataMode
(
uint8_t
mode
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
// Mask in the CPO and CPHA bits of CS
// Mask in the CPO and CPHA bits of CS
bcm2835_peri_set_bits
(
paddr
,
mode
<<
2
,
BCM2835_SPI0_CS_CPOL
|
BCM2835_SPI0_CS_CPHA
);
bcm2835_peri_set_bits
(
paddr
,
mode
<<
2
,
BCM2835_SPI0_CS_CPOL
|
BCM2835_SPI0_CS_CPHA
);
}
}
...
@@ -514,8 +542,8 @@ void bcm2835_spi_setDataMode(uint8_t mode)
...
@@ -514,8 +542,8 @@ void bcm2835_spi_setDataMode(uint8_t mode)
// Writes (and reads) a single byte to SPI
// Writes (and reads) a single byte to SPI
uint8_t
bcm2835_spi_transfer
(
uint8_t
value
)
uint8_t
bcm2835_spi_transfer
(
uint8_t
value
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_spi0
+
BCM2835_SPI0_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_spi0
+
BCM2835_SPI0_FIFO
/
4
;
// This is Polled transfer as per section 10.6.1
// This is Polled transfer as per section 10.6.1
// BUG ALERT: what happens if we get interupted in this section, and someone else
// BUG ALERT: what happens if we get interupted in this section, and someone else
...
@@ -549,8 +577,8 @@ uint8_t bcm2835_spi_transfer(uint8_t value)
...
@@ -549,8 +577,8 @@ uint8_t bcm2835_spi_transfer(uint8_t value)
// Writes (and reads) an number of bytes to SPI
// Writes (and reads) an number of bytes to SPI
void
bcm2835_spi_transfernb
(
char
*
tbuf
,
char
*
rbuf
,
uint32_t
len
)
void
bcm2835_spi_transfernb
(
char
*
tbuf
,
char
*
rbuf
,
uint32_t
len
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_spi0
+
BCM2835_SPI0_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_spi0
+
BCM2835_SPI0_FIFO
/
4
;
uint32_t
TXCnt
=
0
;
uint32_t
TXCnt
=
0
;
uint32_t
RXCnt
=
0
;
uint32_t
RXCnt
=
0
;
...
@@ -568,7 +596,7 @@ void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
...
@@ -568,7 +596,7 @@ void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
while
((
TXCnt
<
len
)
||
(
RXCnt
<
len
))
while
((
TXCnt
<
len
)
||
(
RXCnt
<
len
))
{
{
// TX fifo not full, so add some more bytes
// TX fifo not full, so add some more bytes
while
(
(
bcm2835_peri_read
(
paddr
)
&
BCM2835_SPI0_CS_TXD
)
&&
(
TXCnt
<
len
)
&&
!
(
bcm2835_peri_read
(
paddr
)
&
BCM2835_SPI0_CS_RXR
)
)
while
(
((
bcm2835_peri_read
(
paddr
)
&
BCM2835_SPI0_CS_TXD
))
&&
(
TXCnt
<
len
)
)
{
{
bcm2835_peri_write_nb
(
fifo
,
tbuf
[
TXCnt
]);
bcm2835_peri_write_nb
(
fifo
,
tbuf
[
TXCnt
]);
TXCnt
++
;
TXCnt
++
;
...
@@ -580,18 +608,19 @@ void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
...
@@ -580,18 +608,19 @@ void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
RXCnt
++
;
RXCnt
++
;
}
}
}
}
while
(
!
(
bcm2835_peri_read
(
paddr
)
&
BCM2835_SPI0_CS_DONE
)
)
// Wait for DONE to be set
;
while
(
!
(
bcm2835_peri_read_nb
(
paddr
)
&
BCM2835_SPI0_CS_DONE
))
if
(
TXCnt
==
len
)
bcm2835_peri_set_bits
(
paddr
,
0
,
BCM2835_SPI0_CS_TA
)
;
;
}
// Set TA = 0, and also set the barrier
bcm2835_peri_set_bits
(
paddr
,
0
,
BCM2835_SPI0_CS_TA
);
}
// Writes an number of bytes to SPI
// Writes an number of bytes to SPI
void
bcm2835_spi_writenb
(
char
*
tbuf
,
uint32_t
len
)
void
bcm2835_spi_writenb
(
char
*
tbuf
,
uint32_t
len
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_spi0
+
BCM2835_SPI0_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_spi0
+
BCM2835_SPI0_FIFO
/
4
;
// This is Polled transfer as per section 10.6.1
// This is Polled transfer as per section 10.6.1
// BUG ALERT: what happens if we get interupted in this section, and someone else
// BUG ALERT: what happens if we get interupted in this section, and someone else
...
@@ -637,22 +666,14 @@ void bcm2835_spi_transfern(char* buf, uint32_t len)
...
@@ -637,22 +666,14 @@ void bcm2835_spi_transfern(char* buf, uint32_t len)
void
bcm2835_spi_chipSelect
(
uint8_t
cs
)
void
bcm2835_spi_chipSelect
(
uint8_t
cs
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
if
(
cs
){
bcm2835_gpio_fsel
(
RPI_GPIO_P1_26
,
BCM2835_GPIO_FSEL_ALT0
);
// CE1
bcm2835_gpio_fsel
(
RPI_GPIO_P1_24
,
BCM2835_GPIO_FSEL_INPT
);
// Revert default of CE0 back to input
}
else
{
bcm2835_gpio_fsel
(
RPI_GPIO_P1_24
,
BCM2835_GPIO_FSEL_ALT0
);
// CE0
}
// Mask in the CS bits of CS
// Mask in the CS bits of CS
bcm2835_peri_set_bits
(
paddr
,
cs
,
BCM2835_SPI0_CS_CS
);
bcm2835_peri_set_bits
(
paddr
,
cs
,
BCM2835_SPI0_CS_CS
);
}
}
void
bcm2835_spi_setChipSelectPolarity
(
uint8_t
cs
,
uint8_t
active
)
void
bcm2835_spi_setChipSelectPolarity
(
uint8_t
cs
,
uint8_t
active
)
{
{
volatile
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
uint32_t
*
paddr
=
bcm2835_spi0
+
BCM2835_SPI0_CS
/
4
;
uint8_t
shift
=
21
+
cs
;
uint8_t
shift
=
21
+
cs
;
// Mask in the appropriate CSPOLn bit
// Mask in the appropriate CSPOLn bit
bcm2835_peri_set_bits
(
paddr
,
active
<<
shift
,
1
<<
shift
);
bcm2835_peri_set_bits
(
paddr
,
active
<<
shift
,
1
<<
shift
);
...
@@ -661,12 +682,12 @@ void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active)
...
@@ -661,12 +682,12 @@ void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active)
void
bcm2835_i2c_begin
(
void
)
void
bcm2835_i2c_begin
(
void
)
{
{
#ifdef I2C_V1
#ifdef I2C_V1
volatile
uint32_t
*
paddr
=
bcm2835_bsc0
+
BCM2835_BSC_DIV
/
4
;
uint32_t
*
paddr
=
bcm2835_bsc0
+
BCM2835_BSC_DIV
/
4
;
// Set the I2C/BSC0 pins to the Alt 0 function to enable I2C access on them
// Set the I2C/BSC0 pins to the Alt 0 function to enable I2C access on them
bcm2835_gpio_fsel
(
RPI_GPIO_P1_03
,
BCM2835_GPIO_FSEL_ALT0
);
// SDA
bcm2835_gpio_fsel
(
RPI_GPIO_P1_03
,
BCM2835_GPIO_FSEL_ALT0
);
// SDA
bcm2835_gpio_fsel
(
RPI_GPIO_P1_05
,
BCM2835_GPIO_FSEL_ALT0
);
// SCL
bcm2835_gpio_fsel
(
RPI_GPIO_P1_05
,
BCM2835_GPIO_FSEL_ALT0
);
// SCL
#else
#else
volatile
uint32_t
*
paddr
=
bcm2835_bsc1
+
BCM2835_BSC_DIV
/
4
;
uint32_t
*
paddr
=
bcm2835_bsc1
+
BCM2835_BSC_DIV
/
4
;
// Set the I2C/BSC1 pins to the Alt 0 function to enable I2C access on them
// Set the I2C/BSC1 pins to the Alt 0 function to enable I2C access on them
bcm2835_gpio_fsel
(
RPI_V2_GPIO_P1_03
,
BCM2835_GPIO_FSEL_ALT0
);
// SDA
bcm2835_gpio_fsel
(
RPI_V2_GPIO_P1_03
,
BCM2835_GPIO_FSEL_ALT0
);
// SDA
bcm2835_gpio_fsel
(
RPI_V2_GPIO_P1_05
,
BCM2835_GPIO_FSEL_ALT0
);
// SCL
bcm2835_gpio_fsel
(
RPI_V2_GPIO_P1_05
,
BCM2835_GPIO_FSEL_ALT0
);
// SCL
...
@@ -697,9 +718,9 @@ void bcm2835_i2c_setSlaveAddress(uint8_t addr)
...
@@ -697,9 +718,9 @@ void bcm2835_i2c_setSlaveAddress(uint8_t addr)
{
{
// Set I2C Device Address
// Set I2C Device Address
#ifdef I2C_V1
#ifdef I2C_V1
volatile
uint32_t
*
paddr
=
bcm2835_bsc0
+
BCM2835_BSC_A
/
4
;
uint32_t
*
paddr
=
bcm2835_bsc0
+
BCM2835_BSC_A
/
4
;
#else
#else
volatile
uint32_t
*
paddr
=
bcm2835_bsc1
+
BCM2835_BSC_A
/
4
;
uint32_t
*
paddr
=
bcm2835_bsc1
+
BCM2835_BSC_A
/
4
;
#endif
#endif
bcm2835_peri_write
(
paddr
,
addr
);
bcm2835_peri_write
(
paddr
,
addr
);
}
}
...
@@ -710,9 +731,9 @@ void bcm2835_i2c_setSlaveAddress(uint8_t addr)
...
@@ -710,9 +731,9 @@ void bcm2835_i2c_setSlaveAddress(uint8_t addr)
void
bcm2835_i2c_setClockDivider
(
uint16_t
divider
)
void
bcm2835_i2c_setClockDivider
(
uint16_t
divider
)
{
{
#ifdef I2C_V1
#ifdef I2C_V1
volatile
uint32_t
*
paddr
=
bcm2835_bsc0
+
BCM2835_BSC_DIV
/
4
;
uint32_t
*
paddr
=
bcm2835_bsc0
+
BCM2835_BSC_DIV
/
4
;
#else
#else
volatile
uint32_t
*
paddr
=
bcm2835_bsc1
+
BCM2835_BSC_DIV
/
4
;
uint32_t
*
paddr
=
bcm2835_bsc1
+
BCM2835_BSC_DIV
/
4
;
#endif
#endif
bcm2835_peri_write
(
paddr
,
divider
);
bcm2835_peri_write
(
paddr
,
divider
);
// Calculate time for transmitting one byte
// Calculate time for transmitting one byte
...
@@ -734,15 +755,15 @@ void bcm2835_i2c_set_baudrate(uint32_t baudrate)
...
@@ -734,15 +755,15 @@ void bcm2835_i2c_set_baudrate(uint32_t baudrate)
uint8_t
bcm2835_i2c_write
(
const
char
*
buf
,
uint32_t
len
)
uint8_t
bcm2835_i2c_write
(
const
char
*
buf
,
uint32_t
len
)
{
{
#ifdef I2C_V1
#ifdef I2C_V1
volatile
uint32_t
*
dlen
=
bcm2835_bsc0
+
BCM2835_BSC_DLEN
/
4
;
uint32_t
*
dlen
=
bcm2835_bsc0
+
BCM2835_BSC_DLEN
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_bsc0
+
BCM2835_BSC_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_bsc0
+
BCM2835_BSC_FIFO
/
4
;
volatile
uint32_t
*
status
=
bcm2835_bsc0
+
BCM2835_BSC_S
/
4
;
uint32_t
*
status
=
bcm2835_bsc0
+
BCM2835_BSC_S
/
4
;
volatile
uint32_t
*
control
=
bcm2835_bsc0
+
BCM2835_BSC_C
/
4
;
uint32_t
*
control
=
bcm2835_bsc0
+
BCM2835_BSC_C
/
4
;
#else
#else
volatile
uint32_t
*
dlen
=
bcm2835_bsc1
+
BCM2835_BSC_DLEN
/
4
;
uint32_t
*
dlen
=
bcm2835_bsc1
+
BCM2835_BSC_DLEN
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_bsc1
+
BCM2835_BSC_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_bsc1
+
BCM2835_BSC_FIFO
/
4
;
volatile
uint32_t
*
status
=
bcm2835_bsc1
+
BCM2835_BSC_S
/
4
;
uint32_t
*
status
=
bcm2835_bsc1
+
BCM2835_BSC_S
/
4
;
volatile
uint32_t
*
control
=
bcm2835_bsc1
+
BCM2835_BSC_C
/
4
;
uint32_t
*
control
=
bcm2835_bsc1
+
BCM2835_BSC_C
/
4
;
#endif
#endif
uint32_t
remaining
=
len
;
uint32_t
remaining
=
len
;
...
@@ -805,15 +826,15 @@ uint8_t bcm2835_i2c_write(const char * buf, uint32_t len)
...
@@ -805,15 +826,15 @@ uint8_t bcm2835_i2c_write(const char * buf, uint32_t len)
uint8_t
bcm2835_i2c_read
(
char
*
buf
,
uint32_t
len
)
uint8_t
bcm2835_i2c_read
(
char
*
buf
,
uint32_t
len
)
{
{
#ifdef I2C_V1
#ifdef I2C_V1
volatile
uint32_t
*
dlen
=
bcm2835_bsc0
+
BCM2835_BSC_DLEN
/
4
;
uint32_t
*
dlen
=
bcm2835_bsc0
+
BCM2835_BSC_DLEN
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_bsc0
+
BCM2835_BSC_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_bsc0
+
BCM2835_BSC_FIFO
/
4
;
volatile
uint32_t
*
status
=
bcm2835_bsc0
+
BCM2835_BSC_S
/
4
;
uint32_t
*
status
=
bcm2835_bsc0
+
BCM2835_BSC_S
/
4
;
volatile
uint32_t
*
control
=
bcm2835_bsc0
+
BCM2835_BSC_C
/
4
;
uint32_t
*
control
=
bcm2835_bsc0
+
BCM2835_BSC_C
/
4
;
#else
#else
volatile
uint32_t
*
dlen
=
bcm2835_bsc1
+
BCM2835_BSC_DLEN
/
4
;
uint32_t
*
dlen
=
bcm2835_bsc1
+
BCM2835_BSC_DLEN
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_bsc1
+
BCM2835_BSC_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_bsc1
+
BCM2835_BSC_FIFO
/
4
;
volatile
uint32_t
*
status
=
bcm2835_bsc1
+
BCM2835_BSC_S
/
4
;
uint32_t
*
status
=
bcm2835_bsc1
+
BCM2835_BSC_S
/
4
;
volatile
uint32_t
*
control
=
bcm2835_bsc1
+
BCM2835_BSC_C
/
4
;
uint32_t
*
control
=
bcm2835_bsc1
+
BCM2835_BSC_C
/
4
;
#endif
#endif
uint32_t
remaining
=
len
;
uint32_t
remaining
=
len
;
...
@@ -879,15 +900,15 @@ uint8_t bcm2835_i2c_read(char* buf, uint32_t len)
...
@@ -879,15 +900,15 @@ uint8_t bcm2835_i2c_read(char* buf, uint32_t len)
uint8_t
bcm2835_i2c_read_register_rs
(
char
*
regaddr
,
char
*
buf
,
uint32_t
len
)
uint8_t
bcm2835_i2c_read_register_rs
(
char
*
regaddr
,
char
*
buf
,
uint32_t
len
)
{
{
#ifdef I2C_V1
#ifdef I2C_V1
volatile
uint32_t
*
dlen
=
bcm2835_bsc0
+
BCM2835_BSC_DLEN
/
4
;
uint32_t
*
dlen
=
bcm2835_bsc0
+
BCM2835_BSC_DLEN
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_bsc0
+
BCM2835_BSC_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_bsc0
+
BCM2835_BSC_FIFO
/
4
;
volatile
uint32_t
*
status
=
bcm2835_bsc0
+
BCM2835_BSC_S
/
4
;
uint32_t
*
status
=
bcm2835_bsc0
+
BCM2835_BSC_S
/
4
;
volatile
uint32_t
*
control
=
bcm2835_bsc0
+
BCM2835_BSC_C
/
4
;
uint32_t
*
control
=
bcm2835_bsc0
+
BCM2835_BSC_C
/
4
;
#else
#else
volatile
uint32_t
*
dlen
=
bcm2835_bsc1
+
BCM2835_BSC_DLEN
/
4
;
uint32_t
*
dlen
=
bcm2835_bsc1
+
BCM2835_BSC_DLEN
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_bsc1
+
BCM2835_BSC_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_bsc1
+
BCM2835_BSC_FIFO
/
4
;
volatile
uint32_t
*
status
=
bcm2835_bsc1
+
BCM2835_BSC_S
/
4
;
uint32_t
*
status
=
bcm2835_bsc1
+
BCM2835_BSC_S
/
4
;
volatile
uint32_t
*
control
=
bcm2835_bsc1
+
BCM2835_BSC_C
/
4
;
uint32_t
*
control
=
bcm2835_bsc1
+
BCM2835_BSC_C
/
4
;
#endif
#endif
uint32_t
remaining
=
len
;
uint32_t
remaining
=
len
;
uint32_t
i
=
0
;
uint32_t
i
=
0
;
...
@@ -969,15 +990,15 @@ uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
...
@@ -969,15 +990,15 @@ uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
uint8_t
bcm2835_i2c_write_read_rs
(
char
*
cmds
,
uint32_t
cmds_len
,
char
*
buf
,
uint32_t
buf_len
)
uint8_t
bcm2835_i2c_write_read_rs
(
char
*
cmds
,
uint32_t
cmds_len
,
char
*
buf
,
uint32_t
buf_len
)
{
{
#ifdef I2C_V1
#ifdef I2C_V1
volatile
uint32_t
*
dlen
=
bcm2835_bsc0
+
BCM2835_BSC_DLEN
/
4
;
uint32_t
*
dlen
=
bcm2835_bsc0
+
BCM2835_BSC_DLEN
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_bsc0
+
BCM2835_BSC_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_bsc0
+
BCM2835_BSC_FIFO
/
4
;
volatile
uint32_t
*
status
=
bcm2835_bsc0
+
BCM2835_BSC_S
/
4
;
uint32_t
*
status
=
bcm2835_bsc0
+
BCM2835_BSC_S
/
4
;
volatile
uint32_t
*
control
=
bcm2835_bsc0
+
BCM2835_BSC_C
/
4
;
uint32_t
*
control
=
bcm2835_bsc0
+
BCM2835_BSC_C
/
4
;
#else
#else
volatile
uint32_t
*
dlen
=
bcm2835_bsc1
+
BCM2835_BSC_DLEN
/
4
;
uint32_t
*
dlen
=
bcm2835_bsc1
+
BCM2835_BSC_DLEN
/
4
;
volatile
uint32_t
*
fifo
=
bcm2835_bsc1
+
BCM2835_BSC_FIFO
/
4
;
uint32_t
*
fifo
=
bcm2835_bsc1
+
BCM2835_BSC_FIFO
/
4
;
volatile
uint32_t
*
status
=
bcm2835_bsc1
+
BCM2835_BSC_S
/
4
;
uint32_t
*
status
=
bcm2835_bsc1
+
BCM2835_BSC_S
/
4
;
volatile
uint32_t
*
control
=
bcm2835_bsc1
+
BCM2835_BSC_C
/
4
;
uint32_t
*
control
=
bcm2835_bsc1
+
BCM2835_BSC_C
/
4
;
#endif
#endif
uint32_t
remaining
=
cmds_len
;
uint32_t
remaining
=
cmds_len
;
...
@@ -1070,7 +1091,7 @@ uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint
...
@@ -1070,7 +1091,7 @@ uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint
// Read the System Timer Counter (64-bits)
// Read the System Timer Counter (64-bits)
uint64_t
bcm2835_st_read
(
void
)
uint64_t
bcm2835_st_read
(
void
)
{
{
volatile
uint32_t
*
paddr
;
uint32_t
*
paddr
;
uint32_t
hi
,
lo
;
uint32_t
hi
,
lo
;
uint64_t
st
;
uint64_t
st
;
paddr
=
bcm2835_st
+
BCM2835_ST_CHI
/
4
;
paddr
=
bcm2835_st
+
BCM2835_ST_CHI
/
4
;
...
@@ -1186,7 +1207,7 @@ void *malloc_aligned(size_t size)
...
@@ -1186,7 +1207,7 @@ void *malloc_aligned(size_t size)
static
void
*
mapmem
(
const
char
*
msg
,
size_t
size
,
int
fd
,
off_t
off
)
static
void
*
mapmem
(
const
char
*
msg
,
size_t
size
,
int
fd
,
off_t
off
)
{
{
void
*
map
=
mmap
(
NULL
,
size
,
(
PROT_READ
|
PROT_WRITE
),
MAP_SHARED
,
fd
,
off
);
void
*
map
=
mmap
(
NULL
,
size
,
(
PROT_READ
|
PROT_WRITE
),
MAP_SHARED
,
fd
,
off
);
if
(
MAP_FAILED
==
map
)
if
(
map
==
MAP_FAILED
)
fprintf
(
stderr
,
"bcm2835_init: %s mmap failed: %s
\n
"
,
msg
,
strerror
(
errno
));
fprintf
(
stderr
,
"bcm2835_init: %s mmap failed: %s
\n
"
,
msg
,
strerror
(
errno
));
return
map
;
return
map
;
}
}
...
@@ -1202,19 +1223,38 @@ static void unmapmem(void **pmem, size_t size)
...
@@ -1202,19 +1223,38 @@ static void unmapmem(void **pmem, size_t size)
int
bcm2835_init
(
void
)
int
bcm2835_init
(
void
)
{
{
struct
timeval
tv
;
struct
timeval
tv
;
if
(
debug
)
if
(
debug
)
{
{
bcm2835_pads
=
(
uint32_t
*
)
BCM2835_GPIO_PADS
;
bcm2835_peripherals
=
(
uint32_t
*
)
BCM2835_PERI_BASE
;
bcm2835_clk
=
(
uint32_t
*
)
BCM2835_CLOCK_BASE
;
bcm2835_gpio
=
(
uint32_t
*
)
BCM2835_GPIO_BASE
;
bcm2835_pads
=
bcm2835_peripherals
+
BCM2835_GPIO_PADS
;
bcm2835_pwm
=
(
uint32_t
*
)
BCM2835_GPIO_PWM
;
bcm2835_clk
=
bcm2835_peripherals
+
BCM2835_CLOCK_BASE
;
bcm2835_spi0
=
(
uint32_t
*
)
BCM2835_SPI0_BASE
;
bcm2835_gpio
=
bcm2835_peripherals
+
BCM2835_GPIO_BASE
;
bcm2835_bsc0
=
(
uint32_t
*
)
BCM2835_BSC0_BASE
;
bcm2835_pwm
=
bcm2835_peripherals
+
BCM2835_GPIO_PWM
;
bcm2835_bsc1
=
(
uint32_t
*
)
BCM2835_BSC1_BASE
;
bcm2835_spi0
=
bcm2835_peripherals
+
BCM2835_SPI0_BASE
;
bcm2835_st
=
(
uint32_t
*
)
BCM2835_ST_BASE
;
bcm2835_bsc0
=
bcm2835_peripherals
+
BCM2835_BSC0_BASE
;
bcm2835_bsc1
=
bcm2835_peripherals
+
BCM2835_BSC1_BASE
;
bcm2835_st
=
bcm2835_peripherals
+
BCM2835_ST_BASE
;
return
1
;
// Success
return
1
;
// Success
}
}
// Figure out the base and size of the peripheral address block, based on whether we are on a RPI2 or not,
// using the device-tree
FILE
*
fp
=
fopen
(
BMC2835_RPI2_DT_FILENAME
,
"rb"
);
if
(
fp
)
{
unsigned
char
buf
[
4
];
fseek
(
fp
,
BMC2835_RPI2_DT_PERI_BASE_ADDRESS_OFFSET
,
SEEK_SET
);
if
(
fread
(
buf
,
1
,
sizeof
(
buf
),
fp
)
==
sizeof
(
buf
))
bcm2835_peripherals_base
=
(
uint32_t
*
)(
buf
[
0
]
<<
24
|
buf
[
1
]
<<
16
|
buf
[
2
]
<<
8
|
buf
[
3
]
<<
0
);
fseek
(
fp
,
BMC2835_RPI2_DT_PERI_SIZE_OFFSET
,
SEEK_SET
);
if
(
fread
(
buf
,
1
,
sizeof
(
buf
),
fp
)
==
sizeof
(
buf
))
bcm2835_peripherals_size
=
(
buf
[
0
]
<<
24
|
buf
[
1
]
<<
16
|
buf
[
2
]
<<
8
|
buf
[
3
]
<<
0
);
fclose
(
fp
);
}
// else we are prob on RPi 1 with BCM2835, and use the hardwired defaults
// Now get ready to map the peripherals block
int
memfd
=
-
1
;
int
memfd
=
-
1
;
int
ok
=
0
;
int
ok
=
0
;
// Open the master /dev/memory device
// Open the master /dev/memory device
...
@@ -1225,34 +1265,19 @@ int bcm2835_init(void)
...
@@ -1225,34 +1265,19 @@ int bcm2835_init(void)
goto
exit
;
goto
exit
;
}
}
// GPIO:
// Base of the peripherals block is mapped to VM
bcm2835_gpio
=
(
volatile
uint32_t
*
)
mapmem
(
"gpio"
,
BCM2835_BLOCK_SIZE
,
memfd
,
BCM2835_GPIO_BASE
);
bcm2835_peripherals
=
(
uint32_t
*
)
mapmem
(
"gpio"
,
bcm2835_peripherals_size
,
memfd
,
(
uint32_t
)
bcm2835_peripherals_base
);
if
(
bcm2835_gpio
==
MAP_FAILED
)
goto
exit
;
if
(
bcm2835_peripherals
==
MAP_FAILED
)
goto
exit
;
// PWM
bcm2835_pwm
=
(
volatile
uint32_t
*
)
mapmem
(
"pwm"
,
BCM2835_BLOCK_SIZE
,
memfd
,
BCM2835_GPIO_PWM
);
if
(
bcm2835_pwm
==
MAP_FAILED
)
goto
exit
;
// Clock control (needed for PWM)
bcm2835_clk
=
(
volatile
uint32_t
*
)
mapmem
(
"clk"
,
BCM2835_BLOCK_SIZE
,
memfd
,
BCM2835_CLOCK_BASE
);
if
(
bcm2835_clk
==
MAP_FAILED
)
goto
exit
;
bcm2835_pads
=
(
volatile
uint32_t
*
)
mapmem
(
"pads"
,
BCM2835_BLOCK_SIZE
,
memfd
,
BCM2835_GPIO_PADS
);
if
(
bcm2835_pads
==
MAP_FAILED
)
goto
exit
;
bcm2835_spi0
=
(
volatile
uint32_t
*
)
mapmem
(
"spi0"
,
BCM2835_BLOCK_SIZE
,
memfd
,
BCM2835_SPI0_BASE
);
// Now compute the base addresses of various peripherals, which are at fixed offsets within the mapped peripherals block
if
(
bcm2835_spi0
==
MAP_FAILED
)
goto
exit
;
bcm2835_gpio
=
bcm2835_peripherals
+
BCM2835_GPIO_BASE
;
bcm2835_pwm
=
bcm2835_peripherals
+
BCM2835_GPIO_PWM
;
// I2C
bcm2835_clk
=
bcm2835_peripherals
+
BCM2835_CLOCK_BASE
;
bcm2835_bsc0
=
(
volatile
uint32_t
*
)
mapmem
(
"bsc0"
,
BCM2835_BLOCK_SIZE
,
memfd
,
BCM2835_BSC0_BASE
);
bcm2835_pads
=
bcm2835_peripherals
+
BCM2835_GPIO_PADS
;
if
(
bcm2835_bsc0
==
MAP_FAILED
)
goto
exit
;
bcm2835_spi0
=
bcm2835_peripherals
+
BCM2835_SPI0_BASE
;
bcm2835_bsc0
=
bcm2835_peripherals
+
BCM2835_BSC0_BASE
;
// I2C
bcm2835_bsc1
=
(
volatile
uint32_t
*
)
mapmem
(
"bsc1"
,
BCM2835_BLOCK_SIZE
,
memfd
,
BCM2835_BSC1_BASE
);
bcm2835_bsc1
=
bcm2835_peripherals
+
BCM2835_BSC1_BASE
;
// I2C
if
(
bcm2835_bsc1
==
MAP_FAILED
)
goto
exit
;
bcm2835_st
=
bcm2835_peripherals
+
BCM2835_ST_BASE
;
// ST
bcm2835_st
=
(
volatile
uint32_t
*
)
mapmem
(
"st"
,
BCM2835_BLOCK_SIZE
,
memfd
,
BCM2835_ST_BASE
);
if
(
bcm2835_st
==
MAP_FAILED
)
goto
exit
;
ok
=
1
;
ok
=
1
;
...
@@ -1273,14 +1298,17 @@ exit:
...
@@ -1273,14 +1298,17 @@ exit:
int
bcm2835_close
(
void
)
int
bcm2835_close
(
void
)
{
{
if
(
debug
)
return
1
;
// Success
if
(
debug
)
return
1
;
// Success
unmapmem
((
void
**
)
&
bcm2835_gpio
,
BCM2835_BLOCK_SIZE
);
unmapmem
((
void
**
)
&
bcm2835_pwm
,
BCM2835_BLOCK_SIZE
);
unmapmem
((
void
**
)
&
bcm2835_peripherals
,
bcm2835_peripherals_size
);
unmapmem
((
void
**
)
&
bcm2835_clk
,
BCM2835_BLOCK_SIZE
);
bcm2835_peripherals
=
MAP_FAILED
;
unmapmem
((
void
**
)
&
bcm2835_spi0
,
BCM2835_BLOCK_SIZE
);
bcm2835_gpio
=
MAP_FAILED
;
unmapmem
((
void
**
)
&
bcm2835_bsc0
,
BCM2835_BLOCK_SIZE
);
bcm2835_pwm
=
MAP_FAILED
;
unmapmem
((
void
**
)
&
bcm2835_bsc1
,
BCM2835_BLOCK_SIZE
);
bcm2835_clk
=
MAP_FAILED
;
unmapmem
((
void
**
)
&
bcm2835_st
,
BCM2835_BLOCK_SIZE
);
bcm2835_pads
=
MAP_FAILED
;
unmapmem
((
void
**
)
&
bcm2835_pads
,
BCM2835_BLOCK_SIZE
);
bcm2835_spi0
=
MAP_FAILED
;
bcm2835_bsc0
=
MAP_FAILED
;
bcm2835_bsc1
=
MAP_FAILED
;
bcm2835_st
=
MAP_FAILED
;
return
1
;
// Success
return
1
;
// Success
}
}
...
...
RPi/bcm2835.h
View file @
f06ca7cb
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
/// BCM 2835).
/// BCM 2835).
///
///
/// The version of the package that this documentation refers to can be downloaded
/// The version of the package that this documentation refers to can be downloaded
/// from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.3
6
.tar.gz
/// from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.3
9
.tar.gz
/// You can find the latest version at http://www.airspayce.com/mikem/bcm2835
/// You can find the latest version at http://www.airspayce.com/mikem/bcm2835
///
///
/// Several example programs are provided.
/// Several example programs are provided.
...
@@ -316,6 +316,12 @@
...
@@ -316,6 +316,12 @@
/// \version 1.37 Moved confiure.in to configure.ac as receommnded by autoreconf.<br>
/// \version 1.37 Moved confiure.in to configure.ac as receommnded by autoreconf.<br>
/// Improvements to bcm2835_st_read to account for possible timer overflow, contributed by 'Ed'.<br>
/// Improvements to bcm2835_st_read to account for possible timer overflow, contributed by 'Ed'.<br>
/// Added definitions for Raspberry Pi B+ J8 header GPIO pins.<br>
/// Added definitions for Raspberry Pi B+ J8 header GPIO pins.<br>
/// \version 1.38 Added bcm2835_regbase for the benefit of C# wrappers, patch by Frank Hommers <br>
/// \version 1.39 Beta version of RPi2 compatibility. Not tested here on RPi2 hardware.
/// Testers please confirm correct operation on RPi2.<br>
/// Unneccessary 'volatile' qualifiers removed from all variables and signatures.<br>
/// Removed unsupportable PWM dividers, based on a report from Christophe Cecillon.<br>
/// Minor improvements to spi.c example.<br>
///
///
/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
...
@@ -340,58 +346,92 @@
...
@@ -340,58 +346,92 @@
/// Speed of the core clock core_clk
/// Speed of the core clock core_clk
#define BCM2835_CORE_CLK_HZ 250000000 ///< 250 MHz
#define BCM2835_CORE_CLK_HZ 250000000 ///< 250 MHz
// Physical addresses for various peripheral register sets
/// On RPi2 with BCM2836, the base of the peripherals is read from a /proc file
#define BMC2835_RPI2_DT_FILENAME "/proc/device-tree/soc/ranges"
/// On RPi2, offset into BMC2835_RPI2_DT_FILENAME for the peripherals base address
#define BMC2835_RPI2_DT_PERI_BASE_ADDRESS_OFFSET 4
/// On RPi2, offset into BMC2835_RPI2_DT_FILENAME for the peripherals size address
#define BMC2835_RPI2_DT_PERI_SIZE_OFFSET 8
/// Physical addresses for various peripheral register sets
/// Base Physical Address of the BCM 2835 peripheral registers
/// Base Physical Address of the BCM 2835 peripheral registers
/// Note this is different for the RPi2 BCM2836, where this isderived from /proc/device-tree/soc/ranges
#define BCM2835_PERI_BASE 0x20000000
#define BCM2835_PERI_BASE 0x20000000
/// Base Physical Address of the System Timer registers
/// Size of the perioherals block on RPi 1
#define BCM2835_ST_BASE (BCM2835_PERI_BASE + 0x3000)
#define BCM2835_PERI_SIZE 0x01000000
/// Base Physical Address of the Pads registers
#define BCM2835_GPIO_PADS (BCM2835_PERI_BASE + 0x100000)
/// Offsets for the bases of various peripherals within the peripherals block
/// Base Physical Address of the Clock/timer registers
/// Base Address of the System Timer registers
#define BCM2835_CLOCK_BASE (BCM2835_PERI_BASE + 0x101000)
#define BCM2835_ST_BASE 0x3000
/// Base Physical Address of the GPIO registers
/// Base Address of the Pads registers
#define BCM2835_GPIO_BASE (BCM2835_PERI_BASE + 0x200000)
#define BCM2835_GPIO_PADS 0x100000
/// Base Physical Address of the SPI0 registers
/// Base Address of the Clock/timer registers
#define BCM2835_SPI0_BASE (BCM2835_PERI_BASE + 0x204000)
#define BCM2835_CLOCK_BASE 0x101000
/// Base Physical Address of the BSC0 registers
/// Base Address of the GPIO registers
#define BCM2835_BSC0_BASE (BCM2835_PERI_BASE + 0x205000)
#define BCM2835_GPIO_BASE 0x200000
/// Base Physical Address of the PWM registers
/// Base Address of the SPI0 registers
#define BCM2835_GPIO_PWM (BCM2835_PERI_BASE + 0x20C000)
#define BCM2835_SPI0_BASE 0x204000
/// Base Physical Address of the BSC1 registers
/// Base Address of the BSC0 registers
#define BCM2835_BSC1_BASE (BCM2835_PERI_BASE + 0x804000)
#define BCM2835_BSC0_BASE 0x205000
/// Base Address of the PWM registers
#define BCM2835_GPIO_PWM 0x20C000
/// Base Address of the BSC1 registers
#define BCM2835_BSC1_BASE 0x804000
/// Physical address and size of the peripherals block
/// May be overridden on RPi2
extern
uint32_t
*
bcm2835_peripherals_base
;
/// Size of the peripherals block to be mapped
extern
uint32_t
bcm2835_peripherals_size
;
/// Virtual memory address of the mapped peripherals block
extern
void
*
bcm2835_peripherals
;
/// Base of the ST (System Timer) registers.
/// Base of the ST (System Timer) registers.
/// Available after bcm2835_init has been called
/// Available after bcm2835_init has been called
extern
volatile
uint32_t
*
bcm2835_st
;
extern
uint32_t
*
bcm2835_st
;
/// Base of the GPIO registers.
/// Base of the GPIO registers.
/// Available after bcm2835_init has been called
/// Available after bcm2835_init has been called
extern
volatile
uint32_t
*
bcm2835_gpio
;
extern
uint32_t
*
bcm2835_gpio
;
/// Base of the PWM registers.
/// Base of the PWM registers.
/// Available after bcm2835_init has been called
/// Available after bcm2835_init has been called
extern
volatile
uint32_t
*
bcm2835_pwm
;
extern
uint32_t
*
bcm2835_pwm
;
/// Base of the CLK registers.
/// Base of the CLK registers.
/// Available after bcm2835_init has been called
/// Available after bcm2835_init has been called
extern
volatile
uint32_t
*
bcm2835_clk
;
extern
uint32_t
*
bcm2835_clk
;
/// Base of the PADS registers.
/// Base of the PADS registers.
/// Available after bcm2835_init has been called
/// Available after bcm2835_init has been called
extern
volatile
uint32_t
*
bcm2835_pads
;
extern
uint32_t
*
bcm2835_pads
;
/// Base of the SPI0 registers.
/// Base of the SPI0 registers.
/// Available after bcm2835_init has been called
/// Available after bcm2835_init has been called
extern
volatile
uint32_t
*
bcm2835_spi0
;
extern
uint32_t
*
bcm2835_spi0
;
/// Base of the BSC0 registers.
/// Base of the BSC0 registers.
/// Available after bcm2835_init has been called
/// Available after bcm2835_init has been called
extern
volatile
uint32_t
*
bcm2835_bsc0
;
extern
uint32_t
*
bcm2835_bsc0
;
/// Base of the BSC1 registers.
/// Base of the BSC1 registers.
/// Available after bcm2835_init has been called
/// Available after bcm2835_init has been called
extern
volatile
uint32_t
*
bcm2835_bsc1
;
extern
uint32_t
*
bcm2835_bsc1
;
/// \brief bcm2835RegisterBase
/// Register bases for bcm2835_regbase()
typedef
enum
{
BCM2835_REGBASE_ST
=
1
,
///< Base of the ST (System Timer) registers.
BCM2835_REGBASE_GPIO
=
2
,
///< Base of the GPIO registers.
BCM2835_REGBASE_PWM
=
3
,
///< Base of the PWM registers.
BCM2835_REGBASE_CLK
=
4
,
///< Base of the CLK registers.
BCM2835_REGBASE_PADS
=
5
,
///< Base of the PADS registers.
BCM2835_REGBASE_SPI0
=
6
,
///< Base of the SPI0 registers.
BCM2835_REGBASE_BSC0
=
7
,
///< Base of the BSC0 registers.
BCM2835_REGBASE_BSC1
=
8
///< Base of the BSC1 registers.
}
bcm2835RegisterBase
;
/// Size of memory page on RPi
/// Size of memory page on RPi
#define BCM2835_PAGE_SIZE (4*1024)
#define BCM2835_PAGE_SIZE (4*1024)
...
@@ -437,24 +477,24 @@ extern volatile uint32_t *bcm2835_bsc1;
...
@@ -437,24 +477,24 @@ extern volatile uint32_t *bcm2835_bsc1;
/// Port function select modes for bcm2835_gpio_fsel()
/// Port function select modes for bcm2835_gpio_fsel()
typedef
enum
typedef
enum
{
{
BCM2835_GPIO_FSEL_INPT
=
0
x
00
,
///< Input
BCM2835_GPIO_FSEL_INPT
=
0
b0
00
,
///< Input
BCM2835_GPIO_FSEL_OUTP
=
0
x
01
,
///< Output
BCM2835_GPIO_FSEL_OUTP
=
0
b0
01
,
///< Output
BCM2835_GPIO_FSEL_ALT0
=
0
x04
,
///< Alternate function 0
BCM2835_GPIO_FSEL_ALT0
=
0
b100
,
///< Alternate function 0
BCM2835_GPIO_FSEL_ALT1
=
0
x05
,
///< Alternate function 1
BCM2835_GPIO_FSEL_ALT1
=
0
b101
,
///< Alternate function 1
BCM2835_GPIO_FSEL_ALT2
=
0
x06
,
///< Alternate function 2
BCM2835_GPIO_FSEL_ALT2
=
0
b110
,
///< Alternate function 2
BCM2835_GPIO_FSEL_ALT3
=
0
x07
,
///< Alternate function 3
BCM2835_GPIO_FSEL_ALT3
=
0
b111
,
///< Alternate function 3
BCM2835_GPIO_FSEL_ALT4
=
0
x03
,
///< Alternate function 4
BCM2835_GPIO_FSEL_ALT4
=
0
b011
,
///< Alternate function 4
BCM2835_GPIO_FSEL_ALT5
=
0
x02
,
///< Alternate function 5
BCM2835_GPIO_FSEL_ALT5
=
0
b010
,
///< Alternate function 5
BCM2835_GPIO_FSEL_MASK
=
0
x07
///< Function select bits mask
BCM2835_GPIO_FSEL_MASK
=
0
b111
///< Function select bits mask
}
bcm2835FunctionSelect
;
}
bcm2835FunctionSelect
;
/// \brief bcm2835PUDControl
/// \brief bcm2835PUDControl
/// Pullup/Pulldown defines for bcm2835_gpio_pud()
/// Pullup/Pulldown defines for bcm2835_gpio_pud()
typedef
enum
typedef
enum
{
{
BCM2835_GPIO_PUD_OFF
=
0
x
00
,
///< Off ? disable pull-up/down
BCM2835_GPIO_PUD_OFF
=
0
b
00
,
///< Off ? disable pull-up/down
BCM2835_GPIO_PUD_DOWN
=
0
x
01
,
///< Enable Pull Down control
BCM2835_GPIO_PUD_DOWN
=
0
b
01
,
///< Enable Pull Down control
BCM2835_GPIO_PUD_UP
=
0
x02
///< Enable Pull Up control
BCM2835_GPIO_PUD_UP
=
0
b10
///< Enable Pull Up control
}
bcm2835PUDControl
;
}
bcm2835PUDControl
;
/// Pad control register offsets from BCM2835_GPIO_PADS
/// Pad control register offsets from BCM2835_GPIO_PADS
...
@@ -494,7 +534,9 @@ typedef enum
...
@@ -494,7 +534,9 @@ typedef enum
/// RPi B+ has yet differnet pinouts and these are defined in RPI_BPLUS_*.
/// RPi B+ has yet differnet pinouts and these are defined in RPI_BPLUS_*.
/// At bootup, pins 8 and 10 are set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
/// At bootup, pins 8 and 10 are set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
/// When SPI0 is in use (ie after bcm2835_spi_begin()), SPI0 pins are dedicated to SPI
/// When SPI0 is in use (ie after bcm2835_spi_begin()), SPI0 pins are dedicated to SPI
/// and cant be controlled independently
/// and cant be controlled independently.
/// If you are using the RPi Compute Module, just use the GPIO number: there is no need to use one of these
/// symbolic names
typedef
enum
typedef
enum
{
{
RPI_GPIO_P1_03
=
0
,
///< Version 1, Pin P1-03
RPI_GPIO_P1_03
=
0
,
///< Version 1, Pin P1-03
...
@@ -629,12 +671,10 @@ typedef enum
...
@@ -629,12 +671,10 @@ typedef enum
/// Specify the SPI chip select pin(s)
/// Specify the SPI chip select pin(s)
typedef
enum
typedef
enum
{
{
// Can also use non-standard pins with this lib
BCM2835_SPI_CS0
=
0
,
///< Chip Select 0
BCM2835_SPI_CS0
=
0
,
///< Chip Select 0
BCM2835_SPI_CS1
=
1
,
///< Chip Select 1
BCM2835_SPI_CS1
=
1
,
///< Chip Select 1
BCM2835_SPI_CS2
=
2
,
///< Chip Select 2 (ie pins CS1 and CS2 are asserted)
BCM2835_SPI_CS2
=
2
,
///< Chip Select 2 (ie pins CS1 and CS2 are asserted)
BCM2835_SPI_CS_NONE
=
3
,
///< No CS, control it yourself
BCM2835_SPI_CS_NONE
=
3
,
///< No CS, control it yourself
}
bcm2835SPIChipSelect
;
}
bcm2835SPIChipSelect
;
/// \brief bcm2835SPIClockDivider
/// \brief bcm2835SPIClockDivider
...
@@ -682,6 +722,7 @@ typedef enum
...
@@ -682,6 +722,7 @@ typedef enum
#define BCM2835_SPI_SPEED_16KHZ BCM2835_SPI_CLOCK_DIVIDER_16384
#define BCM2835_SPI_SPEED_16KHZ BCM2835_SPI_CLOCK_DIVIDER_16384
#define BCM2835_SPI_SPEED_8KHZ BCM2835_SPI_CLOCK_DIVIDER_32768
#define BCM2835_SPI_SPEED_8KHZ BCM2835_SPI_CLOCK_DIVIDER_32768
// Defines for I2C
// Defines for I2C
// GPIO register offsets from BCM2835_BSC*_BASE.
// GPIO register offsets from BCM2835_BSC*_BASE.
// Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map
// Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map
...
@@ -788,7 +829,6 @@ typedef enum
...
@@ -788,7 +829,6 @@ typedef enum
#define BCM2835_PWM0_SERIAL 0x0002 ///< Run in serial mode
#define BCM2835_PWM0_SERIAL 0x0002 ///< Run in serial mode
#define BCM2835_PWM0_ENABLE 0x0001 ///< Channel Enable
#define BCM2835_PWM0_ENABLE 0x0001 ///< Channel Enable
/// \brief bcm2835PWMClockDivider
/// \brief bcm2835PWMClockDivider
/// Specifies the divider used to generate the PWM clock from the system clock.
/// Specifies the divider used to generate the PWM clock from the system clock.
/// Figures below give the divider, clock period and clock frequency.
/// Figures below give the divider, clock period and clock frequency.
...
@@ -796,10 +836,6 @@ typedef enum
...
@@ -796,10 +836,6 @@ typedef enum
/// The frequencies shown for each divider have been confirmed by measurement
/// The frequencies shown for each divider have been confirmed by measurement
typedef
enum
typedef
enum
{
{
BCM2835_PWM_CLOCK_DIVIDER_32768
=
32768
,
///< 32768 = 585Hz
BCM2835_PWM_CLOCK_DIVIDER_16384
=
16384
,
///< 16384 = 1171.8Hz
BCM2835_PWM_CLOCK_DIVIDER_8192
=
8192
,
///< 8192 = 2.34375kHz
BCM2835_PWM_CLOCK_DIVIDER_4096
=
4096
,
///< 4096 = 4.6875kHz
BCM2835_PWM_CLOCK_DIVIDER_2048
=
2048
,
///< 2048 = 9.375kHz
BCM2835_PWM_CLOCK_DIVIDER_2048
=
2048
,
///< 2048 = 9.375kHz
BCM2835_PWM_CLOCK_DIVIDER_1024
=
1024
,
///< 1024 = 18.75kHz
BCM2835_PWM_CLOCK_DIVIDER_1024
=
1024
,
///< 1024 = 18.75kHz
BCM2835_PWM_CLOCK_DIVIDER_512
=
512
,
///< 512 = 37.5kHz
BCM2835_PWM_CLOCK_DIVIDER_512
=
512
,
///< 512 = 37.5kHz
...
@@ -859,13 +895,20 @@ extern "C" {
...
@@ -859,13 +895,20 @@ extern "C" {
///
///
/// @{
/// @{
/// Gets the base of a register
/// \param[in] regbase You can use one of the common values BCM2835_REGBASE_*
/// in \ref bcm2835RegisterBase
/// \return the register base
/// \sa Physical Addresses
extern
uint32_t
*
bcm2835_regbase
(
uint8_t
regbase
);
/// Reads 32 bit value from a peripheral address
/// Reads 32 bit value from a peripheral address
/// The read is done twice, and is therefore always safe in terms of
/// The read is done twice, and is therefore always safe in terms of
/// manual section 1.3 Peripheral access precautions for correct memory ordering
/// manual section 1.3 Peripheral access precautions for correct memory ordering
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
/// \return the value read from the 32 bit register
/// \return the value read from the 32 bit register
/// \sa Physical Addresses
/// \sa Physical Addresses
extern
uint32_t
bcm2835_peri_read
(
volatile
uint32_t
*
paddr
);
extern
uint32_t
bcm2835_peri_read
(
uint32_t
*
paddr
);
/// Reads 32 bit value from a peripheral address without the read barrier
/// Reads 32 bit value from a peripheral address without the read barrier
...
@@ -874,7 +917,7 @@ extern "C" {
...
@@ -874,7 +917,7 @@ extern "C" {
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
/// \return the value read from the 32 bit register
/// \return the value read from the 32 bit register
/// \sa Physical Addresses
/// \sa Physical Addresses
extern
uint32_t
bcm2835_peri_read_nb
(
volatile
uint32_t
*
paddr
);
extern
uint32_t
bcm2835_peri_read_nb
(
uint32_t
*
paddr
);
/// Writes 32 bit value from a peripheral address
/// Writes 32 bit value from a peripheral address
...
@@ -883,7 +926,7 @@ extern "C" {
...
@@ -883,7 +926,7 @@ extern "C" {
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
/// \param[in] value The 32 bit value to write
/// \param[in] value The 32 bit value to write
/// \sa Physical Addresses
/// \sa Physical Addresses
extern
void
bcm2835_peri_write
(
volatile
uint32_t
*
paddr
,
uint32_t
value
);
extern
void
bcm2835_peri_write
(
uint32_t
*
paddr
,
uint32_t
value
);
/// Writes 32 bit value from a peripheral address without the write barrier
/// Writes 32 bit value from a peripheral address without the write barrier
/// You should only use this when your code has previously called bcm2835_peri_write()
/// You should only use this when your code has previously called bcm2835_peri_write()
...
@@ -891,7 +934,7 @@ extern "C" {
...
@@ -891,7 +934,7 @@ extern "C" {
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
/// \param[in] value The 32 bit value to write
/// \param[in] value The 32 bit value to write
/// \sa Physical Addresses
/// \sa Physical Addresses
extern
void
bcm2835_peri_write_nb
(
volatile
uint32_t
*
paddr
,
uint32_t
value
);
extern
void
bcm2835_peri_write_nb
(
uint32_t
*
paddr
,
uint32_t
value
);
/// Alters a number of bits in a 32 peripheral regsiter.
/// Alters a number of bits in a 32 peripheral regsiter.
/// It reads the current valu and then alters the bits deines as 1 in mask,
/// It reads the current valu and then alters the bits deines as 1 in mask,
...
@@ -904,7 +947,7 @@ extern "C" {
...
@@ -904,7 +947,7 @@ extern "C" {
/// \param[in] value The 32 bit value to write, masked in by mask.
/// \param[in] value The 32 bit value to write, masked in by mask.
/// \param[in] mask Bitmask that defines the bits that will be altered in the register.
/// \param[in] mask Bitmask that defines the bits that will be altered in the register.
/// \sa Physical Addresses
/// \sa Physical Addresses
extern
void
bcm2835_peri_set_bits
(
volatile
uint32_t
*
paddr
,
uint32_t
value
,
uint32_t
mask
);
extern
void
bcm2835_peri_set_bits
(
uint32_t
*
paddr
,
uint32_t
value
,
uint32_t
mask
);
/// @} // end of lowlevel
/// @} // end of lowlevel
/// \defgroup gpio GPIO register access
/// \defgroup gpio GPIO register access
...
@@ -1117,25 +1160,16 @@ extern "C" {
...
@@ -1117,25 +1160,16 @@ extern "C" {
/// Start SPI operations.
/// Start SPI operations.
/// Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
/// Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
/// to alternate function ALT0, which enables those pins for SPI interface.
/// to alternate function ALT0, which enables those pins for SPI interface.
/// \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave.
/// One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
/// or one of One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
/// by default PI hardware driven using CE0
/// You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to
/// You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to
/// their default functions
/// their default functions
/// \sa bcm2835_spi_end()
/// \sa bcm2835_spi_end()
extern
void
bcm2835_spi_begin
();
extern
void
bcm2835_spi_begin
(
void
);
/// End SPI operations.
/// End SPI operations.
/// SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
/// SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
/// are returned to their default INPUT behaviour.
/// are returned to their default INPUT behaviour.
extern
void
bcm2835_spi_end
(
void
);
extern
void
bcm2835_spi_end
(
void
);
/// Sets the SPI custom Chip Select pin to correct level
/// Defaults to
/// \param[in] level The desired level, LOW or HIGH,
extern
void
bcm2835_spi_setChipSelect
(
uint8_t
level
);
/// Sets the SPI bit order
/// Sets the SPI bit order
/// NOTE: has no effect. Not supported by SPI0.
/// NOTE: has no effect. Not supported by SPI0.
/// Defaults to
/// Defaults to
...
@@ -1160,7 +1194,6 @@ extern "C" {
...
@@ -1160,7 +1194,6 @@ extern "C" {
/// transfer.
/// transfer.
/// \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave.
/// \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave.
/// One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
/// One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
/// or one of One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
extern
void
bcm2835_spi_chipSelect
(
uint8_t
cs
);
extern
void
bcm2835_spi_chipSelect
(
uint8_t
cs
);
/// Sets the chip select pin polarity for a given pin
/// Sets the chip select pin polarity for a given pin
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment