Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/driver/frankencnc.hal
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,11 @@ net spindle-at-speed spindle.0.at-speed <= rp2040_eth.0.spindle.0.at-speed
# GPIO
setp rp2040_eth.0.gpio.00.type [RP2040_ETH_GPIO_TYPES]GPIO_TYPE_NATIVE_OUT_DEBUG
setp rp2040_eth.0.gpio.00.index 6
setp rp2040_eth.0.gpio.00.out 1
setp rp2040_eth.0.gpio.00.out-invert false
setp rp2040_eth.0.gpio.00.in 0

setp rp2040_eth.0.gpio.01.type [RP2040_ETH_GPIO_TYPES]GPIO_TYPE_NATIVE_OUT_DEBUG
setp rp2040_eth.0.gpio.01.index 7
setp rp2040_eth.0.gpio.01.out 1
setp rp2040_eth.0.gpio.01.out-invert true
setp rp2040_eth.0.gpio.01.in 0

setp rp2040_eth.0.gpio.02.type [RP2040_ETH_GPIO_TYPES]GPIO_TYPE_NATIVE_IN_DEBUG
setp rp2040_eth.0.gpio.02.index 8
Expand Down
1 change: 1 addition & 0 deletions src/driver/rp2040_gpio_types.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ GPIO_TYPE_NATIVE_OUT_DEBUG = 3
GPIO_TYPE_NATIVE_IN_DEBUG = 4
GPIO_TYPE_I2C_MCP_OUT = 5
GPIO_TYPE_I2C_MCP_IN = 6
GPIO_TYPE_I2C_MCP_IN_PULLUP = 7

6 changes: 4 additions & 2 deletions src/driver/rp2040_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ uint16_t serialize_gpio(struct NWBuffer* buffer, skeleton_t* data) {
case GPIO_TYPE_NATIVE_IN_DEBUG:
case GPIO_TYPE_NATIVE_IN:
case GPIO_TYPE_I2C_MCP_IN:
case GPIO_TYPE_I2C_MCP_IN_PULLUP:
current_value = *data->gpio_data_in[gpio];
break;
case GPIO_TYPE_NATIVE_OUT:
Expand All @@ -266,10 +267,11 @@ uint16_t serialize_gpio(struct NWBuffer* buffer, skeleton_t* data) {
if(current_value != received_value) {
switch(*data->gpio_type[gpio]) {
case GPIO_TYPE_NATIVE_IN_DEBUG:
printf("DBG: GPIO IN: %u val: %u\n", gpio, current_value);
printf("DBG: GPIO OUT: %u val: %u\n", gpio, current_value);
// Note: no break here.
case GPIO_TYPE_NATIVE_IN:
case GPIO_TYPE_I2C_MCP_IN:
case GPIO_TYPE_I2C_MCP_IN_PULLUP:
// Network update to apply.
*data->gpio_data_in[gpio] = received_value;
*data->gpio_data_in_not[gpio] = !received_value;
Expand All @@ -278,7 +280,7 @@ uint16_t serialize_gpio(struct NWBuffer* buffer, skeleton_t* data) {
confirmation_pending[bank] = true;
break;
case GPIO_TYPE_NATIVE_OUT_DEBUG:
printf("DBG: GPIO OUT: %u val: %u\n", gpio, current_value);
printf("DBG: GPIO IN: %u val: %u\n", gpio, current_value);
// Note: no break here.
case GPIO_TYPE_NATIVE_OUT:
case GPIO_TYPE_I2C_MCP_OUT:
Expand Down
3 changes: 3 additions & 0 deletions src/rp2040/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ target_sources(
network.c
core0.c
core1.c
i2c.c
mcp23017.c
modbus.c
modbus_fuling.c
modbus_huanyang.c
Expand All @@ -44,6 +46,7 @@ target_link_libraries(
hardware_spi
hardware_dma
hardware_pio
hardware_i2c
ETHERNET_FILES
IOLIBRARY_FILES
LOOPBACK_FILES
Expand Down
21 changes: 16 additions & 5 deletions src/rp2040/core0.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "messages.h"
#include "buffer.h"
#include "gpio.h"
#include "i2c.h"
#include "modbus.h"


Expand Down Expand Up @@ -306,12 +307,12 @@ bool unpack_gpio_config(
uint8_t index = message->index;
uint8_t address = message->address;

printf("Configuring gpio. type: %u\tindex: %u\taddress: %u\tcount: %u\n",
gpio_type, index, address, gpio_count);
printf("%u Configuring gpio: %u\t%u\n", *received_count, gpio_type, gpio_count);

config.gpio[gpio_count].type = gpio_type;
config.gpio[gpio_count].index = index;
config.gpio[gpio_count].address = address;
volatile struct ConfigGPIO *cfg = &config.gpio[gpio_count];
cfg->type = gpio_type;
cfg->index = index;
cfg->address = address;

switch(gpio_type) {
case GPIO_TYPE_NATIVE_OUT:
Expand All @@ -331,6 +332,16 @@ bool unpack_gpio_config(
gpio_set_dir(index, GPIO_IN);
gpio_pull_up(index);
break;
case GPIO_TYPE_I2C_MCP_OUT:
case GPIO_TYPE_I2C_MCP_IN:
case GPIO_TYPE_I2C_MCP_IN_PULLUP:
{
int i2c = gpio_i2c_mcp_alloc(address);
if (i2c >= 0) {
i2c_gpio_set_pin_config(&i2c_gpio, i2c, index, gpio_type);
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
} else {
printf("Error ...");
}

break;
}
default:
break;
}
Expand Down
5 changes: 5 additions & 0 deletions src/rp2040/core1.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@

#include "core1.h"
#include "config.h"
#include "i2c.h"
#include "pio.h"

struct i2c_gpio_state i2c_gpio;

void update_all_joint() {
static uint32_t metric = 0;
Expand All @@ -34,6 +36,7 @@ void update_all_joint() {
if(dt > update_period_us * MAX_MISSED_PACKET) {
break;
}
i2c_gpio_poll(&i2c_gpio);
}
if(tick == last_tick) {
// Didn't receive tick semaphore.
Expand Down Expand Up @@ -68,6 +71,7 @@ void update_all_joint() {
for(uint8_t joint = 0; joint < MAX_JOINT; joint++) {
do_steps(joint, update_period_us);
}
i2c_gpio_poll(&i2c_gpio);
}

void core1_main() {
Expand All @@ -78,6 +82,7 @@ void core1_main() {

void init_core1() {
printf("core0: Initializing.\n");
i2c_gpio_init(&i2c_gpio);

if(MAX_JOINT > 4) {
printf("ERROR: Maximum joint count: 4. Configured: %u\n", MAX_JOINT);
Expand Down
119 changes: 57 additions & 62 deletions src/rp2040/gpio.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include <stdio.h>
#include <string.h>

#include "gpio.h"
#include "config.h"
#include "gpio.h"
#include "i2c.h"
#include "messages.h"

#ifdef BUILD_TESTS
Expand All @@ -19,6 +20,7 @@
//uint32_t gpio_i2c_mcp_indexes[MAX_I2C_MCP] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
uint32_t gpio_i2c_mcp_indexes[MAX_I2C_MCP] = {0, 0, 0, 0};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gpio_i2c_mcp_indexes not used any more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used, by gpio_i2c_mcp_alloc.

uint8_t gpio_i2c_mcp_addresses[MAX_I2C_MCP] = {0xff, 0xff, 0xff, 0xff};
uint8_t gpio_last_type[32 * MAX_I2C_MCP];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see this being set but never used.


void update_gpio_config(
const uint8_t gpio,
Expand All @@ -32,22 +34,23 @@ void update_gpio_config(
printf("ERROR: Higher than MAX_GPIO requested. %u\n", gpio);
return;
}
volatile struct ConfigGPIO *cfg = &config.gpio[gpio];

if(type != NULL) {
config.gpio[gpio].type = *type;
cfg->type = *type;
}
if(index != NULL) {
if(*index > 32) {
printf("WARN: GPIO index out of range. Add: %u Index: %u\n", *address, *index);
} else {
config.gpio[gpio].index = *index;
cfg->index = *index;
}
}
if(address != NULL) {
config.gpio[gpio].address = *address;
cfg->address = *address;
}
if(value != NULL) {
config.gpio[gpio].value = *value;
cfg->value = *value;
}
}

Expand Down Expand Up @@ -97,7 +100,7 @@ void gpio_set_values(const uint8_t bank, uint32_t values) {

switch(config.gpio[gpio].type) {
case GPIO_TYPE_NATIVE_OUT_DEBUG:
printf("DBG GPIO OUT: %u IO: %u val: %u\n", gpio, index, new_value);
printf("DBG GPIO: %u IO: %u val: %u\n", gpio, index, new_value);
// Note: no break.
case GPIO_TYPE_NATIVE_OUT:
gpio_local_set_out_pin(index, new_value);
Expand All @@ -108,6 +111,7 @@ void gpio_set_values(const uint8_t bank, uint32_t values) {
default:
break;
}
gpio_last_type[gpio] = type;

update_gpio_config(gpio, NULL, NULL, NULL, &new_value);
}
Expand All @@ -122,68 +126,57 @@ bool gpio_local_get_pin(uint32_t index) {
return gpio_get(index);
}

/* Happens before iterating through gpio data.
* Do any i2c required operations here. */
void gpio_i2c_mcp_prepare() {
for(uint8_t i2c_bucket = 0; i2c_bucket < MAX_I2C_MCP; i2c_bucket++) {
// uint8_t i2c_address = gpio_i2c_mcp_addresses[i2c_bucket];
// TODO: Any other MCP implementation here.
int gpio_i2c_mcp_alloc(uint8_t address) {
int i2c = 0, i2c_free = -1;
for(i2c = 0; i2c < MAX_I2C_MCP; i2c++) {
if(gpio_i2c_mcp_addresses[i2c] == address) {
return i2c;
}
if(gpio_i2c_mcp_addresses[i2c] == 0xFF && i2c_free == -1) {
i2c_free = i2c;
}
}
if (i2c_free != -1) {
gpio_i2c_mcp_addresses[i2c_free] = address;
i2c_gpio.config[i2c_free].i2c_address = address;
i2c_gpio.config[i2c_free].type = I2CGPIO_TYPE_MCP23017;
}
return i2c_free;
}

/* Find all GPIO pins sharing the same i2c address and put
*/
void gpio_i2c_mcp_set_out_pin(uint8_t index, uint8_t address, bool new_value) {
// Find which slot this i2c address is being stored in.
uint8_t i2c = MAX_I2C_MCP;
for(i2c = 0; i2c < MAX_I2C_MCP; i2c++) {
if(gpio_i2c_mcp_addresses[i2c] == address) {
break;
}
if (gpio_i2c_mcp_addresses[i2c] == 0xff) {
// Haven't found this address yet.
// Since this buffer slot is empty, use it for this address.
gpio_i2c_mcp_addresses[i2c] = address;
break;
}
}
int i2c = gpio_i2c_mcp_alloc(address);

if(i2c >= MAX_I2C_MCP) {
if(i2c == -1) {
printf("WARN: Too may i2c addresses. Add: %u Index: %u\n", address, index);
return;
}

// Add new_value to buffer to be sent to this i2c address.
uint8_t bindex = (index >> 3) & 1;
uint8_t bitmask = 0x1 << (index & 7);
uint8_t *data = &i2c_gpio.config[i2c].output_data[bindex];
if(new_value) {
gpio_i2c_mcp_indexes[i2c] |= (0x1 << index);
*data |= bitmask;
} else {
gpio_i2c_mcp_indexes[i2c] &= (~(0x1 << index));
*data &= ~bitmask;
}
}

/* Happens after iterating through GPIO data.
* Do any i2c required operations here. */
void gpio_i2c_mcp_tranceive() {
for(uint8_t i2c_bucket = 0; i2c_bucket < MAX_I2C_MCP; i2c_bucket++) {
// Write gpio_i2c_mcp_indexes[i2c] as output
// then read inputs into same buffer.
uint8_t values = gpio_i2c_mcp_indexes[i2c_bucket];
uint8_t address = gpio_i2c_mcp_addresses[i2c_bucket];
// TODO: Send values to the i2c connected MCP.
printf("i2c addr: %u values: %#04x\n", address, values);

// TODO: Read i2c data into gpio_i2c_mcp_indexes[MAX_I2C_MCP] for later
// UDP transmission.
}
}

bool gpio_i2c_mcp_get_pin(uint8_t index, uint8_t address) {
for(uint8_t i2c = 0; i2c < MAX_I2C_MCP; i2c++) {
if(gpio_i2c_mcp_addresses[i2c] == address) {
return gpio_i2c_mcp_indexes[i2c] | (0x1 << index);
}
bool gpio_i2c_mcp_get_pin(uint8_t index, uint8_t address, uint8_t pullup) {
int i2c = gpio_i2c_mcp_alloc(address);
if(i2c == -1) {
printf("WARN: Too may i2c addresses. Add: %u Index: %u\n", address, index);
return false;
}
return 0;
uint8_t bindex = (index >> 3) & 1;
uint8_t bmask = (1 << (index & 7));
uint8_t data = i2c_gpio.config[i2c].input_data[bindex];
//printf("%02x:%d = %d [%02x, %02x]\n", address, index, (data & bmask), data, bmask);
return data & bmask ? 1 : 0;
}

/* Pack GPIO inputs in buffer for UDP transmission. */
Expand All @@ -209,7 +202,7 @@ void gpio_serialize(struct NWBuffer* tx_buf, size_t* tx_buf_len) {

get_gpio_config(gpio, &type, &index, &address, &previous_value);

switch(config.gpio[gpio].type) {
switch(type) {
case GPIO_TYPE_NATIVE_IN_DEBUG:
case GPIO_TYPE_NATIVE_IN:
new_value = gpio_local_get_pin(index);
Expand All @@ -221,7 +214,8 @@ void gpio_serialize(struct NWBuffer* tx_buf, size_t* tx_buf_len) {
}
break;
case GPIO_TYPE_I2C_MCP_IN:
new_value = gpio_i2c_mcp_get_pin(index, address);
case GPIO_TYPE_I2C_MCP_IN_PULLUP:
new_value = gpio_i2c_mcp_get_pin(index, address, type == GPIO_TYPE_I2C_MCP_IN_PULLUP);
if(previous_value != new_value) {
to_send[bank] = true;
config.gpio_confirmation_pending[bank] = true;
Expand All @@ -234,6 +228,7 @@ void gpio_serialize(struct NWBuffer* tx_buf, size_t* tx_buf_len) {
new_value = previous_value;
break;
}
gpio_last_type[gpio] = type;

values[bank] |= (new_value << (gpio % 32));
}
Expand All @@ -242,20 +237,20 @@ void gpio_serialize(struct NWBuffer* tx_buf, size_t* tx_buf_len) {
reply.type = REPLY_GPIO;

for(uint8_t bank = 0; bank < MAX_GPIO_BANK; bank++) {
if(! config.gpio_confirmation_pending[bank]) {
continue;
}
if(! config.gpio_confirmation_pending[bank]) {
continue;
}

reply.bank = bank;
reply.values = values[bank];
reply.confirmation_pending = to_send[bank];
reply.bank = bank;
reply.values = values[bank];
reply.confirmation_pending = to_send[bank];

*tx_buf_len = pack_nw_buff(tx_buf, &reply, sizeof(reply));
*tx_buf_len = pack_nw_buff(tx_buf, &reply, sizeof(reply));

if(! *tx_buf_len) {
printf("WARN: TX length greater than buffer size. gpio bank: %u\n", bank);
return;
}
if(! *tx_buf_len) {
printf("WARN: TX length greater than buffer size. gpio bank: %u\n", bank);
return;
}
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/rp2040/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ void gpio_set_values(const uint8_t bank, uint32_t values);

void gpio_local_set_out_pin(uint8_t index, bool new_value);

/* Happens before gpio data destined for i2c has been gathered. */
void gpio_i2c_mcp_prepare();

/* Put i2c data in temporary buffer pending gpio_i2c_mcp_tranceive() being called. */
void gpio_i2c_mcp_set_out_pin(uint8_t index, uint8_t address, bool new_value);

/* Happens after all gpio data destined for i2c has been gathered. */
void gpio_i2c_mcp_tranceive();
/* Convert I2C address to the slot number */
int gpio_i2c_mcp_alloc(uint8_t address);

/* Pack GPIO inputs in buffer for UDP transmission. */
void gpio_serialize(struct NWBuffer* tx_buf, size_t* tx_buf_len);
Expand Down
1 change: 1 addition & 0 deletions src/shared/messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,5 +210,6 @@ union ReplyAny {
#define GPIO_TYPE_NATIVE_IN_DEBUG 4
#define GPIO_TYPE_I2C_MCP_OUT 5
#define GPIO_TYPE_I2C_MCP_IN 6
#define GPIO_TYPE_I2C_MCP_IN_PULLUP 7

#endif // UPDATE_TYPES__H