Wednesday, 13 July 2016

Embedded C - USB stack, arm-none-eabi-gcc settings and Matlab interface


I am using LPCOpen (latest realese available for LPC4370) and the usb stack provided within it. I need to build a simple FSM to control the mcu with Matlab and send data from Matlab to the mcu and from the mcu to Maltab. (here another question from me on the same topic)



  • FSM: I'm using char as commands (e.g. Matlab sends 'o', the mcu starts data output

  • DATA TRANSFER: I'm sending data in bulks of 128 32 bits integers each



So as far as I understood I need to implement a CDC USB host.


LPCOPen provides the following examples to start with (and no documentation other than read-me files)




  • usbd_rom_cdc_uart: The example shows how to us USBD ROM stack to creates a CDC UART/Serial port bridge.




  • usbd_rom_cdc_vcom The example shows how to us USBD ROM stack to creates a virtual comm port.





  • usbd_rom_dfu_composite




  • usbd_rom_hid_generic




  • usbd_rom_hid_keyboard





  • usbd_rom_hid_mouse




  • usbd_rom_hid_sio




  • usbd_rom_libusb: The example shows how to us USBD ROM stack to create simple USB data pipes. This example provides libusbdevice encapsulation with simple to use API for non-USB experienced users to develop simple data-pipe applications. The example is tested with http://libusbk.sourceforge.net host side applications. The examples also shows how to handle WCID requests to install libusbk driver. Check https://github.com/pbatard/libwdi/wiki/WCID-Devices for more details.




  • usbd_rom_msc_ram: The example shows how to use USBD ROM stack to creates a USB MSC example that uses RAM. The device appears as unformatted disk with size as 32KB.





Among the above are two examples which I think could use: usbd_rom_cdc_uart and usbd_rom_cdc_vcom.


usbd_rom_cdc_uart is enterely IRQ based and it was not clear to me how I could send/receive data. it's main loop looks like:


while (1) {
/* Sleep until next IRQ happens */
__WFI();
}

So I started with usbd_rom_cdc_vcom which does a loop-back:



DEBUGSTR("USB CDC class based virtual Comm port example!\r\n");

while (1) {
/* Check if host has connected and opened the VCOM port */
if ((vcom_connected() != 0) && (prompt == 0)) {
vcom_write("Hello World!!\r\n", 15);
prompt = 1;
}
/* If VCOM port is opened echo whatever we receive back to host. */
if (prompt) {

rdCnt = vcom_bread(&g_rxBuff[0], 256);
if (rdCnt) {
vcom_write(&g_rxBuff[0], rdCnt);
}
}
/* Sleep until next IRQ happens */
__WFI();
}

So I tested this on a terminal and then tried to move on and use Matlab.



What I found more difficult doing the small messaging. Here some code snippets. From matlab side:


fwrite(serial_object, K_COEFF,  'int32');
if K_COEFF ~= fread(serial_object, 1, 'int32')
error('out of sync');
end
pause(0.0005)

fwrite(serial_object, L_COEFF, 'int32');
if L_COEFF ~= fread(serial_object, 1, 'int32')
error('out of sync');

end
pause(0.0005)

C counterpart:


/*SET K*/
while(!rdCnt)
{rdCnt = vcom_bread(¶m_rxBuff, sizeof(int32_t));}
K_COEFF = param_rxBuff;
vcom_write((uint8_t*)¶m_rxBuff, sizeof(int32_t));
param_rxBuff = 0;

rdCnt = 0;

/*SET L*/
while(!rdCnt)
{rdCnt = vcom_bread(¶m_rxBuff, sizeof(int32_t));}
L_COEFF = param_rxBuff;
vcom_write((uint8_t*)¶m_rxBuff, sizeof(int32_t));
param_rxBuff = 0;
rdCnt = 0;


where vcom_bread and vcom_write are usb stack calls.


Now, this is working. Sometimes.


Some other times the communication goes "out of sync" and Matlab just hangs on printing warnings about the microcontroller not responding. What I noticed is that this depends largely on timing and so also on the compiler settings: I am using arm-none-eabi-gcc and the more I optimize (e.g. O3) the less it works. Does anyone have similar experience of some kind? What should be the best way of interfacing Matlab with an mcu?


EDIT1: As suggested I tried to modify the matlab side:


fwrite(...)
pause(0.001);
flushoutput(serial_object);
flushinput(serial_object);
fread(...)


Unfortunately to no avail. Matlab is still warning me about unsuccessful read.




No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...