SCPI parser and status register model implementation (device side) written in C
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Ondřej Hruška f9d2b4cdc5 Fine error reporting can now be disabled to save program space, added callback for new error, changed some callback names. 9 years ago
example Fine error reporting can now be disabled to save program space, added callback for new error, changed some callback names. 9 years ago
include Fine error reporting can now be disabled to save program space, added callback for new error, changed some callback names. 9 years ago
lib Attempt to make iot compile to a lib 9 years ago
source Fine error reporting can now be disabled to save program space, added callback for new error, changed some callback names. 9 years ago
.gitignore attempt to make it cross platform 9 years ago
LICENSE Initial commit 9 years ago
Makefile Fine error reporting can now be disabled to save program space, added callback for new error, changed some callback names. 9 years ago
README.md improved readme and added scpi.h with all headers included 9 years ago
errorgen.php cleaning 9 years ago
scpi.pro Fine error reporting can now be disabled to save program space, added callback for new error, changed some callback names. 9 years ago
style.astylerc initial 9 years ago

README.md

SCPI parser

This library provides a simple ("KISS") SCPI implementation for embedded devices (instruments).

The implementation is not 100% complete, but it's sufficient for basic SCPI communication.

  • Easy configuration with one const array and callbacks
  • Implements SCPI99 (minimal requirements) - including common commands and status registers
  • Mandatory parts of the SYST and STAT subsystems are built in (ie. error handling)
  • Easy, straightforward API

Feature overview

What's supported

  • Commands with colon (hierarchical header model)
  • Semicolon for chaining commands on the same level
  • Long and short command variants (eg. SYSTem?)
  • String, Int, Float, Bool, CharData arguments
  • Block data argument with callback each N received bytes - allows virtually unlimite binary data length
  • Status Registers
  • Error queue with error numbers and messages (and the required SYST:ERR subsystem)

Built-in commands can be overriden by matching user commands.

Limitations

  • Binary block must be the last argument of a command (callback is run after reading the binary block preamble)

What's missing

  • Number units (mV,V,kW,A,Ohm) and metric suffixes (k,M,G,m,u,n)
  • DEF, MIN, MAX, INF, NINF argument values for numbers
  • Numbered virtual instruments (DAC1:OUT, DAC2:OUT) - currently you need to define the commands twice

Feel free to propose a pull request implementing any missing features.

How to use it

To test it with regular gcc, run the Makefile in the example directory.

The main Makefile builds a library for ARM Cortex M4 (can be easily adjusted for others).

Stubs to implement

Here's an overview of stubs you have to implement (at the time of writing this readme):

#include "scpi.h"

// Receive byte - call:
//   scpi_handle_byte()
//   scpi_handle_string()


// ---- DEVICE IMPLEMENTATION ----

const SCPI_error_desc scpi_user_errors[] = {
	{10, "Custom error"}, // add your custom errors here (positive numbers)
	{/*END*/} // <-- end marker
};


void scpi_send_byte_impl(uint8_t b)
{
	// send the byte to master (over UART?)
}


const char *scpi_device_identifier(void)
{
	// fill in your device info
	// possible to eg. read a serial # from EEPROM
	return "<manufacturer>,<product>,<serial#>,<version>";
}


/* Custom commands */
const SCPI_command_t scpi_commands[] = {
	// see the struct definition for more details. Examples:
	{
		.levels = {"APPLy", "SINe"},
		.params = {SCPI_DT_INT, SCPI_DT_FLOAT, SCPI_DT_FLOAT},
		.callback = cmd_APPL_SIN_cb
	},
	{
		.levels = {"DATA", "BLOB"},
		.params = {SCPI_DT_BLOB},
		.callback = cmd_DATA_BLOB_cb, // <-- command callback
		.blob_chunk = 4,
		.blob_callback = cmd_DATA_BLOB_data // <-- data callback
	},
	{/*END*/} // <-- important! Marks end of the array
};

// ---- OPTIONAL CALLBACKS ----

void scpi_service_request_impl(void)
{
	// Called when the SRQ flag in Status Byte is set.
	// Device should somehow send the request to master.
}

// Device specific implementation of common commands
// (status registers etc are handled internally)
void scpi_user_CLS(void) { /*...*/ }
void scpi_user_RST(void) { /*...*/ }
void scpi_user_TSTq(void) { /*...*/ }

See the header files for more info.