Transitioning away from in-house manufacturing

* preliminary  – I will be writing more thoughts on this over the next week or so *

After a lot of thought, Mark and I have decided to move entirely away from in-house manufacturing.  While it is at least theoretically possible to do in-house manufacturing quite well, and to do it reasonably cost effectively – it takes a huge amount of work and commitment.  It makes sense in some situations — perhaps because either you have no choice or it gives you some sort of advantage.  “Because it’s awesome” is not a good rationale.  This is one of the reasons why it’s good to have some good investors or advisers or board members – some sort of oversight who can call you out when you’re being dumb.

Well, Saleae doesn’t really derive any competitive advantage for in-house manufacturing, apart from the fact that it makes for cool pictures and office tours.

However, it is critical that we find an awesome partner to do the manufacturing.  Someone with ideally much better quality control and processes and capacity than we would on our own.  And ideally the same cost or lower.

I’ve heard lots of stories about factories in China needing constant supervision to assure quality – that you just have to have an engineer basically live there.  This is not something I want to deal with at all.  (I’m sure many factories in China are extremely well run, it’s not like I’ve done a comprehensive survey or something.)

Here’s a reasonable wish list for a contract manufacturing partner I think:

  • The people there are honest, friendly, generally happy, and really care
  • Turnover is low, and people think highly of the management
  • Vendor management, procurement, material resource planning is world class
  • Engineering, QA process control is excellent
  • Direct access to key people – procurement, engineering, project management, QA
  • Fast, efficient, and very clear communication
  • Open book processes, open book costs
  • Over-the-top personal endorsements from other customers at established, excellent companies
  • Reasonably long history; long relationships with other customers
  • Established customers have higher complexity PCBAs / products than yours
  • Willing to work with your volumes
  • Good final price and payment terms

I’m excited to announce that we have in fact found such a partner, and have been working together for several months now. They will be doing a 100% box build for us, for all our products.  Our costs will not increase, and I believe our quality will ultimately improve overall.

This new manufacturing partner is in Taiwan, which Mark and I had the pleasure of visiting recently – and in my estimation it is a truly wonderful country.  We really enjoyed our time there.  I believe other parts of the world may also be good places to find manufacturing partners of a similar caliber and cost.  Not 100% sure, but perhaps Poland, South Korea, and Mexico.

It is difficult to find such good suppliers, and I don’t yet have a great algorithm to share on the matter.  However it is now obvious to me that key partner selection is one of the most critical functions of the CEO (partners could include manufacturing, marketing, accounting, legal, design, etc). Here are a few ideas:

  • Don’t settle – assume that the perfect partner exists, and that your job is to find them.
  • Become comfortable traveling internationally. Spend enough time to really understand the people you’re considering working with.  Are they genuine, good people, who really care?
  • There are “tiers” of partners. They will require different “account sizes.”  You’ll need to figure out what your annual spend is likely to be is and that will automatically narrow the list of firms that will work with you.  Of course most will not put on their website “must have annual spend greater than $500,000” but a quick call will get it sorted.
  • Websites generally speaking aren’t going to be that helpful. Just start setting up calls.  These people can help educate you about the market too, so you will be increasingly sophisticated as time go on.
  • Bigger isn’t necessarily a bad thing. It could be really good if it means great processes are in place. After all, they must have done something right to get big in the first place.  So the question is – will your small account receive awesome service or not.  Will the A players at the firm at least review and sign off the work that the more junior people on your small account are doing?
  • References are everything. Insist on them, and the more the better.  Probably even call their customers that they did not explicitly give you contact information for.
  • Make sure their other customers are in some way aspirational for you. Do you think the partner’s other customers are cool, well run companies you to aspire to be like?
  • Make a comprehensive wish list, and update it as you talk to more and more people.

Ultimately you’re going to have to turn a lot of these companies down – you can only pick one after all.  For me, this is kind of rough.  But that’s life.  However, hopefully you’re now at the beginning of a wonderful, stress-free relationship — and that’s exciting.

*****************

Investors & Cash flow situation

New Offices

Taiwan

Travel in general

Forecast

Software

Cultural differences

Marketing thoughts

China market

Advisers

Outsourcing accounting

Everything’s all right party

Celebrating the little things

Mentors

Why we need to raise Logic’s price

I have always been quite aggressive on keeping prices low. I’m very much more a consumer products guy than an enterprise products guy. I spent a long time working on projects on the side, and I really appreciate the need for great tools that aren’t outrageously expensive – even if professional organizations are far less cost sensitive. I also am a big fan of fairness and value for money. Also, low cost is a competitive advantage in that larger companies aren’t interested in trying to compete, and new entrants aren’t lured in by the promise of massive profits. And I think it has played a pivotal role in Logic become the most popular logic analyzer in the world (logic analyzers are a very small market, but hey, that’s still pretty cool).

I was extremely aggressive on pricing for the new products. The current price includes baked in assumptions about future cost lowering activities, like more in-house manufacturing, including pick and place, machining and anodizing, and injection molding. However, implementing these cost cutting measures requires capital or access to capital. And I’m sorry to say for a number of reasons we don’t have the capitol to aggressively execute on all those measures right now.

In creating the new product lineup, in anticipation of future increased sales, we hired more engineers – not that many really, we’re talking 4-5, but it put us in a moderately cash-flow negative position, which we funded with an SBA-backed term loan. However, since the development took far longer than we wanted we ran low on reserves and so to bridge the gap to we launched a pre-order. This would have worked fine other than for two reasons: 1 – actually getting the products out the door once again took longer than anticipated and 2 – for many of our customers, Logic isn’t the sort of thing you pre-order. It’s great for individuals to pre-order, but clearly not for companies – although many still did which was amazing and awesome. So as the pre-order period stretched on longer than desired, we began burning down cash reserves again.

Ultimately we did ship all the pre-orders, and I’m happy to say that sales rates are good enough so that the new larger company is now profitable by a reasonable margin.

However – this is a paper profit and the cash flow reality is more dire. Any company requires working capital (cash set aside for inventory and cash-flow-gaps – gaps between selling and receiving payment), and I let ours get way too low.

Complicating this, quite a few months ago I decided – and convinced others – that we should do our own pick and place. The new Logic products have FAR more components than the old units, and PCB assembly costs scale with the number of components/board. Because the boards are also expensive – both the board itself and the parts on it – we cannot build in large quantities overseas without a (for us) vast amount of working capital. On paper, doing pick and place in house lets you get close to overseas costs and – critically – allows you to run with very small inventory levels when properly managed. Given the number of boards we build and the number of parts on each board (Pro 16 has 930) this adds up to a pretty compelling story.

The reality of the pick and place has been different. So far I don’t believe I did sufficient due diligence in selecting a supplier and our equipment was both delivered quite late and has been functionally problematic, resulting in slow and delayed production. We are working every day on this issue, and building as fast as we can – and after enormous effort we’re now – fairly slowly — catching up with our backorders.

All this is a long winded way of saying that we need to raise prices. I have no choice. I know it will come as bad news to many. Although I think many would agree that perhaps a Saleae with higher prices is better than no Saleae all.

The new prices are as follows:
Logic 4: $109
Logic 8: $219
Logic Pro 8: $479
Logic Pro 16: $599

In addition to playing a critical role in our near-term survival, longer term higher prices are likely to allow us, with future cost reductions, to potentially keep up a larger software developer staff and develop new features faster, the pace of which I know has been frustratingly slow since all efforts have been directed at the new product support until recently.

In addition, we are raising a small amount debt financing from private individuals to help fund our working capital requirements. Details on that can be found here.

Please feel free to write us with any feedback you like, we read and reply to it all and take it very seriously. Thank you for being a Logic customer, and for all the support over the years. It’s meant a ton to my brother and I, I can assure you.

With kindest regards,
Joe
Co-Founder & CEO

Using the SDK

Do you love your Saleae analyzer, but need it to do something extra, or do something it already does, only differently?  You can do these things, and more, with the Saleae Logic SDKs.  This post is a brief introduction to the Saleae SDKs, providing an overview of the Saleae Scripting Socket API and Analyzer SDK, along with links to documentation, resources, and source code.  Future posts about the SDKs may go into more detail, however this should whet your appetite for Logic customization and control using Saleae SDKs.

Suppose you are designing an embedded system with a requirement to monitor communications, control, or data buses, detect particular activity, and take some action when it occurs.  You could do this in the lab with Logic by using the GUI to configure appropriate triggers, capture, and analyze the data yourself, however, an embedded system usually has to take care of itself, and we can’t afford to have a human in the loop in this hypothetical production system (a human would be much more expensive, and less reliable, than Logic and some code).  This is where Logic’s SDK support comes in.  Using the SDKs, we can configure and control Logic under program control without interacting with the GUI, to capture data when triggered, and then process our captured data with custom analyzers (plugins) for more refined detection capability; when our custom analyzer plugin confirms the event of interest has occurred, the controlling program can take appropriate action.

Scripting Socket API  & Analyzer SDK

Saleae provides SDK support for controlling Logic itself, and for implementing custom plugins for data analysis.  The SDK for controlling Logic is called the Scripting Socket API, and provides programmatic control of and access to the internal functions of Logic, bypassing Logic’s GUI.  The SDK for implementing Logic plugins is called the Analyzer SDK, it provides a framework for developing custom modules to analyze data captured by Logic, and is used by Saleae developers to craft Logic’s protocol analyzer plugins.

Scripting Socket API

The Saleae Scripting Socket API http://support.saleae.com/hc/en-us/articles/201104764-Socket-API-beta gives you remote control and access to Logic’s internal functions and data through command line scripting rvia a network socket.  The Scripting Socket API source and documentation are available at  http://support.saleae.com/hc/en-us/article_attachments/201228475/LogicAutomationController.zip.  After unpacking the archive, look for the documentation, Logic+Automation+Users+Guide.pdf.

Overview

Saleae Logic Analyzers have a scriptable configuration, command, and control interface  via a network socket server, which enables you to programmatically operate Logic and export captured data via a TCP connection.  The scripting socket server is platform independent, consisting of a text-based protocol designed for sending commands to Logic and receiving responses from Logic.

Each command will return back with either an “ACK” or a “NAK” string when Logic executes the command.  If any error occurs, or if the command is unrecognized, the software will return “NAK”.  The scripting interface supports a few commands.  Some commands require arguments.  Arguments must be separated with the comma character: ‘,’.

The scripting socket server will work with any tcp client, once enabled, however Saleae provides a Windows-only console application (with C# source) which will access and pass commands and responses to and from the software’s socket for you.  The automation tester ships pre-built with the Scripting Socket API as LogicAutomationController.exe and can be found in the (bin/Release directory).

Getting Started

The socket connection default is TCP port 10429.  To use the Scripting Socket API, enable the scripting interface in the software by opening the preferences dialog from the options menu, selecting the developer tab, and then check the box for “Enable scripting socket server.”  Save these changes.

Automation Tester Program

Start the Automation Tester Program (LogicAutomationController.exe  in the bin/Release directory) and it prompts you to enter the host ip address; you’ll probably want to just hit Enter to accept the default of ‘localhost’.  Next, you are prompted to provide the host port, hit Enter to accept the default of 10429/tcp (which is the default server port Logic will be listening on, because we did not change the server port when we enabled the scripting interface in the previous step).

The Automation Tester Program will try to connect to Logic and if successful will report

Connecting…
Connected
Enter a string to xmit, q to exit.

If there is an error connecting, check connections, firewalls, etc. and try again.  If connected, you can send commands, receive responses, get help, or start demo mode.

Hitting ‘h’ followed by Enter displays example commands:

Example scripts:
set_sample_rate, 12000000, 6000000
set_num_samples, 1000000
set_trigger, high, negedge, low, none,
capture_to_file, c:/test1.logicdata

Enter a string to xmit, q to exit.

While the application is running, Socket commands can also be typed directly into the command prompt.  When creating automation scripts, it may be simpler to customize the source of the Automation Tester Program using the C# Functions as described in “Using the C# console app”, in Logic+Automation+Users+Guide.pdf..

Demo Mode

Typing ‘demo’ followed by Enter starts demo mode.  The software will run through a sequence of demonstration commands prompted by the enter key.  In Demo Mode the application calls the Demo() function within the SocketAPI class, shown below:

public void Demo()
{

StringHelper.WriteLine(“Demo Mode Initiated”);
GetConnectedDevices();
WaitForConsole();
SelectActiveDevice(2);
WaitForConsole();
SetActiveChannels(new int[] { 0, 1, 2, 3, 4 }, new int[] { 0, 1 });
WaitForConsole();
List<int> digital_channels = new List<int>();
List<int> analog_channels = new List<int>();
GetActiveChannels(digital_channels, analog_channels);
WaitForConsole();
SetNumSamples(2000000);
WaitForConsole();
Capture();
WaitForConsole();

//export captured data

List<SampleRate> sample_rates = GetAvailableSampleRates();
SetSampleRate(sample_rates.First());
WaitForConsole();
Capture();
WaitForConsole();
Trigger[] trigger = { Trigger.High, Trigger.Posedge, Trigger.High, Trigger.None, Trigger.High };
SetTrigger(trigger);
WaitForConsole();
ResetActiveChannels();
WaitForConsole();
SetCapturePretriggerBufferSize(1000000);
WaitForConsole();
Capture();
WaitForConsole();
StringHelper.WriteLine(“Demo Complete”);

}

Using the C# App

The SocketAPI class, in the automation program, directly implements C# functions for controlling the software.

An instance of the SocketAPI class must be constructed in order to establish the socket connection. The constructor takes both the IP address and port number of the requested socket. The default values are set for localhost and the default software socket port.

SocketAPI( String host_str = “127.0.0.1”, int port_input = 10429 )

{

this.port = port_input;
this.host = host_str;
Socket = new TcpClient(host, port);
Stream = Socket.GetStream();

}

The functions may then be called from the created object:

SAPI = new SocketAPI(host, port);
SAPI.FunctionCall();

Functions and commands can be broken down into several categories.  In this brief introduction we will describe one socket command and the corresponding function from each category listed in Logic+Automation+Users+Guide.pdf; for complete coverage, please review the Users Guide.

Software PreCapture

The command to get available sample rates is in the PreCapture category.

Socket Command

Socket Command: get_all_sample_rates

This command returns all the available sample rate combinations for the current performance level and channel combination.

Example: get_all_sample_rates
Response( ${digital sample rate), ${analog sample rate} ):
5000000, 1250000
10000000, 625000

C# Function

List<SampleRate> GetAvailableSampleRates()

This function returns a list of all the sample rates available for the current
performance option and channel combination.

struct SampleRate
{

public int AnalogSampleRate;
public int DigitalSampleRate;

}

Device/Channel Selection

When preparing to capture you may want to confirm the connected devices, and the Get Connected Devices command can help.

Socket Command

Socket Command: get_connected_devices
This command will return a list of the devices currently connected to the computer.  The connected device will have the return parameter ACTIVE at the end of the line.

Example:
get_connected_devices
Response
1, Demo Logic, LOGIC_DEVICE, 0x19b2
2, My Logic 16, LOGIC16_DEVICE, 0x2b13, ACTIVE
ACK

C# Function

ConnectedDevices[] GetConnectedDevices()

The function returns an array of ConnectedDevices structs. The structs contains the type of device, the name, the device id, the index of the device and whether or not the device is currently active.

struct ConnectedDevices
{

String type;
String name;
int device_id;
int index;
bool is_active;

}

Capture Data

When ready to capture, we’ll need to issue the Capture command.

Socket Command

Socket Command: capture

This command starts a capture. It will return NAK if an error occurs.

Example:
capture

C# Function

void Capture()

The function takes no parameters.

Example:
Capture()

Save/Load

After capture you may want to Save the data.

Socket Command

Socket Command: save_to_file
This command saves the results of the current tab to a specified file. (Write permission required)
Example
save_to_file, C:\temp.logicdata

C# Function

void SaveToFile(String file)
The function takes a string with the file name to save to.
Example:
SaveToFile(“C:/temp_file”)

Analysis and Export

In the next section we will introduce the Analyzer SDK; for now, we will use the Get Analyzers command to find out what analyzers are installed.

Socket Command

Socket Command: get_analyzers

This function will return a list of analyzers currently attached to the capture, along with indexes so you can access them later.

Example:
get_analyzers
Return Value:
SPI, 0
I2C, 1
SPI, 2

Please note that each line is separated by the ‘\n’ character.

C# Function

Analyzer[] GetAnalyzers()
The function returns an array of Strings, each containing the name and index of the analyzer.

struct Analyzer
{

String type;
int index;

}

Example:
Analyzer[] Analyzers = GetAnalyzers()

Analyzer SDK

The Saleae Analyzer SDK http://support.saleae.com/hc/en-us/articles/201104644-Analyzer-SDK lets you make your own custom protocol analyzers.  The Analyzer SDK and documentation are available at http://downloads.saleae.com/SDK/SaleaeAnalyzerSdk-1.1.14.zip .  After unpacking the archive, look in the documentation folder for Saleae Analyzer SDK.pdf.

Getting Started

The Analyzer SDK User Guide tells you how to set up your build environment, compile, and debug your Analyzer SDK Project in your choice of Windows, Mac, or Linux, with support for C++.  A sample analyzer source project is provided and used as an example throughout the User Guide.  The sample builds and runs out of the box.

Writing the Code for Your Analyzer Plugin

There are 4 c++ files and 4 header files that you will implement to create your analyzer.  The procedure in the User Guide describes how to build a working analyzer from the sample, and you will be modifying that code to suit your needs.  The User Guide explains customizing the sample code in detail; these are just excerpts, to get you started. Note, you may need to take a look at some of the other Analyzer SDK articles on the help center to get up and running. Depending on what version of the Saleae software you are using, or which OS could require different steps. Please check the analyzer SDK help center article for details.

Conceptually, the analyzer can be broken into 4 main parts – the 4 c++ files.

First, you’ll work on the AnalyzerSettings-derived class. You’ll define the settings your analyzer needs, and create interfaces that’ll allow the Logic software to display a GUI for the settings. You’ll also implement serialization for these settings so they can be saved and recalled from disk.

Next you implement the SimulationDataGenerator class. Here you’ll generate simulated data that can be later to test your analyzer, or provide an example of what your analyzer expects.

Third you’ll create your AnalyzerResults-derived class. This class translates saved results into text for a variety of uses. Here you’ll start thinking about the format your results will be saved in. You probably will revisit your this file after implementing your Analyzer.

Lastly, you’ll implement your Analyzer-derived class. The main thing you’ll do here is translate data streams into results, based on your protocol.

Analyzer Settings

After setting up your analyzer project, and renaming the source files to match your project, the first step is to implement/modify your analyzer’s AnalyzerSettings-derived class.  In this file, you provide a declaration for your uniquely-named, (e.g. {YourName}AnalyzerSettings class). This class must inherit from AnalyzerSettings, and should include the AnalyzerSettings.h header file.  The User Guide describes in detail how to flesh out the class including defining User-modifiable settings such as Bit rate and Bits per transfer, providing an interface object for each settings variable, writing the constructor and destructor, and completing the remainder of the necessary interfaces.

 

SimulationDataGenerator

The next step after creating your uniquely-named, (e.g. {YourName}AnalyzerSettings) files, is to create your SimulationDataGenerator.  Your SimulationDataGenerator class provides simulated data so that you can test your analyzer against controlled, predictable waveforms.  Generally you should make the simulated data match the user settings, so you can easily test under a variety of expected conditions. In addition, simulated data gives end users an example of what to expect when using your analyzer, as well as examples of what the waveforms should look like.  That said, fully implementing simulated data is not absolutely required to make an analyzer.  Besides the constructor and destructor, there are only two required functions, and two required variables.  Other functions and variables can be added, to help implement your simulated data. The User Guide provides details using SimpleSerialSimulationDataGenerator.h as an example starting point.

AnalyzerResults-derived class

After creating your SimulationDataGenerator class, working on your uniquely-named, (e.g. {YourName}AnalyzerResults) files is the next step. AnalyzerResults is what we use to transform our results into text for display and as well as exported files, etc.  In addition to the constructor and destructor, there are 5 functions we’ll need to implement: GenerateBubbleText, GenerateExportFile, GenerateFrameTabularText, GeneratePacketTabularText, and GenerateTransactionTabularText.  The User Guide provides detailed examples.

Analyzer-derived class

Your Analyzer-derived class is the heart of the analyzer. It’s here were we analyze the bits coming in – in real time – and generate analyzer results. Other than a few other housekeeping things, that’s it. Let’s get started with your uniquely-named, (e.g. {YourName}Analyzer.h).

In addition to the constructor and destructor, here are the functions you’ll need to implement:

virtual void WorkerThread();

virtual U32 GenerateSimulationData( U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channels );

virtual U32 GetMinimumSampleRateHz();

virtual const char* GetAnalyzerName() const;

virtual bool NeedsRerun();

extern “C” ANALYZER_EXPORT const char* __cdecl GetAnalyzerName();

extern “C” ANALYZER_EXPORT Analyzer* __cdecl CreateAnalyzer( );

extern “C” ANALYZER_EXPORT void __cdecl DestroyAnalyzer( Analyzer* analyzer );

You’ll also need these member variables:

std::auto_ptr< {YourName}AnalyzerSettings > mSettings;
std::auto_ptr< {YourName}AnalyzerResults > mResults;
{YourName}SimulationDataGenerator mSimulationDataGenerator;
bool mSimulationInitilized;

You’ll also need one AnalyzerChannelData raw pointer for each input. For SerialAnalyzer, for example, we need

AnalyzerChannelData* mSerial;

As you develop your analyzer, you’ll add additional member variables and helper functions depending on your analysis needs.

The User Guide describes in detail how to complete the implementation of your uniquely-named Analyzer, (e.g. {YourName}Analyzer.cpp).

 

Summary

This post introduced the Saleae Scripting Socket API and Analyzer SDK, with links to resources including documentation and code.  Watch the http://support.saleae.com/hc/en-us/categories/200077184-SDKs-Automation-Betas for updates, and look for future posts digging deeper into the SDKs.  If you have a cool custom device application or analysis plugin you’d like to share, please let us know!

How to Easily Debug Embedded Interrupts Using Logic: Part 3

In the second blog post of this feature, we showed you how to capture interrupt signals. This post is our third and final of our series on how to easily debug embedded interrupts. In this post, we will take you through how to use Logic’s measurement capability.

Measure

With our signals captured, we can determine intervals of interest using Logic’s measurement capability. Measurements can be made from a saved capture as well; to load a saved capture, on the right-hand side of Logic’s display, Options->Open Capture. Logic opens the capture at the same viewing location from when it was saved. Moving the mouse pointer to an event of interest displays the associated timing. Double-click on a signal transition to horizontally zoom in. Position the mouse pointer at the left edge of a channel display, and a left-pointing arrow appears; click on it to advance to the previous edge in that direction. On the keyboard, CTRL_PLUS also zooms in, and CTRL_MINUS zooms out.

Logic allows us to to measure timing in our ISR by moving Timing Markers to relative locations in the capture, and Logic computes and displays the result for us. On the right-hand side of Logic’s display, look for the Timing Marker Pair A1 and A2. Using the mouse, click and drag A1 and A2 to points on the capture and Logic will display the time difference A1 – A2. We can use this to measure the performance of our ISR.

Drag A1 to the falling edge of INT0, and drag A2 to the falling edge of Output1 (ISR Active); from this measurement the minimum time required from the assertion of the external interrupt INT0 to the ISR entry is 1.75 microseconds. The minimum time to enter the ISR may be critical; if a device needs service faster than this minimum, a designer may have to increase clock speed.

Drag A1 to the falling edge of Output1 (ISR Active) and drag A2 to the rising edge of the same signal; from this measurement the running time required for the simulated work done in the ISR is 17.33 microseconds. The running time of ISRs should usually be kept as short as possible, and Logic helps us measure the time required so we can evaluate the performance impact of changes to our code.

Drag A1 to the falling edge of INT0, and drag A2 to the rising edge of Output2 (ISR Done); from this measurement the minimum time required from the assertion of the external interrupt INT0 until the ISR completes and control is returned to main is 20 microseconds. The minimum time to fully service an interrupt and return control to main with interrupts enabled and ready to service a subsequent interrupt may be a limiting factor in a system’s capabilities. If servicing interrupts can’t be done fast enough, a designer may need to re-engineer the system to accomodate the service rates available, or take other actions to increase the interrupt service rate.

This video shows our measurement scenario, working with a saved capture:

Analyze Capture
Analyze Capture

Summary

We have shown how to use Logic 4 to debug embedded interrupt issues in a typical embedded system. Logic 4 provides the visibility to understand and verify the timing and correctness of embedded code.

Part 1 
Part 2
Part 3

How to Easily Debug Embedded Interrupts Using Logic: Part 2

Analyze Capture

This blog post is the second of three in our series on how to easily debug embedded interrupts. In the first part of this feature, we went through launching and configuring Logic 4 to get started. In this post, we will go over capturing interrupt signals and saving captures.

Capture

Once you have the Logic 4 configured (including the trigger) and connected to the needed signals and code has been compiled and downloaded to the target, signals from the DUT can be captured and analyzed. Press the green Start button on Logic’s interface, then generate an interrupt on the DUT (in our case by pressing SW1). Initially, we see Logic show “Waiting for trigger”, until our interrupt, then the capture begins, ending after the configured duration. This video shows our capture scenario:

 

Save Capture

The capture can be saved for later analysis. On the right-hand side of Logic’s display, go to Options->Save Capture. This video below shows how to save a capture:

Next, in the third and final part of our series focusing on how to easily debug embedded interrupts, we’ll walk you through measuring interrupt signals.

Image

How to Easily Debug Embedded Interrupts Using Logic: Part 1

debug embedded interrupts

Interrupts are some of the most useful features of typical microcontrollers. As with all things embedded, being able to get hands-on and eyes-on visibility into your interrupt code can make the difference between quickly resolving a coding error and confidently moving on to the next task, or spending a late night debugging by trial and error. The Saleae Logic 4 provides the visibility you need, in an easy to configure user interface allowing you to quickly understand and solve your interrupt issues.

This series of blog posts will show you how to use the Logic 4 to capture, view, and measure interrupt signals generated by a typical embedded system. For an example Device Under Test (DUT), we are using a micro-controller development kit from SiLabs, for their ‘F960 8051 derivative; however, the general ideas here should be useful for other parts as well. Example code demonstrating the handling of external interrupts is provided with many development kits, and this code has been modified to suit this example.

The Hardware

The F960 dev kit provides switches, connectors, lights, and power for the 80C51F960 microcontroller. We use one switch as an external interrupt on INT0, and two GPIO pins, which we call Output1 and Output2, to give Logic visibility into the code. Output1 and Output2 are active low and are pulled up to the positive rail when inactive. Jumper plugs connect one of the switches to the INT0 pin.

The Software

The software provides the necessary configuration for using External Interrupt 0 (/INT0) as an interrupt source connected to a switch. The code executes the initialization routines and then spins in an infinite while() loop. When the interrupt switch is pressed, the edge-triggered /INT0 input will cause an interrupt. The Interrupt Service Routine (ISR) drives Output1 and Output2 low at ISR entry, and does some simulated work (just a counter decrementing from twenty). After the simulated work is complete (the counter reaches zero) Output 1 is set inactive, and the ISR terminates. Output 2 is set inactive in main (with global interrupts disabled).

This software and hardware setup allow us to measure, by triggering on the falling edge of INT0 with the Logic 4, the following:

ISR response time
The time from assertion of the interrupt signal to ISR entry (from
INT0 active to Output 1 active)

ISR running time
The time required by the work done in the ISR (from Output1 active
to Output1 inactive)

ISR service time
The time from assertion of INT0 until the ISR has completed,
control has returned to main, and the system is ready to process
another interrupt

In this example, the software configures the system to use the low-power RC oscillator at 50 KHz for the clock.

Setting-up the Hardware

The hardware including the DUT and Logic were set up according to manufacturer recommendation, with particular care given to anti-static and electrical supply considerations. The Logic User Guide suggests most wall-wart powered devices are mains-isolated, however it is worth using an Ohmmeter to check your setup before applying power. The signals needed for this example are INT0, Output1, and Output2, shown  connected to Logic 4 along with the SYSCLK.

Debug embedded interrupts - Hardware Setup
Logic 4 Connected to DUT

Setting-up the Software

The key parts of the software relevant to this example are main() and the INT0 ISR, shown here.

// MAIN Routine
// Output1 is LED3
// Output2 is LED4
//—————————————————————————–
void main (void)
{

PCA0MD &= ~0x40; // Disable Watchdog timer

Oscillator_Init(); // Initialize the system clock
Port_Init (); // Initialize crossbar and GPIO
Ext_Interrupt_Init(); // Initialize External Interrupts

LED3 = LED_OFF; // Output1 off
LED4 = LED_OFF; // Output2 off
IE_EA = 1; // Global interrupt enable

// Infinite while loop waiting for an interrupt from /INT0

while(1)
{

IE_EA = 0; // Global interrupt disable
LED3 = LED_OFF;
LED4 = LED_OFF; // ISR done, in main

IE_EA = 1; // Global interrupt enable

}

 

}

Debug embedded interrupts - Screenshot

//—————————————————————————–
// /INT0 ISR
//—————————————————————————–
//
// Whenever a negative edge appears on SW1, INT0_ISR is run.
// The interrupt pending flag is automatically cleared by vectoring to the ISR
//
//—————————————————————————–
INTERRUPT(INT0_ISR, INT0_IRQn)
{

int count = 20;
SFRPAGE = LEGACY_PAGE;
LED3 = LED_ON; // ISR start
LED4 = LED_ON;
while(–count > 0); // Simulate ISR work
LED3 = LED_OFF; // ISR work done

}

Debug embedded interrupts - isr

Configure the Logic 4

The next step is to launch and configure the Logic 4. Channel 0 is connected to INT0, Channel 1 to Output1, Channel 2 to Output2, and Channel 3 to SYSCLK. We want to trigger on a switch press, which is connected to INT0, so click on the trigger mode box in the Channel 0 configuration menu and select the falling edge trigger. Name the signals to your preference by clicking on the name in the Channel box and typing a new name. Click on the up-down arrow in the green ‘Start’ button, to configure the capture duration (we don’t need many samples for this example, and Logic accepts fractional seconds here, so I entered 0.1). Over on the right, go to Options->Preferences and select 1M Pre-trigger buffer size. This video shows how to do it.

Now that we have shown you how to configure the Logic 4, learn how to capture here.

Benefits of Using a Data Logger to Debug

A data logger is an electronic device that is used for data acquisition to record data over time according to specific performance parameters. Typically, the device is equipped with or works in conjunction with other instruments or sensors. Data loggers are used across many industries to record measurements such as battery level, vibration, voltage, sensors, temperature, events and more.

Having a data logger for debugging is beneficial because it increases visibility and runs continuously; the data is filtered and qualified to provide the most relevant information. The increased amount of data is key in providing a better understanding of the events that lead up to the bug.

The limitation in using a logic analyzer alone when recording samples is the device’s memory. Once the internal memory reaches capacity, the data can be analyzed. The issue is a ‘dead zone’ in which data goes unrecorded. The dead zone is the small window of time it takes for the logic analyzer to rearm its trigger. This data is lost which may result in the bug going undetected if it occurs during this timeframe.

By using a logic analyzer that has data logging capabilities, visibility is increased and the issue of the dead zone is eliminated. Unlike a typical oscilloscope or logic analyzer, Logic can record many more signals for much longer at a much faster speed. Logic’s built-in data logger enables continuous recording by compressing digital signals thus memory is only affected by changes in digital data. While data loggers usually have a slower sampling rate, Logic Pro 8 and Logic Pro 16 are equipped with a USB 3.0 input, which allows capturing of digital waveforms up to 100MHz, while sampling at 500 MSPS. A faster sampling rate also increases the applications you can use it with.

The advantages of using a logic analyzer with data logging capabilities are apparent. Logic’s data logger is extremely reliable, making testing and measurement easier than ever.

Pre-Order Shipping Status Update

Hello everyone,

There have been some delays with Logic 8 and Logic 16 that have come to light over the last 2 weeks.

Logic 8 

Status: ~45 pre-order customers still do not have their Logic 8’s and we will not be able to ship them for 1.5-2 weeks.

There have been two issues here.  The first is that we ran out of PCBs because of calibration failures, and were unable to get those PCBs working;  More PCBs are currently being assembled but clearly the situation is very frustrating for the last ~45 Logic 8 customers this affects.  I eventually sent an email to these ~45 customers, but it should have been delivered as much as a week or more sooner.

The 2nd issue — and in my mind the more unforgivable issue — is that we started to print out everyone’s labels, including FedEx shipping labels — in an attempt to batch process more efficiently, as well as because we *thought* that we would be shipping all of them over the course of a few days or so.

The trouble with this was that this caused these orders to show up as “Label Printed” in our system — so when people wrote in asking “what is my order status” several of us over here looked up these individual’s orders, concluded that they were just about to ship, and indicated this to the customer along with their tracking number.  This went on for ~2 days before we realized what was happening and notified everyone doing support over here that “Label Printed” no longer meant what it normally did!  This means that perhaps 10-20 customers were directly told that their order was shipping when in fact it wasn’t.  Then — and where we really screwed up — is that for some reason we failed to immediately notify these 10-20 people of our mistake, which resulted in many of them understandably becoming quite upset!

And, as it would turn out, people clicking their “order status” links in their emails also can see a tracking number in there, regardless of if their unit has actually shipped or not.

Logic Pro 16

Status: ~143 pre-order customers still do not have their Logic Pro 16s.  ~30 are shipping today to the oldest of these, and the remaining 110 will be shipping Friday and Monday.

Here we have roughly the same story:  these boards had some sort of assembly or component defect issue (I’m still not sure exactly what it is yet) with some of the ultra-tiny load switch components, causing especially low yield that prevented shipping all the pre-orders as planned.

In addition, we had the same issue as detailed under Logic 8 above regarding the labels being printed early.

Concluding Thoughts

It has been a struggle to juggle the many fires constantly erupting over here — and try to make the right calls as to what gets priority for our highly limited staff.  This incident painfully reinforces how critical it is that we rapidly communicate with customers any issues that arise.

I am enormously frustrated recalling the mistakes that I have personally presided over which have caused such a disagreeable customer experience.   I feel that I have apologized so many times over the past months that it perhaps is in danger of becoming meaningless, so I will refrain from overtly doing so here yet again, but you know how I feel.  The one thing that keeps me going is that we will get though these hard times and with the right fixes to our systems and processes this situation in principal is entirely avoidable going forward.

-Joe Garrison, CEO

First Logic Pro 16s are shipping today!

Logic Pro 16 PCBs

Hello!

Logic Pro 16– Shipping Started!

The very first Logic Pro 16s are shipping today, hooray!  Over the weekend and Monday my brother Mark heroically resolved the last blocking issue.  Pro 16 takes longer to program/calibrate than the other units so I don’t yet have an estimate as to when the very last pre-ordered unit will ship, but mid-next-week seems likely.

Logic Pro 8 – Update

All Pro 8 units are built/calibrated and most pre-ordered units have shipped, remaining units are shipping today and tomorrow.

Logic 8 – Update

All Logic 8s have been tested/assembled; most have shipped and the remaing pre-orders are shipping today/tomorrow.  I’m afraid there were some delays on many international orders due to some issues switching over to FedEx – I apologize for the delay on these international orders!

Logic Pro 8 is now shipping!

Hello Everyone!

Logic Pro 8 – Shipping Started!

We’re happy to report that the first Logic Pro 8’s shipped today, and many more will ship tomorrow.  Woo hoo!  We had a software glitch that bogged down the release of the software for a few days and that is why we couldn’t ship them sooner.  The software glitch is related to certain USB 3.0 host controllers which now seems to be resolved.   It will probably take us until late next week to ship the entire backlog.

Logic Pro 16 – Shipping Starting Next Week

We received the first article production PCBA for Pro 16 last Friday, and the production boards should arrive this Friday.  There’s a couple odds and ends that need to happen software-wise before we can ship that but nothing we shouldn’t be able to crank out over a overly-caffeinated long weekend.

Logic 8 – Shipping the Backlog

We’ve shipped several hundred Logic 8s and are shipping 75-100/day so we should have everyone’s out by Friday/Monday I think.

Some of the first Logic 8's shipped!
Some of the first Logic 8’s shipped!
Logic 4 Black - In Stock!
Logic 4 Black – In Stock!
2014-09-24 19.36.28
Launch t-shirts!