📄 smbus_8c-source.html
字号:
<a name="l00312"></a>00312 *ptr = (<span class="keywordtype">unsigned</span> char)(data>>8);<a name="l00313"></a>00313 <a name="l00314"></a>00314 <span class="keywordflow">if</span>(<a class="code" href="smbus_8c.html#c2304377235fd9b59c79034242b5bd25">TXmsgFull</a>)<a name="l00315"></a>00315 <span class="keywordflow">return</span>;<a name="l00316"></a>00316 <a name="l00317"></a>00317 <a name="l00318"></a>00318 ++<a class="code" href="smbus_8c.html#dbc81bdb8619edc772bba8dbf436d27a">TXmsgHead</a>;<a name="l00319"></a>00319 <a class="code" href="smbus_8c.html#dbc81bdb8619edc772bba8dbf436d27a">TXmsgHead</a> &= (4-1);<a name="l00320"></a>00320 <a class="code" href="smbus_8c.html#4f16d3ad762cebfa2b2b640f7c40b086">TXmsgQty</a>++;<a name="l00321"></a>00321 }<a name="l00322"></a>00322 <a name="l00323"></a>00323 <a name="l00324"></a>00324 <a name="l00325"></a>00325 <a name="l00326"></a>00326 <a name="l00327"></a>00327 <span class="comment">//TWI Interrupt Service Routine</span><a name="l00328"></a>00328 <span class="comment">// This ISR contains a state machine for handling the low-level bus communications.</span><a name="l00329"></a>00329 <span class="comment">// It uses the variable TWI_CmdFlags to communicate the need for message processing</span><a name="l00330"></a>00330 <span class="comment">// to the foreground-based command interpreter. Whenever it passes control off</span><a name="l00331"></a>00331 <span class="comment">// to the foreground routine, the SMBus is halted.</span><a name="l00332"></a>00332 <a name="l00333"></a>00333 <span class="comment">/* Changes to the operation of the SMBus State Machine as of 6/17/2005 (rgf):</span><a name="l00334"></a>00334 <span class="comment"></span><a name="l00335"></a>00335 <span class="comment"> Since there can be multiple Masters on the bus addressing a Smart Battery,</span><a name="l00336"></a>00336 <span class="comment"> namely either a Host or a Charger, it is entirely possible that one Master</span><a name="l00337"></a>00337 <span class="comment"> may support PEC while the other does not. For maximum reliability, we must</span><a name="l00338"></a>00338 <span class="comment"> be able to support the reception of PEC on-the-fly regardless of whether it</span><a name="l00339"></a>00339 <span class="comment"> was used in the past or not.</span><a name="l00340"></a>00340 <span class="comment"></span><a name="l00341"></a>00341 <span class="comment"> To do so, we determine an expected byte count WITHOUT PEC. While receiving,</span><a name="l00342"></a>00342 <span class="comment"> we decrement this counter and store received bytes until either (a) the counter</span><a name="l00343"></a>00343 <span class="comment"> drops below a value of (-1), or (b) we receive a STOP. If we receive a STOP</span><a name="l00344"></a>00344 <span class="comment"> and the counter is not either 0 or -1, this is an error and is flagged as such.</span><a name="l00345"></a>00345 <span class="comment"> (Note that AFTER receiving a STOP, it is not possible to flag an error to the</span><a name="l00346"></a>00346 <span class="comment"> Host or Charger except through the Battery Status flags.) If the counter is</span><a name="l00347"></a>00347 <span class="comment"> zero, this indicates that PEC is disabled. If the counter is -1, this indicates</span><a name="l00348"></a>00348 <span class="comment"> that PEC is enabled. The message will be processed with this knowledge.</span><a name="l00349"></a>00349 <span class="comment"></span><a name="l00350"></a>00350 <span class="comment"> However, since the SCL line is not being held low due to TWINT being left asserted,</span><a name="l00351"></a>00351 <span class="comment"> a different mechanism is needed to hold off incoming messages to the battery</span><a name="l00352"></a>00352 <span class="comment"> until the previous message has been processed. This is done by turning off</span><a name="l00353"></a>00353 <span class="comment"> the generation of ACK on any subsequent bytes and/or messages until the foreground</span><a name="l00354"></a>00354 <span class="comment"> code has finished processing the prior message.</span><a name="l00355"></a>00355 <span class="comment"></span><a name="l00356"></a>00356 <span class="comment"> It is crucial therefore that the foreground code does not change the</span><a name="l00357"></a>00357 <span class="comment"> value of the TWI_CmdFlags variable from being equal to 'SMB_GotCmdData'</span><a name="l00358"></a>00358 <span class="comment"> until after it is completely done with processing of the prior message.</span><a name="l00359"></a>00359 <span class="comment"></span><a name="l00360"></a>00360 <span class="comment"> This mechanism also is valid if a Master attempts to perform a Master Read</span><a name="l00361"></a>00361 <span class="comment"> while the battery is busy. In this case, the second byte from the Master,</span><a name="l00362"></a>00362 <span class="comment"> specifically the SMBus Command byte, will not be acknowledged. The Master</span><a name="l00363"></a>00363 <span class="comment"> is thereby required to generate a STOP condition.</span><a name="l00364"></a>00364 <span class="comment"></span><a name="l00365"></a>00365 <span class="comment">*/</span><a name="l00366"></a>00366 <a name="l00367"></a>00367 <span class="comment">//State Machine states</span><a name="l00368"></a><a class="code" href="smbus_8c.html#df764cbdea00d65edcd07bb9953ad2b7ce05baed30278f132f7d9d27a502e7a0">00368</a> <span class="keyword">enum</span> <span class="comment">/*TWISR_State*/</span> {<a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55bb2ed574d9e01f56cd38bf441a8085640">TW_IDLE</a>=0, <a class="code" href="smbus_8c.html#df764cbdea00d65edcd07bb9953ad2b7ce05baed30278f132f7d9d27a502e7a0">TW_Wait4Stop</a>, <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55b94d13a4b6be6ef4404b13908d933e1ad">TW_Wait4Cmd</a>, <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55bbc8bda251da4d6aae1c2bfb2900c1444">TW_Wait4RW</a>, <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55be4714c204fd9c4052ca3208a63493baa">TW_Wait4Data</a>, <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55b83d27cae0915c8a8002877623dcb0dc9">TW_ReplyData</a>, <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55bd258cb231677f6a95dcf1c9f239e2b36">TW_MSLA_W</a>, <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55b2166c37a639d0f299b5195aa8672bd41">TW_MCMD_W</a>, <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55b5e645a72fc9d3ddf3f193019985ffab5">TW_MDATA_W</a> };<a name="l00369"></a>00369 <a name="l00370"></a><a class="code" href="smbus_8c.html#6fd44d05795c577681c33fe2f105300c">00370</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> <a class="code" href="smbus_8c.html#6fd44d05795c577681c33fe2f105300c">TWISR_state</a> = <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55bb2ed574d9e01f56cd38bf441a8085640">TW_IDLE</a>; <span class="comment">//state variable</span><a name="l00371"></a>00371 <a name="l00372"></a>00372 <a name="l00373"></a>00373 <span class="preprocessor">#pragma vector = TWI_vect</span><a name="l00374"></a><a class="code" href="smbus_8c.html#1f03d433517342e03440452013989dc4">00374</a> <span class="preprocessor"></span>__interrupt <span class="keywordtype">void</span> <a class="code" href="smbus_8c.html#1f03d433517342e03440452013989dc4">TWI_ISR</a>(<span class="keywordtype">void</span>)<a name="l00375"></a>00375 {<a name="l00376"></a>00376 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> TWISR_CmdFeatures = 0; <span class="comment">//Command-related feature flags</span><a name="l00377"></a>00377 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> <a class="code" href="bootloader__smbus_8c.html#5eb4c6bfb0fa42aab6bbd6d25337fd6f">Status</a>;<a name="l00378"></a>00378 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> tmp;<a name="l00379"></a>00379 <a name="l00380"></a>00380 Status = TWSR & 0xF8; <span class="comment">//This identifies what caused the interrupt to fire.</span><a name="l00381"></a>00381 <a name="l00382"></a>00382 <span class="keywordflow">switch</span>(<a class="code" href="smbus_8c.html#6fd44d05795c577681c33fe2f105300c">TWISR_state</a>)<a name="l00383"></a>00383 {<a name="l00384"></a>00384 <span class="keywordflow">default</span>:<a name="l00385"></a>00385 <span class="keywordflow">case</span> <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55bb2ed574d9e01f56cd38bf441a8085640">TW_IDLE</a>: <span class="comment">//If not SLA_W or RSTOP, is an error!</span><a name="l00386"></a>00386 <span class="keywordflow">if</span>(<a class="code" href="bootloader__smbus_8c.html#13ec926035138d61a7e90193645942ee">TWS_SLA_W</a> == Status) <span class="comment">// saw Slave address match with a Write bit</span><a name="l00387"></a>00387 {<a name="l00388"></a>00388 <span class="keywordflow">if</span>(<a class="code" href="bootloader__smbus_8c.html#72f0b2eb64dd62ffa6bb85ef96947543">TWI_CmdFlags</a> == <a class="code" href="bootloader__smbus_8c.html#07b00aac11ba389d5b53e2f9d54bd0bd">SMB_GotCmdData</a>)<a name="l00389"></a>00389 {<a name="l00390"></a>00390 <span class="comment">//Assert that we're 'busy' to SMBus Master by leaving TWEA *off* until we get a STOP.</span><a name="l00391"></a>00391 <span class="comment">//Note that this is 'legal' because we have ALREADY sent an ACK to our Slave Address,</span><a name="l00392"></a>00392 <span class="comment">// as is required by the SMBus specification.</span><a name="l00393"></a>00393 <a class="code" href="smbus_8c.html#6fd44d05795c577681c33fe2f105300c">TWISR_state</a> = <a class="code" href="smbus_8c.html#df764cbdea00d65edcd07bb9953ad2b7ce05baed30278f132f7d9d27a502e7a0">TW_Wait4Stop</a>;<a name="l00394"></a>00394 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE); <span class="comment">//must NOT re-enable ACKing!</span><a name="l00395"></a>00395 <span class="keywordflow">return</span>;<a name="l00396"></a>00396 }<a name="l00397"></a>00397 <span class="keywordflow">else</span><a name="l00398"></a>00398 <a class="code" href="smbus_8c.html#6fd44d05795c577681c33fe2f105300c">TWISR_state</a> = <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55b94d13a4b6be6ef4404b13908d933e1ad">TW_Wait4Cmd</a>;<a name="l00399"></a>00399 }<a name="l00400"></a>00400 <span class="keywordflow">else</span><a name="l00401"></a>00401 <span class="keywordflow">if</span>(<a class="code" href="bootloader__smbus_8c.html#ea29a640c276fdaea02372a2c1ac5f78">TWS_RSTOP</a> == Status) <span class="comment">//Saw a Stop, possibly left over from previous cmd.</span><a name="l00402"></a>00402 {<a name="l00403"></a>00403 ; <span class="comment">//Everything is probably OK. Take no action.</span><a name="l00404"></a>00404 }<a name="l00405"></a>00405 <span class="keywordflow">else</span><a name="l00406"></a>00406 <span class="keywordflow">if</span>(<a class="code" href="bootloader__smbus_8c.html#5bee3e494d47b810f24429d69585e967">TWS_START</a> == Status) <span class="comment">//we have successfully sent a START bit. Handle MASTER mode.</span><a name="l00407"></a>00407 {<a name="l00408"></a>00408 TWDR = <a class="code" href="smbus_8c.html#c47af82e11278b79be8fb40152038444">TW_MTxBuf</a>[<a class="code" href="smbus_8c.html#c8ae296e1c1a72b91325c789bbdff1a0">TW_MTxBufIndex</a>++];<a name="l00409"></a>00409 <a class="code" href="smbus_8c.html#6fd44d05795c577681c33fe2f105300c">TWISR_state</a> = <a class="code" href="bootloader__smbus_8c.html#06fc87d81c62e9abb8790b6e5713c55bd258cb231677f6a95dcf1c9f239e2b36">TW_MSLA_W</a>;<a name="l00410"></a>00410 }<a name="l00411"></a>00411 <span class="keywordflow">else</span> <span class="comment">//had some type of error!</span>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -