<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.element14.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Programmable Electronic Load - Input Enable Functionality</title><link>https://community.element14.com/technologies/test-and-measurement/w/documents/3267/programmable-electronic-load---input-enable-functionality</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>Programmable Electronic Load - Input Enable Functionality</title><link>https://community.element14.com/technologies/test-and-measurement/w/documents/3267/programmable-electronic-load---input-enable-functionality</link><pubDate>Wed, 06 Oct 2021 21:26:37 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:858df8dd-d2bd-4607-92b7-577d96354a7f</guid><dc:creator>Jan Cumps</dc:creator><comments>https://community.element14.com/technologies/test-and-measurement/w/documents/3267/programmable-electronic-load---input-enable-functionality#comments</comments><description>Current Revision posted to Documents by Jan Cumps on 10/6/2021 9:26:37 PM&lt;br /&gt;
&lt;table border="1" class="jiveBorder mce-item-table" height="454" style="border:1px solid #c6c6c6;width:666px;height:323px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;background-color:#ffffdb;padding:6px;"&gt;&lt;p style="margin:0;"&gt;&lt;span style="background-color:#ffffdb;"&gt;This blog documents focuses on the functionality of the Input Enable block of the &lt;/span&gt;&lt;a class="jive-link-wiki-small" href="/technologies/test-and-measurement/w/documents/1896/programmable-electronic-load"&gt;electronic load&lt;/a&gt;&lt;span style="background-color:#ffffdb;"&gt; that &lt;/span&gt;&lt;span&gt;&lt;a href="/members/peteroakes"&gt;Robert Peter Oakes&lt;/a&gt;&lt;/span&gt;&lt;span style="background-color:#ffffdb;"&gt;, &lt;/span&gt;&lt;span&gt;&lt;a href="/members/jc2048"&gt;jc2048&lt;/a&gt;&lt;/span&gt;&lt;span style="background-color:#ffffdb;"&gt; and &lt;/span&gt;&lt;span&gt;&lt;a href="/members/jancumps"&gt;Jan Cumps&lt;/a&gt;&lt;/span&gt;&lt;span style="background-color:#ffffdb;"&gt; are designing.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;We&amp;#39;re using an i²c port extender to drive this functionality. It will be mostly focusing on the firmware but let&amp;#39;s also look at the electronics involved.&lt;/p&gt;&lt;table border="0px" class="jiveBorder mce-item-table" height="357" style="border:0px solid #c6c6c6;width:656px;height:114px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border:0pxpx solid black;border:0px solid #c6c6c6;padding:6px;"&gt;&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/767x897/__key/communityserver-wikis-components-files/00-00-00-00-21/contentimage_5F00_101048.png"&gt;&lt;img alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/wikis/components/files/00/00/00/00/21/contentimage_101048.png-767x897.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=gWUPHIRxmRwAGruc4HMU6g8rfX0PqfGZNEvQzDb26o0%3D&amp;amp;se=2026-04-19T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=t9brCE0DMzVCjsi5Mh4ABA==" style="max-height: 897px;max-width: 767px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;The circuit disables the output by pulling the signal that sets the load&amp;#39;s current to ground. The switch that pulls it to ground is a FET.&lt;/p&gt;&lt;p style="margin:0;"&gt;The interface between that FET and the microcontroller is an i²c controlled port extender. We&amp;#39;re using its P7 as the driver of that switch FET.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;We&amp;#39;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.&lt;/p&gt;&lt;p style="margin:0;"&gt;At the moment the task is only focusing on the single output pin of the port extender that we&amp;#39;re using.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;table border="1" class="jiveBorder mce-item-table" height="75" style="border:1px solid #c6c6c6;width:809px;height:0px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;background-color:#e6f8fa;padding:6px;"&gt;&lt;p style="margin:0;"&gt;In the future this task may change into a more generic one that can set any of the available pin&amp;#39;s function, then read and write as appropriate.&lt;/p&gt;&lt;p style="margin:0;"&gt;We don&amp;#39;t have to worry about that now. Nothing here prevents to make that generalisation later - we don&amp;#39;t need it now.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4&gt;RTOS Tasks overview&lt;/h4&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;table border="1" class="jiveBorder" height="156" style="border:1px solid #c6c6c6;height:95px;width:1128px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Task&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Priority&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Vital&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Stack&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Argument0 (schedule)&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Comments&lt;/strong&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;"&gt;threadInputEnable&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;"&gt;10&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;"&gt;no&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;"&gt;1024&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;"&gt;&lt;p style="margin:0;"&gt;0&lt;/p&gt;&lt;p style="margin:0;"&gt;Managed by QUEUE_NAME_INPUTENABLE&lt;/p&gt;&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;"&gt;reacts on a mail message to enable or disable the input&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4&gt;RTOS MailBox overview&lt;/h4&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;table border="1" class="jiveBorder" height="156" style="border:1px solid #c6c6c6;height:95px;width:1128px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;MailBox&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Message&amp;nbsp; count&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Comment&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Functions&lt;/strong&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;"&gt;QUEUE_NAME_INPUTENABLE&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;"&gt;1&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;"&gt;&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;"&gt;&lt;p style="margin:0;font-family:Verdana, &amp;#39;Verdana Ref&amp;#39;, Geneva, Tahoma, sans-serif;color:#333333;"&gt;wait: threadInputEnable()&lt;/p&gt;&lt;p style="margin:0;font-family:Verdana, &amp;#39;Verdana Ref&amp;#39;, Geneva, Tahoma, sans-serif;color:#333333;"&gt;send: eloadInputEnable()&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;(I mistakenly called all of this Output Enable initially. That&amp;#39;s wrong. The load has an input)&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h4&gt;SCPI Interface&lt;/h4&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;table border="1" class="jiveBorder" height="124" style="border:1px solid #c6c6c6;height:0px;width:1125px;" width="1123"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;SCPI Command&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;status&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Header 3&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Comment&lt;/strong&gt;&lt;/th&gt;&lt;th style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;color:#505050;background-color:#f2f2f2;text-align:left;" valign="middle"&gt;&lt;strong&gt;Header 5&lt;/strong&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;font-family:&amp;#39;courier new&amp;#39;, courier;padding:6px;"&gt;&lt;p style="margin:0;"&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;[:SOURce]:&lt;/span&gt;INPut[:STATe] &amp;lt;b&amp;gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;"&gt;todo&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;"&gt;&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;padding:6px;"&gt;Set the input state to ON or OFF&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;font-family:&amp;#39;courier new&amp;#39;, courier;padding:6px;"&gt;&lt;p style="margin:0;"&gt;INP ON&lt;/p&gt;&lt;p style="margin:0;"&gt;INP OFF&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;font-family:&amp;#39;courier new&amp;#39;, courier;padding:6px;"&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;[:SOURce]:&lt;/span&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;INPut[:STATe]?&lt;/span&gt;&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;"&gt;todo&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;font-family:arial, helvetica, sans-serif;padding:6px;"&gt;&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;font-family:arial, helvetica, sans-serif;padding:6px;"&gt;&lt;p style="margin:0;"&gt;Query the input state&lt;/p&gt;&lt;/td&gt;&lt;td style="border:1px solid black;border:1px solid #c6c6c6;font-family:&amp;#39;courier new&amp;#39;, courier;padding:6px;"&gt;INP?&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;h5&gt;Input Enable&lt;/h5&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;The load is enabled on command, using RTOS MailBox and messaging.&lt;/p&gt;&lt;p style="margin:0;"&gt;The payload for a InputEnable message contains a boolean value that says if it&amp;#39;s on or off.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;typedef struct MsgInputEnable {
     bool value;
} MsgInputEnable;&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;The InputEnable task is started by RTOS. It inialises the Port Extender settings, then waits until it receives a message.&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span style="color:#303030;"&gt;The i²c part is removed here for clarity&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;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, &amp;amp;attr);




    while (1) {
        ssize_t bytes_read;
        bytes_read = mq_receive(mq, (char *)&amp;amp;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(), &amp;amp;d_ioi2cTransaction)) {
//                System_printf(&amp;quot;I2C Bus fault\n&amp;quot;);
//                System_flush();
            } else {
                bInputEnable_State = d_msg.value;
            }


        }
    }
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;The waiting doesn&amp;#39;t take processor time. Check the DAC explanation to see how this is done. We&amp;#39;re reusing the exact same RTOS mailbox mechanism here.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;The state is stored as a variable in inputenable_impl.c.&lt;/p&gt;&lt;p style="margin:0;"&gt;An api function is provided to retrieve this:&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// storage for the state
volatile bool bInputEnable_State = false;
// ...
bool inputenableImplGetInputEnable() {
    return bInputEnable_State;
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;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:&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void eloadInputEnable(bool bEnable) {
    MsgInputEnable pMsg;


    // value has to be validated before it arrives here. We assume it&amp;#39;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&amp;#39;t ready
        mq_send(mq, (char *)&amp;amp;pMsg, MSGINPUTENABLE_SIZE, 0);
    }
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;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:&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// ..
    {.pattern = &amp;quot;[:SOURce]:INPut[:STATe]&amp;quot;, .callback = ELOAD_SetInputState,},
    {.pattern = &amp;quot;[:SOURce]:INPut[:STATe]?&amp;quot;, .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, &amp;#182;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;
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;There is a reason for these three layers. Ask if you want to know them.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;em&gt;todo: investigate the i²c commands to set the port extender in the right initial state and drive it&amp;#39;s output P7 high and low.&lt;/em&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;strong&gt;i²c communication&lt;/strong&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;I&amp;#39;m using the &lt;a class="jive-link-external-small" href="https://www.nxp.com/docs/en/data-sheet/PCA9557.pdf" rel="nofollow ugc noopener" target="_blank"&gt;NXP datasheet&lt;/a&gt; (PCA9557 is available from TI and NXP the one on my prototype is from NXP).&lt;/p&gt;&lt;p style="margin:0;"&gt;The address of our chip is determined by the pins A0 - A3:&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/605x174/__key/communityserver-wikis-components-files/00-00-00-00-21/contentimage_5F00_101049.png"&gt;&lt;img loading="lazy" alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/wikis/components/files/00/00/00/00/21/contentimage_101049.png-605x174.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=8WEcTfgUoRqLEIir%2FGdNJtIX7hodfmWLhE59SaQd5IY%3D&amp;amp;se=2026-04-19T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=2Z0+pwetPs6ktLT0SHquDg==" style="max-height: 174px;max-width: 605px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;Because we&amp;#39;ve tied all of them to ground, our 7-bit address is 0x18.&lt;/p&gt;&lt;p style="margin:0;"&gt;To have the right setup and give the right commands, we need to send instructions to two control registers.&lt;/p&gt;&lt;p style="margin:0;"&gt;Here are the relevant registers for setting the pin directions and setting an output value:&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/600x383/__key/communityserver-wikis-components-files/00-00-00-00-21/contentimage_5F00_101050.png"&gt;&lt;img loading="lazy" alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/wikis/components/files/00/00/00/00/21/contentimage_101050.png-600x383.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=vlwKDOe9lttLKYlHF%2FP%2B3hBzKwHtzsAF%2FOS%2B7RflcPw%3D&amp;amp;se=2026-04-19T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=TTW6Wn2ZcgsLCEQwMa7/iA==" style="max-height: 383px;max-width: 600px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;Our first communication will set all registers to output and drive them all high. That&amp;#39;s going to be the initial state for our application.&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/579x300/__key/communityserver-wikis-components-files/00-00-00-00-21/contentimage_5F00_101051.png"&gt;&lt;img loading="lazy" alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/wikis/components/files/00/00/00/00/21/contentimage_101051.png-579x300.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=LGZYI7E5Z%2FsHguz6xN9gPbH8vwQi8TmdXNX6zHxYD%2Bw%3D&amp;amp;se=2026-04-19T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=BlvAPXtYJlEQr4xj8p1Hwg==" style="max-height: 300px;max-width: 579px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;"&gt;We&amp;#39;ll have to submit 2 times 2 bytes at initialisation, after setting the address:&lt;/p&gt;&lt;p style="margin:0;"&gt;The first time to set the direction.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;address + ~W&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;0x01&lt;/span&gt; (output port register)&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;0xFF&lt;/span&gt; (all values high)&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin:0;"&gt;The second time we enable all as outputs.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;address + ~W&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;0x03&lt;/span&gt; (configuration register)&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;0x00&lt;/span&gt; (all as output)&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Then, during operation, when setting and resetting the P7 of the IC, we have to flip the highest bit in the output port register:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;address + ~W&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;0x01&lt;/span&gt; (output port register)&lt;/li&gt;&lt;li&gt;if enable: &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;0x3F&lt;/span&gt;; if disable &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;0xFF&lt;/span&gt; (we are keeping all other pins high because nothing is happening with them in the current implementation of the load).&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Here is the full implementation of the input enable task, with i²c commands:&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;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(), &amp;amp;d_ioi2cTransaction)) {
//        System_printf(&amp;quot;I2C Bus fault\n&amp;quot;);
//        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(), &amp;amp;d_ioi2cTransaction)) {
//        System_printf(&amp;quot;I2C Bus fault\n&amp;quot;);
//        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, &amp;amp;attr);




    while (1) {
        ssize_t bytes_read;
        bytes_read = mq_receive(mq, (char *)&amp;amp;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(), &amp;amp;d_ioi2cTransaction)) {
//                System_printf(&amp;quot;I2C Bus fault\n&amp;quot;);
//                System_flush();
            } else {
                bInputEnable_State = d_msg.value;
            }


        }
    }
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="display:none;"&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: metrology, boosterpack, port_extender, msp432, scpi, launchpad, laboratory, instrument&lt;/div&gt;
</description></item></channel></rss>