diff --git a/.cproject b/.cproject index a6a9f275..8c605d97 100644 --- a/.cproject +++ b/.cproject @@ -46,7 +46,6 @@ @@ -118,11 +118,12 @@ + - + - + @@ -2521,64 +2522,64 @@ - + - + - + - + - + - - + + - + - + - - - - - + + - + - + - + - + - + + + + diff --git a/.gitignore b/.gitignore index bd486977..1018b798 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ build .vscode/settings.json .vscode/c_cpp_properties.json + +Debug diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index d263907b..ad47745a 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + @@ -138,7 +138,7 @@ - + @@ -150,7 +150,7 @@ - + @@ -162,7 +162,7 @@ - + @@ -174,7 +174,7 @@ - + @@ -186,7 +186,7 @@ - + @@ -198,7 +198,7 @@ - + @@ -210,7 +210,7 @@ - + diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..e80666bf --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..7a2f2f09 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,47 @@ +// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY +// +// PIO Unified Debugger +// +// Documentation: https://docs.platformio.org/page/plus/debugging.html +// Configuration: https://docs.platformio.org/page/projectconf/section_env_debug.html + +{ + "version": "0.2.0", + "configurations": [ + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug", + "executable": "e:/TAI/01_AKB/STM32CubeIDE/STM32F4xx/.pio/build/btt_skr_pro_1_1/firmware.elf", + "projectEnvName": "btt_skr_pro_1_1", + "toolchainBinDir": "C:/Users/tai/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin", + "internalConsoleOptions": "openOnSessionStart", + "svdPath": "C:/Users/tai/.platformio/platforms/ststm32/misc/svd/STM32F40x.svd", + "preLaunchTask": { + "type": "PlatformIO", + "task": "Pre-Debug" + } + }, + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug (skip Pre-Debug)", + "executable": "e:/TAI/01_AKB/STM32CubeIDE/STM32F4xx/.pio/build/btt_skr_pro_1_1/firmware.elf", + "projectEnvName": "btt_skr_pro_1_1", + "toolchainBinDir": "C:/Users/tai/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin", + "internalConsoleOptions": "openOnSessionStart", + "svdPath": "C:/Users/tai/.platformio/platforms/ststm32/misc/svd/STM32F40x.svd" + }, + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug (without uploading)", + "executable": "e:/TAI/01_AKB/STM32CubeIDE/STM32F4xx/.pio/build/btt_skr_pro_1_1/firmware.elf", + "projectEnvName": "btt_skr_pro_1_1", + "toolchainBinDir": "C:/Users/tai/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin", + "internalConsoleOptions": "openOnSessionStart", + "svdPath": "C:/Users/tai/.platformio/platforms/ststm32/misc/svd/STM32F40x.svd", + "loadMode": "manual" + } + ] +} diff --git a/Inc/driver.h b/Inc/driver.h index 6bda8316..8f6b996d 100644 --- a/Inc/driver.h +++ b/Inc/driver.h @@ -305,9 +305,9 @@ #error SD card plugin not supported! #endif -#ifndef I2C_PORT -#define I2C_PORT 2 // GPIOB, SCL_PIN = 10, SDA_PIN = 11 -#endif +//#ifndef I2C_PORT +//#define I2C_PORT 2 // GPIOB, SCL_PIN = 10, SDA_PIN = 11 +//#endif #ifndef SPI_PORT #define SPI_PORT 1 diff --git a/Inc/my_machine.h b/Inc/my_machine.h index 7adb5acd..f55e6b89 100644 --- a/Inc/my_machine.h +++ b/Inc/my_machine.h @@ -1,23 +1,23 @@ /* - my_machine.h - configuration for STM32F4xx ARM processors + my_machine.h - configuration for STM32F4xx ARM processors - Part of grblHAL + Part of grblHAL - Copyright (c) 2020-2021 Terje Io + Copyright (c) 2020-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 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. + 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 . -*/ + You should have received a copy of the GNU General Public License + along with Grbl. If not, see . + */ // NOTE: Only one board may be enabled! // If none is enabled pin mappings from generic_map.h will be used. @@ -32,7 +32,7 @@ //#define BOARD_BTT_SKR_PRO_1_1 // F407 based 3D Printer board //#define BOARD_BTT_SKR_PRO_1_2 // F407 based 3D Printer board //#define BOARD_BTT_SKR_20 // F407 based 3D Printer board -//#define BOARD_MY_MACHINE // Add my_machine_map.h before enabling this! +#define BOARD_MY_MACHINE // Add my_machine_map.h before enabling this! // WARNING: BOARD_BTT_SKR_20 may fry your Trinamic drivers due to bad hardware design. // The risk goes away if Q1 (HY1904C2) is shorted between source (S) and drain (D). @@ -49,14 +49,15 @@ // Uncomment to enable. #if !IS_NUCLEO_DEVKIT // The Nucleo boards has an off-chip UART to USB interface. -#define USB_SERIAL_CDC 1 // Serial communication via native USB. +//#define USB_SERIAL_CDC 1 // Serial communication via native USB. #endif //#define BLUETOOTH_ENABLE 1 // Set to 1 for HC-05 module. Requires and claims one auxillary input pin. -//#define HUANYANG_ENABLE 1 // Set to 1 or 2 for Huanyang VFD spindle. +//#define VFD_ENABLE 101 // Set to 1 or 2 for Huanyang VFD spindle. More here https://github.com/grblHAL/Plugins_spindle +//#define SHIHLIN_ENABLE 1 //#define DUAL_SPINDLE 1 // Uncomment for switching between VFD spindle and PWM output with $32 -//#define MODBUS_ENABLE 1 // Set to 1 for auto direction, 2 for direction signal on auxillary output pin. +//#define MODBUS_ENABLE 3 // Set to 1 for auto direction, 2 for direction signal on auxillary output pin, 3 for shihlin vfd (author:tai) //#define SDCARD_ENABLE 2 // Run gcode programs from SD card. -//#define KEYPAD_ENABLE 1 // Set to 1 for I2C keypad, 2 for other input such as serial data +//#define KEYPAD_ENABLE 2 // Set to 1 for I2C keypad, 2 for other input such as serial data //#define ODOMETER_ENABLE 1 // Odometer plugin. //#define PPI_ENABLE 1 // Laser PPI plugin. To be completed. //#define LASER_COOLANT_ENABLE 1 // Laser coolant plugin. To be completed. @@ -83,4 +84,3 @@ //#define Y_GANGED_LIM_MAX 1 //#define Z_GANGED_LIM_MAX 1 // - diff --git a/Inc/my_machine_map.h b/Inc/my_machine_map.h new file mode 100644 index 00000000..fee333cf --- /dev/null +++ b/Inc/my_machine_map.h @@ -0,0 +1,140 @@ +/* + my_machine_map.h - driver code for F4MPV5 (STM32F407) board + + Part of GrblHAL + + Copyright (c) 2021 atlesg + + 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 . +*/ + +/* Default Pin Assignments: + * A0 X Step | B0 Step En/Dis | C0 (N/A) + * A1 X Direction | B1 Spindle Enable | C1 (N/A) + * A2 Y Step | B2 Spindle Direction | C2 (N/A) + * A3 Y Direction | B3 | C3 (N/A) + * A4 Z Step | B4 | C4 (N/A) + * A5 Z Direction | B5 | C5 (N/A) + * A6 A Step | B6 Reset | C6 (N/A) + * A7 A Direction | B7 Feed Hold | C7 (N/A) + * A8 Spindle PWM | B8 Cycle Start | C8 (N/A) + * A9 Y2 Step | B9 Door Safety | C9 (N/A) + * A10 Y2 Direction | B10 Y2 Limit | C10 (N/A) + * A11 | B11 | C11 (N/A) + * A12 | B12 X Limit | C12 (N/A) + * A13 | B13 Y Limit | C13 + * A14 | B14 Z Limit | C14 Coolant Flood + * A15 | B15 Probe | C15 coolant Mist + */ + + + +#if N_ABC_MOTORS > 1 +#error "Axis configuration is not supported!" +#endif + +#if !defined(STM32F407xx) || HSE_VALUE != 8000000 +#error "This board has STM32F407 processor with a 8MHz crystal, select a corresponding build!" +#endif + +#define BOARD_NAME "F4MPV5_HOSOI" +#define HAS_BOARD_INIT + + + +// Define step pulse output pins. +#define STEP_PORT GPIOA +#define X_STEP_PIN 2 // JM1 +#define Y_STEP_PIN 4 // JM2 +#define Z_STEP_PIN 6 // JM3 +#define STEP_OUTMODE GPIO_MAP + + +#define DIRECTION_PORT GPIOA +#define X_DIRECTION_PIN 3 // JM1 +#define Y_DIRECTION_PIN 5 // JM2 +#define Z_DIRECTION_PIN 7 // JM3 +#define DIRECTION_OUTMODE GPIO_MAP + +// Define stepper driver enable/disable output pin. +#define STEPPERS_ENABLE_PORT GPIOA // JM4-PU +#define STEPPERS_ENABLE_PIN 6 +#define STEPPERS_ENABLE_MASK STEPPERS_ENABLE_BIT + +// Define homing/hard limit switch input pins. +#define LIMIT_PORT GPIOD +#define X_LIMIT_PIN 13 // N12 +#define Y_LIMIT_PIN 14 // N13 +#define Z_LIMIT_PIN 15 // N14 +#define LIMIT_INMODE GPIO_SHIFT12 + +// Define ganged axis or A axis step pulse and step direction output pins. +#if N_ABC_MOTORS == 1 +#define M3_AVAILABLE +#define M3_STEP_PORT STEP_PORT +#define M3_STEP_PIN 6 +#define M3_DIRECTION_PORT DIRECTION_PORT +#define M3_DIRECTION_PIN 7 +#if N_AUTO_SQUARED +#define M3_LIMIT_PORT LIMIT_PORT +#define M3_LIMIT_PIN 15 +#endif +#endif + + // Define spindle enable and spindle direction output pins. +//#define SPINDLE_ENABLE_PORT GPIOB +//#define SPINDLE_ENABLE_PIN 0 // JM5 - PU +//#define SPINDLE_DIRECTION_PORT GPIOB +//#define SPINDLE_DIRECTION_PIN 1 // JM5 - DR + +#define SPINDLE_CW_PORT GPIOE +#define SPINDLE_CW_PIN 2 +#define SPINDLE_CCW_PORT GPIOE +#define SPINDLE_CCW_PIN 3 + +// Define spindle PWM output pin. +//#define SPINDLE_PWM_PORT_BASE GPIOA_BASE +//#define SPINDLE_PWM_PIN 8 + +// Define flood and mist coolant enable output pins. +#define COOLANT_FLOOD_PORT GPIOE +#define COOLANT_FLOOD_PIN 1 +//#define COOLANT_MIST_PORT GPIOB +//#define COOLANT_MIST_PIN 4 + +// Define user-control controls (cycle start, reset, feed hold) input pins. +#define CONTROL_PORT GPIOD +#define RESET_PIN 0 // N0 +#define FEED_HOLD_PIN 1 // N1 +#define CYCLE_START_PIN 2 // N2 +#if SAFETY_DOOR_ENABLE +#define SAFETY_DOOR_PIN 1 +#endif +#define CONTROL_INMODE GPIO_SHIFT6 + +// Define probe switch input pin. +#define PROBE_PORT GPIOD +#define PROBE_PIN 12 // N15 + +// Define main grbl uart port +#define UART_INSTANCE 2 + +// Define Spindle port and pins +#define MODBUS_SERIAL_PORT 3 +//#define MODBUS_DIR_AUX 5 + +// Define I2C Port - avoid confliction with USART3 port +#undef I2C_PORT + +/* EOF */ diff --git a/STM32F4xx Debug.launch b/STM32F4xx Debug.launch new file mode 100644 index 00000000..10671701 --- /dev/null +++ b/STM32F4xx Debug.launch @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Src/driver.c b/Src/driver.c index 4a3d2dbe..6d066621 100644 --- a/Src/driver.c +++ b/Src/driver.c @@ -1887,7 +1887,7 @@ bool driver_init (void) #else hal.info = "STM32F401CC"; #endif - hal.driver_version = "211209"; + hal.driver_version = "211221"; #ifdef BOARD_NAME hal.board = BOARD_NAME; #endif @@ -1954,8 +1954,8 @@ bool driver_init (void) #if USB_SERIAL_CDC stream_connect(usbInit()); -#else - stream_connect(serialInit(115200)); +#elif !defined(UART_INSTANCE) + stream_connect(serialInit(BAUD_RATE)); #endif #ifdef I2C_PORT @@ -2008,6 +2008,8 @@ bool driver_init (void) hal.driver_cap.probe_pull_up = On; #endif + serialRegisterStreams(); + #ifdef HAS_IOPORTS uint32_t i; @@ -2044,7 +2046,10 @@ bool driver_init (void) board_init(); #endif - serialRegisterStreams(); +#if defined(UART_INSTANCE) && USB_SERIAL_CDC == 0 + if(!stream_connect_instance(UART_INSTANCE, BAUD_RATE)) + while(true); // Cannot boot if no communication channel is available! +#endif #if ETHERNET_ENABLE enet_init(); diff --git a/Src/f4mpv4_hosoi.h b/Src/f4mpv4_hosoi.h new file mode 100644 index 00000000..ac4f2555 --- /dev/null +++ b/Src/f4mpv4_hosoi.h @@ -0,0 +1,117 @@ +/* + * f4mpv4_hosoi.h + * + * Created on: Dec 23, 2021 + * Author: tai + */ + +#ifndef F4MPV4_HOSOI_H_ +#define F4MPV4_HOSOI_H_ + +#include +#include "main.h" +#include "driver.h" +#include "serial.h" + +#include "grbl/hal.h" +#include "grbl/limits.h" +#include "grbl/protocol.h" +#include "grbl/motor_pins.h" +#include "grbl/pin_bits_masks.h" +#include "grbl/stepdir_map.h" +#include "grbl/motion_control.h" +#include "grbl/state_machine.h" + +#define PU1_Pin GPIO_PIN_2 +#define PU1_GPIO_Port GPIOA +#define DR1_Pin GPIO_PIN_3 +#define DR1_GPIO_Port GPIOA +#define LedG_Pin GPIO_PIN_6 +#define LedG_GPIO_Port GPIOC +#define LedB_Pin GPIO_PIN_7 +#define LedB_GPIO_Port GPIOC +#define LedR_Pin GPIO_PIN_8 +#define LedR_GPIO_Port GPIOC + +#define led1 GPIOC,GPIO_PIN_6 //GR +#define led2 GPIOC,GPIO_PIN_7 //BL +#define led3 GPIOC,GPIO_PIN_8 //RD +#define led1on HAL_GPIO_WritePin(led1,GPIO_PIN_SET) +#define led2on HAL_GPIO_WritePin(led2,GPIO_PIN_SET) +#define led3on HAL_GPIO_WritePin(led3,GPIO_PIN_SET) +#define led1off HAL_GPIO_WritePin(led1,GPIO_PIN_RESET) +#define led2off HAL_GPIO_WritePin(led2,GPIO_PIN_RESET) +#define led3off HAL_GPIO_WritePin(led3,GPIO_PIN_RESET) +#define led1toggle HAL_GPIO_TogglePin(led1); +#define led2toggle HAL_GPIO_TogglePin(led2); +#define led3toggle HAL_GPIO_TogglePin(led3); + +#define X0 GPIOE,GPIO_PIN_0 +#define X1 GPIOE,GPIO_PIN_1 +#define X2 GPIOE,GPIO_PIN_2 +#define X3 GPIOE,GPIO_PIN_3 +#define X4 GPIOE,GPIO_PIN_4 +#define X5 GPIOE,GPIO_PIN_5 +#define X6 GPIOE,GPIO_PIN_6 +#define X7 GPIOE,GPIO_PIN_7 +#define X8 GPIOE,GPIO_PIN_8 +#define X9 GPIOE,GPIO_PIN_9 +#define X10 GPIOE,GPIO_PIN_10 +#define X11 GPIOE,GPIO_PIN_11 + +#define X0R HAL_GPIO_ReadPin(X0) +#define X1R HAL_GPIO_ReadPin(X1) +#define X2R HAL_GPIO_ReadPin(X2) +#define X3R HAL_GPIO_ReadPin(X3) +#define X4R HAL_GPIO_ReadPin(X4) +#define X5R HAL_GPIO_ReadPin(X5) +#define X6R HAL_GPIO_ReadPin(X6) +#define X7R HAL_GPIO_ReadPin(X7) +#define X8R HAL_GPIO_ReadPin(X8) +#define X9R HAL_GPIO_ReadPin(X9) +#define X10R HAL_GPIO_ReadPin(X10) +#define X11R HAL_GPIO_ReadPin(X11) + +#define X0set HAL_GPIO_WritePin(X0, GPIO_PIN_SET); +#define X1set HAL_GPIO_WritePin(X1, GPIO_PIN_SET); +#define X2set HAL_GPIO_WritePin(X2, GPIO_PIN_SET); +#define X3set HAL_GPIO_WritePin(X3, GPIO_PIN_SET); +#define X4set HAL_GPIO_WritePin(X4, GPIO_PIN_SET); +#define X5set HAL_GPIO_WritePin(X5, GPIO_PIN_SET); +#define X6set HAL_GPIO_WritePin(X6, GPIO_PIN_SET); +#define X7set HAL_GPIO_WritePin(X7, GPIO_PIN_SET); +#define X8set HAL_GPIO_WritePin(X8, GPIO_PIN_SET); +#define X9set HAL_GPIO_WritePin(X9, GPIO_PIN_SET); +#define X10set HAL_GPIO_WritePin(X10, GPIO_PIN_SET); +#define X11set HAL_GPIO_WritePin(X11, GPIO_PIN_SET); + +#define X0clr HAL_GPIO_WritePin(X0, GPIO_PIN_RESET); +#define X1clr HAL_GPIO_WritePin(X1, GPIO_PIN_RESET); +#define X2clr HAL_GPIO_WritePin(X2, GPIO_PIN_RESET); +#define X3clr HAL_GPIO_WritePin(X3, GPIO_PIN_RESET); +#define X4clr HAL_GPIO_WritePin(X4, GPIO_PIN_RESET); +#define X5clr HAL_GPIO_WritePin(X5, GPIO_PIN_RESET); +#define X6clr HAL_GPIO_WritePin(X6, GPIO_PIN_RESET); +#define X7clr HAL_GPIO_WritePin(X7, GPIO_PIN_RESET); +#define X8clr HAL_GPIO_WritePin(X8, GPIO_PIN_RESET); +#define X9clr HAL_GPIO_WritePin(X9, GPIO_PIN_RESET); +#define X10clr HAL_GPIO_WritePin(X10, GPIO_PIN_RESET); +#define X11clr HAL_GPIO_WritePin(X11, GPIO_PIN_RESET); + +#define X0tog HAL_GPIO_TogglePin(X0); +#define X1tog HAL_GPIO_TogglePin(X1); +#define X2tog HAL_GPIO_TogglePin(X2); +#define X3tog HAL_GPIO_TogglePin(X3); +#define X4tog HAL_GPIO_TogglePin(X4); +#define X5tog HAL_GPIO_TogglePin(X5); +#define X6tog HAL_GPIO_TogglePin(X6); +#define X7tog HAL_GPIO_TogglePin(X7); +#define X8tog HAL_GPIO_TogglePin(X8); +#define X9tog HAL_GPIO_TogglePin(X9); +#define X10tog HAL_GPIO_TogglePin(X10); +#define X11tog HAL_GPIO_TogglePin(X11); + + +static void encoder_handler(sys_state_t state); + +#endif /* F4MPV4_HOSOI_H_ */ diff --git a/Src/f4mpv5_hosoi.c b/Src/f4mpv5_hosoi.c new file mode 100644 index 00000000..80b2fb26 --- /dev/null +++ b/Src/f4mpv5_hosoi.c @@ -0,0 +1,1104 @@ +/* + * my_plugin.c + * + * Created on: Dec 10, 2021 + * Author: tai + */ + +#include "f4mpv4_hosoi.h" + +TIM_HandleTypeDef htim2, htim3, htim4; +UART_HandleTypeDef huart4; + +static on_report_options_ptr on_report_options; +static on_execute_realtime_ptr on_execute_realtime; + +stepper_t stepper = + { + 0 + }; + +static bool encoder_interrupt_busy = false; + +static coord_data_t target = + { + 0 + }, origin = + { + 0 + }; +// Initialize planner data struct for motion blocks. +static plan_line_data_t plan_data; + +static void encoder_init(void); +static void encoder_handler(sys_state_t state); + +// Add info about our plugin to the $I report. +static void on_report_my_options(bool newopt) +{ +on_report_options(newopt); + +if (!newopt) + hal.stream.write("[PLUGIN:Blink LED v1.00]" ASCII_EOL); +} + +// ENCODER +#define NUMBER_OF_ENCODER 3 + +volatile int step = 0; +volatile uint32_t counter = 0; +volatile int16_t count = 0; +volatile int16_t prev_count = 0; +volatile int16_t delta_count = 0; +static volatile float sign; + +typedef struct +{ + volatile uint32_t counter; + volatile int16_t count; + volatile int16_t prev_count; + volatile int16_t delta_count; + volatile float sign; + TIM_HandleTypeDef *timer; +} knob_t; + +static knob_t knob_x, knob_y, knob_z; +static knob_t *knob_ptr[NUMBER_OF_ENCODER] = + { + &knob_x, &knob_y, &knob_z + }; + +void TIM2_IRQHandler(void) +{ +HAL_TIM_IRQHandler(&htim2); +} +void TIM3_IRQHandler(void) +{ +HAL_TIM_IRQHandler(&htim3); +} +//void TIM4_IRQHandler(void) +//{ +//HAL_TIM_IRQHandler(&htim4); +//} + +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim_encoder) +{ +GPIO_InitTypeDef GPIO_InitStruct = + { + 0 + }; +if (htim_encoder->Instance == TIM2) + { + __HAL_RCC_TIM2_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM2_IRQn); + } +else if (htim_encoder->Instance == TIM3) + { + __HAL_RCC_TIM3_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM3_IRQn); + } +//else if (htim_encoder->Instance == TIM4) +// { +// __HAL_RCC_TIM4_CLK_ENABLE(); +// __HAL_RCC_GPIOB_CLK_ENABLE(); +// GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; +// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; +// GPIO_InitStruct.Pull = GPIO_NOPULL; +// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; +// GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); +// } + +} + +void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim_encoder) +{ +if (htim_encoder->Instance == TIM2) + { + __HAL_RCC_TIM2_CLK_DISABLE(); + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15); + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3); + HAL_NVIC_DisableIRQ(TIM2_IRQn); + } +else if (htim_encoder->Instance == TIM3) + { + __HAL_RCC_TIM3_CLK_DISABLE(); + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_4 | GPIO_PIN_5); + HAL_NVIC_DisableIRQ(TIM3_IRQn); + } +//else if (htim_encoder->Instance == TIM4) +// { +// __HAL_RCC_TIM4_CLK_DISABLE(); +// HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6 | GPIO_PIN_7); +// } + +} + +int temp = 0; + +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) +{ +/* Prevent unused argument(s) compilation warning */ +UNUSED(htim); +//// HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6); +// counter = __HAL_TIM_GET_COUNTER(htim); +// count = (int16_t) (counter / 4); +// delta_count = count - prev_count; +// if ((delta_count < 0) || (delta_count > 0)) +// { +// protocol_enqueue_rt_command(encoder_handler); +// } + +if (htim == knob_x.timer) + { + knob_x.counter = __HAL_TIM_GET_COUNTER(htim); + knob_x.count = (int16_t) (knob_x.counter / 4); +// if (knob_x.delta_count != 0) +// { +// protocol_enqueue_rt_command(encoder_handler); +// } + } + +if (htim == knob_y.timer) + { + knob_y.counter = __HAL_TIM_GET_COUNTER(htim); + knob_y.count = (int16_t) (knob_y.counter / 4); +// if (knob_z.delta_count != 0) +// { +// protocol_enqueue_rt_command(encoder_handler); +// } + } + +if (htim == knob_z.timer) + { + knob_z.counter = __HAL_TIM_GET_COUNTER(htim); + knob_z.count = (int16_t) (knob_z.counter / 4); +// if (knob_z.delta_count != 0) +// { +// protocol_enqueue_rt_command(encoder_handler); +// } + } +knob_x.delta_count = knob_x.count - knob_x.prev_count; +knob_y.delta_count = knob_y.count - knob_y.prev_count; +knob_z.delta_count = knob_z.count - knob_z.prev_count; + +protocol_enqueue_rt_command(encoder_handler); + +} + +static void encoder_init(void) +{ +// Encoder 1 - OKAY!!! Do not edit +TIM_Encoder_InitTypeDef sConfig = + { + 0 + }; +TIM_MasterConfigTypeDef sMasterConfig = + { + 0 + }; + +//---------------------------------------- +htim2.Instance = TIM2; +htim2.Init.Prescaler = 0; +htim2.Init.CounterMode = TIM_COUNTERMODE_UP; +htim2.Init.Period = 4294967295; +htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; +htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; +sConfig.EncoderMode = TIM_ENCODERMODE_TI12; +sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; +sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; +sConfig.IC1Prescaler = TIM_ICPSC_DIV1; +sConfig.IC1Filter = 0; +sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; +sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; +sConfig.IC2Prescaler = TIM_ICPSC_DIV1; +sConfig.IC2Filter = 0; +if (HAL_TIM_Encoder_Init(&htim2, &sConfig) != HAL_OK) + { + Error_Handler(); + } +sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; +sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; +if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + +//---------------------------------------- +htim3.Instance = TIM3; +htim3.Init.Prescaler = 0; +htim3.Init.CounterMode = TIM_COUNTERMODE_UP; +htim3.Init.Period = 65535; +htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; +htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; +sConfig.EncoderMode = TIM_ENCODERMODE_TI12; +sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; +sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; +sConfig.IC1Prescaler = TIM_ICPSC_DIV1; +sConfig.IC1Filter = 0; +sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; +sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; +sConfig.IC2Prescaler = TIM_ICPSC_DIV1; +sConfig.IC2Filter = 0; +if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK) + { + Error_Handler(); + } +sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; +sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; +if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } +//---------------------------------------- +//htim4.Instance = TIM4; +//htim4.Init.Prescaler = 0; +//htim4.Init.CounterMode = TIM_COUNTERMODE_UP; +//htim4.Init.Period = 65535; +//htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; +//htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; +//sConfig.EncoderMode = TIM_ENCODERMODE_TI1; +//sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; +//sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; +//sConfig.IC1Prescaler = TIM_ICPSC_DIV1; +//sConfig.IC1Filter = 0; +//sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; +//sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; +//sConfig.IC2Prescaler = TIM_ICPSC_DIV1; +//sConfig.IC2Filter = 0; +//if (HAL_TIM_Encoder_Init(&htim4, &sConfig) != HAL_OK) +// { +// Error_Handler(); +// } +//sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; +//sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; +//if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) +// { +// Error_Handler(); +// } +//---------------------------------------- +knob_x.timer = &htim2; +knob_y.timer = &htim3; +knob_z.timer = &htim4; +for (uint8_t i = 0; i < NUMBER_OF_ENCODER; i++) + { + knob_ptr[i]->count = 0; + knob_ptr[i]->counter = 0; + knob_ptr[i]->delta_count = 0; + knob_ptr[i]->prev_count = 0; + } +HAL_TIM_Encoder_Start_IT(knob_x.timer, TIM_CHANNEL_ALL); +HAL_TIM_Encoder_Start_IT(knob_y.timer, TIM_CHANNEL_ALL); +//HAL_TIM_Encoder_Start_IT(knob_z.timer, TIM_CHANNEL_ALL); +} + +static void encoder_handler(sys_state_t state) +{ +//-------------------------------------------------- +//if (encoder_interrupt_busy == true) return; +//if (knob_x.delta_count != 0) +// { +// encoder_interrupt_busy = true; +// sign = knob_x.delta_count >= 0 ? 1.0f : -1.0f; +// plan_line_data_t plan_data_x = +// { +// 0 +// }; +// plan_data.feed_rate = 30000.0f; +// protocol_buffer_synchronize(); +// sync_position(); +// // Get current position. +// system_convert_array_steps_to_mpos(origin.values, sys.position); +// target.x = origin.x + sign * 25.0f; +// knob_x.prev_count = knob_x.count; +// mc_line(target.values, &plan_data_x); +// } +//if (knob_z.delta_count != 0) +// { +// encoder_interrupt_busy = true; +// sign = knob_z.delta_count >= 0 ? 1.0f : -1.0f; +// plan_line_data_t plan_data_z = +// { +// 0 +// }; +// plan_data_z.feed_rate = 30000.0f; +// protocol_buffer_synchronize(); +// sync_position(); +// // Get current position. +// system_convert_array_steps_to_mpos(origin.values, sys.position); +// target.z = origin.z + sign * 25.0f; +// knob_z.prev_count = knob_z.count; +// mc_line(target.values, &plan_data_z); +// } +//encoder_interrupt_busy = false; +//-------------------------------------------------- +knob_x.prev_count = knob_x.count; +knob_y.prev_count = knob_y.count; +knob_z.prev_count = knob_z.count; +if (encoder_interrupt_busy == true) return; +if ((knob_x.delta_count != 0)|| (knob_y.delta_count != 0) || (knob_z.delta_count != 0)) + { + encoder_interrupt_busy = true; + knob_x.sign = knob_x.delta_count >= 0 ? 1.0f : -1.0f; + knob_y.sign = knob_y.delta_count >= 0 ? 1.0f : -1.0f; + knob_z.sign = knob_z.delta_count >= 0 ? 1.0f : -1.0f; + plan_line_data_t plan_data = + { + 0 + }; + plan_data.feed_rate = 30000.0f; + protocol_buffer_synchronize(); + sync_position(); + // Get current position. + system_convert_array_steps_to_mpos(origin.values, sys.position); + if (knob_x.delta_count != 0) target.x = origin.x + knob_x.sign * 5.0f; + if (knob_y.delta_count != 0) target.y = origin.y + knob_y.sign * 5.0f; + if (knob_z.delta_count != 0) target.z = origin.z + knob_z.sign * 5.0f; + + mc_line(target.values, &plan_data); + encoder_interrupt_busy = false; + } +} + +static void blink_led(sys_state_t state) +{ +// static bool led_on = false; +static uint32_t ms = 0; + +if (hal.get_elapsed_ticks() >= ms) + { + ms = hal.get_elapsed_ticks() + 1000; //ms + +// HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6); // Green +// HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_7); // Blue + HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8); // Red + +// Alternative Method +// static bool led_on = false; +// static uint32_t ms = 0; +// +// if (hal.get_elapsed_ticks() >= ms) +// { +// ms = hal.get_elapsed_ticks() + 500; //ms +// led_on = !led_on; +// if (led_on) +// GPIOC->ODR |= GPIO_PIN_13; +// else +// GPIOC->ODR &= ~GPIO_PIN_13; +// } + + // temp - to be deleted +// target.x = sys.position[0] + 20.0f; +// target.y = sys.position[1]; +// hal.stream.write(uitoa(x)); +// hal.stream.write(","); +// hal.stream.write(uitoa(y)); +// hal.stream.write(ASCII_EOL); +// mc_line(target.values, &plan_data); + + } +//protocol_enqueue_rt_command(encoder_handler); +on_execute_realtime(state); +} + +void led_init(void) +{ +GPIO_InitTypeDef GPIO_InitStruct; + +GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; +GPIO_InitStruct.Pull = GPIO_NOPULL; +GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + +GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8; +HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + +HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8, + GPIO_PIN_RESET); +} + +void output_init(void) +{ + +GPIO_InitTypeDef GPIO_InitStruct; + +GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; +GPIO_InitStruct.Pull = GPIO_NOPULL; +GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + +//X0-X11 +GPIO_InitStruct.Pin = GPIO_PIN_All; +HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + +////PU1,DR1-PU8-DR8 +// GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 +// | GPIO_PIN_7; +// HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); +// GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); +// GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3; +// HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); +// +////CS0 +// GPIO_InitStruct.Pin = GPIO_PIN_15; +// HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); +////KEY +// GPIO_InitStruct.Pin = GPIO_PIN_12; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); +} + +/************************************ + * + * SERIAL PORT + * + ************************************/ +const io_stream_t* serial3Init(uint32_t baud_rate); +const io_stream_t* serial4Init(uint32_t baud_rate); +static stream_rx_buffer_t rxbuf3 = + { + 0 + }; +static stream_tx_buffer_t txbuf3 = + { + 0 + }; +static enqueue_realtime_command_ptr enqueue_realtime_command3 = + protocol_enqueue_realtime_command; + +#define USART_GRBL USART3 +#define USART_GRBL_IRQHandler USART3_IRQHandler + +static io_stream_properties_t serial[] = + { + { + .type = StreamType_Serial, + .instance = 2, + .flags.claimable = On, + .flags.claimed = Off, + .flags.connected = On, + .flags.can_set_baud = + On, + .claim = serial3Init + }, + + { + .type = StreamType_Serial, + .instance = 3, + .flags.claimable = On, + .flags.claimed = Off, + .flags.connected = On, + .flags.can_set_baud = + On, + .flags.modbus_ready = On, + .claim = serial4Init + } + + }; + +// +// Returns number of free characters in serial input buffer +// +static uint16_t serial3RxFree(void) +{ +uint16_t tail = rxbuf3.tail, head = rxbuf3.head; + +return RX_BUFFER_SIZE - BUFCOUNT(head, tail, RX_BUFFER_SIZE); +} + +//endregion + +// +// Flushes the serial input buffer +// +static void serial3RxFlush(void) +{ +rxbuf3.tail = rxbuf3.head; +} + +// +// Flushes and adds a CAN character to the serial input buffer +// +static void serial3RxCancel(void) +{ +rxbuf3.data[rxbuf3.head] = ASCII_CAN; +rxbuf3.tail = rxbuf3.head; +rxbuf3.head = BUFNEXT(rxbuf3.head, rxbuf3); +} + +// +// Writes a character to the serial output stream +// +static bool serial3PutC(const char c) +{ +uint16_t next_head = BUFNEXT(txbuf3.head, txbuf3); // Get pointer to next free slot in buffer + +while (txbuf3.tail == next_head) + { // While TX buffer full + if (!hal.stream_blocking_callback()) // check if blocking for space, + return false; // exit if not (leaves TX buffer in an inconsistent state) + } +txbuf3.data[txbuf3.head] = c; // Add data to buffer, +txbuf3.head = next_head; // update head pointer and +USART_GRBL->CR1 |= USART_CR1_TXEIE; // enable TX interrupts + +return true; +} + +// +// Writes a null terminated string to the serial output stream, blocks if buffer full +// +static void serial3WriteS(const char *s) +{ +char c, *ptr = (char*) s; + +while ((c = *ptr++) != '\0') + serial3PutC(c); +} + +// +// Writes a number of characters from string to the serial output stream followed by EOL, blocks if buffer full +// +static void serial3Write(const char *s, uint16_t length) +{ +char *ptr = (char*) s; + +while (length--) + serial3PutC(*ptr++); +} + +// +// serialGetC - returns -1 if no data available +// +static int16_t serial3GetC(void) +{ +uint_fast16_t tail = rxbuf3.tail; // Get buffer pointer + +if (tail == rxbuf3.head) + return -1; // no data available + +char data = rxbuf3.data[tail]; // Get next character +rxbuf3.tail = BUFNEXT(tail, rxbuf3); // and update pointer + +return (int16_t) data; +} + +static bool serial3SuspendInput(bool suspend) +{ +return stream_rx_suspend(&rxbuf3, suspend); +} + +static bool serial3SetBaudRate(uint32_t baud_rate) +{ +// if USART 1/6/9/10 → HAL_RCC_GetPCLK2Freq() - else: HAL_RCC_GetPCLK1Freq() + +USART_GRBL->CR1 = USART_CR1_RE | USART_CR1_TE; +USART_GRBL->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), baud_rate); +USART_GRBL->CR1 |= (USART_CR1_UE | USART_CR1_RXNEIE); + +return true; +} + +static bool serial3Disable(bool disable) +{ +if (disable) + USART_GRBL->CR1 &= ~USART_CR1_RXNEIE; +else + USART_GRBL->CR1 |= USART_CR1_RXNEIE; + +return true; +} + +static bool serial3EnqueueRtCommand(char c) +{ +return enqueue_realtime_command3(c); +} + +static enqueue_realtime_command_ptr serial3SetRtHandler( + enqueue_realtime_command_ptr handler) +{ +enqueue_realtime_command_ptr prev = enqueue_realtime_command3; + +if (handler) + enqueue_realtime_command3 = handler; + +return prev; +} + +const io_stream_t* serial3Init(uint32_t baud_rate) +{ + +static const io_stream_t stream = + { + .type = StreamType_Serial, + .state.connected = On, + .read = serial3GetC, + .write = serial3WriteS, + .write_n = + serial3Write, + .write_char = serial3PutC, + .enqueue_rt_command = serial3EnqueueRtCommand, + .get_rx_buffer_free = + serial3RxFree, + // .get_rx_buffer_count = serial3RxCount, +// .get_tx_buffer_count = serial3TxCount, +// .reset_write_buffer = serial3TxFlush, + .reset_read_buffer = serial3RxFlush, + .cancel_read_buffer = serial3RxCancel, + .suspend_read = serial3SuspendInput, + .disable_rx = serial3Disable, + .set_baud_rate = serial3SetBaudRate, + .set_enqueue_rt_handler = serial3SetRtHandler + }; + +if (serial[0].flags.claimed) + return NULL; + +serial[0].flags.claimed = On; + +GPIO_InitTypeDef GPIO_InitStructure = + { + 0 + }; + +GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; +GPIO_InitStructure.Pull = GPIO_NOPULL; +GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + +__HAL_RCC_GPIOB_CLK_ENABLE(); // USART3 Port +__HAL_RCC_USART3_CLK_ENABLE(); + +GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_11; +GPIO_InitStructure.Alternate = GPIO_AF7_USART3; +HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + +serial3SetBaudRate(baud_rate); + +HAL_NVIC_SetPriority(USART3_IRQn, 0, 0); +HAL_NVIC_EnableIRQ(USART3_IRQn); + +static const periph_pin_t tx = + { + .function = Output_TX, + .group = PinGroup_UART3, + .port = GPIOB, + .pin = 10, + .mode = + { + .mask = PINMODE_OUTPUT + }, + .description = "UART3" + }; + +static const periph_pin_t rx = + { + .function = Input_RX, + .group = PinGroup_UART3, + .port = GPIOB, + .pin = 11, + .mode = + { + .mask = PINMODE_NONE + }, + .description = "UART3" + }; + +hal.periph_port.register_pin(&rx); +hal.periph_port.register_pin(&tx); + +return &stream; +} + +void USART_GRBL_IRQHandler(void) +{ +if (USART_GRBL->SR & USART_SR_RXNE) + { + uint32_t data = USART_GRBL->DR; + if (!enqueue_realtime_command3((char) data)) + { // Check and strip realtime commands... + uint16_t next_head = BUFNEXT(rxbuf3.head, rxbuf3); // Get and increment buffer pointer + if (next_head == rxbuf3.tail) // If buffer full + rxbuf3.overflow = 1; // flag overflow + else + { + rxbuf3.data[rxbuf3.head] = (char) data; // if not add data to buffer + rxbuf3.head = next_head; // and update pointer + } + } + } + +if ((USART_GRBL->SR & USART_SR_TXE) && (USART_GRBL->CR1 & USART_CR1_TXEIE)) + { + uint_fast16_t tail = txbuf3.tail; // Get buffer pointer + USART_GRBL->DR = txbuf3.data[tail]; // Send next character + txbuf3.tail = tail = BUFNEXT(tail, txbuf3); // and increment pointer + if (tail == txbuf3.head) // If buffer empty then + USART_GRBL->CR1 &= ~USART_CR1_TXEIE; // disable UART TX interrupt + } +} + +// SERIAL 4 +static stream_rx_buffer_t rxbuf4 = + { + 0 + }; +static stream_tx_buffer_t txbuf4 = + { + 0 + }; +static enqueue_realtime_command_ptr enqueue_realtime_command4 = + protocol_enqueue_realtime_command; + +#define USART_MODBUS UART4 +#define USART_MODBUS_IRQHandler UART4_IRQHandler + +// +// Returns number of free characters in serial input buffer +// +static uint16_t serial4RxFree(void) +{ +uint16_t tail = rxbuf4.tail, head = rxbuf4.head; + +return RX_BUFFER_SIZE - BUFCOUNT(head, tail, RX_BUFFER_SIZE); +} + +// +// Returns number of characters in serial input buffer +// +static uint16_t serial4RxCount(void) +{ +uint32_t tail = rxbuf4.tail, head = rxbuf4.head; + +return BUFCOUNT(head, tail, RX_BUFFER_SIZE); +} + +// +// Flushes the serial input buffer +// +static void serial4RxFlush(void) +{ +rxbuf4.tail = rxbuf4.head; +} + +// +// Flushes and adds a CAN character to the serial input buffer +// +static void serial4RxCancel(void) +{ +rxbuf4.data[rxbuf4.head] = ASCII_CAN; +rxbuf4.tail = rxbuf4.head; +rxbuf4.head = BUFNEXT(rxbuf4.head, rxbuf4); +} + +// +// Writes a character to the serial output stream +// +static bool serial4PutC(const char c) +{ +uint16_t next_head = BUFNEXT(txbuf4.head, txbuf4); // Get pointer to next free slot in buffer + +while (txbuf4.tail == next_head) + { // While TX buffer full + if (!hal.stream_blocking_callback()) // check if blocking for space, + return false; // exit if not (leaves TX buffer in an inconsistent state) + } +txbuf4.data[txbuf4.head] = c; // Add data to buffer, +txbuf4.head = next_head; // update head pointer and +USART_MODBUS->CR1 |= USART_CR1_TXEIE; // enable TX interrupts + +return true; +} + +// +// Writes a null terminated string to the serial output stream, blocks if buffer full +// +static void serial4WriteS(const char *s) +{ +char c, *ptr = (char*) s; + +while ((c = *ptr++) != '\0') + serial4PutC(c); +} + +// +// Writes a number of characters from string to the serial output stream followed by EOL, blocks if buffer full +// +static void serial4Write(const char *s, uint16_t length) +{ +char *ptr = (char*) s; + +while (length--) + serial4PutC(*ptr++); +} + +// +// Flushes the serial output buffer +// +static void serial4TxFlush(void) +{ +UART4->CR1 &= ~USART_CR1_TXEIE; // Disable TX interrupts +txbuf4.tail = txbuf4.head; +} + +// +// Returns number of characters pending transmission +// +static uint16_t serial4TxCount(void) +{ +uint32_t tail = txbuf4.tail, head = txbuf4.head; + +return BUFCOUNT(head, tail, TX_BUFFER_SIZE) + + (UART4->SR & USART_SR_TC ? 0 : 1); +} + +// +// serialGetC - returns -1 if no data available +// +static int16_t serial4GetC(void) +{ +uint_fast16_t tail = rxbuf4.tail; // Get buffer pointer + +if (tail == rxbuf4.head) + return -1; // no data available + +char data = rxbuf4.data[tail]; // Get next character +rxbuf4.tail = BUFNEXT(tail, rxbuf4); // and update pointer + +return (int16_t) data; +} + +static bool serial4SuspendInput(bool suspend) +{ +return stream_rx_suspend(&rxbuf4, suspend); +} + +static bool serial4SetBaudRate(uint32_t baud_rate) +{ +// if USART 1/6/9/10 → HAL_RCC_GetPCLK2Freq() - else: HAL_RCC_GetPCLK1Freq() + +USART_MODBUS->CR1 = USART_CR1_RE | USART_CR1_TE; +USART_MODBUS->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), 38400); +USART_MODBUS->CR1 |= (USART_CR1_UE | USART_CR1_RXNEIE); + +huart4.Instance = UART4; +huart4.Init.BaudRate = 38400; +huart4.Init.WordLength = UART_WORDLENGTH_9B; +huart4.Init.StopBits = UART_STOPBITS_1; +huart4.Init.Parity = UART_PARITY_EVEN; +huart4.Init.Mode = UART_MODE_TX_RX; +huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE; +huart4.Init.OverSampling = UART_OVERSAMPLING_16; +if (HAL_UART_Init(&huart4) != HAL_OK) + { + Error_Handler(); + } + +return true; +} + +static bool serial4Disable(bool disable) +{ +if (disable) + USART_MODBUS->CR1 &= ~USART_CR1_RXNEIE; +else + USART_MODBUS->CR1 |= USART_CR1_RXNEIE; + +return true; +} + +static bool serial4EnqueueRtCommand(char c) +{ +return enqueue_realtime_command4(c); +} + +static enqueue_realtime_command_ptr serial4SetRtHandler( + enqueue_realtime_command_ptr handler) +{ +enqueue_realtime_command_ptr prev = enqueue_realtime_command4; + +if (handler) + enqueue_realtime_command4 = handler; + +return prev; +} + +const io_stream_t* serial4Init(uint32_t baud_rate) +{ + +static const io_stream_t stream = + { + .type = StreamType_Serial, + .instance = 3, + .state.connected = On, + .read = serial4GetC, + .write = serial4WriteS, + .write_n = serial4Write, + .write_char = serial4PutC, + .enqueue_rt_command = serial4EnqueueRtCommand, + .get_rx_buffer_free = serial4RxFree, + .get_rx_buffer_count = serial4RxCount, + .get_tx_buffer_count = serial4TxCount, + .reset_write_buffer = serial4TxFlush, + .reset_read_buffer = serial4RxFlush, + .cancel_read_buffer = serial4RxCancel, + .suspend_read = serial4SuspendInput, + .disable_rx = serial4Disable, + .set_baud_rate = serial4SetBaudRate, + .set_enqueue_rt_handler = serial4SetRtHandler + }; + +if (serial[1].flags.claimed) + return NULL; + +serial[1].flags.claimed = On; + +GPIO_InitTypeDef GPIO_InitStructure = + { + 0 + }; + +GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; +GPIO_InitStructure.Pull = GPIO_NOPULL; +GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + +__HAL_RCC_GPIOC_CLK_ENABLE(); // USART4 Port +__HAL_RCC_UART4_CLK_ENABLE(); + +GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_11; +GPIO_InitStructure.Alternate = GPIO_AF8_UART4; +HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + +serial4SetBaudRate(baud_rate); + +HAL_NVIC_SetPriority(UART4_IRQn, 0, 0); +HAL_NVIC_EnableIRQ(UART4_IRQn); + +static const periph_pin_t tx = + { + .function = Output_TX, + .group = PinGroup_UART4, + .port = GPIOC, + .pin = 10, + .mode = + { + .mask = PINMODE_OUTPUT + }, + .description = "UART4" + }; + +static const periph_pin_t rx = + { + .function = Input_RX, + .group = PinGroup_UART4, + .port = GPIOC, + .pin = 11, + .mode = + { + .mask = PINMODE_NONE + }, + .description = "UART4" + }; + +hal.periph_port.register_pin(&rx); +hal.periph_port.register_pin(&tx); + +return &stream; +} + +void USART_MODBUS_IRQHandler(void) +{ +if (USART_MODBUS->SR & USART_SR_RXNE) + { + uint32_t data = USART_MODBUS->DR; + if (!enqueue_realtime_command4((char) data)) + { // Check and strip realtime commands... + uint16_t next_head = BUFNEXT(rxbuf4.head, rxbuf4); // Get and increment buffer pointer + if (next_head == rxbuf4.tail) // If buffer full + rxbuf4.overflow = 1; // flag overflow + else + { + rxbuf4.data[rxbuf4.head] = (char) data; // if not add data to buffer + rxbuf4.head = next_head; // and update pointer + } + } + } + +if ((USART_MODBUS->SR & USART_SR_TXE) + && (USART_MODBUS->CR1 & USART_CR1_TXEIE)) + { + uint_fast16_t tail = txbuf4.tail; // Get buffer pointer + USART_MODBUS->DR = txbuf4.data[tail]; // Send next character + txbuf4.tail = tail = BUFNEXT(tail, txbuf4); // and increment pointer + if (tail == txbuf4.head) // If buffer empty then + USART_MODBUS->CR1 &= ~USART_CR1_TXEIE; // disable UART TX interrupt + } +} + +/************************************ + * + * MAIN CODE + * + ************************************/ + +/************************************ + * + * MAIN CODE + * + ************************************/ +void board_init(void) +{ +// Add info about our plugin to the $I report. +on_report_options = grbl.on_report_options; +grbl.on_report_options = on_report_my_options; + +// Add blink LED function to grblHAL foreground process +led_init(); +on_execute_realtime = grbl.on_execute_realtime; +grbl.on_execute_realtime = blink_led; + +// Enable F4MPV5 outputs +output_init(); +// Enable Steppers +X0set +; + +// Enable Encoder Timer +encoder_init(); +//HAL_TIM_Encoder_Start_IT(&htim2, TIM_CHANNEL_ALL); + +// Enable UART +static io_stream_details_t streams = + { + .n_streams = sizeof(serial) / sizeof(io_stream_properties_t), .streams = + serial, + }; +stream_register_streams(&streams); +// Enable VFD Spindle Control + +// Enable Constant Jogging +memset(&plan_data, 0, sizeof(plan_line_data_t)); // Zero plan_data struct + +} + diff --git a/Src/serial.c b/Src/serial.c index 6cd5f701..33656004 100644 --- a/Src/serial.c +++ b/Src/serial.c @@ -268,7 +268,7 @@ const io_stream_t *serialInit (uint32_t baud_rate) .port = GPIOA, .pin = 2, .mode = { .mask = PINMODE_OUTPUT }, - .description = "Primary UART" + .description = "UART1" }; static const periph_pin_t rx = { .function = Input_RX, @@ -276,7 +276,7 @@ const io_stream_t *serialInit (uint32_t baud_rate) .port = GPIOA, .pin = 3, .mode = { .mask = PINMODE_NONE }, - .description = "Primary UART" + .description = "UART1" }; @@ -299,7 +299,7 @@ const io_stream_t *serialInit (uint32_t baud_rate) .port = GPIOA, .pin = 9, .mode = { .mask = PINMODE_OUTPUT }, - .description = "Primary UART" + .description = "UART1" }; static const periph_pin_t rx = { @@ -308,7 +308,7 @@ const io_stream_t *serialInit (uint32_t baud_rate) .port = GPIOA, .pin = 10, .mode = { .mask = PINMODE_NONE }, - .description = "Primary UART" + .description = "UART1" }; #endif @@ -566,20 +566,20 @@ const io_stream_t *serial2Init (uint32_t baud_rate) static const periph_pin_t tx = { .function = Output_TX, - .group = PinGroup_UART2, + .group = PinGroup_UART + stream.instance, .port = GPIOA, .pin = 9, .mode = { .mask = PINMODE_OUTPUT }, - .description = "Secondary UART" + .description = "UART2" }; static const periph_pin_t rx = { .function = Input_RX, - .group = PinGroup_UART2, + .group = PinGroup_UART + stream.instance, .port = GPIOA, .pin = 10, .mode = { .mask = PINMODE_NONE }, - .description = "Secondary UART" + .description = "UART2" }; #else @@ -603,20 +603,20 @@ const io_stream_t *serial2Init (uint32_t baud_rate) static const periph_pin_t tx = { .function = Output_TX, - .group = PinGroup_UART2, + .group = PinGroup_UART + stream.instance, .port = GPIOA, .pin = 2, .mode = { .mask = PINMODE_OUTPUT }, - .description = "Secondary UART" + .description = "UART2" }; static const periph_pin_t rx = { .function = Input_RX, - .group = PinGroup_UART2, + .group = PinGroup_UART + stream.instance, .port = GPIOA, .pin = 3, .mode = { .mask = PINMODE_NONE }, - .description = "Secondary UART" + .description = "UART2" }; #endif diff --git a/Src/stm32f4xx_hal_msp.c b/Src/stm32f4xx_hal_msp.c index 63f0d4ca..1df04fa7 100644 --- a/Src/stm32f4xx_hal_msp.c +++ b/Src/stm32f4xx_hal_msp.c @@ -1,22 +1,22 @@ /* USER CODE BEGIN Header */ /** - ****************************************************************************** - * File Name : stm32f4xx_hal_msp.c - * Description : This file provides code for the MSP Initialization - * and de-Initialization codes. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ + ****************************************************************************** + * File Name : stm32f4xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ @@ -32,7 +32,7 @@ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN Define */ - + /* USER CODE END Define */ /* Private macro -------------------------------------------------------------*/ @@ -59,28 +59,29 @@ /* USER CODE END 0 */ /** - * Initializes the Global MSP. - */ + * Initializes the Global MSP. + */ void HAL_MspInit(void) { - /* USER CODE BEGIN MspInit 0 */ +/* USER CODE BEGIN MspInit 0 */ - /* USER CODE END MspInit 0 */ +/* USER CODE END MspInit 0 */ - __HAL_RCC_SYSCFG_CLK_ENABLE(); - __HAL_RCC_PWR_CLK_ENABLE(); +__HAL_RCC_SYSCFG_CLK_ENABLE(); +__HAL_RCC_PWR_CLK_ENABLE(); - HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); +HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); - /* System interrupt init*/ +/* System interrupt init*/ - /* USER CODE BEGIN MspInit 1 */ +/* USER CODE BEGIN MspInit 1 */ - /* USER CODE END MspInit 1 */ +/* USER CODE END MspInit 1 */ } /* USER CODE BEGIN 1 */ + /* USER CODE END 1 */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/