Skip to content

Commit e74d66e

Browse files
committed
Add error handling of SPI low level API
- Now processing return result and throwing exception with encoded error code on failure. - Update declaration of ThrowError function.
1 parent 1e32aa4 commit e74d66e

File tree

2 files changed

+64
-9
lines changed

2 files changed

+64
-9
lines changed

src/Com.SkyworksInc.NanoFramework.Devices.Spi/com_sky_nf_dev_spi_native.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_S
6565
//--//
6666

6767
static HRESULT ExecuteTransfer(CLR_RT_StackFrame &stack);
68-
static HRESULT ThrowError(CLR_RT_StackFrame &stack, CLR_INT32 errorCode);
68+
static HRESULT ThrowError(CLR_RT_StackFrame &stack, CLR_UINT32 errorCode);
6969
};
7070

7171
struct Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_Spi_SpiException

targets/AzureRTOS/SiliconLabs/_nanoCLR/Com.SkyworksInc.NanoFramework.Devices.Spi/com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_Spi_SpiBus.cpp

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ typedef Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_
1313
typedef Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_Spi_SpiBaseConfiguration
1414
SpiBaseConfiguration;
1515
typedef Library_corlib_native_System_SpanByte SpanByte;
16+
typedef Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_Spi_SpiException SpiException;
1617

1718
static HRESULT SPI_nWrite_nRead(
1819
NF_PAL_SPI *palSpi,
@@ -119,7 +120,8 @@ bool System_Device_IsLongRunningOperation(
119120
}
120121
}
121122

122-
HRESULT ExecuteTransfer(CLR_RT_StackFrame &stack)
123+
HRESULT Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_Spi_SpiBus::ExecuteTransfer(
124+
CLR_RT_StackFrame &stack)
123125
{
124126
NANOCLR_HEADER();
125127

@@ -135,6 +137,7 @@ HRESULT ExecuteTransfer(CLR_RT_StackFrame &stack)
135137
int16_t readOffset = 0;
136138
int16_t writeOffset = 0;
137139
bool fullDuplex;
140+
int32_t operationResult;
138141

139142
bool isLongRunningOperation;
140143
uint32_t estimatedDurationMiliseconds;
@@ -270,7 +273,7 @@ HRESULT ExecuteTransfer(CLR_RT_StackFrame &stack)
270273
// Start SPI transfer
271274
// We can ask for async transfer by setting callback but it depends if underlying supports it
272275
// return of CLR_E_BUSY means async started
273-
hr = SPI_nWrite_nRead(
276+
operationResult = SPI_nWrite_nRead(
274277
palSpi,
275278
SpiConfigs[busIndex - 1],
276279
rws,
@@ -280,10 +283,15 @@ HRESULT ExecuteTransfer(CLR_RT_StackFrame &stack)
280283
(int32_t)readSize);
281284

282285
// Async transfer started, go to custom 2 state (wait completion)
283-
if (hr == CLR_E_BUSY)
286+
if (operationResult == CLR_E_BUSY)
284287
{
285288
stack.m_customState = 2;
286289
}
290+
else if (operationResult != S_OK)
291+
{
292+
// Something went wrong with SPI transfer
293+
NANOCLR_CHECK_HRESULT(ThrowError(stack, operationResult));
294+
}
287295
}
288296

289297
// Waiting for Async operation to complete
@@ -327,6 +335,7 @@ static HRESULT SPI_nWrite_nRead(
327335
NANOCLR_HEADER();
328336

329337
bool busConfigIsHalfDuplex;
338+
Ecode_t transferResult;
330339

331340
// If callback then use async operation
332341
bool sync = (wrc.callback == 0);
@@ -382,7 +391,7 @@ static HRESULT SPI_nWrite_nRead(
382391
{
383392
// Full duplex
384393
// Uses the largest buffer size as transfer size
385-
NF_SpiDriver_MTransferB(
394+
transferResult = NF_SpiDriver_MTransferB(
386395
palSpi->Handle,
387396
palSpi->WriteBuffer,
388397
palSpi->ReadBuffer,
@@ -397,7 +406,13 @@ static HRESULT SPI_nWrite_nRead(
397406
// // half duplex operation, set output enable
398407
// palSpi->Handle->spi->CR1 |= SPI_CR1_BIDIOE;
399408
// }
400-
NF_SpiDriver_MTransmitB(palSpi->Handle, palSpi->WriteBuffer, palSpi->WriteSize);
409+
transferResult = NF_SpiDriver_MTransmitB(palSpi->Handle, palSpi->WriteBuffer, palSpi->WriteSize);
410+
411+
// bail out if the transmit operation failed
412+
if (transferResult != ECODE_EMDRV_SPIDRV_OK)
413+
{
414+
NANOCLR_SET_AND_LEAVE(transferResult);
415+
}
401416

402417
// receive operation
403418
// TODO
@@ -406,7 +421,7 @@ static HRESULT SPI_nWrite_nRead(
406421
// // half duplex operation, set output enable
407422
// palSpi->Handle->spi->CR1 &= ~SPI_CR1_BIDIOE;
408423
// }
409-
NF_SpiDriver_MReceiveB(palSpi->Handle, palSpi->ReadBuffer, palSpi->ReadSize);
424+
transferResult = NF_SpiDriver_MReceiveB(palSpi->Handle, palSpi->ReadBuffer, palSpi->ReadSize);
410425
}
411426
}
412427
else
@@ -421,7 +436,7 @@ static HRESULT SPI_nWrite_nRead(
421436
// // half duplex operation, set output enable
422437
// palSpi->Handle->spi->CR1 &= ~SPI_CR1_BIDIOE;
423438
// }
424-
NF_SpiDriver_MReceiveB(palSpi->Handle, palSpi->ReadBuffer, palSpi->ReadSize);
439+
transferResult = NF_SpiDriver_MReceiveB(palSpi->Handle, palSpi->ReadBuffer, palSpi->ReadSize);
425440
}
426441
else
427442
{
@@ -432,9 +447,11 @@ static HRESULT SPI_nWrite_nRead(
432447
// half duplex operation, set output enable
433448
// palSpi->Handle->spi->CR1 |= SPI_CR1_BIDIOE;
434449
}
435-
NF_SpiDriver_MTransmitB(palSpi->Handle, palSpi->WriteBuffer, palSpi->WriteSize);
450+
transferResult = NF_SpiDriver_MTransmitB(palSpi->Handle, palSpi->WriteBuffer, palSpi->WriteSize);
436451
}
437452
}
453+
454+
NANOCLR_SET_AND_LEAVE(transferResult);
438455
}
439456
else
440457
{
@@ -658,3 +675,41 @@ HRESULT Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_
658675

659676
NANOCLR_NOCLEANUP();
660677
}
678+
679+
HRESULT Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_Spi_SpiBus::ThrowError(
680+
CLR_RT_StackFrame &stack,
681+
CLR_UINT32 errorCode)
682+
{
683+
NANOCLR_HEADER();
684+
685+
SpiError spiErrorCode;
686+
687+
CLR_RT_HeapBlock &res = stack.m_owningThread->m_currentException;
688+
689+
if ((Library_corlib_native_System_Exception::CreateInstance(
690+
res,
691+
g_CLR_RT_WellKnownTypes.m_SocketException,
692+
CLR_E_FAIL,
693+
&stack)) == S_OK)
694+
{
695+
// Set the error code
696+
if (errorCode == ECODE_EMDRV_SPIDRV_TIMEOUT)
697+
{
698+
spiErrorCode = SpiError_Timeout;
699+
}
700+
else if (errorCode == ECODE_EMDRV_SPIDRV_ABORTED)
701+
{
702+
spiErrorCode = SpiError_Aborted;
703+
}
704+
else
705+
{
706+
spiErrorCode = SpiError_Unknown;
707+
}
708+
709+
res.Dereference()[SpiException::FIELD___errorCode].SetInteger((CLR_UINT32)spiErrorCode);
710+
}
711+
712+
NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION);
713+
714+
NANOCLR_NOCLEANUP();
715+
}

0 commit comments

Comments
 (0)