<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Manfredas Zabarauskas&#039; Blog &#187; windows ce</title>
	<atom:link href="http://blog.zabarauskas.com/tag/windows-ce/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zabarauskas.com</link>
	<description>We are what we repeatedly do; excellence, then, is not an act but a habit. -- Aristotle</description>
	<lastBuildDate>Tue, 29 Nov 2011 03:23:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>SMRP6400/SMDK64X0 IIC synchronization problems</title>
		<link>http://blog.zabarauskas.com/smrp6400smdk6410-iic-synchronization-problems/</link>
		<comments>http://blog.zabarauskas.com/smrp6400smdk6410-iic-synchronization-problems/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 21:45:12 +0000</pubDate>
		<dc:creator>Manfredas Zabarauskas</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drivers]]></category>
		<category><![CDATA[iic]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[samsung]]></category>
		<category><![CDATA[smdk6400]]></category>
		<category><![CDATA[smdk6410]]></category>
		<category><![CDATA[smrp6400]]></category>
		<category><![CDATA[windows ce]]></category>

		<guid isPermaLink="false">http://blog.zabarauskas.com/?p=116</guid>
		<description><![CDATA[Since last week we have spent quite some time debugging Samsung SMRP6400/SMDK64X0 IIC drivers, I thought I might share with one particular example here. It is both a good showcase of the hardware/software synchronization issues and since the bugs are in the latest version of the drivers shipped together with the development platforms, it might [...]]]></description>
			<content:encoded><![CDATA[<p><small><div class="wp-caption alignright" style="width: 191px"><img title="Debugging Samsung SMRP6400" src="http://blog.zabarauskas.com/img/100_0139_small.jpg" alt="Debugging Samsung SMRP6400" width="181" height="150" /><p class="wp-caption-text">Debugging Samsung SMRP6400</p></div></small></p>
<p>Since last week we have spent quite some time debugging Samsung SMRP6400/SMDK64X0 IIC drivers, I thought I might share with one particular example here. It is both a good showcase of the hardware/software synchronization issues and since the bugs are in the latest version of the drivers shipped together with the development platforms, it might save someone from additional headaches.</p>
<p>So, while working on the drivers for IIC one of our automated tests to make sure that IIC still works was to write some data on the bus, do an immediate read-back and verify that both data written and read back matches; something similar to this:</p>
<pre>UCHAR outData[3] = { REGISTER, DATA_BYTE_1, DATA_BYTE2 };
UCHAR inData[2] = { 0, 0 };

IIC_Write(SLAVE_ADDRESS, outData, 3);
IIC_Read(SLAVE_ADDRESS, REGISTER, inData, 2);

if ((inData[0] != DATA_BYTE_1) || (inData[1] != DATA_BYTE_2))
{
    DEBUGMSG(ERROR_MSG,
             (TEXT("Immediate write/read data mismatch: data sent [0x%X " \
                   "0x%X] differs from the data received [0x%X, 0x%X]."),
                   DATA_BYTE_1, DATA_BYTE_2, inData[0], inData[1]));
}</pre>
<p>However, after we added some IIC read calls from another hardware driver it started spitting fire throwing the following error message:</p>
<pre>Immediate write/read data mismatch: data sent <strong>[0xCA, 0xFE]</strong>
differs from the data received <strong>[0xCA, 0xFE]</strong>.</pre>
<p>Now this clearly meant we had a serious problem: the error message was saying that the data does not match, which obviously was not the case as shown by the message text!</p>
<p>Since we were pretty confident about our side of things, as well as the readings from the scope, it seemed like a good time to start looking at the Samsung IIC drivers (and especially s3c64X0_iic_lib.cpp). The driver structure there is pretty straightforward: the first read/write byte on the bus triggers the hardware IRQ, which is mapped to SysIntr triggering a transfer event; then any subsequent call to a read/write function blocks waiting for a <code>transfer-done</code> event, which is triggered when the last byte is read/written in the IST.</p>
<p>Everything looks sane up to the point where a <code>transfer-done</code> event is signalled from the IST (pseudocode, not the original code below, due to the legal issues):</p>
<pre>static HANDLE ghTransferEvent;
static HANDLE ghTransferDone;
static DWORD IICSysIntr;

...

static DWORD IST(LPVOID lpContext)
{
    BOOL bTransferDone = FALSE;

    while (TRUE) {
        WaitForSingleObject(ghTransferEvent, INFINITE);

        switch (IIC_BUS_STATUS) {
            case MASTER_RECEIVE:
                // receive bytes and store them in the buffer
            break;

            case MASTER_TRANSMIT:
                // transmit bytes from the buffer in memory
                if (LAST_BYTE) bTransferDone = TRUE;
            break;

            InterruptDone(IICSysIntr);

            if (bTransferDone) {
                SetEvent(ghTransferDone);
            }
        }
    }
}</pre>
<p>Two major problems with this code are:</p>
<ol>
<li>The <code>bTransferDone</code> variable is never set from the IIC read, and hence the <code>transfer-done</code> event for bus reads is never triggered,</li>
<li>After the <code>bTransferDone</code> is set from the IIC write, it is never reset, hence the <code>transfer-done</code> event is triggered after reading/writing single byte on the bus in all subsequent transactions.</li>
</ol>
<p>That explains the initial test case failure: during the write/immediate read data comparison the data arrives exactly between the <code>if</code> statement and the following printout, thus triggering the error message, but printing the correct data to the output due to the early signal of the event.</p>
<p>The way to solve this is also straightforward: make sure that the <code>bTransferDone</code> variable is cleared after the <code>transfer-done</code> event is triggered, and make sure that master-receive mode sets the <code>bTransferDone</code> variable after reading the last byte of the transaction from the IIC bus.</p>
<p>In pseudocode it would look similar to:</p>
<pre>static DWORD IST(LPVOID context)
{
    BOOL bTransferDone = FALSE;

    while (TRUE) {
        WaitForSingleObject(ghTransferEvent, INFINITE);

        switch (IIC_BUS_STATUS) {
            case MASTER_RECEIVE:
                // receive bytes and store them in the buffer
                if (LAST_BYTE) bTransferDone = TRUE;
            break;

            case MASTER_TRANSMIT:
                // transmit bytes from the buffer in memory
                if (LAST_BYTE) bTransferDone = TRUE;
            break;

            InterruptDone(IICSysIntr);

            if (bTransferDone) {
                bTransferDone = FALSE;
                SetEvent(ghTransferDone);
            }
        }
    }
}</pre>
<p>The lesson of the day (quoting my colleague) is: "<em>The first rule about multithreading - you're wrong</em>".</p>
<div class="wp-caption alignleft" style="width: 652px"><img title="At work. Wolfson Microelectronics PLC, 2009" src="http://blog.zabarauskas.com/img/100_0138_small.jpg" alt="At work. Wolfson Microelectronics PLC, 2009" width="642" height="496" /><p class="wp-caption-text">At work. Wolfson Microelectronics PLC, 2009</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.zabarauskas.com/smrp6400smdk6410-iic-synchronization-problems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- www.000webhost.com Analytics Code -->
<script type="text/javascript" src="http://analytics.hosting24.com/count.php"></script>
<noscript><a href="http://www.hosting24.com/"><img src="http://analytics.hosting24.com/count.php" alt="web hosting" /></a></noscript>
<!-- End Of Analytics Code -->

