<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>8-bit MicrocontrollersのトピックRe: PWM decoding. Best practice</title>
    <link>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161803#M9855</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Mac,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Many thanks indeed for your quick response !&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Yes, the microseconds is a challenge to handle. Even my bus is 24Mhz, its not enough to calculate something between of pulses.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Basically the device send CRC at the and of sequence. 40 bit is a 5 byte. First four is data and last one is CRC. So, it will be easy to detect the failure. Also, project is not critical to the other interrupt ruitines during the reading of this particular sensor.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is what I have now:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This function looks exactly as&amp;nbsp;you mention: set port to OUT, send logical zero, switch to input mode, turn on TPM CH0&lt;/P&gt;&lt;P&gt;to capture.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;void &lt;FONT size="2"&gt;&lt;STRONG&gt;HumStartSignal&lt;/STRONG&gt;(&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;{&lt;/P&gt;&lt;P align="left"&gt;h_cnt=0;&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC = 0x0; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// RESET counters for the channels,&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC_CH0F = 0; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Reset ELS0A/B to set port as regular port, Reset CH0F flag.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;HUMportDD = 0xFF; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Switch port to OUT&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;HUMport = 0x00; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Clear port (set Low)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;WaitNms(25); // Wait 25ms&lt;/P&gt;&lt;P&gt;HUMport = 0x01; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Set pin to HIGH&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;HUMportDD = 0x00; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Switch port to IN&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Set CH0 in Input Capture Mode on falling edges (this command reset counters as well)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// CHnF CHnIE MSnB MSnA ELSnB ELSnA 0 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC = 0x48;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is IRQ routine:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;interrupt &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;STRONG&gt;TPM1C0_ISR&lt;/STRONG&gt;(&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;{&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC_CH0F = 0; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// ACK channel interrupt. Reading flag, then write a 0 to the bit.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;h_var[h_cnt++] = TPM1C0V;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And here is external function to analyse the h_var array:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;unsigned&amp;nbsp;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;long&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;STRONG&gt;HumReadByte&lt;/STRONG&gt;(&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;{&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;unsigned&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;char&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;i;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;unsigned&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;long&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;num = 0;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;delta;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;(i=0; i&amp;lt;h_cnt; i+=2){&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp; delta = h_tik[i+1] - h_tik[i];&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;(delta &amp;gt; 70 &amp;amp;&amp;amp; delta &amp;lt; 110)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; num = ((num &amp;lt;&amp;lt; 1) | 1);&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;(delta &amp;gt; 50 &amp;amp;&amp;amp; delta &amp;lt; 70)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; num = (num &amp;lt;&amp;lt; 1);&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp; }&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;num;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Then in main loop I call them like this:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;HumStartSignal();&lt;/P&gt;&lt;P align="left"&gt;WaitNms(50); // wait 50 ms&lt;/P&gt;&lt;P&gt;&lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;num = HumReadByte();&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#3F7F5F"&gt;&lt;FONT color="#3F7F5F"&gt;So, the idea is to use Interrupt to gather "time stamps" for each event. And then analyse it in the main program.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#3F7F5F"&gt;&lt;FONT color="#3F7F5F"&gt;Unfortunately, for some uncertain reason this code cannot be handled by debugger. It goes through only if I commented out HumReadByte().&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#3F7F5F"&gt;&lt;FONT color="#3F7F5F"&gt;I did try various value for stack in PRM. The MAP file shows this one:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;Summary of section sizes per section type:&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;READ_ONLY (R): 10CB (dec: 4299)&lt;/P&gt;&lt;P align="left"&gt;READ_WRITE (R/W): 599 (dec: 1433)&lt;/P&gt;&lt;P&gt;NO_INIT (N/I): AC (dec: 172)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I don't think its a memory issue, since JM60 has 60K ROM plus 4K RAM. There is no warnings. Its just hang.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Sometimes debugger jump to this line:&lt;/P&gt;&lt;P align="left"&gt;&lt;U&gt;INIT_SP_FROM_STARTUP_DESC()&lt;/U&gt;; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;/*lint !e960 MISRA 14.3 REQ, not a null statement (instead: several HLI statements) */&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;d0ct0r&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Fri, 11 May 2012 21:23:02 GMT</pubDate>
    <dc:creator>d0ct0r</dc:creator>
    <dc:date>2012-05-11T21:23:02Z</dc:date>
    <item>
      <title>PWM decoding. Best practice</title>
      <link>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161801#M9853</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hello Folks,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I would like to hear an advise what would be best practice to decode PWM (or sort of PWM) ?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;To be more detailed, lets take DHT11 Humidity Sensor as an example. This little fellow suppose to send 40 bit sequence as soon as some port send logical '0' to it (see attached file).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is my code to initiate communication:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;void &lt;SPAN style="font-size: 2;"&gt;&lt;STRONG&gt;HumStartSignal&lt;/STRONG&gt;(&lt;/SPAN&gt;&lt;STRONG style=": ; color: #7F0055; font-size: 2;"&gt;void&lt;/STRONG&gt;&lt;SPAN style=": ; font-size: 2;"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;{&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC = 0x0; &lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// RESET counters for the channels,&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC_CH0F = 0; &lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// Reset ELS0A/B to set port as regular port, Reset CH0F flag.&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;HUMportDD = 0xFF; &lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// Switch port to OUT&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;HUMport = 0x00; &lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// Clear port (set Low)&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;WaitNms(25); &lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// Wait&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;HUMport = 0x01; &lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// Set pin to HIGH&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;HUMportDD = 0x00; &lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// Switch port to IN&lt;/SPAN&gt;&lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// Set CH0 in Input Capture Mode on falling edges (this command reset counters as well)&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;&lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// CHnF CHnIE MSnB MSnA ELSnB ELSnA 0 0 -&amp;gt; 01001000 / (RE: 01000100 44) / (AE: 01001100) 4C)&lt;/SPAN&gt;&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC = 0x48;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Now, I need your expertise what to do next. For sure I have interrupt function for TPM1 CH0. I did try to use it, but I don't like&amp;nbsp;how its&amp;nbsp;looks like. Also, time to time my whole projects hangs if I start to use it.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;// Not whole function. just a scetch&lt;/P&gt;&lt;P&gt;TPM1C0SC_CH0F = 0; &lt;SPAN style=": ; color: #3F7F5F; font-size: 2;"&gt;// ACK channel interrupt. Reading flag, then write a 0 to the bit.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;// calculate delta between previous IRQ&lt;/P&gt;&lt;P&gt;delta =TPM1C0V - oldcounter;&lt;/P&gt;&lt;P&gt;oldcounter = TPM1C0V;&lt;/P&gt;&lt;P&gt;if (delta &amp;gt; 40 &amp;amp;&amp;amp; delta &amp;lt; 110)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; htvar = ((htvar&amp;lt;&amp;lt;1) | 1) // ONE&lt;/P&gt;&lt;P&gt;else&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;htvar = ((htvar &amp;lt;&amp;lt;1) ) // ZERO&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Then I tried to create function outside of IRQ which cold handle that. However its failed too.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Whole idea suppose to be like this:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Send ONE to the sensor and right away read its response and parse it somehow.&lt;/P&gt;&lt;P&gt;I'll be appreciate for the ideas and avises. Thanks !&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 11 May 2012 04:21:46 GMT</pubDate>
      <guid>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161801#M9853</guid>
      <dc:creator>d0ct0r</dc:creator>
      <dc:date>2012-05-11T04:21:46Z</dc:date>
    </item>
    <item>
      <title>Re: PWM decoding. Best practice</title>
      <link>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161802#M9854</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;There is no "best practice" to accomplish this&amp;nbsp; type of decoding.&amp;nbsp; You will require a reliable method that takes into account the specific constraints of the particular project.&amp;nbsp; Depending on those constraints, different approaches may be required.&amp;nbsp; It is possible that such constraints may&amp;nbsp;cause the decoding to sometimes unavoidably fail.&amp;nbsp; Under these circumstances it is necessary to be able to detect such a&amp;nbsp;failure, so that a new reading may be commenced.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The decoding process is time critical.&amp;nbsp; To minimize the number of timer&amp;nbsp;interrupts required, it should suffice to measure the period between each pair of negative edges.&amp;nbsp; The critical timing interval will be for the 0-bit, with a total period of 76 microseconds.&amp;nbsp; Assuming the bus frequency is 8 MHz, this would correspond with 608 cycles.&amp;nbsp; Obviously, more cycles would be available&amp;nbsp;at higher bus frequencies.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Assuming that&amp;nbsp;TPM&amp;nbsp;channel is set for input capture mode, and that an interrupt will occur on every negative edge, the following operations may need to be completed within the critical limit -&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Completion of any ISR current currently being processed when the capture occurs.&lt;/LI&gt;&lt;LI&gt;The potential execution of all other queued ISRs&amp;nbsp;with higher priority than the TPM channel ISR.&lt;/LI&gt;&lt;LI&gt;Execution of the TPM channel ISR itself.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;You will need to determine the worst case cycles for all ISRs to determine the susceptibility to decode failure.&amp;nbsp; If items 1 and 2&amp;nbsp;are present only infrequently, and item 3 easily meets the timing requirement, you might decide to accept the occasional decode failure on the basis that a second attempt then has a high chance of succeeding.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;An alternative solution is to globally disable&amp;nbsp;interrupts just prior to the completion of the start pulse, and to detect the sequence of&amp;nbsp;input capture events by polling the TPM channel flag.&amp;nbsp; However, this will mean that all&amp;nbsp;interrupt execution will be delayed by about 4 milliseconds.&amp;nbsp; The feasibility of this approach will depend on whether the project uses any other time critical processes.&amp;nbsp; For example, this method would be problematic if you also&amp;nbsp; required&amp;nbsp;SCI receive&amp;nbsp;operation at 2400 bit/s, or higher.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;You would process each bit period by comparing with a threshold period of, say 100 microseconds.&amp;nbsp; A period less than the threshold would represent a 0-bit, and greater than the threshold a 1-bit.&amp;nbsp; To minimize ISR processing cycles,&amp;nbsp;there may be some advantage in considering judicious use of inline assembly code for the serial data&amp;nbsp;shifting process, where the carry status bit&amp;nbsp;can be directly used.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;You will also need to detect whether the pulse sequence is actually completed.&amp;nbsp; I would suggest to setup another TPM channel for software output compare mode,&amp;nbsp;set for a timeout period of, say 150-200us relative to each input capture time.&amp;nbsp; If the compare event&amp;nbsp;should ever occur, this will&amp;nbsp;immediately indicate an error condition.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I notice that the start pulse is not time critical, provided a minimum duration is met.&amp;nbsp; This is most easily generated if the TPM pin is operating as GPIO at this point.&amp;nbsp; Input capture mode would be selected after the start pulse is completed.&amp;nbsp; Whenever the data line has a high state the pin is best set as&amp;nbsp;an input, prior to selection of input capture mode.&amp;nbsp; The following macros would achieve this&amp;nbsp;(assuming PTAD0&amp;nbsp;is the data pin).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT face="courier new,courier"&gt;#define DLOW&amp;nbsp; PTADD_PTADD0 = 1; PTAD_PTAD0 = 0&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="courier new,courier"&gt;#define DHIGH&amp;nbsp;PTADD_PTADD0 = 0&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Once input capture mode is selected, the pin will be an input, independent of the GPIO data direction.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;To use the TPM module&amp;nbsp;for longer timing&amp;nbsp;durations, such as the start pulse, rather than set a large prescale value so that the overflow period is greater than the timing duration, you might alternatively generate a shorter, periodic&amp;nbsp;"tick" interval.&amp;nbsp; In this case, a tick period of 2ms would be appropriate.&amp;nbsp; For the start pulse duration, you would count 20 of these intervals.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Mac&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 11 May 2012 17:42:13 GMT</pubDate>
      <guid>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161802#M9854</guid>
      <dc:creator>bigmac</dc:creator>
      <dc:date>2012-05-11T17:42:13Z</dc:date>
    </item>
    <item>
      <title>Re: PWM decoding. Best practice</title>
      <link>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161803#M9855</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Mac,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Many thanks indeed for your quick response !&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Yes, the microseconds is a challenge to handle. Even my bus is 24Mhz, its not enough to calculate something between of pulses.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Basically the device send CRC at the and of sequence. 40 bit is a 5 byte. First four is data and last one is CRC. So, it will be easy to detect the failure. Also, project is not critical to the other interrupt ruitines during the reading of this particular sensor.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is what I have now:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This function looks exactly as&amp;nbsp;you mention: set port to OUT, send logical zero, switch to input mode, turn on TPM CH0&lt;/P&gt;&lt;P&gt;to capture.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;void &lt;FONT size="2"&gt;&lt;STRONG&gt;HumStartSignal&lt;/STRONG&gt;(&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;{&lt;/P&gt;&lt;P align="left"&gt;h_cnt=0;&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC = 0x0; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// RESET counters for the channels,&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC_CH0F = 0; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Reset ELS0A/B to set port as regular port, Reset CH0F flag.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;HUMportDD = 0xFF; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Switch port to OUT&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;HUMport = 0x00; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Clear port (set Low)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;WaitNms(25); // Wait 25ms&lt;/P&gt;&lt;P&gt;HUMport = 0x01; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Set pin to HIGH&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;HUMportDD = 0x00; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Switch port to IN&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// Set CH0 in Input Capture Mode on falling edges (this command reset counters as well)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// CHnF CHnIE MSnB MSnA ELSnB ELSnA 0 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC = 0x48;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is IRQ routine:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;interrupt &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;STRONG&gt;TPM1C0_ISR&lt;/STRONG&gt;(&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;{&lt;/P&gt;&lt;P align="left"&gt;TPM1C0SC_CH0F = 0; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;// ACK channel interrupt. Reading flag, then write a 0 to the bit.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;h_var[h_cnt++] = TPM1C0V;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And here is external function to analyse the h_var array:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;unsigned&amp;nbsp;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;long&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;STRONG&gt;HumReadByte&lt;/STRONG&gt;(&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;{&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;unsigned&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;char&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;i;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;unsigned&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;long&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;num = 0;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;delta;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;(i=0; i&amp;lt;h_cnt; i+=2){&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp; delta = h_tik[i+1] - h_tik[i];&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;(delta &amp;gt; 70 &amp;amp;&amp;amp; delta &amp;lt; 110)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; num = ((num &amp;lt;&amp;lt; 1) | 1);&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;(delta &amp;gt; 50 &amp;amp;&amp;amp; delta &amp;lt; 70)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; num = (num &amp;lt;&amp;lt; 1);&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp; }&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;num;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Then in main loop I call them like this:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;HumStartSignal();&lt;/P&gt;&lt;P align="left"&gt;WaitNms(50); // wait 50 ms&lt;/P&gt;&lt;P&gt;&lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;num = HumReadByte();&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#3F7F5F"&gt;&lt;FONT color="#3F7F5F"&gt;So, the idea is to use Interrupt to gather "time stamps" for each event. And then analyse it in the main program.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#3F7F5F"&gt;&lt;FONT color="#3F7F5F"&gt;Unfortunately, for some uncertain reason this code cannot be handled by debugger. It goes through only if I commented out HumReadByte().&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#3F7F5F"&gt;&lt;FONT color="#3F7F5F"&gt;I did try various value for stack in PRM. The MAP file shows this one:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;Summary of section sizes per section type:&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;READ_ONLY (R): 10CB (dec: 4299)&lt;/P&gt;&lt;P align="left"&gt;READ_WRITE (R/W): 599 (dec: 1433)&lt;/P&gt;&lt;P&gt;NO_INIT (N/I): AC (dec: 172)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I don't think its a memory issue, since JM60 has 60K ROM plus 4K RAM. There is no warnings. Its just hang.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Sometimes debugger jump to this line:&lt;/P&gt;&lt;P align="left"&gt;&lt;U&gt;INIT_SP_FROM_STARTUP_DESC()&lt;/U&gt;; &lt;FONT color="#3F7F5F" size="2"&gt;&lt;FONT color="#3F7F5F" size="2"&gt;/*lint !e960 MISRA 14.3 REQ, not a null statement (instead: several HLI statements) */&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;d0ct0r&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 11 May 2012 21:23:02 GMT</pubDate>
      <guid>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161803#M9855</guid>
      <dc:creator>d0ct0r</dc:creator>
      <dc:date>2012-05-11T21:23:02Z</dc:date>
    </item>
    <item>
      <title>Re: PWM decoding. Best practice</title>
      <link>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161804#M9856</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;This is&amp;nbsp;correction for HumreadByte:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;unsigned &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;short&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;STRONG&gt;HumReadByte&lt;/STRONG&gt; (&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;{&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;unsigned&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;char&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;i;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;unsigned&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;long&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;num = 0;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;unsigned&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;count = 0;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;delta;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;(i=0; i&amp;lt;h_cnt; i++) {&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delta = h_tik[i+1] - h_tik[i];&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; num = ((num &amp;lt;&amp;lt; 1) | 1);&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;if&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size="2"&gt;&lt;FONT size="2"&gt;(delta &amp;gt; 50 &amp;amp;&amp;amp; delta &amp;lt; 70)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; num = (num &amp;lt;&amp;lt; 1);&lt;/P&gt;&lt;P align="left"&gt;}&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#7F0055" size="2"&gt;&lt;FONT color="#7F0055" size="2"&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT size="2"&gt;&lt;FONT size="2"&gt;num;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P align="left"&gt;}&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;I did analyse its output. It looks promissing. I got 41 bits. First one could be ignored - its a begin of the cycle. It has 126 ticks duration (my tick is 1.333uS long - 24mhz with prescale equal to 32)&lt;/P&gt;&lt;P align="left"&gt;&amp;nbsp;&lt;/P&gt;&lt;P align="left"&gt;The things which puzzled me a lot - is why I need to comment out the other subrotine(s) to be able to run the code mentioned above. For me its looks like its not enough memory. But as I said early - there should be plenty available.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 11 May 2012 22:28:22 GMT</pubDate>
      <guid>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161804#M9856</guid>
      <dc:creator>d0ct0r</dc:creator>
      <dc:date>2012-05-11T22:28:22Z</dc:date>
    </item>
    <item>
      <title>Re: PWM decoding. Best practice</title>
      <link>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161805#M9857</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;HR /&gt;&lt;P&gt;d0ct0r wrote:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Yes, the microseconds is a challenge to handle. Even my bus is 24Mhz, its not enough to calculate something between of pulses.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Basically the device send CRC at the and of sequence. 40 bit is a 5 byte. First four is data and last one is CRC. So, it will be easy to detect the failure. Also, project is not critical to the other interrupt ruitines during the reading of this particular sensor.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Firstly, if you are able to globally disable interrupts for a period of 4 ms, I suggest that you use polling, rather than interrupts.&amp;nbsp; This should simplify the coding, and will avoid the cycle overhead associated with each interrupt.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I disagree with your statement that it is not possible to do any processing&amp;nbsp;for&amp;nbsp;the previous&amp;nbsp;data bit, within the period of the next data bit.&amp;nbsp; The data&amp;nbsp;bit processing code that I managed to&amp;nbsp;achieve&amp;nbsp;requires about 128 cycles (checked with FCS).&amp;nbsp; This is well within the worst case 1820 cycles available with a 24MHz bus frequency.&lt;/P&gt;&lt;P&gt;Even though a checksum byte (not a CRC) is present in the data, a timeout process must also be present to prevent the possibility that you will wait indefinitely (or until COP reset occurs), for a capture event that never arrives.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The following untested code snippet makes use of the TPM overflow to time the start bit duration, again using polling.&amp;nbsp; The timeout period is accomplished using channel 1 of the TPM.&amp;nbsp; The static variables used by the code, including a 5-byte array for the result, are placed within zero page RAM, for better cycle efficiency.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;// Static variables:#pragma DATA_SEG __SHORT_SEG MY_ZEROPAGEstatic word oldval, delta;static byte result[5];   // Array for sensor read result#pragma DATA_SEG DEFAULT #define THRESHOLD   2400     // 100us @ 24 MHz bus frequency#define MAXTIME     4800     // 200us @ 24 MHz bus frequency                             // TPM1 prescale = 1#define DATA_LOW    PTEDD_PTEDD2 = 1; PTED_PTED2 = 0#define DATA_HIGH   PTEDD_PTEDD2 = 0/***********************************************************************/byte read_sensor( void){   byte bitcnt = 40;   byte startcnt = 8;           // Start pulse duration (2.73 ms increment)   DATA_LOW;                    // Commence start pulse   TPM1SC = 0x08;               // TPM1 - bus clock, prescale 1, no int.   do {                        // Start pulse timing      __RESET_WATCHDOG();      TPM1SC_TOF = 0;           // Clear overflow flag      while (!TPM1SC_TOF);      // Wait for overflow flag set   } while (--startcnt);        // Loop until timing is complete   DisableInterrupts;      // Global disable   DATA_HIGH;       // End of start pulse   TPM1C0SC = 0x08;             // Input capture on falling edge (polling)   TPM1C0SC_CH0F = 0;           // Clear capture flag   TPM1C1SC = 0x10;             // Software output compare (polling)      TPM1C1V = TPM1CNT + MAXTIME; // Set timeout interval   TPM1C1SC_CH1F = 0;           // Clear timeout flag   while (!TPM1C0SC_CH0F) {     // Wait for first capture event      if (TPM1C1SC_CH1F) {      // Test for timeout         TPM1C0SC = 0;          // Disable TPM capture channel         EnableInterrupts;         return 1;              // Indicate read error      }   }   TPM1C0SC_CH0F = 0;           // Clear capture flag      // Process first "response" bit   TPM1C1V = TPM1C0V + MAXTIME; // Set timeout interval   TPM1C1SC_CH1F = 0;           // Ensure timeout flag is clear   while (!TPM1C0SC_CH0F) {     // Wait for capture event      if (TPM1C1SC_CH1F) {      // Test for bit timeout         TPM1C0SC = 0;          // Disable TPM capture channel         EnableInterrupts;         return 1;              // Indicate read error      }   }   TPM1C0SC_CH0F = 0;           // Clear capture flag   oldval = TPM1C0V;      // Process the data bits   do {                               asm {                     // Shift result ready for next data bit         lsl  result:4         rol  result:3                        rol  result:2                        rol  result:1                        rol  result:0                     }      TPM1C1V = oldval + MAXTIME; // Set next timeout interval      TPM1C1SC_CH1F = 0;        // Ensure timeout flag is clear      while (!TPM1C0SC_CH0F) {  // Wait for capture event         if (TPM1C1SC_CH1F) {   // Test for bit timeout            TPM1C0SC = 0;       // Disable TPM capture channel            EnableInterrupts;            return 1;           // Indicate read error         }      }      TPM1C0SC_CH0F = 0;        // Clear capture flag      delta = TPM1C0V - oldval; // Period of bit sequence      oldval = TPM1C0V;         // Update value      if (delta &amp;gt;= THRESHOLD)   // Test current bit state         result[4] |= 1;   } while (--bitcnt);      TPM1C0SC = 0;                // Disable TPM capture channel   EnableInterrupts;   return 0;                    // Indicate valid read}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Mac&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 29 Oct 2020 09:07:36 GMT</pubDate>
      <guid>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161805#M9857</guid>
      <dc:creator>bigmac</dc:creator>
      <dc:date>2020-10-29T09:07:36Z</dc:date>
    </item>
    <item>
      <title>Re: PWM decoding. Best practice</title>
      <link>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161806#M9858</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Mac,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;You've made my day !!! Much thanks ! Will keep your solution as a reference.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Meantime, I solve the constrains with Development Tool to upgrade USBDM from 4.9.3 to 4.9.4b. I was close to give up Motorola MCU thinking its a software limitation for code development. I am happy that it was a some bug outside of MCU and CodeWarrior. &amp;nbsp;Will continue to explore Freescale world. Once again - thanks for your posts.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 12 May 2012 11:30:25 GMT</pubDate>
      <guid>https://community.nxp.com/t5/8-bit-Microcontrollers/PWM-decoding-Best-practice/m-p/161806#M9858</guid>
      <dc:creator>d0ct0r</dc:creator>
      <dc:date>2012-05-12T11:30:25Z</dc:date>
    </item>
  </channel>
</rss>

