Skip to content

Commit

Permalink
scpi flow component separated from MP scripting
Browse files Browse the repository at this point in the history
  • Loading branch information
mvladic committed Nov 18, 2021
1 parent 92cac3a commit 7723039
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 123 deletions.
Binary file modified scripts/DC Power App/DC Power.app
Binary file not shown.
192 changes: 92 additions & 100 deletions scripts/DC Power App/DC Power.eez-project

Large diffs are not rendered by default.

146 changes: 135 additions & 11 deletions src/eez/flow/components/scpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,126 @@
#include <stdio.h>

#include <eez/alloc.h>
#include <eez/scripting/scripting.h>

#include <eez/flow/components.h>
#include <eez/flow/flow_defs_v3.h>
#include <eez/flow/expression.h>
#include <eez/flow/queue.h>
#include <eez/flow/debugger.h>

#include <bb3/psu/datetime.h>
#include <bb3/psu/scpi/psu.h>

using namespace eez::gui;

namespace eez {
namespace flow {

////////////////////////////////////////////////////////////////////////////////

using namespace eez::scpi;
using namespace eez::psu::scpi;

static char g_scpiData[SCPI_PARSER_INPUT_BUFFER_LENGTH + 1];
static size_t g_scpiDataLen;
static int_fast16_t g_lastError;

size_t SCPI_Write(scpi_t *context, const char *data, size_t len) {
len = MIN(len, SCPI_PARSER_INPUT_BUFFER_LENGTH - g_scpiDataLen);
if (len > 0) {
memcpy(g_scpiData + g_scpiDataLen, data, len);
g_scpiDataLen += len;
g_scpiData[g_scpiDataLen] = 0;
}
return len;
}

scpi_result_t SCPI_Flush(scpi_t *context) {
return SCPI_RES_OK;
}

int SCPI_Error(scpi_t *context, int_fast16_t err) {
g_lastError = err;

if (err != 0) {
DebugTrace("**ERROR");

char datetime_buffer[32] = { 0 };
if (psu::datetime::getDateTimeAsString(datetime_buffer)) {
DebugTrace(" [%s]", datetime_buffer);
}

DebugTrace(": %d,\"%s\"\r\n", (int16_t)err, SCPI_ErrorTranslate(err));

if (err == SCPI_ERROR_INPUT_BUFFER_OVERRUN) {
psu::scpi::onBufferOverrun(*context);
}
}

return 0;
}

scpi_result_t SCPI_Control(scpi_t *context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) {
return SCPI_RES_OK;
}

scpi_result_t SCPI_Reset(scpi_t *context) {
return eez::reset() ? SCPI_RES_OK : SCPI_RES_ERR;
}

static scpi_reg_val_t g_scpiPsuRegs[SCPI_PSU_REG_COUNT];
static scpi_psu_t g_scpiPsuContext = { g_scpiPsuRegs };

static scpi_interface_t g_scpiInterface = {
SCPI_Error, SCPI_Write, SCPI_Control, SCPI_Flush, SCPI_Reset,
};

static char g_scpiInputBuffer[SCPI_PARSER_INPUT_BUFFER_LENGTH];
static scpi_error_t g_errorQueueData[SCPI_PARSER_ERROR_QUEUE_SIZE + 1];

scpi_t g_scpiContext;

////////////////////////////////////////////////////////////////////////////////

bool getLatestScpiResult(const char **resultText, size_t *resultTextLen, int *err) {
if (g_lastError != 0) {
if (err) {
*err = g_lastError;
}
return false;
}

if (g_scpiDataLen >= 2 && g_scpiData[g_scpiDataLen - 2] == '\r' && g_scpiData[g_scpiDataLen - 1] == '\n') {
g_scpiDataLen -= 2;
g_scpiData[g_scpiDataLen] = 0;
}

if (g_scpiDataLen >= 3 && g_scpiData[0] == '"' && g_scpiData[g_scpiDataLen - 1] == '"') {
// replace "" with "
size_t j = 1;
size_t i;
for (i = 1; i < g_scpiDataLen - 2; i++, j++) {
g_scpiData[j] = g_scpiData[i];
if (g_scpiData[i] == '"' && g_scpiData[i + 1] == '"') {
i++;
}
}
g_scpiData[j] = g_scpiData[i];
g_scpiData[j + 1] = '"';
g_scpiDataLen -= i - j;
}

// if (g_scpiDataLen > 0) {
// DebugTrace("< %s\n", g_scpiData);
// }

*resultText = g_scpiData;
*resultTextLen = g_scpiDataLen;
return true;
}

////////////////////////////////////////////////////////////////////////////////

// When passed quoted string as '"str"' it will return unquoted string as 'str'.
// Returns false if passed value is not a valid string.
bool parseScpiString(const char *&textArg, size_t &textLenArg) {
Expand Down Expand Up @@ -62,6 +169,7 @@ bool parseScpiString(const char *&textArg, size_t &textLenArg) {
return true;
}

////////////////////////////////////////////////////////////////////////////////

struct ScpiComponentExecutionState : public ComponenentExecutionState {
uint8_t op;
Expand All @@ -82,28 +190,44 @@ struct ScpiComponentExecutionState : public ComponenentExecutionState {
g_waitingForScpiResult = nullptr;
return true;
}
} else {
g_waitingForScpiResult = this;
g_scpiResultIsReady = false;

return false;
}

stringAppendString(commandOrQueryText, sizeof(commandOrQueryText), "\n");
scripting::executeScpiFromFlow(commandOrQueryText);
}
g_waitingForScpiResult = this;
g_scpiResultIsReady = false;

sendMessageToLowPriorityThread(FLOW_EXECUTE_SCPI);
return false;
}
};

ScpiComponentExecutionState *ScpiComponentExecutionState::g_waitingForScpiResult;
bool ScpiComponentExecutionState::g_scpiResultIsReady;

////////////////////////////////////////////////////////////////////////////////

void scpiComponentInit() {
eez::psu::scpi::init(g_scpiContext, g_scpiPsuContext, &g_scpiInterface, g_scpiInputBuffer, SCPI_PARSER_INPUT_BUFFER_LENGTH, g_errorQueueData, SCPI_PARSER_ERROR_QUEUE_SIZE + 1);

ScpiComponentExecutionState::g_waitingForScpiResult = nullptr;
}

void scpiResultIsReady() {
void executeScpi() {
g_scpiDataLen = 0;
g_lastError = 0;

input(g_scpiContext,
(const char *)ScpiComponentExecutionState::g_waitingForScpiResult->commandOrQueryText,
strlen(ScpiComponentExecutionState::g_waitingForScpiResult->commandOrQueryText)
);
input(g_scpiContext, "\r\n", 2);

ScpiComponentExecutionState::g_scpiResultIsReady = true;
}

////////////////////////////////////////////////////////////////////////////////

struct ScpiActionComponent : public Component {
uint8_t instructions[1];
};
Expand Down Expand Up @@ -178,7 +302,7 @@ void executeScpiComponent(FlowState *flowState, unsigned componentIndex) {
const char *resultText;
size_t resultTextLen;
int err;
if (!scripting::getLatestScpiResult(&resultText, &resultTextLen, &err)) {
if (!getLatestScpiResult(&resultText, &resultTextLen, &err)) {
char errorMessage[300];
snprintf(errorMessage, sizeof(errorMessage), "%s\n", SCPI_ErrorTranslate(err));

Expand Down Expand Up @@ -240,7 +364,7 @@ void executeScpiComponent(FlowState *flowState, unsigned componentIndex) {
const char *resultText;
size_t resultTextLen;
int err;
if (!scripting::getLatestScpiResult(&resultText, &resultTextLen, &err)) {
if (!getLatestScpiResult(&resultText, &resultTextLen, &err)) {
char errorMessage[300];
snprintf(errorMessage, sizeof(errorMessage), "%s\n", SCPI_ErrorTranslate(err));

Expand Down Expand Up @@ -268,7 +392,7 @@ void executeScpiComponent(FlowState *flowState, unsigned componentIndex) {
const char *resultText;
size_t resultTextLen;
int err;
if (!scripting::getLatestScpiResult(&resultText, &resultTextLen, &err)) {
if (!getLatestScpiResult(&resultText, &resultTextLen, &err)) {
char errorMessage[300];
snprintf(errorMessage, sizeof(errorMessage), "%s\n", SCPI_ErrorTranslate(err));

Expand Down
7 changes: 6 additions & 1 deletion src/eez/flow/flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ unsigned start(Assets *assets) {
onStarted(assets);

for (uint32_t i = 0; i < assets->pages.count; i++) {
g_pagesFlowState[i] = initPageFlowState(assets, i, nullptr, 0);
auto page = assets->pages.item(assets, i);
if (!(page->flags & PAGE_IS_USED_AS_CUSTOM_WIDGET)) {
g_pagesFlowState[i] = initPageFlowState(assets, i, nullptr, 0);
} else {
g_pagesFlowState[i] = nullptr;
}
}
g_mainPageFlowState = g_pagesFlowState[0];

Expand Down
3 changes: 2 additions & 1 deletion src/eez/flow/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ struct FlowState;

unsigned start(eez::gui::Assets *assets);
void tick();
void scpiResultIsReady();
void stop();

FlowState *getFlowState(int16_t pageId, const WidgetCursor &widgetCursor);
Expand All @@ -42,5 +41,7 @@ void onDebuggerClientConnected();
void onDebuggerClientDisconnected();
void onDebuggerInputAvailable();

void executeScpi();

} // flow
} // eez
5 changes: 3 additions & 2 deletions src/eez/gui/assets.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ struct ListOfFundamentalType {

////////////////////////////////////////////////////////////////////////////////

#define SHADOW_FLAG 1
#define CLOSE_PAGE_IF_TOUCHED_OUTSIDE_FLAG 2
#define SHADOW_FLAG (1 << 0)
#define CLOSE_PAGE_IF_TOUCHED_OUTSIDE_FLAG (1 << 1)
#define PAGE_IS_USED_AS_CUSTOM_WIDGET (1 << 2)

struct Widget {
uint16_t type;
Expand Down
5 changes: 0 additions & 5 deletions src/eez/scripting/flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,6 @@ void flowTick() {
}
}

void executeScpiFromFlow(const char *commandOrQueryText) {
// DebugTrace("> %s\n", commandOrQueryText);
executeScpi(commandOrQueryText, true);
}

////////////////////////////////////////////////////////////////////////////////

void executeFlowAction(const WidgetCursor &widgetCursor, int16_t actionId) {
Expand Down
1 change: 0 additions & 1 deletion src/eez/scripting/scripting.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ bool stopScript(int *err = nullptr);
inline bool isIdle() { return g_state == STATE_IDLE; }

bool executeScpiFromMP(const char *commandOrQueryText, const char **resultText, size_t *resultTextLen);
void executeScpiFromFlow(const char *commandOrQueryText);
bool getLatestScpiResult(const char **resultText, size_t *resultTextLen, int *err);

bool isFlowRunning();
Expand Down
2 changes: 0 additions & 2 deletions src/eez/scripting/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ void oneIter() {
if (event.status == osEventMessage) {
if (event.value.v == QUEUE_MESSAGE_START_MP_SCRIPT) {
startMpScript();
} else if (event.value.v == QUEUE_MESSAGE_SCPI_RESULT) {
flow::scpiResultIsReady();
}
} else {
//flowTick();
Expand Down
5 changes: 5 additions & 0 deletions src/eez/tasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#endif

#include <eez/tasks.h>
#include <eez/flow/flow.h>
#include <eez/scripting/scripting.h>
#include <eez/sound.h>
#include <eez/hmi.h>
Expand Down Expand Up @@ -293,6 +294,10 @@ void lowPriorityThreadOneIter() {
scripting::onLowPriorityQueueMessage(type, param);
}

else if (type == FLOW_EXECUTE_SCPI ) {
flow::executeScpi();
}

else {
if (type == THREAD_MESSAGE_SAVE_LIST) {
int err;
Expand Down
2 changes: 2 additions & 0 deletions src/eez/tasks.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ enum LowPriorityThreadMessage {

MP_LAST_MESSAGE_TYPE,

FLOW_EXECUTE_SCPI,

THREAD_MESSAGE_SAVE_LIST,
THREAD_MESSAGE_SD_DETECT_IRQ,
THREAD_MESSAGE_DLOG_STATE_TRANSITION,
Expand Down

0 comments on commit 7723039

Please sign in to comment.