element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Test & Tools
  • Technologies
  • More
Test & Tools
Blog PST.. Experimental event / trigger support for Pico SCPI labTool - 4: let TinyUSB USBTMC code use SCPI-LIB's Status Byte register
  • Blog
  • Forum
  • Documents
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Test & Tools to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 22 Sep 2023 3:58 PM Date Created
  • Views 808 views
  • Likes 8 likes
  • Comments 1 comment
  • pico_usbtmc_scpi
  • pico
  • USBTMC
  • Pico SCPI labTool
  • labview
Related
Recommended

PST.. Experimental event / trigger support for Pico SCPI labTool - 4: let TinyUSB USBTMC code use SCPI-LIB's Status Byte register

Jan Cumps
Jan Cumps
22 Sep 2023
PST.. Experimental event / trigger support for Pico SCPI labTool - 4: let TinyUSB USBTMC code use SCPI-LIB's Status Byte register

The Pico SCPI labTool (PST) allows you to connect your PC to equipment to control and monitor all sorts of things. It runs on a Raspberry Pico. It would be nice if the PST could supports device dependent SCPI registers. They can be used to notify a LabVIEW flow from the device. I'd be happy if we can notify LabVIEW when a GPIO input changed logic level.
In this post: let the USBTMC code use the same status register as the SCPI library.

image

part 1: PST.. Experimental event / trigger support for Pico SCPI labTool - 1: investigate 
part 2: PST.. Experimental event / trigger support for Pico SCPI labTool - 2: design the registers 
part 3: PST.. Experimental event / trigger support for Pico SCPI labTool - 3: Instrument Specific Registers Test
part 4: PST.. Experimental event / trigger support for Pico SCPI labTool - 4: let TinyUSB USBTMC code use SCPI-LIB's Status Byte register 
part 5:  PST.. Experimental event / trigger support for Pico SCPI labTool - 5: Propagation to IEEE488.2 SCPI Registers Test 
part 6: PST.. Experimental event / trigger support for Pico SCPI labTool - 6: Service Request from Instrument to LabVIEW flow 
part 7: PST.. Experimental event / trigger support for Pico SCPI labTool - 7: Test Service Request from Instrument to LabVIEW flow 

History: why do I have 2 status registers

When I started developing the firmware, I combined the TinyUSB USBTMC example with the a SCPI lib that I know well. But I didn't know a lot about the TinyUSB example.
I investigated what part of the example code received the SCPI commands, and what part sent the reply.
I connected the SCPI lib input and output functions to these two parts. Tested, and I got it to work.
I didn't make many more changes to the example code. Happy that it worked, and ran stable.

What I didn't understand at the time, was that the status variable in that example was mimicking the SCPI IEEE488.2 STB (Status Byte) register. I thought it was a variable to entertain the program's state machine.

When I started to dig deeper into SCPI registers, and got a better understanding, I realised that this status variable was in fact a partly implemented STB. Just enough to be able to test the TinyUSB USBTMC profile. Excellent for a test bed. But my project should have a single STB. I left the integration incomplete. And it prevented me to start using the Service Request functionality.

Compare the 2 STBs

The TinyUSB USBTMC state machine needs a STB. Nothing stops it from using the SCPI lib's one. It's actually the desired outcome. But how do I migrate?

TinyUSB sample code implementation

The example is deliberately minimal. It allows to let the your design enumerate as a Test and Measurement component. And it can listen and reply to a *IDN? command.
The STB in that example takes care that this functionality works.

#define IEEE4882_STB_QUESTIONABLE (0x08u)
#define IEEE4882_STB_MAV          (0x10u)
#define IEEE4882_STB_SER          (0x20u)
#define IEEE4882_STB_SRQ          (0x40u)

static volatile uint8_t status;

In the state machine, the relevant bits are used to decide what the driver has to do. I'm happy with how they made this example: the author used the correct bits, and documents that.

SCPI lib implementation

That's a full standard compliant register implementation, with connections to Query register, Event register, Operation Status register, ...
I'm not presenting the code here, but will show two API calls that you can use to read and write the registers.

scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name);

void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val);

These are not just a getter and setter. They have (IEEE488.2 specified) side effects. Setting a value may fan out to other registers, if so configured. And a read may (or may not) clear a register - again based on the specs of the standard.

But having these two functions makes the migration easy.

Migration

First, I abused the compiler, to show me where the TinyUSB code uses the status. For that, I commented out the variable, and then compiled the code. Each compiler error indicates a line of code that uses the variable.

image

Then I put a TODO comment at each of these occurrences. VS Code has a Todo module, that will give you a list of all lines that you tagged with todo.
I now have a worklist of code to adapt.

My integration strategy was to create two bridge functions that will make the SCPI STB look, for the TinyUSB code, identical as the original variable.

uint8_t getSTB() {
  return (uint8_t) SCPI_RegGet(&scpi_context, SCPI_REG_STB);
}

void setSTB(uint8_t stb) {
  SCPI_RegSet(&scpi_context, SCPI_REG_STB, (scpi_reg_val_t) stb);
}

I then visited each of my Todos, and retrieved the SCPI STB with the helper before that code in a local variable (with the same name as the original one that I commented out).
After the code that manipulated the variable, I updated the SCPI LIB STB with the other helper function. Example:

bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg) {
  (void)msg;
  // Let trigger set the SRQ
  uint8_t status = getSTB();
  status |= IEEE4882_STB_SRQ;
  setSTB(status);
  return true;
}

Rinse and repeat until all Todos are gone, and code compiles again.

I tested extensively, to see if this refactoring has any impact on stability and functional code. All was good.

link to all posts

  • Sign in to reply
Parents
  • DAB
    DAB over 2 years ago

    Nice update Jan.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • DAB
    DAB over 2 years ago

    Nice update Jan.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube