diff --git a/targets/ChibiOS/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp b/targets/ChibiOS/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp index 44fa139f35..1ea2f72662 100644 --- a/targets/ChibiOS/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp +++ b/targets/ChibiOS/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp @@ -606,104 +606,104 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeWrite___VOID CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + { + NF_PAL_UART *palUart = NULL; - NF_PAL_UART *palUart = NULL; - - uint8_t *data; - unsigned int length = 0; - size_t count = 0; - int16_t writeOffset = 0; + uint8_t *data; + unsigned int length = 0; + size_t count = 0; + int16_t writeOffset = 0; - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - if (pThis[FIELD___disposed].NumericByRef().u1 != 0) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); - } + if (pThis[FIELD___disposed].NumericByRef().u1 != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } - // dereference the data buffer from the argument - CLR_RT_HeapBlock_Array *dataBuffer = stack.Arg1().DereferenceArray(); - writeOffset = stack.Arg2().NumericByRef().s4; - count = stack.Arg3().NumericByRef().s4; + // dereference the data buffer from the argument + CLR_RT_HeapBlock_Array *dataBuffer = stack.Arg1().DereferenceArray(); + writeOffset = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; - // get a the pointer to the array by using the first element of the array - data = dataBuffer->GetElement(writeOffset); + // get a the pointer to the array by using the first element of the array + data = dataBuffer->GetElement(writeOffset); - // get the size of the buffer - length = dataBuffer->m_numOfElements; + // get the size of the buffer + length = dataBuffer->m_numOfElements; - if (count > length) - { - NANOCLR_SET_AND_LEAVE(CLR_E_BUFFER_TOO_SMALL); - } + if (count > length) + { + NANOCLR_SET_AND_LEAVE(CLR_E_BUFFER_TOO_SMALL); + } - // get pointer to PAL UART - switch ((int)pThis[FIELD___portIndex].NumericByRef().s4) - { + // get pointer to PAL UART + switch ((int)pThis[FIELD___portIndex].NumericByRef().s4) + { #if defined(NF_SERIAL_COMM_STM32_UART_USE_USART1) && (NF_SERIAL_COMM_STM32_UART_USE_USART1 == TRUE) - case 1: - palUart = &Uart1_PAL; - break; + case 1: + palUart = &Uart1_PAL; + break; #endif #if defined(NF_SERIAL_COMM_STM32_UART_USE_USART2) && (NF_SERIAL_COMM_STM32_UART_USE_USART2 == TRUE) - case 2: - palUart = &Uart2_PAL; - break; + case 2: + palUart = &Uart2_PAL; + break; #endif #if defined(NF_SERIAL_COMM_STM32_UART_USE_USART3) && (NF_SERIAL_COMM_STM32_UART_USE_USART3 == TRUE) - case 3: - palUart = &Uart3_PAL; - break; + case 3: + palUart = &Uart3_PAL; + break; #endif #if defined(NF_SERIAL_COMM_STM32_UART_USE_UART4) && (NF_SERIAL_COMM_STM32_UART_USE_UART4 == TRUE) - case 4: - palUart = &Uart4_PAL; - break; + case 4: + palUart = &Uart4_PAL; + break; #endif #if defined(NF_SERIAL_COMM_STM32_UART_USE_UART5) && (NF_SERIAL_COMM_STM32_UART_USE_UART5 == TRUE) - case 5: - palUart = &Uart5_PAL; - break; + case 5: + palUart = &Uart5_PAL; + break; #endif #if defined(NF_SERIAL_COMM_STM32_UART_USE_USART6) && (NF_SERIAL_COMM_STM32_UART_USE_USART6 == TRUE) - case 6: - palUart = &Uart6_PAL; - break; + case 6: + palUart = &Uart6_PAL; + break; #endif #if defined(NF_SERIAL_COMM_STM32_UART_USE_UART7) && (NF_SERIAL_COMM_STM32_UART_USE_UART7 == TRUE) - case 7: - palUart = &Uart7_PAL; - break; + case 7: + palUart = &Uart7_PAL; + break; #endif #if defined(NF_SERIAL_COMM_STM32_UART_USE_UART8) && (NF_SERIAL_COMM_STM32_UART_USE_UART8 == TRUE) - case 8: - palUart = &Uart8_PAL; - break; + case 8: + palUart = &Uart8_PAL; + break; #endif - } - - // check if there is enough room in the buffer - if (palUart->TxRingBuffer.Capacity() - palUart->TxRingBuffer.Length() < count) - { - // not enough room in the buffer - NANOCLR_SET_AND_LEAVE(CLR_E_BUFFER_TOO_SMALL); - } + } - // push data to buffer - size_t bytesWritten = palUart->TxRingBuffer.Push(data, count); + // check if there is enough room in the buffer + if (palUart->TxRingBuffer.Capacity() - palUart->TxRingBuffer.Length() < count) + { + // not enough room in the buffer + NANOCLR_SET_AND_LEAVE(CLR_E_BUFFER_TOO_SMALL); + } - // check if all requested bytes were written - if (bytesWritten != count) - { - // not sure if this is the best exception to throw here... - NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); - } + // push data to buffer + size_t bytesWritten = palUart->TxRingBuffer.Push(data, count); - // null pointers and vars - pThis = NULL; + // check if all requested bytes were written + if (bytesWritten != count) + { + // not sure if this is the best exception to throw here... + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + // null pointers and vars + pThis = NULL; + } NANOCLR_NOCLEANUP(); } diff --git a/targets/FreeRTOS/NXP/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp b/targets/FreeRTOS/NXP/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp index 6628210b62..834d8233a8 100644 --- a/targets/FreeRTOS/NXP/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp +++ b/targets/FreeRTOS/NXP/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp @@ -148,12 +148,14 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::get_BytesToRead___ { NANOCLR_HEADER(); - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); + NF_PAL_UART *palUart; uint8_t uartNum = 0; size_t read_count = 0; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + if (pThis[FIELD___disposed].NumericByRef().u1 != 0) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); @@ -167,7 +169,7 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::get_BytesToRead___ NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - NF_PAL_UART *palUart = Uart_PAL[uartNum]; + palUart = Uart_PAL[uartNum]; read_count = palUart->RxBytesToRead; stack.SetResult_U4(read_count); @@ -179,6 +181,7 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeDispose___VO { NANOCLR_HEADER(); + NF_PAL_UART *palUart; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); @@ -194,7 +197,7 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeDispose___VO NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - NF_PAL_UART *palUart = Uart_PAL[uartNum]; + palUart = Uart_PAL[uartNum]; // Free ring buffers memory free(palUart->TxBuffer); @@ -466,116 +469,116 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeWrite___VOID HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeStore___U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + { + NF_PAL_UART *palUart = NULL; - NF_PAL_UART *palUart = NULL; - - size_t length = 0; - - int64_t *timeoutTicks; - bool eventResult = true; - bool txOk = false; + size_t length = 0; - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); + int64_t *timeoutTicks; + bool eventResult = true; + bool txOk = false; - if (pThis[FIELD___disposed].NumericByRef().u1 != 0) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); - } + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - uint8_t uartNum = pThis[FIELD___portIndex].NumericByRef().s4; + if (pThis[FIELD___disposed].NumericByRef().u1 != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } - // Quit if parameters or device is invalid or out of range - if (uartNum >= (sizeof(Uart_PAL) / sizeof(Uart_PAL[0]))) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + uint8_t uartNum = pThis[FIELD___portIndex].NumericByRef().s4; - palUart = Uart_PAL[uartNum]; + // Quit if parameters or device is invalid or out of range + if (uartNum >= (sizeof(Uart_PAL) / sizeof(Uart_PAL[0]))) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } - // as we are transsmiting data, we can discard recive buffer - // assuming that we can't RX and TX simultaneously - size_t rx_size = 0; - palUart->RxRingBuffer.Push(1); - rx_size = palUart->RxRingBuffer.Length(); - palUart->RxRingBuffer.Pop(rx_size); + palUart = Uart_PAL[uartNum]; - // setup timeout from _writeTimeout field - NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTimeSpan(pThis[FIELD___writeTimeout], timeoutTicks)); + // as we are transsmiting data, we can discard recive buffer + // assuming that we can't RX and TX simultaneously + size_t rx_size = 0; + palUart->RxRingBuffer.Push(1); + rx_size = palUart->RxRingBuffer.Length(); + palUart->RxRingBuffer.Pop(rx_size); - // push dummy length value onto the eval stack - // this is going to be used to store how many bytes where buffered to Tx - if (stack.m_customState == 1) - { - stack.PushValueI4(0); - // bump custom state so the read value above is pushed only once - stack.m_customState = 2; - } + // setup timeout from _writeTimeout field + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTimeSpan(pThis[FIELD___writeTimeout], timeoutTicks)); - // check if there is anything the buffer - if (palUart->TxRingBuffer.Length() > 0) - { - // check if there is a TX operation ongoing - if (palUart->TxOngoingCount == 0) + // push dummy length value onto the eval stack + // this is going to be used to store how many bytes where buffered to Tx + if (stack.m_customState == 1) { - // OK to Tx - txOk = true; + stack.PushValueI4(0); + // bump custom state so the read value above is pushed only once + stack.m_customState = 2; } - else + + // check if there is anything the buffer + if (palUart->TxRingBuffer.Length() > 0) { - // need to wait for the ongoing operation to complete before starting a new one + // check if there is a TX operation ongoing + if (palUart->TxOngoingCount == 0) + { + // OK to Tx + txOk = true; + } + else + { + // need to wait for the ongoing operation to complete before starting a new one + } } - } - - if (txOk) - { - // Optimize buffer for sequential reading - palUart->TxRingBuffer.OptimizeSequence(); - // Get data length available in the buffer - length = palUart->TxRingBuffer.Length(); + if (txOk) + { + // Optimize buffer for sequential reading + palUart->TxRingBuffer.OptimizeSequence(); - // Push to the stack how many bytes bytes where buffered for Tx - stack.m_evalStack[1].NumericByRef().s4 = length; + // Get data length available in the buffer + length = palUart->TxRingBuffer.Length(); - // Set TX ongoing count - palUart->TxOngoingCount = length; + // Push to the stack how many bytes bytes where buffered for Tx + stack.m_evalStack[1].NumericByRef().s4 = length; - // Set transfer structure to nano ring buffer - palUart->xfer.data = (uint8_t *)palUart->TxRingBuffer.Reader(); - palUart->xfer.dataSize = length; - // Notify task that we want to transmit data. - xTaskNotify(palUart->xWTaskToNotify, 0x01, eSetBits); - } + // Set TX ongoing count + palUart->TxOngoingCount = length; - NANOCLR_CHECK_HRESULT( - g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_SerialPortOut, eventResult)); + // Set transfer structure to nano ring buffer + palUart->xfer.data = (uint8_t *)palUart->TxRingBuffer.Reader(); + palUart->xfer.dataSize = length; + // Notify task that we want to transmit data. + xTaskNotify(palUart->xWTaskToNotify, 0x01, eSetBits); + } - if (eventResult) - { - // Notify the task that the transmission is complete. - // pop elements from ring buffer, just pop - palUart->TxRingBuffer.Pop(palUart->TxOngoingCount); + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_SerialPortOut, eventResult)); - // reset Tx ongoing count - palUart->TxOngoingCount = 0; + if (eventResult) + { + // Notify the task that the transmission is complete. + // pop elements from ring buffer, just pop + palUart->TxRingBuffer.Pop(palUart->TxOngoingCount); - length = stack.m_evalStack[1].NumericByRef().s4; - } - else - { - palUart->TxRingBuffer.Pop(palUart->TxOngoingCount); - palUart->TxOngoingCount = 0; - NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); - } + // reset Tx ongoing count + palUart->TxOngoingCount = 0; - // pop length and timeout heap block from stack - stack.PopValue(); - stack.PopValue(); + length = stack.m_evalStack[1].NumericByRef().s4; + } + else + { + palUart->TxRingBuffer.Pop(palUart->TxOngoingCount); + palUart->TxOngoingCount = 0; + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } - stack.SetResult_U4(length); + // pop length and timeout heap block from stack + stack.PopValue(); + stack.PopValue(); + stack.SetResult_U4(length); + } NANOCLR_NOCLEANUP(); } @@ -583,125 +586,126 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeRead___U4__S CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + { + CLR_RT_HeapBlock_Array *dataBuffer = NULL; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + int64_t *timeoutTicks; - CLR_RT_HeapBlock_Array *dataBuffer = NULL; - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); - int64_t *timeoutTicks; - - bool eventResult = true; - - uint8_t uartNum = 0; - size_t bytesRead = 0; - size_t bytesToRead = 0; - size_t readOffset = 0; - - uint8_t *data = NULL; - - size_t count = 0; + bool eventResult = true; - if (pThis[FIELD___disposed].NumericByRef().u1 != 0) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); - } + uint8_t uartNum = 0; + size_t bytesRead = 0; + size_t bytesToRead = 0; + size_t readOffset = 0; - uartNum = pThis[FIELD___portIndex].NumericByRef().s4; + uint8_t *data = NULL; - // Quit if parameters or device is invalid or out of range - if (uartNum >= (sizeof(Uart_PAL) / sizeof(Uart_PAL[0]))) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + size_t count = 0; - NF_PAL_UART *palUart = Uart_PAL[uartNum]; + if (pThis[FIELD___disposed].NumericByRef().u1 != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } - // dereference the data buffer from the argument - dataBuffer = stack.Arg1().DereferenceArray(); - // The offset to start filling the buffer - readOffset = stack.Arg2().NumericByRef().s4; + uartNum = pThis[FIELD___portIndex].NumericByRef().s4; - // get a the pointer to the array by using the first element of the array - data = dataBuffer->GetElement(readOffset); + // Quit if parameters or device is invalid or out of range + if (uartNum >= (sizeof(Uart_PAL) / sizeof(Uart_PAL[0]))) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } - // get how many bytes are requested to read - count = stack.Arg3().NumericByRef().s4; + NF_PAL_UART *palUart = Uart_PAL[uartNum]; - CLR_RT_HeapBlock hbTimeout; - hbTimeout.SetInteger((CLR_INT64)pThis[FIELD___readTimeout].NumericByRef().s4 * TIME_CONVERSION__TO_MILLISECONDS); - // setup timeout - NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + // dereference the data buffer from the argument + dataBuffer = stack.Arg1().DereferenceArray(); + // The offset to start filling the buffer + readOffset = stack.Arg2().NumericByRef().s4; - // Check what's avaliable in Rx ring buffer - if (palUart->RxRingBuffer.Length() >= count) - { - // read from Rx ring buffer - bytesToRead = count; + // get a the pointer to the array by using the first element of the array + data = dataBuffer->GetElement(readOffset); - // we have enough bytes, skip wait for event - eventResult = false; + // get how many bytes are requested to read + count = stack.Arg3().NumericByRef().s4; - // clear event by getting it - Events_Get(SYSTEM_EVENT_FLAG_COM_IN); - } - else - { + CLR_RT_HeapBlock hbTimeout; + hbTimeout.SetInteger( + (CLR_INT64)pThis[FIELD___readTimeout].NumericByRef().s4 * TIME_CONVERSION__TO_MILLISECONDS); + // setup timeout + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); - if (stack.m_customState == 1) + // Check what's avaliable in Rx ring buffer + if (palUart->RxRingBuffer.Length() >= count) { + // read from Rx ring buffer + bytesToRead = count; - // not enough bytes available, have to read from UART - palUart->RxBytesToRead = count; + // we have enough bytes, skip wait for event + eventResult = false; // clear event by getting it Events_Get(SYSTEM_EVENT_FLAG_COM_IN); + } + else + { + + if (stack.m_customState == 1) + { + + // not enough bytes available, have to read from UART + palUart->RxBytesToRead = count; - // don't read anything from the buffer yet - bytesToRead = 0; + // clear event by getting it + Events_Get(SYSTEM_EVENT_FLAG_COM_IN); + + // don't read anything from the buffer yet + bytesToRead = 0; + } } - } - while (eventResult) - { - if (stack.m_customState == 1) + while (eventResult) { - if (bytesToRead > 0) + if (stack.m_customState == 1) { - // enough bytes available - eventResult = false; + if (bytesToRead > 0) + { + // enough bytes available + eventResult = false; + } + else + { // need to read from the UART + // update custom state + stack.m_customState = 2; + } } else - { // need to read from the UART - // update custom state - stack.m_customState = 2; - } - } - else - { - // wait for event - NANOCLR_CHECK_HRESULT( - g_CLR_RT_ExecutionEngine - .WaitEvents(stack.m_owningThread, *timeoutTicks, Event_SerialPortIn, eventResult)); - - if (!eventResult) { - // event timeout - NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + // wait for event + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine + .WaitEvents(stack.m_owningThread, *timeoutTicks, Event_SerialPortIn, eventResult)); + + if (!eventResult) + { + // event timeout + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } } } - } - - if (bytesToRead > 0) - { - // pop the requested bytes from the ring buffer - bytesRead = palUart->RxRingBuffer.Pop(data, bytesToRead); - } - // pop timeout heap block from stack and return how many bytes were read - stack.PopValue(); + if (bytesToRead > 0) + { + // pop the requested bytes from the ring buffer + bytesRead = palUart->RxRingBuffer.Pop(data, bytesToRead); + } - // return how many bytes were read - stack.SetResult_U4(bytesRead); + // pop timeout heap block from stack and return how many bytes were read + stack.PopValue(); + // return how many bytes were read + stack.SetResult_U4(bytesRead); + } NANOCLR_NOCLEANUP(); } @@ -709,12 +713,15 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeSetWatchChar { NANOCLR_HEADER(); + NF_PAL_UART *palUart; + uint8_t uartNum; + // get a pointer to the managed object instance and check that it's not NULL CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); // Choose the driver for this SerialDevice - uint8_t uartNum = (uint8_t)pThis[FIELD___portIndex].NumericByRef().s4; + uartNum = (uint8_t)pThis[FIELD___portIndex].NumericByRef().s4; // Quit if parameters or device is invalid or out of range if (uartNum >= (sizeof(Uart_PAL) / sizeof(Uart_PAL[0]))) @@ -722,7 +729,7 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeSetWatchChar NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - NF_PAL_UART *palUart = Uart_PAL[uartNum]; + palUart = Uart_PAL[uartNum]; // set watch char palUart->WatchChar = (uint8_t)pThis[FIELD___watchChar].NumericByRef().u1;