Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
arduino-pico
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
arduino-pico
Commits
73336ddd
Commit
73336ddd
authored
Mar 27, 2021
by
Earle F. Philhower, III
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add I2C slave support and include a simple example
Also fix the initial pins for the 2nd I2C interface onboard.
parent
09ec5e0d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
138 additions
and
9 deletions
+138
-9
libraries/Wire/Wire.cpp
libraries/Wire/Wire.cpp
+69
-9
libraries/Wire/Wire.h
libraries/Wire/Wire.h
+5
-0
libraries/Wire/examples/TalkingToMyself/TalkingToMyself.ino
libraries/Wire/examples/TalkingToMyself/TalkingToMyself.ino
+64
-0
No files found.
libraries/Wire/Wire.cpp
View file @
73336ddd
...
...
@@ -24,6 +24,8 @@
#include <Arduino.h>
#include <hardware/gpio.h>
#include <hardware/i2c.h>
#include <hardware/irq.h>
#include <hardware/regs/intctrl.h>
#include "Wire.h"
TwoWire
::
TwoWire
(
i2c_inst_t
*
i2c
,
pin_size_t
sda
,
pin_size_t
scl
)
{
...
...
@@ -85,11 +87,16 @@ void TwoWire::begin() {
_buffLen
=
0
;
}
static
void
_handler0
()
{
Wire
.
onIRQ
();
}
static
void
_handler1
()
{
Wire1
.
onIRQ
();
}
// Slave mode
void
TwoWire
::
begin
(
uint8_t
addr
)
{
// Slave mode isn't documented in the SDK, need to twiddle raw registers
// and use bare interrupts. TODO to implement, for now.
#if 0
if
(
_running
)
{
// ERROR
return
;
...
...
@@ -97,11 +104,54 @@ void TwoWire::begin(uint8_t addr) {
_slave
=
true
;
i2c_init
(
_i2c
,
_clkHz
);
i2c_set_slave_mode
(
_i2c
,
true
,
addr
);
// Our callback IRQ
_i2c
->
hw
->
intr_mask
=
(
1
<<
10
)
|
(
1
<<
9
)
|
(
1
<<
5
)
|
(
1
<<
2
);
int
irqNo
=
I2C0_IRQ
+
i2c_hw_index
(
_i2c
);
irq_set_exclusive_handler
(
irqNo
,
i2c_hw_index
(
_i2c
)
==
0
?
_handler0
:
_handler1
);
irq_set_enabled
(
irqNo
,
true
);
gpio_set_function
(
_sda
,
GPIO_FUNC_I2C
);
gpio_pull_up
(
_sda
);
gpio_set_function
(
_scl
,
GPIO_FUNC_I2C
);
gpio_pull_up
(
_scl
);
#endif
_running
=
true
;
}
void
TwoWire
::
onIRQ
()
{
if
(
_i2c
->
hw
->
intr_stat
&
(
1
<<
10
))
{
_buffLen
=
0
;
_buffOff
=
0
;
_slaveStartDet
=
true
;
_i2c
->
hw
->
clr_start_det
;
}
if
(
_i2c
->
hw
->
intr_stat
&
(
1
<<
9
))
{
if
(
_onReceiveCallback
)
{
_onReceiveCallback
(
_buffLen
);
}
_buffLen
=
0
;
_buffOff
=
0
;
_slaveStartDet
=
false
;
_i2c
->
hw
->
clr_stop_det
;
}
if
(
_i2c
->
hw
->
intr_stat
&
(
1
<<
5
))
{
// RD_REQ
if
(
_onRequestCallback
)
{
_onRequestCallback
();
}
_i2c
->
hw
->
clr_rd_req
;
}
if
(
_i2c
->
hw
->
intr_stat
&
(
1
<<
2
))
{
// RX_FULL
if
(
_slaveStartDet
&&
(
_buffLen
<
sizeof
(
_buff
)))
{
_buff
[
_buffLen
++
]
=
_i2c
->
hw
->
data_cmd
&
0xff
;
}
else
{
_i2c
->
hw
->
data_cmd
;
}
}
}
void
TwoWire
::
end
()
{
...
...
@@ -161,11 +211,22 @@ uint8_t TwoWire::endTransmission() {
}
size_t
TwoWire
::
write
(
uint8_t
ucData
)
{
if
(
!
_running
||
!
_txBegun
||
(
_buffLen
==
sizeof
(
_buff
))
)
{
if
(
!
_running
)
{
return
0
;
}
_buff
[
_buffLen
++
]
=
ucData
;
return
1
;
if
(
_slave
)
{
// Wait for a spot in the TX FIFO
while
(
0
==
_i2c
->
hw
->
status
&
(
1
<<
1
))
{
/* noop wait */
}
_i2c
->
hw
->
data_cmd
=
ucData
;
return
1
;
}
else
{
if
(
!
_txBegun
||
(
_buffLen
==
sizeof
(
_buff
)))
{
return
0
;
}
_buff
[
_buffLen
++
]
=
ucData
;
return
1
;
}
}
size_t
TwoWire
::
write
(
const
uint8_t
*
data
,
size_t
quantity
)
{
...
...
@@ -213,5 +274,4 @@ void TwoWire::onRequest(void(*function)(void))
}
TwoWire
Wire
(
i2c0
,
0
,
1
);
TwoWire
Wire1
(
i2c1
,
4
,
5
);
TwoWire
Wire1
(
i2c1
,
2
,
3
);
libraries/Wire/Wire.h
View file @
73336ddd
...
...
@@ -75,6 +75,9 @@ public:
inline
size_t
write
(
int
n
)
{
return
write
((
uint8_t
)
n
);
}
using
Print
::
write
;
// IRQ callback
void
onIRQ
();
private:
i2c_inst_t
*
_i2c
;
pin_size_t
_sda
;
...
...
@@ -94,6 +97,8 @@ private:
void
(
*
_onRequestCallback
)(
void
);
void
(
*
_onReceiveCallback
)(
int
);
bool
_slaveStartDet
=
false
;
// TWI clock frequency
static
const
uint32_t
TWI_CLOCK
=
100000
;
};
...
...
libraries/Wire/examples/TalkingToMyself/TalkingToMyself.ino
0 → 100644
View file @
73336ddd
// Simple I2C master and slave demo - Earle F. Philhower, III
// Released into the public domain
//
// Using both onboard I2C interfaces, have one master and one slave
// and send data both ways between them
//
// To run, connect GPIO0 to GPIO2, GPIO1 to GPIO3 on a single Pico
#include <Wire.h>
void
setup
()
{
Serial
.
begin
(
115200
);
delay
(
5000
);
Wire
.
begin
();
Wire1
.
begin
(
0x30
);
Wire1
.
onReceive
(
recv
);
Wire1
.
onRequest
(
req
);
}
static
char
buff
[
100
];
void
loop
()
{
static
int
p
;
char
b
[
90
];
// Write a value over I2C to the slave
Serial
.
println
(
"Sending..."
);
Wire
.
beginTransmission
(
0x30
);
sprintf
(
b
,
"pass %d"
,
p
++
);
Wire
.
write
(
b
,
strlen
(
b
));
Wire
.
endTransmission
();
// Ensure the slave processing is done and print it out
delay
(
1000
);
Serial
.
printf
(
"buff: '%s'
\r\n
"
,
buff
);
// Read from the slave and print out
Wire
.
requestFrom
(
0x30
,
6
);
Serial
.
print
(
"
\n
recv: '"
);
while
(
Wire
.
available
())
{
Serial
.
print
((
char
)
Wire
.
read
());
}
Serial
.
println
(
"'"
);
delay
(
1000
);
}
// These are called in an **INTERRUPT CONTEXT** which means NO serial port
// access (i.e. Serial.print is illegal) and no memory allocations, etc.
// Called when the I2C slave gets written to
void
recv
(
int
len
)
{
int
i
;
// Just stuff the sent bytes into a global the main routine can pick up and use
for
(
i
=
0
;
i
<
len
;
i
++
)
buff
[
i
]
=
Wire1
.
read
();
buff
[
i
]
=
0
;
}
// Called when the I2C slave is read from
void
req
()
{
static
int
ctr
=
765
;
char
buff
[
7
];
// Return a simple incrementing hex value
sprintf
(
buff
,
"%06X"
,
(
ctr
++
)
%
65535
);
Wire1
.
write
(
buff
,
6
);
}
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