Skip to content

Commit

Permalink
eRPC updates 07/2021
Browse files Browse the repository at this point in the history
-- Fix the order of commands in underlyingReceive and underlyingSend of UART CMSIS transport.
-- Fix (revert) the sequence of commands in MUTransport::rx_cb (bug unintentionally introduced by Github pull request #158).
-- Identify the used LINK hw during the runtime (LPCLINK2 vs. MCULINK) in transport.py.
-- Improve I2cSlaveTransport
-- Add reference links into erpc/README.md.
-- Update license file.
  • Loading branch information
MichalPrincNXP committed Jul 13, 2021
1 parent 1429add commit 9849c5d
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 23 deletions.
34 changes: 33 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,36 @@ Copyright 2014-2016 Freescale Semiconductor, Inc.
Copyright 2016-2021 NXP
All rights reserved.

SPDX-License-Identifier: BSD-3-Clause
The BSD 3 Clause License

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ To get the board list with multicore support (eRPC included) use filtering based
<MCUXpressoSDK_install_dir>/boards/<board_name>/multiprocessor_examples for eRPC multiprocessor examples (UART or SPI transports used).<br>
eRPC examples use 'erpc_' name prefix.

## References

This section provides links to interesting erpc-based projects, articles, blogs or guides:

* [erpc (EmbeddedRPC) getting started notes](https://programmersought.com/article/37585084512/)
* [ERPC Linux Local Environment Construction and Use](https://programmersought.com/article/88827920353/)
* [The New Wio Terminal eRPC Firmware](https://www.hackster.io/Salmanfarisvp/the-new-wio-terminal-erpc-firmware-bfd8bd)

## Directories

`doc` - Documentation.
Expand Down
18 changes: 16 additions & 2 deletions erpc_c/transports/erpc_i2c_slave_transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ using namespace erpc;
#error "Please define the ERPC_BOARD_I2C_INT_GPIO used to notify when the I2C Slave is ready to transmit"
#endif

#define I2C_SLAVE_TRANSPORT_ADDR_7BIT (0x7EU)

////////////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////////////
Expand All @@ -41,7 +43,7 @@ typedef struct i2c_clb_user_data
uint8_t *rx_buffer;
uint32_t rx_size;
} I2C_CLB_USER_DATA, *I2C_CLB_USER_DATA_PTR;
static I2C_CLB_USER_DATA volatile s_callback_user_data = { NULL, 0 };
static volatile I2C_CLB_USER_DATA s_callback_user_data = { NULL, 0, NULL, 0 };

////////////////////////////////////////////////////////////////////////////////
// Code
Expand Down Expand Up @@ -112,18 +114,26 @@ static void I2C_SlaveUserCallback(I2C_Type *base, volatile i2c_slave_transfer_t
/* Update information for transmit process */
transfer->txData = ((I2C_CLB_USER_DATA *)userData)->tx_buffer;
transfer->txSize = ((I2C_CLB_USER_DATA *)userData)->tx_size;
transfer->rxData = NULL;
transfer->rxSize = 0;
break;

/* Setup the slave receive buffer */
case kI2C_SlaveReceiveEvent:
/* Update information for received process */
transfer->rxData = ((I2C_CLB_USER_DATA *)userData)->rx_buffer;
transfer->rxSize = ((I2C_CLB_USER_DATA *)userData)->rx_size;
transfer->txData = NULL;
transfer->txSize = 0;
break;

/* The master has sent a stop transition on the bus */
case kI2C_SlaveCompletionEvent:
transport->transfer_cb();
transfer->rxData = NULL;
transfer->rxSize = 0;
transfer->txData = NULL;
transfer->txSize = 0;
break;

default:
Expand Down Expand Up @@ -159,7 +169,7 @@ erpc_status_t I2cSlaveTransport::init(void)
i2c_slave_config_t i2cConfig;

I2C_SlaveGetDefaultConfig(&i2cConfig);
i2cConfig.address0.address = (0x7EU); // I2C_MASTER_SLAVE_ADDR_7BIT
i2cConfig.address0.address = (I2C_SLAVE_TRANSPORT_ADDR_7BIT);

I2C_SlaveInit(m_i2cBaseAddr, &i2cConfig, m_srcClock_Hz);
I2C_SlaveTransferCreateHandle(m_i2cBaseAddr, &s_handle, I2C_SlaveUserCallback, (void *)&s_callback_user_data);
Expand All @@ -177,6 +187,8 @@ erpc_status_t I2cSlaveTransport::underlyingReceive(uint8_t *data, uint32_t size)

s_callback_user_data.rx_buffer = data;
s_callback_user_data.rx_size = size;
s_callback_user_data.tx_buffer = NULL;
s_callback_user_data.tx_size = 0;

status =
I2C_SlaveTransferNonBlocking(m_i2cBaseAddr, &s_handle, kI2C_SlaveAddressMatchEvent | kI2C_SlaveCompletionEvent);
Expand Down Expand Up @@ -205,6 +217,8 @@ erpc_status_t I2cSlaveTransport::underlyingSend(const uint8_t *data, uint32_t si
status_t status;
s_isTransferCompleted = false;

s_callback_user_data.rx_buffer = NULL;
s_callback_user_data.rx_size = 0;
s_callback_user_data.tx_buffer = (uint8_t *)data;
s_callback_user_data.tx_size = size;

Expand Down
2 changes: 1 addition & 1 deletion erpc_c/transports/erpc_mu_transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ void MUTransport::rx_cb(void)
if (m_rxCntBytes >= m_rxMsgSize)
{
m_rxBuffer = NULL;
MU_DisableInterrupts(m_muBase, (1U << (MU_CR_RIEn_SHIFT + MU_RR_COUNT - MU_REG_COUNT)));
#if !ERPC_THREADS_IS(NONE)
MU_DisableInterrupts(m_muBase, (1U << (MU_CR_RIEn_SHIFT + MU_RR_COUNT - MU_REG_COUNT)));
m_rxSemaphore.putFromISR();
#endif
}
Expand Down
4 changes: 2 additions & 2 deletions erpc_c/transports/erpc_uart_cmsis_transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ erpc_status_t UartTransport::init(void)
erpc_status_t UartTransport::underlyingReceive(uint8_t *data, uint32_t size)
{
erpc_status_t erpcStatus = kErpcStatus_ReceiveFailed;
int32_t status = (*m_uartDrv).Receive(data, size);

s_isTransferReceiveCompleted = false;
int32_t status = (*m_uartDrv).Receive(data, size);

if (status == ARM_DRIVER_OK)
{
Expand All @@ -126,9 +126,9 @@ erpc_status_t UartTransport::underlyingReceive(uint8_t *data, uint32_t size)
erpc_status_t UartTransport::underlyingSend(const uint8_t *data, uint32_t size)
{
erpc_status_t erpcStatus = kErpcStatus_SendFailed;
int32_t status = (*m_uartDrv).Send(data, size);

s_isTransferSendCompleted = false;
int32_t status = (*m_uartDrv).Send(data, size);

if (status == ARM_DRIVER_OK)
{
Expand Down
66 changes: 49 additions & 17 deletions erpc_python/erpc/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,28 @@ def __init__(self, baudrate = None, cs_gpio_port = None, cs_gpio_pin = None):
self._baudrate = baudrate
self._cs_gpio_port = cs_gpio_port
self._cs_gpio_pin = cs_gpio_pin
self._gpioport = 0
self._gpiopin = 0
self._gpiomode = 0

# Load DLL from default directory without any debugging prints
self.sio = LIBUSBSIO()

# Get number of LIBUSBSIO devices
res = self.sio.GetNumPorts ()
res = self.sio.GetNumPorts(pidvids = [LIBUSBSIO.PIDVID_LPCLINK2])
if res!=0:
self._gpioport = 1
self._gpiopin = 2
self._gpiomode = 1
else:
res = self.sio.GetNumPorts(pidvids = [LIBUSBSIO.PIDVID_MCULINK])
if res!=0:
self._gpioport = 0
self._gpiopin = 4
self._gpiomode = 0x100
else:
print('No LIBUSBSIO devices found \r\n')
return
print('Total LIBUSBSIO devices: %d \r\n' % res)

# Open device at index 0
Expand All @@ -237,11 +253,11 @@ def __init__(self, baudrate = None, cs_gpio_port = None, cs_gpio_pin = None):
self._hSPIPort = self.sio.SPI_Open (int(self._baudrate), portNum=0, dataSize=8, preDelay=0)

# Configure GPIO pin for SPI master-slave signalling
res = self.sio.GPIO_ConfigIOPin (1, 2, 1)
res = self.sio.GPIO_ConfigIOPin (self._gpioport, self._gpiopin, self._gpiomode)
print('GPIO_ConfigIOPin res: %d \r\n' % res)
res = self.sio.GPIO_SetPortInDir (1, 2)
res = self.sio.GPIO_SetPortInDir (self._gpioport, self._gpiopin)
print('GPIO_SetPortInDir res: %d \r\n' % res)
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
print('GPIO_GetPin res: %d \r\n' % res)

def close(self):
Expand All @@ -252,9 +268,9 @@ def close(self):

def _base_send(self, message):
# Wait for SPI master-slave signalling GPIO pin to be in low state
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
while (1 == res):
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
# Send the header first
data, rxbytesnumber = self._hSPIPort.Transfer (0, 15, message[:self.HEADER_LEN], self.HEADER_LEN, 0 )
if rxbytesnumber>0:
Expand All @@ -265,10 +281,10 @@ def _base_send(self, message):
print('SPI transfer error: %d' % rxbytesnumber)

def _base_receive(self, count):
# Wait for SPI master-slave signalling GPIO pin to be in low state
res = self.sio.GPIO_GetPin (1, 2)
# Wait for SPI master-slave signalling GPIO pin to be in low state
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
while (1 == res):
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
data, rxbytesnumber = self._hSPIPort.Transfer (0, 15, range(count), count, 0 )
if rxbytesnumber>0:
#print('SPI received %d number of bytes' % rxbytesnumber)
Expand All @@ -290,12 +306,28 @@ def __init__(self, baudrate = None):
baudrate = 100000

self._baudrate = baudrate
self._gpioport = 0
self._gpiopin = 0
self._gpiomode = 0

# Load DLL from default directory without any debugging prints
self.sio = LIBUSBSIO()

#Get number of LIBUSBSIO devices
res = self.sio.GetNumPorts ()
res = self.sio.GetNumPorts(pidvids = [LIBUSBSIO.PIDVID_LPCLINK2])
if res!=0:
self._gpioport = 1
self._gpiopin = 2
self._gpiomode = 1
else:
res = self.sio.GetNumPorts(pidvids = [LIBUSBSIO.PIDVID_MCULINK])
if res!=0:
self._gpioport = 1
self._gpiopin = 3
self._gpiomode = 0x100
else:
print('No LIBUSBSIO devices found \r\n')
return
print('Total LIBUSBSIO devices: %d \r\n' % res)

# Open device at index 0
Expand All @@ -318,11 +350,11 @@ def __init__(self, baudrate = None):
self._hI2CPort = self.sio.I2C_Open (int(self._baudrate), 0, 0)

# Configure GPIO pin for I2C master-slave signalling
res = self.sio.GPIO_ConfigIOPin (1, 2, 1)
res = self.sio.GPIO_ConfigIOPin (self._gpioport, self._gpiopin, self._gpiomode)
print('GPIO_ConfigIOPin res: %d \r\n' % res)
res = self.sio.GPIO_SetPortInDir (1, 2)
res = self.sio.GPIO_SetPortInDir (self._gpioport, self._gpiopin)
print('GPIO_SetPortInDir res: %d \r\n' % res)
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
print('GPIO_GetPin res: %d \r\n' % res)

def close(self):
Expand All @@ -333,9 +365,9 @@ def close(self):

def _base_send(self, message):
# Wait for I2C master-slave signalling GPIO pin to be in low state
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
while (1 == res):
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
# Send the header first
data, rxbytesnumber = self._hI2CPort.FastXfer (0x7E, message[:self.HEADER_LEN], self.HEADER_LEN, 0, 0)
if rxbytesnumber>0:
Expand All @@ -347,9 +379,9 @@ def _base_send(self, message):

def _base_receive(self, count):
# Wait for I2C master-slave signalling GPIO pin to be in low state
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
while (1 == res):
res = self.sio.GPIO_GetPin (1, 2)
res = self.sio.GPIO_GetPin (self._gpioport, self._gpiopin)
# Issue the I2C_Transfer API
data, rxbytesnumber = self._hI2CPort.FastXfer (0x7E, 0, 0, count, 0)
if rxbytesnumber>0:
Expand Down

0 comments on commit 9849c5d

Please sign in to comment.