📄 smbus_8c-source.html
字号:
<a name="l00212"></a>00212 }<a name="l00213"></a>00213 <a name="l00214"></a>00214 <a name="l00215"></a>00215 <a name="l00216"></a>00216 <a name="l00217"></a>00217 <a name="l00218"></a>00218 <span class="comment">/* *************************************************************************</span><a name="l00219"></a>00219 <span class="comment"> *</span><a name="l00220"></a>00220 <span class="comment"> * Low-Level SMBus Communications State Machine</span><a name="l00221"></a>00221 <span class="comment"> *</span><a name="l00222"></a>00222 <span class="comment"> ************************************************************************* */</span><a name="l00223"></a>00223 <a name="l00224"></a>00224 <span class="comment">/*</span><a name="l00225"></a>00225 <span class="comment"></span><a name="l00226"></a>00226 <span class="comment">Slave Mode</span><a name="l00227"></a>00227 <span class="comment">-------------</span><a name="l00228"></a>00228 <span class="comment"></span><a name="l00229"></a>00229 <span class="comment"></span><a name="l00230"></a>00230 <span class="comment"></span><a name="l00231"></a>00231 <span class="comment">Master Mode</span><a name="l00232"></a>00232 <span class="comment">-------------</span><a name="l00233"></a>00233 <span class="comment"></span><a name="l00234"></a>00234 <span class="comment">Master mode is initiated by foreground code. When a message is available for</span><a name="l00235"></a>00235 <span class="comment">transmission via Master mode (typically due to a timer expiring), it</span><a name="l00236"></a>00236 <span class="comment">is placed in the TWI Master TX buffer. However, transmission cannot begin</span><a name="l00237"></a>00237 <span class="comment">immediately due to the SMBus requirement that "A bus master is required to</span><a name="l00238"></a>00238 <span class="comment">check for bus idle time of 50 us."</span><a name="l00239"></a>00239 <span class="comment"></span><a name="l00240"></a>00240 <span class="comment">To meet this requirement, the AVR's pin-change detection mechanism is used</span><a name="l00241"></a>00241 <span class="comment">to monitor for bus idle conditions. PA5 must be wired externally to the</span><a name="l00242"></a>00242 <span class="comment">SMBCLK signal (pin 5 on CONN1) to allow this functionality. (Alternately,</span><a name="l00243"></a>00243 <span class="comment">in the user's production system, any I/O signal with pin-change capability</span><a name="l00244"></a>00244 <span class="comment">can be used instead of PA5 if desired.) PA5 is also used to check for the</span><a name="l00245"></a>00245 <span class="comment">SMCLK pin being held low for extended periods by other devices on the bus</span><a name="l00246"></a>00246 <span class="comment">as well as checking if the AVR itself doing so locally.</span><a name="l00247"></a>00247 <span class="comment"></span><a name="l00248"></a>00248 <span class="comment">A 3-level system is employed to ensure bus availability. First, the presence</span><a name="l00249"></a>00249 <span class="comment">of a message in the transmit buffer results in execution of the foreground code</span><a name="l00250"></a>00250 <span class="comment">that manages Master mode. Next, if the Slave state machine is not in the</span><a name="l00251"></a>00251 <span class="comment">IDLE state, no attempt is made to take control of the bus. Lastly, PA5 is</span><a name="l00252"></a>00252 <span class="comment">checked to be sure it is not currently at a logical zero condition. At this</span><a name="l00253"></a>00253 <span class="comment">point the bus appears to be free, so a flag (called TEST50US) is asserted to</span><a name="l00254"></a>00254 <span class="comment">indicate that the 50uS test has now begun; the Pin-Change Interrupt for PA5 is</span><a name="l00255"></a>00255 <span class="comment">also enabled. The foreground SMBus Master mode management code is then exited.</span><a name="l00256"></a>00256 <span class="comment">With a clock speed of only 1MHz, 50 uS corresponds to only 50 instructions at</span><a name="l00257"></a>00257 <span class="comment">most. Therefore, when the code is re-entered it is guaranteed that at least</span><a name="l00258"></a>00258 <span class="comment">50uS has passed.</span><a name="l00259"></a>00259 <span class="comment"></span><a name="l00260"></a>00260 <span class="comment">When the pin-change interrupt is active, bus activity will</span><a name="l00261"></a>00261 <span class="comment">trigger the pin-change interrupt. The corresponding ISR will clear the TEST50US</span><a name="l00262"></a>00262 <span class="comment">flag, indicating that the bus is not free. Thus, when the foreground code is</span><a name="l00263"></a>00263 <span class="comment">re-entered, if the flag is not asserted but there is a message in the buffer,</span><a name="l00264"></a>00264 <span class="comment">it is understood that the test has failed and must be started again; thus the</span><a name="l00265"></a>00265 <span class="comment">flag will again be asserted and the routine will be exited.</span><a name="l00266"></a>00266 <span class="comment"></span><a name="l00267"></a>00267 <span class="comment">When the foreground code is eventually re-entered with the flag still asserted,</span><a name="l00268"></a>00268 <span class="comment">and if the PA5 pin is not low, and the TWI ISR Slave State Machine is in IDLE,</span><a name="l00269"></a>00269 <span class="comment">action is immediately taken to begin transmission while the bus is free. An</span><a name="l00270"></a>00270 <span class="comment">additional interlock flag (SMLOCK) is asserted to indicate that Master mode has</span><a name="l00271"></a>00271 <span class="comment">been entered by the TWI Hardware, so that the foreground code will not attempt to</span><a name="l00272"></a>00272 <span class="comment">repeatedly initiate a transmission for the same message. (Note that checking</span><a name="l00273"></a>00273 <span class="comment">for the IDLE state is required due to the possibility that the ISR could have</span><a name="l00274"></a>00274 <span class="comment">been activated just after the flag was last asserted. Additionally it is possible</span><a name="l00275"></a>00275 <span class="comment">that another slave device is halting the bus by keeping SMCLK low for an extended</span><a name="l00276"></a>00276 <span class="comment">period, so this needs to also be checked before attempting to take over the bus.)</span><a name="l00277"></a>00277 <span class="comment"></span><a name="l00278"></a>00278 <span class="comment">If the AVR is successful in taking ownership of the bus, at the completion of the</span><a name="l00279"></a>00279 <span class="comment">transmission of the desired Slave address the ISR will be activated with a Status</span><a name="l00280"></a>00280 <span class="comment">code of 0x??. As a result, the state machine will now vector into the states</span><a name="l00281"></a>00281 <span class="comment">related to Master Mode transmission, and the ISR will handle all further aspects</span><a name="l00282"></a>00282 <span class="comment">of the transmission. Alternately, if the TWI module is unsuccessful in taking over</span><a name="l00283"></a>00283 <span class="comment">the bus, the TWI ISR will still be entered but with Status codes that are indicative</span><a name="l00284"></a>00284 <span class="comment">of an error having occurred. In this latter case, the SMLOCK and TEST50US flags will</span><a name="l00285"></a>00285 <span class="comment">be cleared to force another bus takeover attempt in the future.</span><a name="l00286"></a>00286 <span class="comment"></span><a name="l00287"></a>00287 <span class="comment">*/</span><a name="l00288"></a>00288 <a name="l00289"></a>00289 <a name="l00290"></a>00290 <a name="l00291"></a><a class="code" href="smbus_8c.html#a7bbbb66632f1e6d02a04a2fcce1a174">00291</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> <a class="code" href="smbus_8c.html#a7bbbb66632f1e6d02a04a2fcce1a174">TXmsg</a>[4][4]; <span class="comment">//leave room for PEC</span><a name="l00292"></a><a class="code" href="smbus_8c.html#dbc81bdb8619edc772bba8dbf436d27a">00292</a> <span class="keyword">volatile</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> <a class="code" href="smbus_8c.html#dbc81bdb8619edc772bba8dbf436d27a">TXmsgHead</a> = 0;<a name="l00293"></a><a class="code" href="smbus_8c.html#dbf168926577042100974bfb5f729abb">00293</a> <span class="keyword">volatile</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> <a class="code" href="smbus_8c.html#dbf168926577042100974bfb5f729abb">TXmsgTail</a> = 0;<a name="l00294"></a><a class="code" href="smbus_8c.html#4f16d3ad762cebfa2b2b640f7c40b086">00294</a> <span class="keyword">volatile</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> <a class="code" href="smbus_8c.html#4f16d3ad762cebfa2b2b640f7c40b086">TXmsgQty</a> = 0;<a name="l00295"></a>00295 <a name="l00296"></a><a class="code" href="smbus_8c.html#052be4fcee0ac81e1c63a06f4c7f6dbc">00296</a> <span class="preprocessor">#define TXmsgEmpty (TXmsgQty == 0)</span><a name="l00297"></a><a class="code" href="smbus_8c.html#c2304377235fd9b59c79034242b5bd25">00297</a> <span class="preprocessor"></span><span class="preprocessor">#define TXmsgFull (TXmsgQty == 4)</span><a name="l00298"></a><a class="code" href="smbus_8c.html#83b4a23934b4a918f7615cadb682e122">00298</a> <span class="preprocessor"></span><span class="preprocessor">#define TXmsgDelete {++TXmsgTail; TXmsgTail &= (4-1); TXmsgQty--;}</span><a name="l00299"></a>00299 <span class="preprocessor"></span><a name="l00300"></a>00300 <span class="comment">//We will compute the PEC for the message as well.</span><a name="l00301"></a><a class="code" href="smbus_8h.html#34b79a751618c0940e95f347f627baec">00301</a> <span class="keywordtype">void</span> <a class="code" href="smbus_8c.html#34b79a751618c0940e95f347f627baec">MasterInsertMsg</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> addr, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> cmd, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> data)<a name="l00302"></a>00302 { <span class="comment">//Note that the Charger address is ALWAYS 0x12! (sbsm100.pdf, 5.2)</span><a name="l00303"></a>00303 <span class="comment">//The Host address is always 0x16.</span><a name="l00304"></a>00304 <span class="comment">//The addr always assumes WRITE.</span><a name="l00305"></a>00305 <span class="comment">//We only do a WORD WRITE.</span><a name="l00306"></a>00306 <a name="l00307"></a>00307 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> * ptr = <a class="code" href="smbus_8c.html#a7bbbb66632f1e6d02a04a2fcce1a174">TXmsg</a>[<a class="code" href="smbus_8c.html#dbc81bdb8619edc772bba8dbf436d27a">TXmsgHead</a>];<a name="l00308"></a>00308 <a name="l00309"></a>00309 *ptr++ = addr;<a name="l00310"></a>00310 *ptr++ = cmd;<a name="l00311"></a>00311 *ptr++ = (<span class="keywordtype">unsigned</span> char) data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -