Skip to content

Commit

Permalink
Updated for the changed ioports/crossbar interfaces.
Browse files Browse the repository at this point in the history
Added NeoPixel driver for the new HAL RGB API. Untested.
  • Loading branch information
terjeio committed Jan 19, 2024
1 parent 53468bb commit 3111cbc
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 35 deletions.
84 changes: 72 additions & 12 deletions driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
Part of grblHAL
Copyright (c) 2021-2024 Terje Io
Copyright (c) 2021 Volksolive
Copyright (c) 2021-2024 Terje Io
Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -44,6 +44,7 @@
#include "driver.h"
#include "serial.h"
#include "driverPIO.pio.h"
#include "ws2812.pio.h"

#include "grbl/crossbar.h"
#include "grbl/machine_limits.h"
Expand Down Expand Up @@ -132,6 +133,17 @@ static uint c_step_sm;
#endif
#endif

#ifdef NEOPIXELS_PIN

#ifndef NEOPIXELS_NUM
#define NEOPIXELS_NUM 1
#endif

static PIO neop_pio;
static uint neop_sm;

#endif

typedef union
{
uint32_t value;
Expand Down Expand Up @@ -1094,7 +1106,7 @@ static void limitsEnable (bool on, axes_signals_t homing_cycle)
pin = xbar_fn_to_axismask(limit_inputs.pins.inputs[i].id);
disable = limit_inputs.pins.inputs[i].group == PinGroup_Limit ? (pin.mask & homing_source.min.mask) : (pin.mask & homing_source.max.mask);
}
pinEnableIRQ(&limit_inputs.pins.inputs[i], disable ? IRQ_Mode_None : limit_inputs.pins.inputs[i].irq_mode);
pinEnableIRQ(&limit_inputs.pins.inputs[i], disable ? IRQ_Mode_None : limit_inputs.pins.inputs[i].mode.irq_mode);
} while (i);

#if TRINAMIC_ENABLE
Expand Down Expand Up @@ -1651,15 +1663,15 @@ static void mpg_select (sys_state_t state)
{
stream_mpg_enable(DIGITAL_IN(mpg_pin->bit) == 0);

pinEnableIRQ(mpg_pin, (mpg_pin->irq_mode = sys.mpg_mode ? IRQ_Mode_Rising : IRQ_Mode_Falling));
pinEnableIRQ(mpg_pin, (mpg_pin->mode.irq_mode = sys.mpg_mode ? IRQ_Mode_Rising : IRQ_Mode_Falling));
}

static void mpg_enable (sys_state_t state)
{
if (sys.mpg_mode != (DIGITAL_IN(mpg_pin->bit) == 0))
mpg_select(state);
else
pinEnableIRQ(mpg_pin, (mpg_pin->irq_mode = sys.mpg_mode ? IRQ_Mode_Rising : IRQ_Mode_Falling));
pinEnableIRQ(mpg_pin, (mpg_pin->mode.irq_mode = sys.mpg_mode ? IRQ_Mode_Rising : IRQ_Mode_Falling));
}

#endif
Expand Down Expand Up @@ -1816,7 +1828,7 @@ void settings_changed (settings_t *settings, settings_changed_flags_t changed)
input->debounce = false;
input->invert = false;

input->irq_mode = IRQ_Mode_None;
input->mode.irq_mode = IRQ_Mode_None;
pullup = input->group == PinGroup_AuxInput;

gpio_init(input->pin);
Expand Down Expand Up @@ -1849,7 +1861,7 @@ void settings_changed (settings_t *settings, settings_changed_flags_t changed)
safety_door = input;
pullup = !settings->control_disable_pullup.safety_door_ajar;
input->invert = control_fei.safety_door_ajar;
input->irq_mode = safety_door->invert ? IRQ_Mode_Low : IRQ_Mode_High;
input->mode.irq_mode = safety_door->invert ? IRQ_Mode_Low : IRQ_Mode_High;
break;
#endif
case Input_Probe:
Expand Down Expand Up @@ -1903,12 +1915,12 @@ void settings_changed (settings_t *settings, settings_changed_flags_t changed)
#endif
case Input_I2CStrobe:
pullup = true;
input->irq_mode = IRQ_Mode_Change;
input->mode.irq_mode = IRQ_Mode_Change;
break;

case Input_SPIIRQ:
pullup = true;
input->irq_mode = IRQ_Mode_Falling;
input->mode.irq_mode = IRQ_Mode_Falling;
break;

default:
Expand All @@ -1919,7 +1931,7 @@ void settings_changed (settings_t *settings, settings_changed_flags_t changed)

case PinGroup_Limit:
case PinGroup_Control:
input->irq_mode = input->invert ? IRQ_Mode_Falling : IRQ_Mode_Rising;
input->mode.irq_mode = input->invert ? IRQ_Mode_Falling : IRQ_Mode_Rising;
break;

case PinGroup_AuxInput:
Expand All @@ -1935,7 +1947,7 @@ void settings_changed (settings_t *settings, settings_changed_flags_t changed)
gpio_set_inover(input->pin, input->invert ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL);

if (!(input->group == PinGroup_Limit || input->group == PinGroup_AuxInput))
pinEnableIRQ(input, input->irq_mode);
pinEnableIRQ(input, input->mode.irq_mode);

if (input->id == Input_Probe)
probeConfigure(false, false);
Expand Down Expand Up @@ -2067,6 +2079,29 @@ void setPeriphPinDescription (const pin_function_t function, const pin_group_t g
} while(ppin);
}

#ifdef NEOPIXELS_PIN

static void rgb_out (uint8_t device, rgb_color_t color)
{
static uint8_t pixels[NEOPIXELS_NUM * 4] = {0};

if(device < NEOPIXELS_NUM) {

device *= 4;
pixels[device++] = color.G;
pixels[device++] = color.R;
pixels[device] = color.B;

uint_fast16_t i = NEOPIXELS_NUM;

for(i = 0; i < NEOPIXELS_NUM; i++) {
pio_sm_put_blocking(neop_pio, neop_sm, (uint32_t *)pixels[idx]);
}
}
}

#endif

// Initializes MCU peripherals
static bool driver_setup (settings_t *settings)
{
Expand Down Expand Up @@ -2192,6 +2227,28 @@ static bool driver_setup (settings_t *settings)
#endif
#endif

#ifdef NEOPIXELS_PIN

int nsm;
#ifdef GPIO_PIO_1
neop_pio = pio0;
#else
neop_pio = pio1;
#endif

if((nsm = pio_claim_unused_sm(neop_pio, true)) != -1) {

neop_sm = (uint)nsm;
hal.rgb.out = rgb_out;
hal.rgb.num_devices = NEOPIXELS_NUM;
hal.rgb.cap = (rgb_color_t){ .R = 255, .G = 255, .B = 255 };

pio_offset = pio_add_program(neop_pio, &ws2812_program);
ws2812_program_init(neop_pio, neop_sm, pio_offset, NEOPIXELS_PIN, 800000, false);
}

#endif

#if SDCARD_ENABLE
sdcard_init();
#endif
Expand Down Expand Up @@ -2273,7 +2330,7 @@ bool driver_init (void)
systick_hw->csr = M0PLUS_SYST_CSR_TICKINT_BITS | M0PLUS_SYST_CSR_ENABLE_BITS;

hal.info = "RP2040";
hal.driver_version = "240110";
hal.driver_version = "240119";
hal.driver_options = "SDK_" PICO_SDK_VERSION_STRING;
hal.driver_url = GRBL_URL "/RP2040";
#ifdef BOARD_NAME
Expand Down Expand Up @@ -2431,6 +2488,7 @@ bool driver_init (void)

for(i = 0; i < sizeof(inputpin) / sizeof(input_signal_t); i++) {
input = &inputpin[i];
input->mode.input = input->cap.input = On;
if(input->group == PinGroup_AuxInput) {
if(aux_inputs.pins.inputs == NULL)
aux_inputs.pins.inputs = input;
Expand Down Expand Up @@ -2461,13 +2519,15 @@ bool driver_init (void)

for(i = 0; i < sizeof(outputpin) / sizeof(output_signal_t); i++) {
output = &outputpin[i];
output->mode.output = On;
if(output->group == PinGroup_AuxOutput) {
if(aux_outputs.pins.outputs == NULL)
aux_outputs.pins.outputs = output;
output->id = Output_Aux0 + aux_outputs.n_pins++;
} else if(output->group == PinGroup_AuxOutputAnalog) {
if(aux_outputs_analog.pins.outputs == NULL)
aux_outputs_analog.pins.outputs = output;
output->mode.analog = On;
output->id = Output_Analog_Aux0 + aux_outputs_analog.n_pins++;
}
}
Expand Down Expand Up @@ -2511,7 +2571,7 @@ bool driver_init (void)
#if AUX_CONTROLS_ENABLED
for(i = AuxCtrl_ProbeDisconnect; i < AuxCtrl_NumEntries; i++) {
if(aux_ctrl[i].enabled) {
if((aux_ctrl[i].enabled = ioports_enumerate(Port_Digital, Port_Input, (pin_mode_t){ .irq_mode = aux_ctrl[i].irq_mode }, true, aux_claim, (void *)&aux_ctrl[i])))
if((aux_ctrl[i].enabled = ioports_enumerate(Port_Digital, Port_Input, (pin_cap_t){ .irq_mode = aux_ctrl[i].irq_mode, .claimable = On }, aux_claim, (void *)&aux_ctrl[i])))
hal.signals_cap.mask |= aux_ctrl[i].cap.mask;
}
}
Expand Down
6 changes: 3 additions & 3 deletions driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Part of grblHAL
Copyright (c) 2021-2023 Terje Io
Copyright (c) 2021-2024 Terje Io
Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -276,10 +276,10 @@ typedef struct {
uint32_t bit;
uint8_t port;
bool invert;
pin_irq_mode_t irq_mode;
volatile bool active;
volatile bool debounce;
pin_mode_t cap;
pin_cap_t cap;
pin_mode_t mode;
ioport_interrupt_callback_ptr interrupt_callback;
aux_ctrl_t *aux_ctrl;
const char *description;
Expand Down
17 changes: 8 additions & 9 deletions ioports.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ inline static __attribute__((always_inline)) int32_t get_input (const input_sign
break;
} while(--delay && !sys.abort);

pinEnableIRQ(input, input->irq_mode); // Restore pin interrupt status
pinEnableIRQ(input, input->mode.irq_mode); // Restore pin interrupt status
}

} else {
Expand Down Expand Up @@ -144,15 +144,15 @@ static bool register_interrupt_handler (uint8_t port, pin_irq_mode_t irq_mode, i
input_signal_t *input = &aux_in[port];

if((ok = (irq_mode & input->cap.irq_mode) == irq_mode && interrupt_callback != NULL)) {
input->irq_mode = irq_mode;
input->mode.irq_mode = irq_mode;
input->interrupt_callback = interrupt_callback;
pinEnableIRQ(input, irq_mode);
}

if(irq_mode == IRQ_Mode_None || !ok) {
while(spin_lock);
// EXTI->IMR &= ~input->bit; // Disable pin interrupt
input->irq_mode = IRQ_Mode_None;
input->mode.irq_mode = IRQ_Mode_None;
input->interrupt_callback = NULL;
}
}
Expand All @@ -171,10 +171,9 @@ static xbar_t *get_pin_info (io_port_type_t type, io_port_direction_t dir, uint8

if(dir == Port_Input && port < digital.in.n_ports) {
port = ioports_map(digital.in, port);
pin.mode.input = On;
pin.mode.irq_mode = aux_in[port].irq_mode;
pin.mode.can_remap = !aux_in[port].cap.remapped;
pin.mode = aux_in[port].mode;
pin.cap = aux_in[port].cap;
pin.cap.claimable = !pin.mode.claimed;
pin.function = aux_in[port].id;
pin.group = aux_in[port].group;
pin.pin = aux_in[port].pin;
Expand All @@ -186,7 +185,7 @@ static xbar_t *get_pin_info (io_port_type_t type, io_port_direction_t dir, uint8
if(dir == Port_Output && port < digital.out.n_ports) {
port = ioports_map(digital.out, port);
pin.mode = aux_out[port].mode;
pin.mode.output = On;
XBAR_SET_CAP(pin.cap, pin.mode);
pin.function = aux_out[port].id;
pin.group = aux_out[port].group;
pin.pin = aux_out[port].pin;
Expand Down Expand Up @@ -223,7 +222,7 @@ static bool claim (io_port_type_t type, io_port_direction_t dir, uint8_t *port,

if(dir == Port_Input) {

if((ok = digital.in.map && *port < digital.in.n_ports && !aux_in[*port].cap.claimed)) {
if((ok = digital.in.map && *port < digital.in.n_ports && !aux_in[*port].mode.claimed)) {

uint8_t i;

Expand All @@ -234,7 +233,7 @@ static bool claim (io_port_type_t type, io_port_direction_t dir, uint8_t *port,
aux_in[digital.in.map[i]].description = iports_get_pnum(digital, i);
}

aux_in[*port].cap.claimed = On;
aux_in[*port].mode.claimed = On;
aux_in[*port].description = description;

digital.in.map[hal.port.num_digital_in] = *port;
Expand Down
22 changes: 19 additions & 3 deletions ioports_analog.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2023 Terje Io
Copyright (c) 2023-2024 Terje Io
Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -38,6 +38,20 @@ static get_pin_info_ptr get_pin_info_digital;
static claim_port_ptr claim_digital;
static swap_pins_ptr swap_pins_digital;

static void set_pwm_cap (xbar_t *output, bool servo_pwm)
{
uint_fast8_t i = analog.out.n_ports;

if(output) do {
i--;
if(aux_out_analog[i].pin == output->pin) {
aux_out_analog[i].mode.pwm = !servo_pwm;
aux_out_analog[i].mode.servo_pwm = servo_pwm;
break;
}
} while(i);
}

static bool init_pwm (xbar_t *output, pwm_config_t *config)
{
bool ok;
Expand All @@ -57,6 +71,8 @@ static bool init_pwm (xbar_t *output, pwm_config_t *config)
pwm_config_set_output_polarity(&pwm_config, (!channel & config->invert), (channel & config->invert));

pwm_init(pwm_gpio_to_slice_num(output->pin), &pwm_config, true);

set_pwm_cap(output, config->servo_mode);
}

return ok;
Expand Down Expand Up @@ -87,8 +103,8 @@ static xbar_t *get_pin_info (io_port_type_t type, io_port_direction_t dir, uint8
if(dir == Port_Output && port < analog.out.n_ports) {
port = ioports_map(analog.out, port);
pin.mode = aux_out_analog[port].mode;
pin.mode.output = pin.mode.analog = On;
pin.cap = pin.mode;
pin.mode.pwm = !pin.mode.servo_pwm; //?? for easy filtering
XBAR_SET_CAP(pin.cap, pin.mode);
pin.function = aux_out_analog[port].id;
pin.group = aux_out_analog[port].group;
pin.pin = aux_out_analog[port].pin;
Expand Down
Loading

0 comments on commit 3111cbc

Please sign in to comment.