element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • 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
Test & Tools
  • Technologies
  • More
Test & Tools
Documents Programmable Electronic Load - Input Enable Functionality
  • Blog
  • Forum
  • Documents
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Test & Tools to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 2 Dec 2017 12:19 PM Date Created
  • Last Updated Last Updated: 6 Oct 2021 9:26 PM
  • Views 1191 views
  • Likes 4 likes
  • Comments 4 comments
Related
Recommended

Programmable Electronic Load - Input Enable Functionality

This blog documents focuses on the functionality of the Input Enable block of the electronic load that Robert Peter Oakes, jc2048 and Jan Cumps are designing.

We're using an i²c port extender to drive this functionality. It will be mostly focusing on the firmware but let's also look at the electronics involved.

image

 

The circuit disables the output by pulling the signal that sets the load's current to ground. The switch that pulls it to ground is a FET.

The interface between that FET and the microcontroller is an i²c controlled port extender. We're using its P7 as the driver of that switch FET.

 

We'll have to create an RTOS task that puts all pins of the extender in correct mode. Then it has to listen and react on messages that indicate whether the input has to be on or off.

At the moment the task is only focusing on the single output pin of the port extender that we're using.

 

In the future this task may change into a more generic one that can set any of the available pin's function, then read and write as appropriate.

We don't have to worry about that now. Nothing here prevents to make that generalisation later - we don't need it now.

 

RTOS Tasks overview

 

TaskPriorityVitalStackArgument0 (schedule)Comments
threadInputEnable10no1024

0

Managed by QUEUE_NAME_INPUTENABLE

reacts on a mail message to enable or disable the input

 

RTOS MailBox overview

 

MailBoxMessage  countCommentFunctions
QUEUE_NAME_INPUTENABLE1

wait: threadInputEnable()

send: eloadInputEnable()

 

(I mistakenly called all of this Output Enable initially. That's wrong. The load has an input)

 

SCPI Interface

 

SCPI CommandstatusHeader 3CommentHeader 5

[:SOURce]:INPut[:STATe] <b>

todoSet the input state to ON or OFF

INP ON

INP OFF

[:SOURce]:INPut[:STATe]?todo

Query the input state

INP?

 

Input Enable

 

The load is enabled on command, using RTOS MailBox and messaging.

The payload for a InputEnable message contains a boolean value that says if it's on or off.

 

typedef struct MsgInputEnable {
     bool value;
} MsgInputEnable;

 

The InputEnable task is started by RTOS. It inialises the Port Extender settings, then waits until it receives a message.

The i²c part is removed here for clarity

 

void *threadInputEnable(void *arg0) {


// ...

    mqd_t mq;
    struct mq_attr attr;


    attr.mq_flags = 0;
    attr.mq_maxmsg = 1;
    attr.mq_msgsize = MSGINPUTENABLE_SIZE;
    attr.mq_curmsgs = 0;
    mq = mq_open(QUEUE_NAME_INPUTENABLE, O_CREAT | O_RDONLY, 0644, &attr);




    while (1) {
        ssize_t bytes_read;
        bytes_read = mq_receive(mq, (char *)&d_msg, MSGINPUTENABLE_SIZE, NULL);


        /* wait for mailbox to be posted by writer() */
        if (bytes_read) {
            d_iotxBuffer[1] = d_msg.value ? 0x3F : 0xFF; // bit 7 low is output enable.
            if (! I2C_transfer(i2c_implGetHandle(), &d_ioi2cTransaction)) {
//                System_printf("I2C Bus fault\n");
//                System_flush();
            } else {
                bInputEnable_State = d_msg.value;
            }


        }
    }
}

 

The waiting doesn't take processor time. Check the DAC explanation to see how this is done. We're reusing the exact same RTOS mailbox mechanism here.

 

The state is stored as a variable in inputenable_impl.c.

An api function is provided to retrieve this:

 

// storage for the state
volatile bool bInputEnable_State = false;
// ...
bool inputenableImplGetInputEnable() {
    return bInputEnable_State;
}

 

The eload api (this is the generic interface for the whole instrument, it can serve events from the SCPI module and from other GUIs - hardware or software) provides two api functions to wrap this:

 

void eloadInputEnable(bool bEnable) {
    MsgInputEnable pMsg;


    // value has to be validated before it arrives here. We assume it's valid
    pMsg.value = bEnable;
    /* enqueue message */
    mqd_t mq;
    mq = mq_open(QUEUE_NAME_INPUTENABLE, O_WRONLY);
    if (mq != ((mqd_t)(-1))) { // only send data if the message queue has been initialised by the receiving end. Else our instrument isn't ready
        mq_send(mq, (char *)&pMsg, MSGINPUTENABLE_SIZE, 0);
    }
}

 

 

The SCPI implementation has two table entries to understand both set and get calls, and a service routine to fullfill the request. These routines call the eload api:

 

// ..
    {.pattern = "[:SOURce]:INPut[:STATe]", .callback = ELOAD_SetInputState,},
    {.pattern = "[:SOURce]:INPut[:STATe]?", .callback = ELOAD_GetInputState,},
// ..

static scpi_result_t ELOAD_SetInputState(scpi_t * context) {
    scpi_bool_t param1;

    /* read first parameter if present */
    if (!SCPI_ParamBool(context, ¶m1, TRUE)) {
        return SCPI_RES_ERR;
    }
    eloadInputEnable(param1);
    return SCPI_RES_OK;
}


static scpi_result_t ELOAD_GetInputState(scpi_t * context) {
    SCPI_ResultBool(context, eloadInputEnabled());
    return SCPI_RES_OK;
}

 

There is a reason for these three layers. Ask if you want to know them.

 

todo: investigate the i²c commands to set the port extender in the right initial state and drive it's output P7 high and low.

 

i²c communication

 

I'm using the NXP datasheet (PCA9557 is available from TI and NXP the one on my prototype is from NXP).

The address of our chip is determined by the pins A0 - A3:

image

Because we've tied all of them to ground, our 7-bit address is 0x18.

To have the right setup and give the right commands, we need to send instructions to two control registers.

Here are the relevant registers for setting the pin directions and setting an output value:

 

image

Our first communication will set all registers to output and drive them all high. That's going to be the initial state for our application.

image

We'll have to submit 2 times 2 bytes at initialisation, after setting the address:

The first time to set the direction.

  • address + ~W
  • 0x01 (output port register)
  • 0xFF (all values high)

The second time we enable all as outputs.

  • address + ~W
  • 0x03 (configuration register)
  • 0x00 (all as output)

 

Then, during operation, when setting and resetting the P7 of the IC, we have to flip the highest bit in the output port register:

  • address + ~W
  • 0x01 (output port register)
  • if enable: 0x3F; if disable 0xFF (we are keeping all other pins high because nothing is happening with them in the current implementation of the load).

 

Here is the full implementation of the input enable task, with i²c commands:

 

void *threadInputEnable(void *arg0) {


    MsgInputEnable d_msg;
    d_ioi2cTransaction.writeBuf = d_iotxBuffer;
    d_ioi2cTransaction.readBuf = d_iorxBuffer;
    d_ioi2cTransaction.slaveAddress = PORTEXTENDER_I2C_ADDR;
    d_ioi2cTransaction.writeCount = 2;
    d_ioi2cTransaction.readCount = 0;


    // initialise and set output to off


    // first set all outputs to high


    d_iotxBuffer[0] = 0x01; // control register: select output port register
    d_iotxBuffer[1] = 0xFF; // set each bit high in the output register
    if (! I2C_transfer(i2c_implGetHandle(), &d_ioi2cTransaction)) {
//        System_printf("I2C Bus fault\n");
//        System_flush();
    }


    d_iotxBuffer[0] = 0x03; // control register: select configuration register
    d_iotxBuffer[1] = 0x00; // set each bit low so that all 8 pins are outputs (recommended state for unused pins)
    if (! I2C_transfer(i2c_implGetHandle(), &d_ioi2cTransaction)) {
//        System_printf("I2C Bus fault\n");
//        System_flush();
    }




    // from now on we only write to the output port register.
    // Value d_txBuffer[0] can be fixed outside the loop


    d_iotxBuffer[0] = 0x01; // control register: select output port register


    mqd_t mq;
    struct mq_attr attr;


    attr.mq_flags = 0;
    attr.mq_maxmsg = 1;
    attr.mq_msgsize = MSGINPUTENABLE_SIZE;
    attr.mq_curmsgs = 0;
    mq = mq_open(QUEUE_NAME_INPUTENABLE, O_CREAT | O_RDONLY, 0644, &attr);




    while (1) {
        ssize_t bytes_read;
        bytes_read = mq_receive(mq, (char *)&d_msg, MSGINPUTENABLE_SIZE, NULL);


        /* wait for mailbox to be posted by writer() */
        if (bytes_read) {
            d_iotxBuffer[1] = d_msg.value ? 0x3F : 0xFF; // bit 7 low is output enable.
            if (! I2C_transfer(i2c_implGetHandle(), &d_ioi2cTransaction)) {
//                System_printf("I2C Bus fault\n");
//                System_flush();
            } else {
                bInputEnable_State = d_msg.value;
            }


        }
    }
}

  • metrology
  • boosterpack
  • port_extender
  • msp432
  • scpi
  • launchpad
  • laboratory
  • instrument
  • Share
  • History
  • More
  • Cancel
  • Sign in to reply

Top Comments

  • Jan Cumps
    Jan Cumps over 7 years ago +3
    Measurements without initialisation. The switch FET Q1 gate is 5 V and the FET is pulling drain to ground. The load's set signal (left of D2, it happens to be 11.5 V but could be any driving voltage that…
  • Jan Cumps
    Jan Cumps over 7 years ago +2
    Firmware APIs are extended for input enable. The SCPI command to set the input state is: INP ON|OFF The command to get the state is: INP? These commands are in line with what other SCPI enabled loads do…
  • Jan Cumps
    Jan Cumps over 7 years ago in reply to Jan Cumps +2
    Now with 1²c commands. The functionality works. The switch FET determines if the signal to the power FET is enabled by listening to SCPI command INP ON|OFF
  • Jan Cumps
    Jan Cumps over 7 years ago

    adapted to SimpleLink RTOS idioms and POSIX API

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

    Now with 1²c commands. The functionality works. The switch FET determines if the signal to the power FET is enabled by listening to SCPI command INP ON|OFF

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

    Firmware APIs are extended for input enable.

    The SCPI command to set the input state is:

    INP ON|OFF

    The command to get the state is:

    INP?

    These commands are in line with what other SCPI enabled loads do.

    The full, offical command is

    [:SOURce]:INPut [:STATe]...

    and that's supported by the load. Only the capital letters outside of square brackets are mandatory.

     

    The i2c part isn't implemented yet, so there's no hardware change - only the firmware layers from parser to the inputenable API are ready.

     

    The current version is available on GitHUB as https://github.com/jancumps/msp432/tree/master/MSP432_SCPI_ElectronicLoad

    This works on a plain MSP432 LaunchPad without any board mounted.

    Plug it in, launch Peter's GUI and execute:

    INP?
    INP ON
    INP?
    INP OFF
    INP?

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

    Measurements without initialisation. The switch FET Q1 gate is 5 V and the FET is pulling drain to ground.

    The load's set signal (left of D2, it happens to be 11.5 V but could be any driving voltage that the load sends to the output power FET) will never make it to the power FET because switching FET Q1 overrides it.

    image

    Next steps is to control P7 of the extender and see if this whole setup works. Again, that's an exercise in i²c more than an electronics thing.

    • Cancel
    • Vote Up +3 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