Skip to content

Commit 1ae2a21

Browse files
committed
Initial i2ctaret commit
1 parent fa3e265 commit 1ae2a21

File tree

4 files changed

+203
-1
lines changed

4 files changed

+203
-1
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2022 Mark Komus, Ken Stillson, im-redactd
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "shared-bindings/i2ctarget/I2CTarget.h"
28+
29+
#include "common-hal/busio/I2C.h"
30+
31+
#include "py/mperrno.h"
32+
#include "py/mphal.h"
33+
#include "shared-bindings/busio/I2C.h"
34+
#include "py/runtime.h"
35+
36+
#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
37+
38+
STATIC i2c_inst_t *i2c[2] = {i2c0, i2c1};
39+
40+
#define NO_PIN 0xff
41+
42+
void common_hal_i2ctarget_i2c_target_construct(i2ctarget_i2c_target_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda,
43+
uint8_t *addresses, unsigned int num_addresses, bool smbus) {
44+
self->peripheral = NULL;
45+
46+
// I2C pins have a regular pattern. SCL is always odd and SDA is even. They match up in pairs
47+
// so we can divide by two to get the instance. This pattern repeats.
48+
size_t scl_instance = (scl->number / 2) % 2;
49+
size_t sda_instance = (sda->number / 2) % 2;
50+
if (scl->number % 2 == 1 && sda->number % 2 == 0 && scl_instance == sda_instance) {
51+
self->peripheral = i2c[sda_instance];
52+
}
53+
54+
if (self->peripheral == NULL) {
55+
raise_ValueError_invalid_pins();
56+
}
57+
58+
if ((i2c_get_hw(self->peripheral)->enable & I2C_IC_ENABLE_ENABLE_BITS) != 0) {
59+
mp_raise_ValueError(translate("I2C peripheral in use"));
60+
}
61+
62+
if (num_addresses > 1) {
63+
mp_raise_ValueError(translate("Only one address is allowed"));
64+
}
65+
66+
self->addresses = addresses;
67+
self->num_addresses = num_addresses;
68+
self->scl_pin = scl->number;
69+
self->sda_pin = sda->number;
70+
71+
// Have to specify a baudrate even if the i2c target does not use it
72+
const uint32_t frequency = 400000;
73+
i2c_init(self->peripheral, frequency);
74+
75+
gpio_set_function(sda->number, GPIO_FUNC_I2C);
76+
gpio_set_function(scl->number, GPIO_FUNC_I2C);
77+
78+
gpio_set_pulls(sda->number, true, false);
79+
gpio_set_pulls(scl->number, true, false);
80+
81+
self->peripheral->hw->intr_mask |= I2C_IC_INTR_MASK_M_RESTART_DET_BITS;
82+
i2c_set_slave_mode(self->peripheral, true, self->addresses[0]);
83+
84+
return;
85+
}
86+
87+
bool common_hal_i2ctarget_i2c_target_deinited(i2ctarget_i2c_target_obj_t *self) {
88+
return self->sda_pin == NO_PIN;
89+
}
90+
91+
void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self) {
92+
if (common_hal_i2ctarget_i2c_target_deinited(self)) {
93+
return;
94+
}
95+
96+
i2c_deinit(self->peripheral);
97+
98+
reset_pin_number(self->sda_pin);
99+
reset_pin_number(self->scl_pin);
100+
self->sda_pin = NO_PIN;
101+
self->scl_pin = NO_PIN;
102+
103+
return;
104+
}
105+
106+
static int i2c_peripheral_check_error(i2ctarget_i2c_target_obj_t *self, bool raise) {
107+
return 0;
108+
}
109+
110+
int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) {
111+
if (!((self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS) || (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RD_REQ_BITS))) {
112+
return 0;
113+
}
114+
115+
*address = self->peripheral->hw->sar;
116+
*is_read = !(self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS);
117+
*is_restart = ((self->peripheral->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_RD_REQ_RESET) != 0);
118+
119+
common_hal_i2ctarget_i2c_target_ack(self, true);
120+
return 1;
121+
}
122+
123+
int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) {
124+
if (self->peripheral->hw->status & I2C_IC_STATUS_RFNE_BITS) {
125+
*data = (uint8_t)self->peripheral->hw->data_cmd;
126+
return 1;
127+
} else {
128+
return 0;
129+
}
130+
}
131+
132+
int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) {
133+
if (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_TX_ABRT_BITS) {
134+
self->peripheral->hw->clr_tx_abrt;
135+
}
136+
137+
const size_t IC_TX_BUFFER_DEPTH = 16;
138+
size_t space = IC_TX_BUFFER_DEPTH - self->peripheral->hw->txflr;
139+
140+
if (space > 0) {
141+
self->peripheral->hw->data_cmd = data;
142+
self->peripheral->hw->clr_rd_req;
143+
return 1;
144+
} else {
145+
return 0;
146+
}
147+
}
148+
149+
void common_hal_i2ctarget_i2c_target_ack(i2ctarget_i2c_target_obj_t *self, bool ack) {
150+
return;
151+
}
152+
153+
void common_hal_i2ctarget_i2c_target_close(i2ctarget_i2c_target_obj_t *self) {
154+
return;
155+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2022 Mark Komus, Ken Stillson, im-redactd
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_RPI_COMMON_HAL_I2C_TARGET_H
28+
#define MICROPY_INCLUDED_RPI_COMMON_HAL_I2C_TARGET_H
29+
30+
#include "py/obj.h"
31+
#include "common-hal/microcontroller/Pin.h"
32+
#include "src/rp2_common/hardware_i2c/include/hardware/i2c.h"
33+
34+
typedef struct {
35+
mp_obj_base_t base;
36+
37+
uint8_t *addresses;
38+
unsigned int num_addresses;
39+
40+
i2c_inst_t *peripheral;
41+
42+
uint8_t scl_pin;
43+
uint8_t sda_pin;
44+
} i2ctarget_i2c_target_obj_t;
45+
46+
#endif MICROPY_INCLUDED_RPI_COMMON_HAL_BUSIO_I2C_TARGET_H
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// No i2ctarget module functions.

ports/raspberrypi/mpconfigport.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ CIRCUITPY_ROTARYIO_SOFTENCODER = 1
2020
# Things that need to be implemented.
2121
# Use PWM interally
2222
CIRCUITPY_FREQUENCYIO = 0
23-
CIRCUITPY_I2CTARGET = 0
23+
CIRCUITPY_I2CTARGET = 1
2424
CIRCUITPY_NVM = 1
2525
# Use PIO interally
2626
CIRCUITPY_PULSEIO ?= 1

0 commit comments

Comments
 (0)