@@ -13,6 +13,7 @@ typedef Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_
1313typedef Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_Spi_SpiBaseConfiguration
1414 SpiBaseConfiguration;
1515typedef Library_corlib_native_System_SpanByte SpanByte;
16+ typedef Library_com_sky_nf_dev_spi_native_Com_SkyworksInc_NanoFramework_Devices_Spi_SpiException SpiException;
1617
1718static 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