https://github.com/j123b567/scpi-parser
Dependents: scpi_sx127x scpi_sx127x_firstTest MLX90418_I2C_master
ieee488.c
00001 /*- 00002 * Copyright (c) 2012-2013 Jan Breuer, 00003 * 00004 * All Rights Reserved 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are 00008 * met: 00009 * 1. Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00018 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 00019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 00022 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00023 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 00024 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 /** 00029 * @file scpi_ieee488.c 00030 * @date Thu Nov 15 10:58:45 UTC 2012 00031 * 00032 * @brief Implementation of IEEE488.2 commands and state model 00033 * 00034 * 00035 */ 00036 00037 #include "scpi/parser.h" 00038 #include "scpi/ieee488.h" 00039 #include "scpi/error.h" 00040 #include "scpi/constants.h" 00041 00042 #include <stdio.h> 00043 00044 /** 00045 * Update register value 00046 * @param context 00047 * @param name - register name 00048 */ 00049 static void regUpdate(scpi_t * context, scpi_reg_name_t name) { 00050 SCPI_RegSet(context, name, SCPI_RegGet(context, name)); 00051 } 00052 00053 /** 00054 * Update STB register according to value and its mask register 00055 * @param context 00056 * @param val value of register 00057 * @param mask name of mask register (enable register) 00058 * @param stbBits bits to clear or set in STB 00059 */ 00060 static void regUpdateSTB(scpi_t * context, scpi_reg_val_t val, scpi_reg_name_t mask, scpi_reg_val_t stbBits) { 00061 if (val & SCPI_RegGet(context, mask)) { 00062 SCPI_RegSetBits(context, SCPI_REG_STB, stbBits); 00063 } else { 00064 SCPI_RegClearBits(context, SCPI_REG_STB, stbBits); 00065 } 00066 } 00067 00068 /** 00069 * Get register value 00070 * @param name - register name 00071 * @return register value 00072 */ 00073 scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name) { 00074 if ((name < SCPI_REG_COUNT) && (context->registers != NULL)) { 00075 return context->registers[name]; 00076 } else { 00077 return 0; 00078 } 00079 } 00080 00081 /** 00082 * Wrapper function to control interface from context 00083 * @param context 00084 * @param ctrl number of controll message 00085 * @param value value of related register 00086 */ 00087 static size_t writeControl(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 00088 if (context && context->interface && context->interface->control) { 00089 return context->interface->control(context, ctrl, val); 00090 } else { 00091 return 0; 00092 } 00093 } 00094 00095 /** 00096 * Set register value 00097 * @param name - register name 00098 * @param val - new value 00099 */ 00100 void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val) { 00101 scpi_bool_t srq = FALSE; 00102 scpi_reg_val_t mask; 00103 scpi_reg_val_t old_val; 00104 00105 if ((name >= SCPI_REG_COUNT) || (context->registers == NULL)) { 00106 return; 00107 } 00108 00109 /* store old register value */ 00110 old_val = context->registers[name]; 00111 00112 /* set register value */ 00113 context->registers[name] = val; 00114 00115 /** @TODO: remove recutsion */ 00116 switch (name) { 00117 case SCPI_REG_STB: 00118 mask = SCPI_RegGet(context, SCPI_REG_SRE); 00119 mask &= ~STB_SRQ; 00120 if (val & mask) { 00121 val |= STB_SRQ; 00122 /* avoid sending SRQ if nothing has changed */ 00123 if (old_val != val) { 00124 srq = TRUE; 00125 } 00126 } else { 00127 val &= ~STB_SRQ; 00128 } 00129 break; 00130 case SCPI_REG_SRE: 00131 regUpdate(context, SCPI_REG_STB); 00132 break; 00133 case SCPI_REG_ESR: 00134 regUpdateSTB(context, val, SCPI_REG_ESE, STB_ESR); 00135 break; 00136 case SCPI_REG_ESE: 00137 regUpdate(context, SCPI_REG_ESR); 00138 break; 00139 case SCPI_REG_QUES: 00140 regUpdateSTB(context, val, SCPI_REG_QUESE, STB_QES); 00141 break; 00142 case SCPI_REG_QUESE: 00143 regUpdate(context, SCPI_REG_QUES); 00144 break; 00145 case SCPI_REG_OPER: 00146 regUpdateSTB(context, val, SCPI_REG_OPERE, STB_OPS); 00147 break; 00148 case SCPI_REG_OPERE: 00149 regUpdate(context, SCPI_REG_OPER); 00150 break; 00151 00152 00153 case SCPI_REG_COUNT: 00154 /* nothing to do */ 00155 break; 00156 } 00157 00158 /* set updated register value */ 00159 context->registers[name] = val; 00160 00161 if (srq) { 00162 writeControl(context, SCPI_CTRL_SRQ, SCPI_RegGet(context, SCPI_REG_STB)); 00163 } 00164 } 00165 00166 /** 00167 * Set register bits 00168 * @param name - register name 00169 * @param bits bit mask 00170 */ 00171 void SCPI_RegSetBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits) { 00172 SCPI_RegSet(context, name, SCPI_RegGet(context, name) | bits); 00173 } 00174 00175 /** 00176 * Clear register bits 00177 * @param name - register name 00178 * @param bits bit mask 00179 */ 00180 void SCPI_RegClearBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits) { 00181 SCPI_RegSet(context, name, SCPI_RegGet(context, name) & ~bits); 00182 } 00183 00184 /** 00185 * Clear event register 00186 * @param context 00187 */ 00188 void SCPI_EventClear(scpi_t * context) { 00189 /* TODO */ 00190 SCPI_RegSet(context, SCPI_REG_ESR, 0); 00191 } 00192 00193 /** 00194 * *CLS - This command clears all status data structures in a device. 00195 * For a device which minimally complies with SCPI. (SCPI std 4.1.3.2) 00196 * @param context 00197 * @return 00198 */ 00199 scpi_result_t SCPI_CoreCls(scpi_t * context) { 00200 SCPI_EventClear(context); 00201 SCPI_ErrorClear(context); 00202 SCPI_RegSet(context, SCPI_REG_OPER, 0); 00203 SCPI_RegSet(context, SCPI_REG_QUES, 0); 00204 return SCPI_RES_OK; 00205 } 00206 00207 /** 00208 * *ESE 00209 * @param context 00210 * @return 00211 */ 00212 scpi_result_t SCPI_CoreEse(scpi_t * context) { 00213 int32_t new_ESE; 00214 if (SCPI_ParamInt(context, &new_ESE, TRUE)) { 00215 SCPI_RegSet(context, SCPI_REG_ESE, (scpi_reg_val_t)new_ESE); 00216 } 00217 return SCPI_RES_OK; 00218 } 00219 00220 /** 00221 * *ESE? 00222 * @param context 00223 * @return 00224 */ 00225 scpi_result_t SCPI_CoreEseQ(scpi_t * context) { 00226 SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_ESE)); 00227 return SCPI_RES_OK; 00228 } 00229 00230 /** 00231 * *ESR? 00232 * @param context 00233 * @return 00234 */ 00235 scpi_result_t SCPI_CoreEsrQ(scpi_t * context) { 00236 SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_ESR)); 00237 SCPI_RegSet(context, SCPI_REG_ESR, 0); 00238 return SCPI_RES_OK; 00239 } 00240 00241 /** 00242 * *IDN? 00243 * 00244 * field1: MANUFACTURE 00245 * field2: MODEL 00246 * field4: SUBSYSTEMS REVISIONS 00247 * 00248 * example: MANUFACTURE,MODEL,0,01-02-01 00249 * @param context 00250 * @return 00251 */ 00252 scpi_result_t SCPI_CoreIdnQ(scpi_t * context) { 00253 int i; 00254 for (i = 0; i<4; i++) { 00255 if (context->idn[i]) { 00256 SCPI_ResultMnemonic(context, context->idn[i]); 00257 } else { 00258 SCPI_ResultMnemonic(context, "0"); 00259 } 00260 } 00261 return SCPI_RES_OK; 00262 } 00263 00264 /** 00265 * *OPC 00266 * @param context 00267 * @return 00268 */ 00269 scpi_result_t SCPI_CoreOpc(scpi_t * context) { 00270 SCPI_RegSetBits(context, SCPI_REG_ESR, ESR_OPC); 00271 return SCPI_RES_OK; 00272 } 00273 00274 /** 00275 * *OPC? 00276 * @param context 00277 * @return 00278 */ 00279 scpi_result_t SCPI_CoreOpcQ(scpi_t * context) { 00280 /* Operation is always completed */ 00281 SCPI_ResultInt(context, 1); 00282 return SCPI_RES_OK; 00283 } 00284 00285 /** 00286 * *RST 00287 * @param context 00288 * @return 00289 */ 00290 scpi_result_t SCPI_CoreRst(scpi_t * context) { 00291 if (context && context->interface && context->interface->reset) { 00292 return context->interface->reset(context); 00293 } 00294 return SCPI_RES_OK; 00295 } 00296 00297 /** 00298 * *SRE 00299 * @param context 00300 * @return 00301 */ 00302 scpi_result_t SCPI_CoreSre(scpi_t * context) { 00303 int32_t new_SRE; 00304 if (SCPI_ParamInt(context, &new_SRE, TRUE)) { 00305 SCPI_RegSet(context, SCPI_REG_SRE, (scpi_reg_val_t)new_SRE); 00306 } 00307 return SCPI_RES_OK; 00308 } 00309 00310 /** 00311 * *SRE? 00312 * @param context 00313 * @return 00314 */ 00315 scpi_result_t SCPI_CoreSreQ(scpi_t * context) { 00316 SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_SRE)); 00317 return SCPI_RES_OK; 00318 } 00319 00320 /** 00321 * *STB? 00322 * @param context 00323 * @return 00324 */ 00325 scpi_result_t SCPI_CoreStbQ(scpi_t * context) { 00326 SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_STB)); 00327 return SCPI_RES_OK; 00328 } 00329 00330 /** 00331 * *TST? 00332 * @param context 00333 * @return 00334 */ 00335 scpi_result_t SCPI_CoreTstQ(scpi_t * context) { 00336 (void) context; 00337 SCPI_ResultInt(context, 0); 00338 return SCPI_RES_OK; 00339 } 00340 00341 /** 00342 * *WAI 00343 * @param context 00344 * @return 00345 */ 00346 scpi_result_t SCPI_CoreWai(scpi_t * context) { 00347 (void) context; 00348 /* NOP */ 00349 return SCPI_RES_OK; 00350 }
Generated on Tue Jul 12 2022 19:30:15 by 1.7.2