/*- * Copyright (c) 2012-2013 Jan Breuer, * * All Rights Reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file scpi_ieee488.c * @date Thu Nov 15 10:58:45 UTC 2012 * * @brief Implementation of IEEE488.2 commands and state model * * */ #include "scpi.h" #include "scpi_ieee488.h" #include "scpi_error.h" #include "scpi_constants.h" #include #include /* register array */ static scpi_reg_val_t regs[SCPI_REG_COUNT]; /** * Update register value * @param name - register name */ static void SCPI_RegUpdate(scpi_reg_name_t name) { SCPI_RegSet(name, SCPI_RegGet(name)); } /** * Get register value * @param name - register name * @return register value */ scpi_reg_val_t SCPI_RegGet(scpi_reg_name_t name) { if (name < SCPI_REG_COUNT) { return regs[name]; } else { return 0; } } /** * Set register value * @param name - register name * @param val - new value */ void SCPI_RegSet(scpi_reg_name_t name, scpi_reg_val_t val) { if (name >= SCPI_REG_COUNT) { return; } // set register value regs[name] = val; switch (name) { case SCPI_REG_STB: if (val & (SCPI_RegGet(SCPI_REG_SRE) &~STB_SRQ)) { val |= STB_SRQ; } else { val &= ~STB_SRQ; } break; case SCPI_REG_SRE: SCPI_RegUpdate(SCPI_REG_STB); break; case SCPI_REG_ESR: if (val & SCPI_RegGet(SCPI_REG_ESE)) { SCPI_RegSetBits(SCPI_REG_STB, STB_ESR); } else { SCPI_RegClearBits(SCPI_REG_STB, STB_ESR); } break; case SCPI_REG_ESE: SCPI_RegUpdate(SCPI_REG_ESR); break; case SCPI_REG_QUES: if (val & SCPI_RegGet(SCPI_REG_QUESE)) { SCPI_RegSetBits(SCPI_REG_STB, STB_QES); } else { SCPI_RegClearBits(SCPI_REG_STB, STB_QES); } break; case SCPI_REG_QUESE: SCPI_RegUpdate(SCPI_REG_QUES); break; case SCPI_REG_OPER: if (val & SCPI_RegGet(SCPI_REG_OPERE)) { SCPI_RegSetBits(SCPI_REG_STB, STB_OPS); } else { SCPI_RegClearBits(SCPI_REG_STB, STB_OPS); } break; case SCPI_REG_OPERE: SCPI_RegUpdate(SCPI_REG_OPER); break; case SCPI_REG_COUNT: // nothing to do break; } // set updated register value regs[name] = val; } /** * Set register bits * @param name - register name * @param bits bit mask */ void SCPI_RegSetBits(scpi_reg_name_t name, scpi_reg_val_t bits) { SCPI_RegSet(name, SCPI_RegGet(name) | bits); } /** * Clear register bits * @param name - register name * @param bits bit mask */ void SCPI_RegClearBits(scpi_reg_name_t name, scpi_reg_val_t bits) { SCPI_RegSet(name, SCPI_RegGet(name) & ~bits); } /* ============ */ void SCPI_EventClear(void) { // TODO SCPI_RegSet(SCPI_REG_ESR, 0); } /** * *CLS * @param context * @return */ int SCPI_CoreCls(scpi_context_t * context) { (void) context; SCPI_EventClear(); SCPI_ErrorClear(context); SCPI_RegSet(SCPI_REG_OPER, 0); SCPI_RegSet(SCPI_REG_QUES, 0); return 0; } /** * *ESE * @param context * @return */ int SCPI_CoreEse(scpi_context_t * context) { int32_t new_ESE; if (SCPI_ParamInt(context, &new_ESE, TRUE)) { SCPI_RegSet(SCPI_REG_ESE, new_ESE); } return 0; } /** * *ESE? * @param context * @return */ int SCPI_CoreEseQ(scpi_context_t * context) { (void) context; SCPI_ResultInt(context, SCPI_RegGet(SCPI_REG_ESE)); return 0; } /** * *ESR? * @param context * @return */ int SCPI_CoreEsrQ(scpi_context_t * context) { (void) context; SCPI_ResultInt(context, SCPI_RegGet(SCPI_REG_ESR)); SCPI_RegSet(SCPI_REG_ESR, 0); return 0; } /** * *IDN? * @param context * @return */ int SCPI_CoreIdnQ(scpi_context_t * context) { (void) context; SCPI_ResultString(context, SCPI_MANUFACTURE); SCPI_ResultString(context, SCPI_DEV_NAME); SCPI_ResultString(context, SCPI_DEV_VERSION); return 0; } /** * *OPC * @param context * @return */ int SCPI_CoreOpc(scpi_context_t * context) { (void) context; SCPI_RegSetBits(SCPI_REG_ESR, ESR_OPC); return 0; } /** * *OPC? * @param context * @return */ int SCPI_CoreOpcQ(scpi_context_t * context) { (void) context; // Operation is always completed SCPI_ResultInt(context, 1); return 0; } /** * *RST * @param context * @return */ int SCPI_CoreRst(scpi_context_t * context) { if (context && context->interface && context->interface->reset) { return context->interface->reset(context); } return 0; } /** * *SRE * @param context * @return */ int SCPI_CoreSre(scpi_context_t * context) { int32_t new_SRE; if (SCPI_ParamInt(context, &new_SRE, TRUE)) { SCPI_RegSet(SCPI_REG_SRE, new_SRE); } return 0; } /** * *SRE? * @param context * @return */ int SCPI_CoreSreQ(scpi_context_t * context) { (void) context; SCPI_ResultInt(context, SCPI_RegGet(SCPI_REG_SRE)); return 0; } /** * *STB? * @param context * @return */ int SCPI_CoreStbQ(scpi_context_t * context) { (void) context; SCPI_ResultInt(context, SCPI_RegGet(SCPI_REG_STB)); return 0; } /** * *TST? * @param context * @return */ int SCPI_CoreTstQ(scpi_context_t * context) { (void) context; int result = 0; if (context && context->interface && context->interface->test) { result = context->interface->test(context); } SCPI_ResultInt(context, result); return 0; } /** * *WAI * @param context * @return */ int SCPI_CoreWai(scpi_context_t * context) { (void) context; // NOP return 0; }