• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

テスト用のあれこれ共用フォルダ


Commit MetaInfo

修訂c12f9258baee7f46ef7950f09e7734f98ed36b0d (tree)
時間2018-09-22 16:46:15
作者takemasa <suikan@user...>
Commitertakemasa

Log Message

Make error handling of the SPI error handling.

All error is now passed to application. And if the error is
unknown, it re-initialize the SPI.

Beside of SPI, some I2C syslog are changed.

Change Summary

差異

--- a/stm32_development/murasaki/murasaki/abstractspimaster.hpp
+++ b/stm32_development/murasaki/murasaki/abstractspimaster.hpp
@@ -33,7 +33,7 @@ class AbstractSpiMaster:public murasaki::AbstractPeripheral
3333 * @param timeout_ms Timeout limit [mS]
3434 * @return true if transfer complete, false if timeout
3535 */
36- virtual bool TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier * spi_spec,
36+ virtual SpiStatus TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier * spi_spec,
3737 const uint8_t * tx_data,
3838 uint8_t * rx_data, unsigned int size,
3939 murasaki::WaitMilliSeconds timeout_ms = murasaki::kwmsIndefinitely)=0;
--- a/stm32_development/murasaki/murasaki/i2cmaster.cpp
+++ b/stm32_development/murasaki/murasaki/i2cmaster.cpp
@@ -46,7 +46,6 @@ murasaki::I2cStatus I2cMaster::Transmit(
4646 const uint8_t* tx_data,
4747 unsigned int tx_size,
4848 WaitMilliSeconds timeout_ms) {
49- murasaki::I2cStatus result;
5049
5150 I2C_SYSLOG("Enter");
5251
@@ -90,12 +89,11 @@ murasaki::I2cStatus I2cMaster::Transmit(
9089 MURASAKI_SYSLOG(kfaI2cMaster, kseEmergency, "Error is not handled")
9190
9291 }
93- result = interrupt_status_;
9492 }
9593 critical_section_->Leave();
9694
9795 I2C_SYSLOG("Return");
98- return result;
96+ return interrupt_status_;
9997 }
10098
10199 murasaki::I2cStatus I2cMaster::Receive(
@@ -103,7 +101,6 @@ murasaki::I2cStatus I2cMaster::Receive(
103101 uint8_t* rx_data,
104102 unsigned int rx_size,
105103 WaitMilliSeconds timeout_ms) {
106- murasaki::I2cStatus result;
107104
108105 I2C_SYSLOG("Enter");
109106
@@ -149,13 +146,12 @@ murasaki::I2cStatus I2cMaster::Receive(
149146 MURASAKI_SYSLOG(kfaI2cMaster, kseEmergency, "Error is not handled")
150147
151148 }
152- result = interrupt_status_;
153149
154150 }
155151 critical_section_->Leave();
156152
157153 I2C_SYSLOG("Return");
158- return result;
154+ return interrupt_status_;
159155 }
160156
161157 murasaki::I2cStatus I2cMaster::TransmitThenReceive(
@@ -255,15 +251,11 @@ murasaki::I2cStatus I2cMaster::TransmitThenReceive(
255251
256252 }
257253
258- result = interrupt_status_;
259-
260-
261-
262254 }
263255 critical_section_->Leave();
264256
265257 I2C_SYSLOG("Return");
266- return result; // return false if timeout
258+ return interrupt_status_; // return false if timeout
267259 }
268260
269261 bool I2cMaster::TransmitCompleteCallback(void* ptr) {
@@ -315,21 +307,21 @@ bool I2cMaster::HandleError(void* ptr) {
315307 if (peripheral_ == ptr) {
316308 // Check error and halde it.
317309 if (peripheral_->ErrorCode & HAL_I2C_ERROR_AF) {
318- I2C_SYSLOG("HAL_I2C_ERROR_AF");
310+ MURASAKI_SYSLOG(kfaI2cMaster, kseWarning, "HAL_I2C_ERROR_AF");
319311 // This interrupt happen when device doesn't respond or return NAK.
320312 interrupt_status_ = murasaki::ki2csNak;
321313 // abort the processing
322314 sync_->Release();
323315 }
324316 else if (peripheral_->ErrorCode & HAL_I2C_ERROR_BERR) {
325- I2C_SYSLOG("HAL_I2C_ERROR_BERR");
317+ MURASAKI_SYSLOG(kfaI2cMaster, kseWarning, "HAL_I2C_ERROR_BERR");
326318 // This interrupt happen when device
327319 interrupt_status_ = murasaki::ki2csBussError;
328320 // abort the processing
329321 sync_->Release();
330322 }
331323 else if (peripheral_->ErrorCode & HAL_I2C_ERROR_ARLO) {
332- I2C_SYSLOG("HAL_I2C_ERROR_ARLO");
324+ MURASAKI_SYSLOG(kfaI2cMaster, kseWarning, "HAL_I2C_ERROR_ARLO");
333325 // This interrupt happen when device
334326 interrupt_status_ = murasaki::ki2csArbitrationLost;
335327 // abort the processing
@@ -338,12 +330,8 @@ bool I2cMaster::HandleError(void* ptr) {
338330 else {
339331 MURASAKI_SYSLOG(kfaI2cMaster, kseEmergency, "Error is not handled");
340332
341- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_I2C_ERROR_BERR); // handled in "if" clause
342- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_I2C_ERROR_ARLO); // handled in "if" clause
343- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_I2C_ERROR_AF); // handled in "if" clause
344333 MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_I2C_ERROR_OVR); // Doesn't occur in master
345334 MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_I2C_ERROR_DMA); // Doesn't occur in this implemenattion
346- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_I2C_ERROR_TIMEOUT); // Doesn't occur in this implemenattion
347335 #ifdef HAL_I2C_ERROR_SIZE
348336 MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_I2C_ERROR_SIZE);
349337 #endif
--- a/stm32_development/murasaki/murasaki/i2cmaster.hpp
+++ b/stm32_development/murasaki/murasaki/i2cmaster.hpp
@@ -63,6 +63,15 @@ namespace murasaki {
6363 *
6464 * Both methods can be called from only the task context. If these are called in the ISR
6565 * context, the result is unknown.
66+ *
67+ * * Note : In case an time out occurs during transmit / receive, this implementation
68+ * casells HAL_I2C_MASTER_ABORT_IT(). But it is unknown whether this is right thing to do.
69+ * The HAL reference of the STM32F7 is not clear for this case. For example, it doesn't tell
70+ * what programmer do to stop the transfer at the middle. And also, it doesn't tell what's happen
71+ * if the HAL_I2C_MASTER_ABORT_IT() is called.
72+ *
73+ * According to the source code of the HAL_I2C_MASTER_ABORT_IT(), no interrupt will be
74+ * raised by this API call.
6675 */
6776 class I2cMaster : public AbstractI2CMaster
6877 {
--- a/stm32_development/murasaki/murasaki/murasaki_defs.hpp
+++ b/stm32_development/murasaki/murasaki/murasaki_defs.hpp
@@ -208,7 +208,8 @@ enum SpiStatus
208208 kspisOverflow, //!< Over run.
209209 kspisFrameError, //!< Error on TI frame mode.
210210 kspisDMA, //!< DMA error
211- kspisErrorFlag //!< Other error flag.
211+ kspisErrorFlag, //!< Other error flag.
212+ kspisAbort //!< Problem in abort process. No way to recover.
212213 };
213214
214215
--- a/stm32_development/murasaki/murasaki/spimaster.cpp
+++ b/stm32_development/murasaki/murasaki/spimaster.cpp
@@ -41,13 +41,12 @@ SpiMaster::~SpiMaster()
4141
4242 }
4343
44-bool SpiMaster::TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier* spi_spec,
44+SpiStatus SpiMaster::TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier* spi_spec,
4545 const uint8_t* tx_data,
4646 uint8_t* rx_data,
4747 unsigned int size,
4848 murasaki::WaitMilliSeconds timeout_ms)
4949 {
50- bool result;
5150
5251 SPIM_SYSLOG("Enter");
5352
@@ -61,6 +60,9 @@ bool SpiMaster::TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier* spi_spec
6160 {
6261 SPIM_SYSLOG("Start re-configuring SPI master");
6362
63+ // This value will be updated by TransmitAndReceiveCompleteCallback
64+ interrupt_status_ = murasaki::kspisTimeOut;
65+
6466 // Change the clock porarity & phase
6567 // todo is following right?
6668 MURASAKI_ASSERT(HAL_SPI_DeInit(peripheral_) == HAL_OK);
@@ -91,7 +93,28 @@ bool SpiMaster::TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier* spi_spec
9193 MURASAKI_ASSERT(HAL_OK == status);
9294
9395 // wait for the completion
94- result = sync_->Wait(timeout_ms); // return false if timeout
96+ sync_->Wait(timeout_ms); // return false if timeout
97+ SPIM_SYSLOG("Sync released.")
98+
99+ // check the status from interrupt
100+ switch (interrupt_status_)
101+ {
102+ case murasaki::kspisOK:
103+ SPIM_SYSLOG("Receive complete successfully")
104+ break;
105+ case murasaki::ki2csTimeOut:
106+ MURASAKI_SYSLOG(kfaSpiMaster, kseWarning, "Receive timeout")
107+ // Abort on-going and not terminated transfer.
108+ HAL_SPI_DMAStop(peripheral_);
109+ break;
110+ default:
111+ MURASAKI_SYSLOG(kfaI2cMaster, kseEmergency, "Error is not handled")
112+ SPIM_SYSLOG("Re-initialize the SPI")
113+ // Desable SPI to try to clear the current error status. Then, re-enable.
114+ HAL_SPI_DeInit(peripheral_);
115+ HAL_SPI_Init(peripheral_);
116+
117+ }
95118
96119 SPIM_SYSLOG("End SPI master transferring");
97120 }
@@ -101,7 +124,7 @@ bool SpiMaster::TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier* spi_spec
101124 critical_section_->Leave();
102125
103126 SPIM_SYSLOG("Return");
104- return result;
127+ return interrupt_status_;
105128
106129 }
107130
@@ -114,12 +137,17 @@ bool SpiMaster::TransmitAndReceiveCompleteCallback(void* ptr)
114137 // if matches, release task
115138 if (peripheral_ == ptr) {
116139 SPIM_SYSLOG("Release sync");
140+ // report normal completion
141+ interrupt_status_ = murasaki::kspisOK;
142+ // release waiting task
117143 sync_->Release();
118144 SPIM_SYSLOG("Return");
145+ // This interrupt is for this device.
119146 return true;
120147 }
121148 else {
122149 SPIM_SYSLOG("Return");
150+ // This interrupt is not for this device.
123151 return false;
124152 }
125153 }
@@ -131,16 +159,57 @@ bool SpiMaster::HandleError(void* ptr)
131159 MURASAKI_ASSERT(nullptr != ptr)
132160
133161 if (peripheral_ == ptr) {
134- // Check error, and print if exist.
135- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_SPI_ERROR_MODF);
136- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_SPI_ERROR_CRC);
137- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_SPI_ERROR_OVR);
138- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_SPI_ERROR_FRE);
139- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_SPI_ERROR_DMA);
140- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_SPI_ERROR_FLAG);
162+
163+ // Check error and halde it.
164+ if (peripheral_->ErrorCode & HAL_SPI_ERROR_CRC) {
165+ MURASAKI_SYSLOG(kfaSpiMaster, kseWarning, "HAL_SPI_ERROR_CRC");
166+ // This happens only in the CRC mode
167+ interrupt_status_ = murasaki::kspisModeCRC;
168+ // abort the processing
169+ sync_->Release();
170+ }
171+ else if (peripheral_->ErrorCode & HAL_SPI_ERROR_OVR) {
172+ MURASAKI_SYSLOG(kfaSpiMaster, kseWarning, "HAL_SPI_ERROR_OVR");
173+ // This interrupt happen when the DMA is too slow to handle the received data.
174+ interrupt_status_ = murasaki::kspisOverflow;
175+ // abort the processing
176+ sync_->Release();
177+ }
178+ else if (peripheral_->ErrorCode & HAL_SPI_ERROR_FRE) {
179+ MURASAKI_SYSLOG(kfaSpiMaster, kseWarning, "HAL_SPI_ERROR_FRE");
180+ // This interrupt is the frame error of the the TI frame mode
181+ interrupt_status_ = murasaki::kspisFrameError;
182+ // abort the processing
183+ sync_->Release();
184+ }
185+ else if (peripheral_->ErrorCode & HAL_SPI_ERROR_DMA) {
186+ MURASAKI_SYSLOG(kfaSpiMaster, kseWarning, "HAL_SPI_ERROR_DMA");
187+ // This interrupt emans something happen in DMA unit
188+ interrupt_status_ = murasaki::kspisDMA;
189+ // abort the processing
190+ sync_->Release();
191+ }
192+ else if (peripheral_->ErrorCode & HAL_SPI_ERROR_FLAG) {
193+ MURASAKI_SYSLOG(kfaSpiMaster, kseWarning, "HAL_SPI_ERROR_FLAG");
194+ // This interrupt emans something is recorded as error flag.
195+ interrupt_status_ = murasaki::kspisErrorFlag;
196+ // abort the processing
197+ sync_->Release();
198+ }
141199 #ifdef HAL_SPI_ERROR_ABORT
142- MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_SPI_ERROR_ABORT);
200+ else if (peripheral_->ErrorCode & HAL_SPI_ERROR_ABORT) {
201+ MURASAKI_SYSLOG(kfaSpiMaster, kseWarning, "HAL_SPI_ERROR_ABORT");
202+ // This interrupt happen when program causes problem during abort process
203+ // No way to recover.
204+ interrupt_status_ = murasaki::kspisAbort;
205+ // abort the processing
206+ sync_->Release();
207+ }
143208 #endif
209+ else
210+ {
211+ MURASAKI_SYSLOG(kfaSpiMaster, kseWarning, "Unknown error interrupt")
212+ }
144213 SPIM_SYSLOG("Return");
145214 return true; // report the ptr matched
146215 }
--- a/stm32_development/murasaki/murasaki/spimaster.hpp
+++ b/stm32_development/murasaki/murasaki/spimaster.hpp
@@ -57,6 +57,13 @@ namespace murasaki {
5757 *
5858 * Both methods can be called from only the task context. If these are called in the ISR
5959 * context, the result is unknown.
60+ *
61+ * Note : The behavior of when the timeout happen is not tested. Actually, it should not happen
62+ * because DMA is taken in SPI transmission. Murasaki stpos internal DMA, interrupt and SPI processing
63+ * internally then, return.
64+ *
65+ * Other error will cause the re-initializing of the SPI master. Murasaki doesn't support
66+ * any of CRC detection, TI frame mode or Multi-master SPI.
6067 * @ingroup MURASAKI_GROUP
6168 */
6269 class SpiMaster : public AbstractSpiMaster
@@ -83,7 +90,7 @@ class SpiMaster : public AbstractSpiMaster
8390 * from the spi_spec. And then, assert the chips elect through the spi_spec during the
8491 * data transfer.
8592 */
86- virtual bool TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier * spi_spec,
93+ virtual SpiStatus TransmitAndReceive(murasaki::AbstractSpiSlaveSpecifier * spi_spec,
8794 const uint8_t * tx_data,
8895 uint8_t * rx_data, unsigned int size,
8996 murasaki::WaitMilliSeconds timeout_ms = murasaki::kwmsIndefinitely);
@@ -116,6 +123,8 @@ class SpiMaster : public AbstractSpiMaster
116123 SPI_HandleTypeDef * const peripheral_; // SPI peripheral handler.
117124 Synchronizer * const sync_; // sync between task and interrupt
118125 CriticalSection * const critical_section_; // protect memberfunction
126+ private:
127+ SpiStatus interrupt_status_;
119128 };
120129
121130 } /* namespace murasaki */
--- a/stm32_development/nucleo-l152re-fujitsubo-test/nucleo-l152re-fujitsubo-test Debug.cfg
+++ b/stm32_development/nucleo-l152re-fujitsubo-test/nucleo-l152re-fujitsubo-test Debug.cfg
@@ -10,7 +10,6 @@ set WORKAREASIZE 0x8000
1010 transport select "hla_swd"
1111
1212 set CHIPNAME STM32L152RETx
13-set BOARDNAME NUCLEO-L152RE
1413
1514 # Enable debug when in low power modes
1615 set ENABLE_LOW_POWER 1