diff --git a/grblHAL_Teensy4/src/driver.h b/grblHAL_Teensy4/src/driver.h index bdd164c..644aeab 100644 --- a/grblHAL_Teensy4/src/driver.h +++ b/grblHAL_Teensy4/src/driver.h @@ -39,6 +39,10 @@ #define DIGITAL_IN(gpio) (!!(gpio.reg->DR & gpio.bit)) #define DIGITAL_OUT(gpio, on) { if(on) gpio.reg->DR_SET = gpio.bit; else gpio.reg->DR_CLEAR = gpio.bit; } +#ifndef MCP3221_ENABLE +#define MCP3221_ENABLE 0 +#endif + #if USB_SERIAL_CDC > 0 //#define UART_DEBUG // For development only - enable only with USB_SERIAL_CDC enabled and SPINDLE_HUANYANG disabled #endif @@ -137,6 +141,9 @@ #if KEYPAD_ENABLE #error "KEYPAD_ENABLE requires I2C_PORT to be defined!" #endif + #if MCP3221_ENABLE + #error "MCP3221_ENABLE requires I2C_PORT to be defined!" + #endif #endif #if !(SPINDLEPWMPIN == 12 || SPINDLEPWMPIN == 13) diff --git a/grblHAL_Teensy4/src/i2c.c b/grblHAL_Teensy4/src/i2c.c index 0cd831e..7ce4355 100644 --- a/grblHAL_Teensy4/src/i2c.c +++ b/grblHAL_Teensy4/src/i2c.c @@ -3,7 +3,7 @@ Part of grblHAL - Some parts of this code is Copyright (c) 2020 Terje Io + Some parts of this code is Copyright (c) 2020-2021 Terje Io Some parts are derived/pulled from WireIMXRT.cpp in the Teensyduino Core Library (no copyright header) @@ -166,6 +166,7 @@ typedef enum { I2CState_ReceiveNext, I2CState_ReceiveNextToLast, I2CState_ReceiveLast, + I2CState_Poll, I2CState_Error } i2c_state_t; @@ -273,7 +274,7 @@ uint8_t *I2C_Receive (uint32_t i2cAddr, uint8_t *buf, uint16_t bytes, bool block return i2c.buffer; } -void I2C_Send (uint32_t i2cAddr, uint8_t *buf, uint16_t bytes, bool block) +bool I2C_Send (uint32_t i2cAddr, uint8_t *buf, uint16_t bytes, bool block) { i2c.count = bytes; i2c.data = buf ? buf : i2c.buffer; @@ -290,8 +291,19 @@ void I2C_Send (uint32_t i2cAddr, uint8_t *buf, uint16_t bytes, bool block) i2c.state = i2c.count == 0 ? I2CState_AwaitCompletion : (i2c.count == 1 ? I2CState_SendLast : I2CState_SendNext); - if(block) - while(i2cIsBusy); + if(block) { + while(i2cIsBusy) { + if(bytes == 0) { + hal.delay_ms(2, 0); + if(port->MSR & LPI2C_MSR_PLTF) { + wait_ready(); + i2c.state = I2CState_Error; + } + } + } + } + + return !block || i2c.state != I2CState_Error; } uint8_t *I2C_ReadRegister (uint32_t i2cAddr, uint8_t *buf, uint8_t abytes, uint16_t bytes, bool block) diff --git a/grblHAL_Teensy4/src/i2c.h b/grblHAL_Teensy4/src/i2c.h index 9f1c461..a8eb565 100644 --- a/grblHAL_Teensy4/src/i2c.h +++ b/grblHAL_Teensy4/src/i2c.h @@ -1,7 +1,7 @@ /* i2c.h - I2C interface - Driver code for IMXRT1062 processor (on Teensy 4.0 board) + Driver code for IMXRT1062 processor (on Teensy 4.x board) Part of grblHAL @@ -29,7 +29,7 @@ void i2c_init (void); uint8_t *I2C_Receive (uint32_t i2cAddr, uint8_t *buf, uint16_t bytes, bool block); -void I2C_Send (uint32_t i2cAddr, uint8_t *buf, uint16_t bytes, bool block); +bool I2C_Send (uint32_t i2cAddr, uint8_t *buf, uint16_t bytes, bool block); uint8_t *I2C_ReadRegister (uint32_t i2cAddr, uint8_t *buf, uint8_t abytes, uint16_t bytes, bool block); #if TRINAMIC_ENABLE && TRINAMIC_I2C diff --git a/grblHAL_Teensy4/src/ioports.c b/grblHAL_Teensy4/src/ioports.c index 37cf4e6..79feb97 100644 --- a/grblHAL_Teensy4/src/ioports.c +++ b/grblHAL_Teensy4/src/ioports.c @@ -22,6 +22,7 @@ */ #include "driver.h" +#include "mcp3221.h" #ifdef HAS_IOPORTS @@ -31,7 +32,7 @@ #include "grbl/protocol.h" -static uint_fast8_t aux_n_in, aux_n_out; +static uint_fast8_t aux_n_in, aux_n_out, analog_n_in; static volatile uint32_t event_bits; static volatile bool spin_lock = false; static input_signal_t *aux_in; @@ -202,8 +203,10 @@ static int32_t wait_on_input (bool digital, uint8_t port, wait_mode_t wait_mode, if(port < aux_n_in) value = get_input(&aux_in[port], (settings.ioport.invert_in.mask << port) & 0x01, wait_mode, timeout); } -// else if(port == 0) -// value = analogRead(41); +#if MCP3221_ENABLE + else if(port < analog_n_in) + value = (int32_t)MCP3221_read(); +#endif return value; } @@ -257,6 +260,11 @@ void ioports_init (pin_group_pins_t *aux_inputs, pin_group_pins_t *aux_outputs) if((hal.port.num_digital_out = aux_n_out = aux_outputs->n_pins)) hal.port.digital_out = digital_out; +#if MCP3221_ENABLE + if(MCP3221_init()) + hal.port.num_analog_in = analog_n_in = 1; +#endif + hal.port.set_pin_description = set_pin_description; details.on_get_settings = grbl.on_get_settings; diff --git a/grblHAL_Teensy4/src/mcp3221.c b/grblHAL_Teensy4/src/mcp3221.c new file mode 100644 index 0000000..7c1dcf1 --- /dev/null +++ b/grblHAL_Teensy4/src/mcp3221.c @@ -0,0 +1,41 @@ +/* + mcp3221.c - analog input from a MCP3221 I2C ADC + + Driver code for IMXRT1062 processor (on Teensy 4.x board) + + Part of grblHAL + + Copyright (c) 2021 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grbl. If not, see . +*/ + +#include "i2c.h" +#include "mcp3221.h" + +uint16_t MCP3221_read (void) +{ + uint8_t value[2]; + + I2C_Receive(MCP3221_ADDRESS, value, 2, true); + + return value[0] << 8 | value[1]; +} + +bool MCP3221_init (void) +{ + i2c_init(); + + return I2C_Send(MCP3221_ADDRESS, NULL, 0, true); +} diff --git a/grblHAL_Teensy4/src/mcp3221.h b/grblHAL_Teensy4/src/mcp3221.h new file mode 100644 index 0000000..bae3ff6 --- /dev/null +++ b/grblHAL_Teensy4/src/mcp3221.h @@ -0,0 +1,31 @@ +/* + mcp3221.h - analog input from a MCP3221 I2C ADC + + Driver code for IMXRT1062 processor (on Teensy 4.x board) + + Part of grblHAL + + Copyright (c) 2021 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grbl. If not, see . +*/ + +#pragma once + +#define MCP3221_ADDRESS 0b1001101 + +uint16_t MCP3221_read (void); +bool MCP3221_init (void); + +/*EOF*/ diff --git a/grblHAL_Teensy4/src/my_machine.h b/grblHAL_Teensy4/src/my_machine.h index f46a475..fa5aa14 100644 --- a/grblHAL_Teensy4/src/my_machine.h +++ b/grblHAL_Teensy4/src/my_machine.h @@ -49,18 +49,20 @@ N_AXIS has a default value of 3, edit grbl\config.h to increase. */ -#define USB_SERIAL_CDC 2 // 1 for Arduino class library and 2 for PJRC C library. Comment out to use UART communication. +//#define USB_SERIAL_CDC 2 // 1 for Arduino class library and 2 for PJRC C library. Comment out to use UART communication. //#define USB_SERIAL_WAIT 1 // Wait for USB connection before starting grblHAL. -//#define BLUETOOTH_ENABLE 1 // Set to 1 for HC-05 module. Requires Bluetooth plugin. +//#define BLUETOOTH_ENABLE 1 // Set to 1 for HC-05 module. Requires Bluetooth plugin. //#define SPINDLE_HUANYANG 1 // Set to 1 or 2 for Huanyang VFD spindle. Requires spindle plugin. //#define QEI_ENABLE 1 // Enable quadrature encoder interfaces. Max value is 1. Requires encoder plugin. //#define ETHERNET_ENABLE 1 // Ethernet streaming. Requires networking plugin. //#define SDCARD_ENABLE 1 // Run gcode programs from SD card, requires sdcard plugin. //#define KEYPAD_ENABLE 1 // I2C keypad for jogging etc., requires keypad plugin. //#define PLASMA_ENABLE 1 // Plasma/THC plugin. To be completed. +//#define MCP3221_ENABLE 1 // Enable analog input via MCP3221 ADC. //#define PPI_ENABLE 1 // Laser PPI plugin. To be completed. //#define ODOMETER_ENABLE 1 // Odometer plugin. //#define OPENPNP_ENABLE 1 // OpenPNP plugin. To be completed. +//#define FANS_ENABLE 1 // Enable fan control via M106/M107. Requires fans plugin. //#define EEPROM_ENABLE 1 // I2C EEPROM support. Set to 1 for 24LC16(2K), 2 for larger sizes. Requires eeprom plugin. //#define EEPROM_IS_FRAM 1 // Uncomment when EEPROM is enabled and chip is FRAM, this to remove write delay. //#define SPINDLE_SYNC_ENABLE 1 // Enable spindle sync support (G33, G76). !! NOTE: Alpha quality - enable only for test or verification.