auto-sync
This commit is contained in:
parent
e9a334af67
commit
35a88fddbf
|
@ -77,6 +77,8 @@
|
|||
//#define EFI_POTENTIOMETER FALSE
|
||||
#define EFI_POTENTIOMETER TRUE
|
||||
|
||||
#define EFI_ANALOG_SENSORS TRUE
|
||||
|
||||
#define EFI_MAX_31855 TRUE
|
||||
|
||||
#define EFI_MCP_3208 FALSE
|
||||
|
|
|
@ -108,7 +108,7 @@ static void sayHello(void) {
|
|||
printMsg(&logger, "EFI_SIGNAL_EXECUTOR_HW_TIMER=%d", EFI_SIGNAL_EXECUTOR_HW_TIMER);
|
||||
#endif
|
||||
|
||||
#ifdef EFI_SHAFT_POSITION_INPUT
|
||||
#if defined(EFI_SHAFT_POSITION_INPUT) || defined(__DOXYGEN__)
|
||||
printMsg(&logger, "EFI_SHAFT_POSITION_INPUT=%d", EFI_SHAFT_POSITION_INPUT);
|
||||
#endif
|
||||
#ifdef EFI_INTERNAL_ADC
|
||||
|
|
|
@ -43,10 +43,7 @@
|
|||
#include "speed_density.h"
|
||||
|
||||
#include "advance_map.h"
|
||||
#if EFI_TUNER_STUDIO
|
||||
#include "tunerstudio.h"
|
||||
#endif /* EFI_TUNER_STUDIO */
|
||||
|
||||
#include "fuel_math.h"
|
||||
#include "main_trigger_callback.h"
|
||||
#include "engine_math.h"
|
||||
|
@ -161,7 +158,7 @@ void printSensors(Engine *engine) {
|
|||
}
|
||||
|
||||
void printState(Engine *engine, int currentCkpEventCounter) {
|
||||
#if EFI_SHAFT_POSITION_INPUT
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
printSensors(engine);
|
||||
|
||||
engine_configuration_s *engineConfiguration = engine->engineConfiguration;
|
||||
|
@ -434,7 +431,7 @@ static THD_WORKING_AREA(tsThreadStack, UTILITY_THREAD_STACK_SIZE);
|
|||
#if EFI_TUNER_STUDIO
|
||||
|
||||
void updateTunerStudioState(Engine *engine, TunerStudioOutputChannels *tsOutputChannels) {
|
||||
#if EFI_SHAFT_POSITION_INPUT
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
int rpm = getRpmE(engine);
|
||||
#else
|
||||
int rpm = 0;
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#ifndef TUNERSTUDIO_H_
|
||||
#define TUNERSTUDIO_H_
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_TUNER_STUDIO
|
||||
#include "tunerstudio_configuration.h"
|
||||
#include "engine.h"
|
||||
|
||||
|
@ -55,4 +58,6 @@ typedef pre_packed struct
|
|||
unsigned char value;
|
||||
} TunerStudioWriteValueRequest;
|
||||
|
||||
#endif /* EFI_TUNER_STUDIO */
|
||||
|
||||
#endif /* TUNERSTUDIO_H_ */
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
#if EFI_TUNER_STUDIO
|
||||
|
||||
TunerStudioState tsState;
|
||||
TunerStudioOutputChannels tsOutputChannels;
|
||||
/**
|
||||
|
@ -158,3 +160,5 @@ void handleTestCommand(void) {
|
|||
*/
|
||||
tunerStudioWriteData((const uint8_t *) " ts_p_alive\r\n", 8);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_PWM_TESTER
|
||||
|
||||
#include "PwmTester.h"
|
||||
#include "EfiWave.h"
|
||||
#include "pwm_generator_logic.h"
|
||||
|
@ -39,3 +42,5 @@ void initPwmTester(void) {
|
|||
addConsoleActionI("pwmtest", startPwmTest);
|
||||
// un-comment this to start pwm test on start up startPwmTest(1000);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_FSIO
|
||||
|
||||
#include "le_functions.h"
|
||||
#include "allsensors.h"
|
||||
#include "rpm_calculator.h"
|
||||
|
@ -68,3 +71,5 @@ void setFsioExt(engine_configuration_s *engineConfiguration, int index, brain_pi
|
|||
void setFsio(engine_configuration_s *engineConfiguration, int index, brain_pin_e pin, const char * exp) {
|
||||
setFsioExt(engineConfiguration, index, pin, exp, 0);
|
||||
}
|
||||
|
||||
#endif /* EFI_FSIO */
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_FSIO
|
||||
|
||||
#include "logic_expression.h"
|
||||
#include "le_functions.h"
|
||||
|
||||
|
@ -422,3 +425,5 @@ void parseUserFsio(DECLARE_ENGINE_PARAMETER_F) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* EFI_FSIO */
|
||||
|
|
|
@ -110,7 +110,7 @@ Engine * engine = &_engine;
|
|||
|
||||
static msg_t csThread(void) {
|
||||
chRegSetThreadName("status");
|
||||
#if EFI_SHAFT_POSITION_INPUT
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
while (true) {
|
||||
int rpm = getRpm();
|
||||
int is_cranking = isCrankingR(rpm);
|
||||
|
@ -194,6 +194,7 @@ static void cylinderCleanupControl(Engine *engine) {
|
|||
}
|
||||
}
|
||||
|
||||
#if EFI_FSIO
|
||||
static LECalculator calc;
|
||||
extern LEElement * fsioLogics[LE_COMMAND_COUNT];
|
||||
|
||||
|
@ -233,6 +234,102 @@ static void setPinState(io_pin_e ioPin, LEElement *element, Engine *engine) {
|
|||
}
|
||||
}
|
||||
|
||||
static void showFsio(const char *msg, LEElement *element) {
|
||||
if (msg != NULL)
|
||||
scheduleMsg(&logger, "%s:", msg);
|
||||
while (element != NULL) {
|
||||
scheduleMsg(&logger, "action %d: fValue=%f iValue=%d", element->action, element->fValue, element->iValue);
|
||||
element = element->next;
|
||||
}
|
||||
scheduleMsg(&logger, "<end>");
|
||||
}
|
||||
|
||||
static void showFsioInfo(void) {
|
||||
scheduleMsg(&logger, "sys used %d/user used %d", sysPool.getSize(), userPool.getSize());
|
||||
showFsio("a/c", acRelayLogic);
|
||||
showFsio("fuel", fuelPumpLogic);
|
||||
showFsio("fan", radiatorFanLogic);
|
||||
showFsio("alt", alternatorLogic);
|
||||
|
||||
for (int i = 0; i < LE_COMMAND_COUNT; i++) {
|
||||
char * exp = boardConfiguration->le_formulas[i];
|
||||
if (exp[0] != 0) {
|
||||
/**
|
||||
* in case of FSIO user interface indexes are starting with 0, the argument for that
|
||||
* is the fact that the target audience is more software developers
|
||||
*/
|
||||
scheduleMsg(&logger, "FSIO #%d [%s] at %s@%dHz value=%f", i, exp,
|
||||
hwPortname(boardConfiguration->fsioPins[i]), boardConfiguration->fsioFrequency[i],
|
||||
engineConfiguration2->fsioLastValue[i]);
|
||||
// scheduleMsg(&logger, "user-defined #%d value=%f", i, engine->engineConfiguration2->fsioLastValue[i]);
|
||||
showFsio(NULL, fsioLogics[i]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < LE_COMMAND_COUNT; i++) {
|
||||
float v = boardConfiguration->fsio_setting[i];
|
||||
if (!cisnan(v)) {
|
||||
scheduleMsg(&logger, "user property #%d: %f", i + 1, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setFsioSetting(float indexF, float value) {
|
||||
int index = indexF;
|
||||
if (index < 0 || index >= LE_COMMAND_COUNT) {
|
||||
scheduleMsg(&logger, "invalid index %d", index);
|
||||
return;
|
||||
}
|
||||
engineConfiguration->bc.fsio_setting[index] = value;
|
||||
showFsioInfo();
|
||||
}
|
||||
|
||||
static void setFsioFrequency(int index, int frequency) {
|
||||
index--;
|
||||
if (index < 0 || index >= LE_COMMAND_COUNT) {
|
||||
scheduleMsg(&logger, "invalid index %d", index);
|
||||
return;
|
||||
}
|
||||
boardConfiguration->fsioFrequency[index] = frequency;
|
||||
scheduleMsg(&logger, "Setting FSIO frequency %d on #%d", frequency, index + 1);
|
||||
}
|
||||
|
||||
static void setFsioPin(const char *indexStr, const char *pinName) {
|
||||
int index = atoi(indexStr) - 1;
|
||||
if (index < 0 || index >= LE_COMMAND_COUNT) {
|
||||
scheduleMsg(&logger, "invalid index %d", index);
|
||||
return;
|
||||
}
|
||||
brain_pin_e pin = parseBrainPin(pinName);
|
||||
// todo: extract method - code duplication with other 'set_xxx_pin' methods?
|
||||
if (pin == GPIO_INVALID) {
|
||||
scheduleMsg(&logger, "invalid pin name [%s]", pinName);
|
||||
return;
|
||||
}
|
||||
boardConfiguration->fsioPins[index] = pin;
|
||||
scheduleMsg(&logger, "FSIO pin #%d [%s]", (index + 1), hwPortname(pin));
|
||||
}
|
||||
|
||||
static void setUserOutput(const char *indexStr, const char *quotedLine, Engine *engine) {
|
||||
int index = atoi(indexStr) - 1;
|
||||
if (index < 0 || index >= LE_COMMAND_COUNT) {
|
||||
scheduleMsg(&logger, "invalid index %d", index);
|
||||
return;
|
||||
}
|
||||
char * l = unquote((char*) quotedLine);
|
||||
if (strlen(l) > LE_COMMAND_LENGTH - 1) {
|
||||
scheduleMsg(&logger, "Too long %d", strlen(l));
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleMsg(&logger, "setting user out #%d to [%s]", index + 1, l);
|
||||
strcpy(engine->engineConfiguration->bc.le_formulas[index], l);
|
||||
// this would apply the changes
|
||||
parseUserFsio(PASS_ENGINE_PARAMETER_F);
|
||||
showFsioInfo();
|
||||
}
|
||||
|
||||
#endif /* EFI_FSIO */
|
||||
|
||||
static void onEvenyGeneralMilliseconds(Engine *engine) {
|
||||
/**
|
||||
* We need to push current value into the 64 bit counter often enough so that we do not miss an overflow
|
||||
|
@ -249,6 +346,8 @@ static void onEvenyGeneralMilliseconds(Engine *engine) {
|
|||
engine->watchdog();
|
||||
engine->updateSlowSensors();
|
||||
|
||||
#if EFI_FSIO
|
||||
|
||||
for (int i = 0; i < LE_COMMAND_COUNT; i++) {
|
||||
handleFsio(engine, i);
|
||||
}
|
||||
|
@ -270,6 +369,7 @@ static void onEvenyGeneralMilliseconds(Engine *engine) {
|
|||
if (boardConfiguration->fanPin != GPIO_UNASSIGNED) {
|
||||
// setPinState(FAN_RELAY, radiatorFanLogic, engine);
|
||||
}
|
||||
#endif
|
||||
|
||||
updateErrorCodes();
|
||||
|
||||
|
@ -337,100 +437,6 @@ static void printAnalogInfo(void) {
|
|||
|
||||
static THD_WORKING_AREA(csThreadStack, UTILITY_THREAD_STACK_SIZE); // declare thread stack
|
||||
|
||||
static void showFsio(const char *msg, LEElement *element) {
|
||||
if (msg != NULL)
|
||||
scheduleMsg(&logger, "%s:", msg);
|
||||
while (element != NULL) {
|
||||
scheduleMsg(&logger, "action %d: fValue=%f iValue=%d", element->action, element->fValue, element->iValue);
|
||||
element = element->next;
|
||||
}
|
||||
scheduleMsg(&logger, "<end>");
|
||||
}
|
||||
|
||||
static void showFsioInfo(void) {
|
||||
scheduleMsg(&logger, "sys used %d/user used %d", sysPool.getSize(), userPool.getSize());
|
||||
showFsio("a/c", acRelayLogic);
|
||||
showFsio("fuel", fuelPumpLogic);
|
||||
showFsio("fan", radiatorFanLogic);
|
||||
showFsio("alt", alternatorLogic);
|
||||
|
||||
for (int i = 0; i < LE_COMMAND_COUNT; i++) {
|
||||
char * exp = boardConfiguration->le_formulas[i];
|
||||
if (exp[0] != 0) {
|
||||
/**
|
||||
* in case of FSIO user interface indexes are starting with 0, the argument for that
|
||||
* is the fact that the target audience is more software developers
|
||||
*/
|
||||
scheduleMsg(&logger, "FSIO #%d [%s] at %s@%dHz value=%f", i, exp,
|
||||
hwPortname(boardConfiguration->fsioPins[i]), boardConfiguration->fsioFrequency[i],
|
||||
engineConfiguration2->fsioLastValue[i]);
|
||||
// scheduleMsg(&logger, "user-defined #%d value=%f", i, engine->engineConfiguration2->fsioLastValue[i]);
|
||||
showFsio(NULL, fsioLogics[i]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < LE_COMMAND_COUNT; i++) {
|
||||
float v = boardConfiguration->fsio_setting[i];
|
||||
if (!cisnan(v)) {
|
||||
scheduleMsg(&logger, "user property #%d: %f", i + 1, v);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void setFsioSetting(float indexF, float value) {
|
||||
int index = indexF;
|
||||
if (index < 0 || index >= LE_COMMAND_COUNT) {
|
||||
scheduleMsg(&logger, "invalid index %d", index);
|
||||
return;
|
||||
}
|
||||
engineConfiguration->bc.fsio_setting[index] = value;
|
||||
showFsioInfo();
|
||||
}
|
||||
|
||||
static void setFsioFrequency(int index, int frequency) {
|
||||
index--;
|
||||
if (index < 0 || index >= LE_COMMAND_COUNT) {
|
||||
scheduleMsg(&logger, "invalid index %d", index);
|
||||
return;
|
||||
}
|
||||
boardConfiguration->fsioFrequency[index] = frequency;
|
||||
scheduleMsg(&logger, "Setting FSIO frequency %d on #%d", frequency, index + 1);
|
||||
}
|
||||
|
||||
static void setFsioPin(const char *indexStr, const char *pinName) {
|
||||
int index = atoi(indexStr) - 1;
|
||||
if (index < 0 || index >= LE_COMMAND_COUNT) {
|
||||
scheduleMsg(&logger, "invalid index %d", index);
|
||||
return;
|
||||
}
|
||||
brain_pin_e pin = parseBrainPin(pinName);
|
||||
// todo: extract method - code duplication with other 'set_xxx_pin' methods?
|
||||
if (pin == GPIO_INVALID) {
|
||||
scheduleMsg(&logger, "invalid pin name [%s]", pinName);
|
||||
return;
|
||||
}
|
||||
boardConfiguration->fsioPins[index] = pin;
|
||||
scheduleMsg(&logger, "FSIO pin #%d [%s]", (index + 1), hwPortname(pin));
|
||||
}
|
||||
|
||||
static void setUserOutput(const char *indexStr, const char *quotedLine, Engine *engine) {
|
||||
int index = atoi(indexStr) - 1;
|
||||
if (index < 0 || index >= LE_COMMAND_COUNT) {
|
||||
scheduleMsg(&logger, "invalid index %d", index);
|
||||
return;
|
||||
}
|
||||
char * l = unquote((char*) quotedLine);
|
||||
if (strlen(l) > LE_COMMAND_LENGTH - 1) {
|
||||
scheduleMsg(&logger, "Too long %d", strlen(l));
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleMsg(&logger, "setting user out #%d to [%s]", index + 1, l);
|
||||
strcpy(engine->engineConfiguration->bc.le_formulas[index], l);
|
||||
// this would apply the changes
|
||||
parseUserFsio(PASS_ENGINE_PARAMETER_F);
|
||||
showFsioInfo();
|
||||
}
|
||||
|
||||
static void setInt(const int offset, const int value) {
|
||||
int *ptr = (int *) (&((char *) engine->engineConfiguration)[offset]);
|
||||
|
@ -490,7 +496,7 @@ void initEngineContoller(Engine *engine) {
|
|||
}
|
||||
#endif /* EFI_WAVE_ANALYZER */
|
||||
|
||||
#if EFI_SHAFT_POSITION_INPUT
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* there is an implicit dependency on the fact that 'tachometer' listener is the 1st listener - this case
|
||||
* other listeners can access current RPM value
|
||||
|
@ -585,16 +591,18 @@ void initEngineContoller(Engine *engine) {
|
|||
}
|
||||
}
|
||||
|
||||
#if EFI_FSIO
|
||||
addConsoleActionSSP("set_fsio", (VoidCharPtrCharPtrVoidPtr) setUserOutput, engine);
|
||||
addConsoleActionSS("set_fsio_pin", (VoidCharPtrCharPtr) setFsioPin);
|
||||
addConsoleActionII("set_fsio_frequency", (VoidIntInt) setFsioFrequency);
|
||||
addConsoleActionFF("set_fsio_setting", setFsioSetting);
|
||||
addConsoleAction("fsioinfo", showFsioInfo);
|
||||
#endif
|
||||
|
||||
addConsoleActionSS("set_float", (VoidCharPtrCharPtr) setFloat);
|
||||
addConsoleActionII("set_int", (VoidIntInt) setInt);
|
||||
addConsoleActionI("get_float", getFloat);
|
||||
addConsoleActionI("get_int", getInt);
|
||||
|
||||
addConsoleActionFF("set_fsio_setting", setFsioSetting);
|
||||
addConsoleAction("fsioinfo", showFsioInfo);
|
||||
initEval(engine);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "engine_configuration.h"
|
||||
#include "engine.h"
|
||||
|
||||
#if EFI_IDLE_CONTROL || defined(__DOXYGEN__)
|
||||
|
||||
static THD_WORKING_AREA(ivThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||
|
||||
/**
|
||||
|
@ -152,3 +154,5 @@ void startIdleThread(Engine *engine) {
|
|||
addConsoleActionI("set_idle_pwm", setIdleValvePwm);
|
||||
addConsoleActionIP("set_idle_enabled", (VoidIntVoidPtr) setIdleControlEnabled, engine);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__)
|
||||
|
||||
#include "ignition_central.h"
|
||||
#include "io_pins.h"
|
||||
#include "signal_executor.h"
|
||||
|
@ -37,3 +40,5 @@ void initIgnitionCentral(void) {
|
|||
outputPinRegisterExt2(getPinName(pin), pin, boardConfiguration->ignitionPins[i], &boardConfiguration->ignitionPinMode);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// todo: merge with ignition_central and rename this file?
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__)
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "error_handling.h"
|
||||
#include "map.h"
|
||||
|
||||
#if EFI_ANALOG_SENSORS || defined(__DOXYGEN__)
|
||||
|
||||
extern engine_configuration_s * engineConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -67,3 +69,5 @@ float getBaroPressure(void) {
|
|||
float voltage = getVoltageDivided(engineConfiguration->baroSensor.hwChannel);
|
||||
return decodePressure(voltage, &engineConfiguration->baroSensor);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
|
||||
#include "trigger_central.h"
|
||||
#include "trigger_decoder.h"
|
||||
#include "main_trigger_callback.h"
|
||||
|
@ -306,3 +309,5 @@ void initTriggerCentral(Engine *engine) {
|
|||
initHistogram(&triggerCallback, "all callbacks");
|
||||
#endif /* EFI_HISTOGRAMS */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
|
||||
#include "obd_error_codes.h"
|
||||
#include "trigger_decoder.h"
|
||||
#include "cyclic_buffer.h"
|
||||
|
@ -445,3 +448,4 @@ void initTriggerDecoder(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -273,7 +273,7 @@ void initHardware(Logging *logger, Engine *engine) {
|
|||
// todo: figure out better startup logic
|
||||
initTriggerCentral(engine);
|
||||
|
||||
#if EFI_SHAFT_POSITION_INPUT
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
initShaftPositionInputCapture();
|
||||
#endif /* EFI_SHAFT_POSITION_INPUT */
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "main.h"
|
||||
|
||||
#if EFI_SHAFT_POSITION_INPUT
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
|
||||
#include "trigger_input.h"
|
||||
#include "wave_analyzer_hw.h"
|
||||
|
|
|
@ -30,4 +30,6 @@
|
|||
#define EFI_SHAFT_POSITION_INPUT TRUE
|
||||
#define EFI_ENGINE_CONTROL TRUE
|
||||
|
||||
#define EFI_ANALOG_SENSORS TRUE
|
||||
|
||||
#endif /* EFIFEATURES_H_ */
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
|
||||
#define EFI_WAVE_CHART TRUE
|
||||
|
||||
#define EFI_ANALOG_SENSORS TRUE
|
||||
|
||||
#define EFI_ANALOG_CHART TRUE
|
||||
#define EFI_HISTOGRAMS TRUE
|
||||
|
||||
|
|
Loading…
Reference in New Issue