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 Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • 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
Personal Blogs
  • Community Hub
  • More
Personal Blogs
Legacy Personal Blogs Create a Programmable Instrument with SCPI - Part 2: Serial over USB
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 17 Sep 2016 7:31 PM Date Created
  • Views 3826 views
  • Likes 3 likes
  • Comments 2 comments
  • smart_instrument
  • gpib
  • usb
  • uart
  • texas_instruments
  • labview
  • scpi
  • hercules
  • launchpad
Related
Recommended

Create a Programmable Instrument with SCPI - Part 2: Serial over USB

Jan Cumps
Jan Cumps
17 Sep 2016
For a hardware evaluation project I'm working on, I want to create a device that can be controlled via LabView.
LabView can talk to instruments using serial out of the box, and it knows how to talk Standard Commands for Programmable Instruments (SCPI).

 

image

 

In this blog I'm writing the serial communication firmware for a Hercules safety microcontroller.

 

 

SCPI Physical Communications Link is Undefined

SCPI does not care how you connect your two systems. That's what wikipedia says about SCPI - and it's true. You'll find instruments that can talk SCPI over TCP/IP, a GPIB interface, a serial port or via USB.

The heart of my test device is a Hercules RM46 LaunchPad. It has a USB connector that's bridged with one of the Hercules' serial communication modules.

 

On the PC, this USB is available as a COM port (UART).

Good enough for LabVIEW - it supports serial communication out of box.

 

 

Design Decisions for Serial Comms

Listening for LabVIEW commands isn't the only thing the test instrument will have to do. The SCPI interface is only one of its functionalities.

That means that we can't just sit there and wait for data to arrive on the serial comms interface. We'll have to use another strategy.

 

I'm using a real-time operating system (freeRTOS) as the basis for the firmware. That will make my work to look after multiple functionalities simpler.

 

I'll have a task that picks up any data sent over the USB and sends the info to the SCPI parser. But that task is not going to read from the USB.

To handle the part of fetching data and bringing it into the application scope, I'm setting up a Read interrupt.

The Hercules driver for SCI automatically runs in background mode when you do that (i.e.: the sciRead() function of that API returns immediately without reading the data - it just prepares the receive buffer).

Once the read interrupt fires, the data is ready.

Because the length of the SCPI commands are variable, I'm reading one character at a time and start processing the info when I receive a terminator character.

 

Configure the RTOS and the Serial Communication Driver

You configure Hercules microcontrollers with HALCogen. The tool will do four tasks for us.

  • create source code for the freeRTOS Hercules port
  • generate initialisation code for the peripherals - the serial communications module in this case
  • configure clock, memory, interrupts
  • generate source code for the device APIs - again for the serial comms module in this design.

 

HALCoGen is a round-trip configurator. You can safely switch between the tool and your source - both directions.

 

The first task is to opt for an RTOS project.

You do that when you create your project.

Select the correct controller, and opt for the FREERTOS entry.

 

image

 

You can set RTOS specific settings in a dedicated configuration pane.

 

image

That's it for the RTOS.

Later, when we ask HALCoGen to generate our project code, it will create the Hercules port sources and will put these configuration settings in the relevant freeRTOS config files.

 

Next, we configure the serial communications device.

When you enable the driver, HALCoGen will create driver API source code.

 

image

 

Then you set the parameters. These will end up in the API's initialisation function.

I flag that I want to use the Read interrupt.

 

image

 

The baud rate is set to 9600, with 8,2,N (LabVIEW will have to use the same settings when talking to our instrument)

image

image

 

The last thing we have to do is enable the interrupt handler for the serial comms module.

Because we've configured High Level interrupt on the module page, we'll have to enable the corresponding high level interrupt in the vector.

 

image

 

HALCoGen can now generate our project sources. Over to the IDE.

 

Firmware

Because we use an RTOS, our main() is almost empty.

The first part calls the serial comms API init function to apply the settings we've done in HALCoGen.

Then we enable the interrupts.

The Read interrupt will fire from the moment we get data on the serial port.

 

The second part of main() registers our RTOS tasks and starts the engine.

 

void main(void)
{
/* USER CODE BEGIN (3) */
    sciInit();
    _enable_IRQ();

    // Register the command interpreter
    vStartUARTCommandInterpreterTask();

    // start RTOS
    vTaskStartScheduler();
    while(1);
/* USER CODE END */
}

 

We don't have to do anything in the serial communications interrupt handler (for now at least. We add functionality in the next blog post).

Just by defining that we want to use a read trigger, the API knows how to behave.

 

If you disable the read trigger, the serial comms API will run in blocking mode.

if you call sciRead(size),  the function will wait until you receive size bytes, and then return. The SCI buffer will contain the bytes read.

 

If you enable the read trigger, the API runs in non-blocking mode.

If you call sciRead(size),  the function prepares the buffer and trigger, and immediately returns. Your program can proceed with other things.

When you receive size bytes, the trigger fires (and you can act on that if you want) and in parallel the data is available in the SCI buffer.

 

 

In my firmware, I have an RTOS job that will pick up any character received, and that re-builds a SCPI command string from them.

Once the string is complete (when we receive a 0x0A character), we send it to the SCPI parser API, and return the result to LabVIEW.

... or, that's what will happen in the future. At this moment I just echo the string back, as a proof of concept.

 

 

void prvUARTCommandConsoleTask(void *pvParameters) {

    ( void ) pvParameters;
    _uRxChar = 0U;
    uint32_t i = 0L;

    sciReceive(scilinREG, 1, (uint8 *)&_uRxChar);

    for( ;; )
    {
        /* Only interested in reading one character at a time. */
        if (_uRxChar) {
            _uCommandBuffer[i] = _uRxChar;
            i++; // todo this must be controlled, reset the buffer after a command is finished or error when overrunning
            if (_uRxChar == 0x0A) {
                // we have a command. Send it to the parser queue
                // test implementation: echo
                sciSend(scilinREG, i, _uCommandBuffer); // todo remove this.

                i = 0U;
            }
            _uRxChar = 0U;
            sciReceive(scilinREG, 1, (uint8 *)&_uRxChar);
        }
    }
}

 

Test in LabVIEW

There's an example (Simple Serial) that sends the *IDN? command to a serial device, and shows the reply it receives from that device.

That's an excellent test bed candidate.

 

I need to set the serial parameters correctly. My Hercules LaunchPad USB is registered as COM4.

image

In HALCoGen, I had set up the serial parameters as 9600, 8, 2, N.

When I run the Simple Serial example, the SCPI command *IDN? is sent to COM4, and half a second later LabVIEW tries to read the reply.

Because my test firmware just sends the command back that it received, the program should show *IDN? in the result pane.

It should also show a data count of 6 (5 characters + the closing character 0x0A are all sent back).

 

image

 

Related Blog

Create a Programmable Instrument with SCPI - Part 1: Parser Library
Create a Programmable Instrument with SCPI - Part 2: Serial over USB
Create a Programmable Instrument with SCPI - Part 3: First Conversation *IDN?
Create a Programmable Instrument with SCPI - Part 4: Error Handling by Default
Create a Programmable Instrument with SCPI - Part 5: First Hardware Commands
Create a Programmable Instrument with SCPI - Part 6: LabVIEW Integration
Create a Programmable Instrument with SCPI - Part 7: Talk to Hardware Registers
  • Sign in to reply

Top Comments

  • Jan Cumps
    Jan Cumps over 8 years ago +1
    First successfully parsed SCPI command:
  • Robert Peter Oakes
    Robert Peter Oakes over 8 years ago +1
    I will be following with great interest as I will probably implement in different hardware but principals are all the same. thanks for great project
  • Robert Peter Oakes
    Robert Peter Oakes over 8 years ago

    I will be following with great interest as I will probably implement in different hardware but principals are all the same. thanks for great project

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 8 years ago

    First successfully parsed SCPI command:

     

    image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
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