diff --git a/.vscode/settings.json b/.vscode/settings.json index 314f86f..fd74a15 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,8 +3,7 @@ "idf.portWin": "COM72", "idf.adapterTargetName": "esp32s3", "idf.openOcdConfigs": [ - "interface/ftdi/esp32_devkitj_v1.cfg", - "target/esp32s3.cfg" + "board/esp32s3-builtin.cfg" ], "files.associations": { "freertos.h": "c", @@ -52,7 +51,11 @@ "tuple": "c", "type_traits": "c", "utility": "c", - "compare": "c" + "compare": "c", + "cmath": "c", + "utils.h": "c", + "task.h": "c", + "stdlib.h": "c" }, "editor.formatOnSave": false, "cSpell.words": [ diff --git a/components/asic/bm1366.c b/components/asic/bm1366.c index 153bd16..e84309c 100644 --- a/components/asic/bm1366.c +++ b/components/asic/bm1366.c @@ -15,7 +15,7 @@ #include #include -#define BM1366_RST_PIN GPIO_NUM_1 +#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET #define TYPE_JOB 0x20 #define TYPE_CMD 0x40 @@ -318,13 +318,13 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count) // reset the BM1366 via the RTS line static void _reset(void) { - gpio_set_level(BM1366_RST_PIN, 0); + gpio_set_level(GPIO_ASIC_RESET, 0); // delay for 100ms vTaskDelay(100 / portTICK_PERIOD_MS); // set the gpio pin high - gpio_set_level(BM1366_RST_PIN, 1); + gpio_set_level(GPIO_ASIC_RESET, 1); // delay for 100ms vTaskDelay(100 / portTICK_PERIOD_MS); @@ -344,8 +344,8 @@ uint8_t BM1366_init(uint64_t frequency, uint16_t asic_count) memset(asic_response_buffer, 0, SERIAL_BUF_SIZE); - esp_rom_gpio_pad_select_gpio(BM1366_RST_PIN); - gpio_set_direction(BM1366_RST_PIN, GPIO_MODE_OUTPUT); + esp_rom_gpio_pad_select_gpio(GPIO_ASIC_RESET); + gpio_set_direction(GPIO_ASIC_RESET, GPIO_MODE_OUTPUT); // reset the bm1366 _reset(); diff --git a/components/asic/bm1368.c b/components/asic/bm1368.c index 802a70d..81f27c5 100644 --- a/components/asic/bm1368.c +++ b/components/asic/bm1368.c @@ -1,4 +1,5 @@ #include "bm1368.h" + #include "crc.h" #include "global_state.h" #include "serial.h" @@ -14,7 +15,7 @@ #include #include -#define BM1368_RST_PIN GPIO_NUM_1 +#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET #define TYPE_JOB 0x20 #define TYPE_CMD 0x40 @@ -121,9 +122,9 @@ void BM1368_set_version_mask(uint32_t version_mask) static void _reset(void) { - gpio_set_level(BM1368_RST_PIN, 0); + gpio_set_level(GPIO_ASIC_RESET, 0); vTaskDelay(100 / portTICK_PERIOD_MS); - gpio_set_level(BM1368_RST_PIN, 1); + gpio_set_level(GPIO_ASIC_RESET, 1); vTaskDelay(100 / portTICK_PERIOD_MS); } @@ -242,8 +243,8 @@ uint8_t BM1368_init(uint64_t frequency, uint16_t asic_count) memset(asic_response_buffer, 0, CHUNK_SIZE); - esp_rom_gpio_pad_select_gpio(BM1368_RST_PIN); - gpio_set_direction(BM1368_RST_PIN, GPIO_MODE_OUTPUT); + esp_rom_gpio_pad_select_gpio(GPIO_ASIC_RESET); + gpio_set_direction(GPIO_ASIC_RESET, GPIO_MODE_OUTPUT); _reset(); diff --git a/components/asic/bm1370.c b/components/asic/bm1370.c index 05bc067..2c6b18d 100644 --- a/components/asic/bm1370.c +++ b/components/asic/bm1370.c @@ -15,7 +15,7 @@ #include #include -#define BM1370_RST_PIN GPIO_NUM_1 +#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET #define TYPE_JOB 0x20 #define TYPE_CMD 0x40 @@ -329,13 +329,13 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count) // reset the BM1370 via the RTS line static void _reset(void) { - gpio_set_level(BM1370_RST_PIN, 0); + gpio_set_level(GPIO_ASIC_RESET, 0); // delay for 100ms vTaskDelay(100 / portTICK_PERIOD_MS); // set the gpio pin high - gpio_set_level(BM1370_RST_PIN, 1); + gpio_set_level(GPIO_ASIC_RESET, 1); // delay for 100ms vTaskDelay(100 / portTICK_PERIOD_MS); @@ -355,8 +355,8 @@ uint8_t BM1370_init(uint64_t frequency, uint16_t asic_count) memset(asic_response_buffer, 0, SERIAL_BUF_SIZE); - esp_rom_gpio_pad_select_gpio(BM1370_RST_PIN); - gpio_set_direction(BM1370_RST_PIN, GPIO_MODE_OUTPUT); + esp_rom_gpio_pad_select_gpio(GPIO_ASIC_RESET); + gpio_set_direction(GPIO_ASIC_RESET, GPIO_MODE_OUTPUT); // reset the bm1370 _reset(); diff --git a/components/asic/bm1397.c b/components/asic/bm1397.c index ae10016..7c39b1a 100644 --- a/components/asic/bm1397.c +++ b/components/asic/bm1397.c @@ -15,7 +15,7 @@ #include "mining.h" #include "global_state.h" -#define BM1397_RST_PIN GPIO_NUM_1 +#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET #define TYPE_JOB 0x20 #define TYPE_CMD 0x40 @@ -278,13 +278,13 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count) // reset the BM1397 via the RTS line static void _reset(void) { - gpio_set_level(BM1397_RST_PIN, 0); + gpio_set_level(GPIO_ASIC_RESET, 0); // delay for 100ms vTaskDelay(100 / portTICK_PERIOD_MS); // set the gpio pin high - gpio_set_level(BM1397_RST_PIN, 1); + gpio_set_level(GPIO_ASIC_RESET, 1); // delay for 100ms vTaskDelay(100 / portTICK_PERIOD_MS); @@ -296,8 +296,8 @@ uint8_t BM1397_init(uint64_t frequency, uint16_t asic_count) memset(asic_response_buffer, 0, SERIAL_BUF_SIZE); - esp_rom_gpio_pad_select_gpio(BM1397_RST_PIN); - gpio_set_direction(BM1397_RST_PIN, GPIO_MODE_OUTPUT); + esp_rom_gpio_pad_select_gpio(GPIO_ASIC_RESET); + gpio_set_direction(GPIO_ASIC_RESET, GPIO_MODE_OUTPUT); // reset the bm1397 _reset(); diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index ee5d8f7..0faff7c 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -5,7 +5,6 @@ SRCS "EMC2101.c" "i2c_bitaxe.c" "INA260.c" - "led_controller.c" "main.c" "nvs_config.c" "display.c" diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 34249ab..10dd8a1 100755 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -1,4 +1,45 @@ menu "Bitaxe Configuration" + + menu "GPIO Pin Configuration" + + config GPIO_BUTTON_BOOT + int "Boot button GPIO pin" + default 0 + help + GPIO pin connected to the LED. + + config GPIO_ASIC_RESET + int "ASIC reset GPIO pin" + default 1 + help + GPIO pin connected to the Button. + + config GPIO_ASIC_ENABLE + int "ASIC enable GPIO pin" + default 10 + help + GPIO pin for I2C data line (SDA). + + config GPIO_PLUG_SENSE + int "Barrel plug sense GPIO pin" + default 12 + help + GPIO pin for I2C clock line (SCL). + + config GPIO_I2C_SDA + int "I2C SDA Pin" + default 47 + help + GPIO pin for I2C clock line (SCL). + + config GPIO_I2C_SCL + int "I2C SCL Pin" + default 48 + help + GPIO pin for I2C clock line (SCL). + + endmenu + config ASIC_VOLTAGE int "ASIC Core Voltage (mV)" range 1000 1800 diff --git a/main/i2c_bitaxe.c b/main/i2c_bitaxe.c index 6ed70f8..e72a186 100644 --- a/main/i2c_bitaxe.c +++ b/main/i2c_bitaxe.c @@ -2,8 +2,10 @@ #include "esp_log.h" #include "i2c_bitaxe.h" -#define I2C_MASTER_SCL_IO 48 /*!< GPIO number used for I2C master clock */ -#define I2C_MASTER_SDA_IO 47 /*!< GPIO number used for I2C master data */ +#define GPIO_I2C_SDA CONFIG_GPIO_I2C_SDA +#define GPIO_I2C_SCL CONFIG_GPIO_I2C_SCL + +#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ #define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */ #define I2C_MASTER_TIMEOUT_MS 1000 @@ -21,8 +23,8 @@ esp_err_t i2c_bitaxe_init(void) i2c_master_bus_config_t i2c_bus_config = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = I2C_MASTER_NUM, - .scl_io_num = I2C_MASTER_SCL_IO, - .sda_io_num = I2C_MASTER_SDA_IO, + .scl_io_num = GPIO_I2C_SCL, + .sda_io_num = GPIO_I2C_SDA, .glitch_ignore_cnt = 7, .flags.enable_internal_pullup = true, }; diff --git a/main/input.c b/main/input.c index bcbb912..5728efa 100644 --- a/main/input.c +++ b/main/input.c @@ -5,7 +5,8 @@ #include "esp_lvgl_port.h" #include "driver/gpio.h" -#define BUTTON_BOOT_GPIO GPIO_NUM_0 +#define GPIO_BUTTON_BOOT CONFIG_GPIO_BUTTON_BOOT + #define ESP_INTR_FLAG_DEFAULT 0 #define LONG_PRESS_DURATION_MS 2000 @@ -24,7 +25,7 @@ static void button_read(lv_indev_t *indev, lv_indev_data_t *data) static void IRAM_ATTR button_isr_handler(void *arg) { - bool pressed = gpio_get_level(BUTTON_BOOT_GPIO) == 0; // LOW when pressed + bool pressed = gpio_get_level(GPIO_BUTTON_BOOT) == 0; // LOW when pressed button_state = pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; } @@ -46,7 +47,7 @@ esp_err_t input_init(void (*button_short_clicked_cb)(void), void (*button_long_p // Button handling gpio_config_t io_conf = { - .pin_bit_mask = (1ULL << BUTTON_BOOT_GPIO), + .pin_bit_mask = (1ULL << GPIO_BUTTON_BOOT), .mode = GPIO_MODE_INPUT, .pull_up_en = GPIO_PULLUP_ENABLE, .intr_type = GPIO_INTR_ANYEDGE @@ -55,7 +56,7 @@ esp_err_t input_init(void (*button_short_clicked_cb)(void), void (*button_long_p // Install ISR service and hook the interrupt handler ESP_RETURN_ON_ERROR(gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT), TAG, "Error installing ISR service"); - ESP_RETURN_ON_ERROR(gpio_isr_handler_add(BUTTON_BOOT_GPIO, button_isr_handler, NULL), TAG, "Error adding ISR handler"); + ESP_RETURN_ON_ERROR(gpio_isr_handler_add(GPIO_BUTTON_BOOT, button_isr_handler, NULL), TAG, "Error adding ISR handler"); lv_group_t * group = lv_group_create(); lv_group_set_default(group); diff --git a/main/led_controller.c b/main/led_controller.c deleted file mode 100644 index 6ceb459..0000000 --- a/main/led_controller.c +++ /dev/null @@ -1,122 +0,0 @@ -#include -#include "esp_err.h" -#include "driver/ledc.h" -#include "driver/gpio.h" - -// LEDS -#define LEDX_R GPIO_NUM_35 -#define LEDX_G GPIO_NUM_36 -#define LEDX_B GPIO_NUM_37 -#define LEDZ_R GPIO_NUM_5 -#define LEDZ_G GPIO_NUM_6 -#define LEDZ_B GPIO_NUM_7 - -void initLEDs(void) -{ - gpio_set_direction(LEDX_R, GPIO_MODE_OUTPUT); - gpio_set_direction(LEDX_G, GPIO_MODE_OUTPUT); - gpio_set_direction(LEDX_B, GPIO_MODE_OUTPUT); - gpio_set_direction(LEDZ_R, GPIO_MODE_OUTPUT); - gpio_set_direction(LEDZ_G, GPIO_MODE_OUTPUT); - gpio_set_direction(LEDZ_B, GPIO_MODE_OUTPUT); - - gpio_set_level(LEDX_R, 0); - gpio_set_level(LEDX_G, 0); - gpio_set_level(LEDX_B, 0); - gpio_set_level(LEDZ_R, 0); - gpio_set_level(LEDZ_G, 0); - gpio_set_level(LEDZ_B, 0); -} - -void ledc_init(void) -{ - // Prepare and then apply the LEDC PWM timer configuration - ledc_timer_config_t ledc_timer = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .timer_num = LEDC_TIMER_0, - .duty_resolution = LEDC_TIMER_12_BIT, // Set duty resolution to 12 bits - .freq_hz = 5000, // Set output frequency at 5 kHz - .clk_cfg = LEDC_AUTO_CLK}; - ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); - - // Prepare and then apply the LEDC PWM channel configuration - ledc_channel_config_t ledc_channel0 = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_0, - .timer_sel = LEDC_TIMER_0, - .intr_type = LEDC_INTR_DISABLE, - .gpio_num = 35, // Define the output GPIO - .duty = 0, // Set duty to 0% - .hpoint = 0}; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel0)); - - ledc_channel_config_t ledc_channel1 = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_1, - .timer_sel = LEDC_TIMER_0, - .intr_type = LEDC_INTR_DISABLE, - .gpio_num = 36, // Define the output GPIO - .duty = 0, // Set duty to 0% - .hpoint = 0}; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel1)); - - ledc_channel_config_t ledc_channel2 = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_2, - .timer_sel = LEDC_TIMER_0, - .intr_type = LEDC_INTR_DISABLE, - .gpio_num = 37, // Define the output GPIO - .duty = 0, // Set duty to 0% - .hpoint = 0}; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel2)); - - ledc_channel_config_t ledc_channel3 = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_3, - .timer_sel = LEDC_TIMER_0, - .intr_type = LEDC_INTR_DISABLE, - .gpio_num = 38, // Define the output GPIO - .duty = 0, // Set duty to 0% - .hpoint = 0}; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel3)); - - ledc_channel_config_t ledc_channel4 = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_4, - .timer_sel = LEDC_TIMER_0, - .intr_type = LEDC_INTR_DISABLE, - .gpio_num = 39, // Define the output GPIO - .duty = 0, // Set duty to 0% - .hpoint = 0}; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel4)); - - ledc_channel_config_t ledc_channel5 = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_5, - .timer_sel = LEDC_TIMER_0, - .intr_type = LEDC_INTR_DISABLE, - .gpio_num = 40, // Define the output GPIO - .duty = 0, // Set duty to 0% - .hpoint = 0}; - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel5)); -} - -void led_set(void) -{ - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 3000)); // r - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, 1000)); // g - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2, 0)); // b - - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_3, 3000)); // r - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_4, 1000)); // g - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_5, 0)); // b - - // Update duty to apply the new value - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2)); - - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_3)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_4)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_5)); -} \ No newline at end of file diff --git a/main/led_controller.h b/main/led_controller.h deleted file mode 100644 index bdf2002..0000000 --- a/main/led_controller.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef LED_CONTROLLER_H_ -#define LED_CONTROLLER_H_ - -void initLEDs(void); -void ledc_init(void); -void led_set(void); - -#endif /* LED_CONTROLLER_H_ */ \ No newline at end of file diff --git a/main/self_test/self_test.c b/main/self_test/self_test.c index 1418159..f2724db 100644 --- a/main/self_test/self_test.c +++ b/main/self_test/self_test.c @@ -22,6 +22,8 @@ #include "utils.h" #include "TPS546.h" +#define GPIO_ASIC_ENABLE CONFIG_GPIO_ASIC_ENABLE + #define TESTS_FAILED 0 #define TESTS_PASSED 1 @@ -212,8 +214,8 @@ esp_err_t test_voltage_regulator(GlobalState * GLOBAL_STATE) { case DEVICE_ULTRA: case DEVICE_SUPRA: // turn ASIC on - gpio_set_direction(GPIO_NUM_10, GPIO_MODE_OUTPUT); - gpio_set_level(GPIO_NUM_10, 0); + gpio_set_direction(GPIO_ASIC_ENABLE, GPIO_MODE_OUTPUT); + gpio_set_level(GPIO_ASIC_ENABLE, 0); break; case DEVICE_GAMMA: default: diff --git a/main/system.c b/main/system.c index 51c18a4..aac5524 100644 --- a/main/system.c +++ b/main/system.c @@ -24,7 +24,6 @@ #include "INA260.h" #include "adc.h" #include "connect.h" -#include "led_controller.h" #include "nvs_config.h" #include "display.h" #include "input.h" diff --git a/main/tasks/power_management_task.c b/main/tasks/power_management_task.c index 0bd0a8d..b96abd3 100644 --- a/main/tasks/power_management_task.c +++ b/main/tasks/power_management_task.c @@ -1,3 +1,4 @@ +#include #include "EMC2101.h" #include "INA260.h" #include "bm1397.h" @@ -11,7 +12,10 @@ #include "serial.h" #include "TPS546.h" #include "vcore.h" -#include + +#define GPIO_ASIC_ENABLE CONFIG_GPIO_ASIC_ENABLE +#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET +#define GPIO_PLUG_SENSE CONFIG_GPIO_PLUG_SENSE #define POLL_RATE 2000 #define MAX_TEMP 90.0 @@ -93,21 +97,21 @@ void POWER_MANAGEMENT_task(void * pvParameters) case DEVICE_ULTRA: case DEVICE_SUPRA: if (GLOBAL_STATE->board_version < 402 || GLOBAL_STATE->board_version > 499) { - // Configure GPIO12 as input(barrel jack) 1 is plugged in + // Configure plug sense pin as input(barrel jack) 1 is plugged in gpio_config_t barrel_jack_conf = { - .pin_bit_mask = (1ULL << GPIO_NUM_12), + .pin_bit_mask = (1ULL << GPIO_PLUG_SENSE), .mode = GPIO_MODE_INPUT, }; gpio_config(&barrel_jack_conf); - int barrel_jack_plugged_in = gpio_get_level(GPIO_NUM_12); + int barrel_jack_plugged_in = gpio_get_level(GPIO_PLUG_SENSE); - gpio_set_direction(GPIO_NUM_10, GPIO_MODE_OUTPUT); + gpio_set_direction(GPIO_ASIC_ENABLE, GPIO_MODE_OUTPUT); if (barrel_jack_plugged_in == 1 || !power_management->HAS_PLUG_SENSE) { // turn ASIC on - gpio_set_level(GPIO_NUM_10, 0); + gpio_set_level(GPIO_ASIC_ENABLE, 0); } else { // turn ASIC off - gpio_set_level(GPIO_NUM_10, 1); + gpio_set_level(GPIO_ASIC_ENABLE, 1); } } break; @@ -165,7 +169,7 @@ void POWER_MANAGEMENT_task(void * pvParameters) EMC2101_set_fan_speed(1); if (power_management->HAS_POWER_EN) { - gpio_set_level(GPIO_NUM_10, 1); + gpio_set_level(GPIO_ASIC_ENABLE, 1); } nvs_config_set_u16(NVS_CONFIG_ASIC_VOLTAGE, 1000); nvs_config_set_u16(NVS_CONFIG_ASIC_FREQ, 50); @@ -201,7 +205,7 @@ void POWER_MANAGEMENT_task(void * pvParameters) // Turn off core voltage VCORE_set_voltage(0.0, GLOBAL_STATE); } else if (power_management->HAS_POWER_EN) { - gpio_set_level(GPIO_NUM_10, 1); + gpio_set_level(GPIO_ASIC_ENABLE, 1); } nvs_config_set_u16(NVS_CONFIG_ASIC_VOLTAGE, 1000); nvs_config_set_u16(NVS_CONFIG_ASIC_FREQ, 50); @@ -263,12 +267,12 @@ void POWER_MANAGEMENT_task(void * pvParameters) } } - // Read the state of GPIO12 + // Read the state of plug sense pin if (power_management->HAS_PLUG_SENSE) { - int gpio12_state = gpio_get_level(GPIO_NUM_12); - if (gpio12_state == 0) { + int gpio_plug_sense_state = gpio_get_level(GPIO_PLUG_SENSE); + if (gpio_plug_sense_state == 0) { // turn ASIC off - gpio_set_level(GPIO_NUM_10, 1); + gpio_set_level(GPIO_ASIC_ENABLE, 1); } }