every 2nd AT91Boot_Open() call on USB connected board fails

Microchip in-system programming solution: SAM-BA

Moderators: nferre, fab

presssaft
Posts: 11
Joined: Thu Oct 13, 2011 2:57 pm

every 2nd AT91Boot_Open() call on USB connected board fails

Tue Jun 14, 2016 4:42 pm

Hei hei,

we have a custom board based on an AT91SAM9G20-EK but with less RAM and this connected with 16 bit instead of 32 bit. USB and DBGU circuitry are the same as on the EK board. Based on SAM-BA v2.16 we could successfully build our own applets. This works fine so far in SAM-BA GUI itself with our recompiled applets. I can connect and work via USB and see debug output on DBGU (serial console).

Now we wrote a custom tool for testing and flashing the board, based on the examples coming with SAM-BA, especially the one for VS6 without MFC. After having trouble with our application, I verified the odd behavior with all three examples, so I'm sure it's not my fault, but a bug in sam-ba.dll or the USB driver for the CPU. What happens is this:

From AT91Boot_Scan() I get the following list of devices:

Code: Select all

\USBserial\COM9
COM1
COM2
COM3
Then in the examples the first entry is used, in my application I can select it, what ends up in (from the ole_without_mfc example):

Code: Select all

pAT91BootDLL->AT91Boot_Open(pTest[0], &h_handle);
So basically it's like:

Code: Select all

pAT91BootDLL->AT91Boot_Open( "\USBserial\COM9", &h_handle);
Now this call hangs exactly every second time. No matter if started as Debug from Visual Studio 6 or starting the compiled .exe file. One call succeeds, for the next one execution hangs somewhere inside sam-ba.dll (at least this is what the call trace in VS6 shows), the next call succeeds, and so on.

This does not happen if I connect over serial, e.g. COM1.

:(

Can anyone reproduce this? Is this a known bug? Has anyone a solution? Will Atmel fix this?

I did not try (yet) with older SAM-BA releases. Is there a chance v2.15 or earlier don't have this bug?

Greets
presssaft
Posts: 11
Joined: Thu Oct 13, 2011 2:57 pm

Re: every 2nd AT91Boot_Open() call on USB connected board fa

Wed Jun 15, 2016 11:25 am

What puzzles me is the AT91Boot_Scan() already leads to an error. If I start the OLE_without_MFC example in VS6 (F5), it stops in the debugger with this call trace:

Code: Select all

NTDLL! 7c91120e()
NTDLL! 7c97f26e()
NTDLL! 7c980456()
NTDLL! 7c95bafc()
NTDLL! 7c92a1ba()
MSVCRT! 77bfc2de()
SAM-BA! 10001494()
SAM-BA! 100045a4()
SAMBADLL_Lib::ISAMBADLL::AT91Boot_Scan(unsigned char * 0x0012ff30) line 81 + 18 bytes
main(int 1, char * * 0x00891110) line 112
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 7c816037()
The debug window itself shows:

Code: Select all

HEAP[OLE_without_MFC.exe]: Invalid Address specified to RtlFreeHeap( 00870000, 10001417 )
However I can not call AT91Boot_Open() with a correct looking string like "COM1" without calling AT91Boot_Scan() before, because this returns no valid handle. :?
blue_z
Location: USA
Posts: 1549
Joined: Thu Apr 19, 2007 10:15 pm

Re: every 2nd AT91Boot_Open() call on USB connected board fa

Wed Jun 15, 2016 9:24 pm

presssaft wrote:Hei hei,
What kind of salutation is that?
presssaft wrote:we have a custom board based on an AT91SAM9G20-EK but with less RAM and this connected with 16 bit instead of 32 bit.
So how thoroughly has your board been checked out?
Have you ever used a memory test/exerciser like the one in U-Boot?

Regards
presssaft
Posts: 11
Joined: Thu Oct 13, 2011 2:57 pm

Re: every 2nd AT91Boot_Open() call on USB connected board fa

Thu Jun 16, 2016 9:50 am

blue_z wrote:
presssaft wrote:Hei hei,
What kind of salutation is that?
It's norwegian, or lets say scandinavian. See e.g. http://mylittlenorway.com/norwegian-les ... -good-bye/ – I lived in Norway in 2009 and it's a warm and friendly hello. I use this for years in very different places on the net and you're the first one who asks. ;) :)
blue_z wrote:
presssaft wrote:we have a custom board based on an AT91SAM9G20-EK but with less RAM and this connected with 16 bit instead of 32 bit.
So how thoroughly has your board been checked out?
Have you ever used a memory test/exerciser like the one in U-Boot?
The board is quite mature, we started developing it in 2010 and meanwhile it reached hardware revision 3.2. Additionally to the short RAM test of the extram SAM-BA applet shipped by Atmel we have a custom RAM test as a SAM-BA applet based on http://www.barrgroup.com/Embedded-Syste ... st-Suite-C – We tested several boards and those are used in production with U-Boot and Linux for years now, I'm pretty sure the RAM is okay.

As I said, there are no problems connecting over serial (DBGU), the problem is over USB only and always when calling AT91Boot_Open() from my application. On one attempt it hangs, on the other everything is working fine. We can successfully test the RAM and the NAND flash over USB, the bootloader(s) written to NAND flash actually boot.

Maybe interesting: with SAM-BA itself (not our application accessing sam-ba.dll) the connection over USB is always successful, which is weird, because in the AT09423 application note it looks like SAM-BA itself also accesses the target through this library. :|

I'll try a different board with a completely different layout but the same CPU, but have to wait for my colleague first.
blue_z
Location: USA
Posts: 1549
Joined: Thu Apr 19, 2007 10:15 pm

Re: every 2nd AT91Boot_Open() call on USB connected board fa

Thu Jun 16, 2016 9:10 pm

And to eliminate the obvious:
You're aware of the errata, and booting with the 32 kHz external oscillator?

Regards
presssaft
Posts: 11
Joined: Thu Oct 13, 2011 2:57 pm

Re: every 2nd AT91Boot_Open() call on USB connected board fa

Fri Jun 17, 2016 8:01 am

blue_z wrote:And to eliminate the obvious:
You're aware of the errata, and booting with the 32 kHz external oscillator?
I was not aware of the errata, but I double checked now. We have the 32.768 kHz crystal and OSCSEL is connected to VDDBU through a 100k series resistor. Multimeter shows 1.04V on VDDBU and 1.03V on OSCSEL. According to datasheet this has to be somewhere between 0.9V and 1.1V.

The device is reliably detected as USB device and always shows up correctly in Windows device manager or with lsusb on Linux. It is connected through a USB 2.0 port and we tried different host PCs, same symptoms on both.

Meanwhile I checked the other board from my colleague and it also boots with the crystal and according to schematic OSCSEL is connected to VDDBU, I did not measure the voltages though. Those boards have been flashed with SAM-BA GUI (or script) over USB for years, however with the new application linking sam-ba.dll or even the examples coming with sam-ba v2.16 it hangs on every second call to at91boot_open().

FWIW we are compiling with MS Visual Studio 6 on Windows XP (on a virtual machine with airgap), both with latest service packs.
presssaft
Posts: 11
Joined: Thu Oct 13, 2011 2:57 pm

Re: every 2nd AT91Boot_Open() call on USB connected board fa

Fri Jun 24, 2016 9:47 am

Together with a colleague we used Sysinternals Portmon now to compare what happens on the USB serial line when using the sam-ba.dll and when using SAM-BA v2.16 and found something interesting.

First see the log if a AT91Boot_Open() call to sam-ba.dll hangs:

Code: Select all

0  0.00000000  isNCLtest.exe  IRP_MJ_CREATE  USBSER000  Options: Open 
0  0.00001090  SUCCESS  
1  0.00000000  isNCLtest.exe  IOCTL_SERIAL_SET_TIMEOUTS  USBSER000  RI:2009077889 RM:8822600 RC:2009077900 WM:8822600 WC:1240128
1  0.00000084  SUCCESS  
2  0.00000000  isNCLtest.exe  IOCTL_SERIAL_SET_censored_SIZE  USBSER000  InSize: 8192 OutSize: 8192
2  0.00000056  SUCCESS  
3  0.00000000  isNCLtest.exe  IOCTL_SERIAL_GET_BAUD_RATE  USBSER000  
3  0.00457851  SUCCESS  
4  0.00000000  isNCLtest.exe  IOCTL_SERIAL_GET_LINE_CONTROL  USBSER000  
4  0.01258316  SUCCESS  
5  0.00000000  isNCLtest.exe  IOCTL_SERIAL_GET_CHARS  USBSER000  
5  0.00000056  SUCCESS  
6  0.00000000  isNCLtest.exe  IOCTL_SERIAL_GET_HANDFLOW  USBSER000  
6  0.00000028  SUCCESS  
7  0.00000000  isNCLtest.exe  IRP_MJ_WRITE  USBSER000  Length 2: N#
7  0.00095431  SUCCESS  
8  0.00000000  isNCLtest.exe  IRP_MJ_READ  USBSER000  Length 2
8  17.08611905  CANCELLED  
9  0.00000000  isNCLtest.exe  IRP_MJ_CLEANUP  USBSER000  
9  0.00000084  SUCCESS  
10  0.00000000  isNCLtest.exe  IRP_MJ_CLOSE  USBSER000  
10  0.00076323  SUCCESS  
After sending N# nothing is returned by the device.

Now the second call (up to the first real request just reading the DBGU_CIDR register):

Code: Select all

0  0.00000000  isNCLtest.exe  IRP_MJ_CREATE  USBSER000  Options: Open 
0  0.00001117  SUCCESS  
1  0.00000000  isNCLtest.exe  IOCTL_SERIAL_SET_TIMEOUTS  USBSER000  RI:2009077889 RM:8822600 RC:2009077900 WM:8822600 WC:1240128
1  0.00000056  SUCCESS  
2  0.00000000  isNCLtest.exe  IOCTL_SERIAL_SET_censored_SIZE  USBSER000  InSize: 8192 OutSize: 8192
2  0.00000056  SUCCESS  
3  0.00000000  isNCLtest.exe  IOCTL_SERIAL_GET_BAUD_RATE  USBSER000  
3  0.00071545  SUCCESS  
4  0.00000000  isNCLtest.exe  IOCTL_SERIAL_GET_LINE_CONTROL  USBSER000  
4  0.00099566  SUCCESS  
5  0.00000000  isNCLtest.exe  IOCTL_SERIAL_GET_CHARS  USBSER000  
5  0.00000028  SUCCESS  
6  0.00000000  isNCLtest.exe  IOCTL_SERIAL_GET_HANDFLOW  USBSER000  
6  0.00000056  SUCCESS  
7  0.00000000  isNCLtest.exe  IRP_MJ_WRITE  USBSER000  Length 2: N#
7  0.00100823  SUCCESS  
8  0.00000000  isNCLtest.exe  IRP_MJ_READ  USBSER000  Length 2
8  0.00020114  SUCCESS  Length 2: ..
9  0.00000000  isNCLtest.exe  IRP_MJ_WRITE  USBSER000  Length 12: wFFFFF240,4#
9  0.00120295  SUCCESS  
10  0.00000000  isNCLtest.exe  IRP_MJ_READ  USBSER000  Length 4
10  0.00020338  SUCCESS  Length 4: ....
It's essentially the same, only with the device answering.

And now what SAM-BA v2.16 does, also up to reading the Chip ID register:

Code: Select all

0  0.00000000  sam-ba.exe  IRP_MJ_CREATE  USBSER000  Options: Overwrite 
0  0.00001062  SUCCESS  
1  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_BAUD_RATE  USBSER000  
1  0.00135492  SUCCESS  
2  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_LINE_CONTROL  USBSER000  
2  0.00098085  SUCCESS  
3  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_CHARS  USBSER000  
3  0.00000056  SUCCESS  
4  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_HANDFLOW  USBSER000  
4  0.00000056  SUCCESS  
5  0.00000000  sam-ba.exe  IRP_MJ_CLEANUP  USBSER000  
5  0.00000084  SUCCESS  
6  0.00000000  sam-ba.exe  IRP_MJ_CLOSE  USBSER000  
6  0.00107667  SUCCESS  
7  0.00000000  sam-ba.exe  IRP_MJ_CREATE  USBSER000  Options: Open 
7  0.00000363  SUCCESS  
8  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_censored_SIZE  USBSER000  InSize: 4096 OutSize: 4096
8  0.00000056  SUCCESS  
9  0.00000000  sam-ba.exe  IOCTL_SERIAL_PURGE  USBSER000  Purge: TXABORT RXABORT TXCLEAR RXCLEAR
9  0.00000056  SUCCESS  
10  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_TIMEOUTS  USBSER000  RI:0 RM:0 RC:0 WM:0 WC:0
10  0.00000056  SUCCESS  
11  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_BAUD_RATE  USBSER000  
11  0.00103952  SUCCESS  
12  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_LINE_CONTROL  USBSER000  
12  0.00111383  SUCCESS  
13  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_CHARS  USBSER000  
13  0.00000056  SUCCESS  
14  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_HANDFLOW  USBSER000  
14  0.00000056  SUCCESS  
15  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_BAUD_RATE  USBSER000  
15  0.00101186  SUCCESS  
16  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_LINE_CONTROL  USBSER000  
16  0.00113841  SUCCESS  
17  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_CHARS  USBSER000  
17  0.00000056  SUCCESS  
18  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_HANDFLOW  USBSER000  
18  0.00000056  SUCCESS  
19  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_BAUD_RATE  USBSER000  Rate: 115200
19  0.00216424  SUCCESS  
20  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_RTS  USBSER000  
20  0.00000056  SUCCESS  
21  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_DTR  USBSER000  
21  0.00107360  SUCCESS  
22  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_LINE_CONTROL  USBSER000  StopBits: 1 Parity: NONE WordLength: 8
22  0.00218659  SUCCESS  
23  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_CHAR  USBSER000  EOF:0 ERR:0 BRK:0 EVT:0 XON:0 XOFF:0
23  0.00000084  SUCCESS  
24  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_HANDFLOW  USBSER000  Shake:1 Replace:40 XonLimit:0 XoffLimit:0
24  0.00000056  SUCCESS  
25  0.00000000  sam-ba.exe  IRP_MJ_WRITE  USBSER000  Length 3: N#.
25  0.00103449  SUCCESS  
26  0.00000000  sam-ba.exe  IOCTL_SERIAL_PURGE  USBSER000  Purge: RXABORT RXCLEAR
26  0.00000084  SUCCESS  
27  0.00000000  sam-ba.exe  IOCTL_SERIAL_PURGE  USBSER000  Purge: TXABORT TXCLEAR 
27  0.00000084  SUCCESS  
28  0.00000000  sam-ba.exe  IRP_MJ_CLEANUP  USBSER000  
28  0.00000084  SUCCESS  
29  0.00000000  sam-ba.exe  IRP_MJ_CLOSE  USBSER000  
29  0.00087665  SUCCESS  
30  0.00000000  sam-ba.exe  IRP_MJ_CREATE  USBSER000  Options: Open 
30  0.00000531  SUCCESS  
31  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_TIMEOUTS  USBSER000  RI:2009077889 RM:12973416 RC:2009077900 WM:12973416 WC:1242240
31  0.00000056  SUCCESS  
32  0.00000000  sam-ba.exe  IOCTL_SERIAL_SET_censored_SIZE  USBSER000  InSize: 8192 OutSize: 8192
32  0.00000028  SUCCESS  
33  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_BAUD_RATE  USBSER000  
33  0.00107388  SUCCESS  
34  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_LINE_CONTROL  USBSER000  
34  0.00106019  SUCCESS  
35  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_CHARS  USBSER000  
35  0.00000056  SUCCESS  
36  0.00000000  sam-ba.exe  IOCTL_SERIAL_GET_HANDFLOW  USBSER000  
36  0.00000028  SUCCESS  
37  0.00000000  sam-ba.exe  IRP_MJ_WRITE  USBSER000  Length 2: N#
37  0.00098001  SUCCESS  
38  0.00000000  sam-ba.exe  IRP_MJ_READ  USBSER000  Length 2
38  0.00000112  SUCCESS  Length 2: ..
39  0.00000000  sam-ba.exe  IRP_MJ_WRITE  USBSER000  Length 12: wFFFFF240,4#
39  0.00137336  SUCCESS  
40  0.00000000  sam-ba.exe  IRP_MJ_READ  USBSER000  Length 4
40  0.00000084  SUCCESS  Length 4: ....
This looks to me like a workaround. The port is opened, some options set, three bytes send, queues cleared and so on, the port closed again and then reopened for starting …

:roll:

Now the documentation says, just call AT91Boot_Scan() and AT91Boot_Open() and you can work with the device. No word about scan, fake open the port, clear everything, close the port, and then really open it.

:?:
presssaft
Posts: 11
Joined: Thu Oct 13, 2011 2:57 pm

Re: every 2nd AT91Boot_Open() call on USB connected board fa

Fri Jul 29, 2016 11:10 am

presssaft wrote: This looks to me like a workaround. The port is opened, some options set, three bytes send, queues cleared and so on, the port closed again and then reopened for starting …

:roll:

Now the documentation says, just call AT91Boot_Scan() and AT91Boot_Open() and you can work with the device. No word about scan, fake open the port, clear everything, close the port, and then really open it.
We actually implemented a workaround now, too. If anyone needs this, pass the string you got from AT91Boot_Scan() as dev_name and call the below stuff before AT91Boot_Open():

Code: Select all

void MyClass::PrepareDevicePort( const char *dev_name )
{
	int		i;
	char	*com_name, *lastbackslash, port_str[DEVICE_STR_LEN],
			test_str[DEVICE_STR_LEN];
	HANDLE	h_dev;
	DCB		dcb;
	DWORD	bytes_written;

	/*	init string buffer	*/
	(void) memset( test_str, '\0', sizeof(test_str) );
	(void) strncpy( test_str, dev_name, sizeof(test_str) - 1 );

	/*	find USB device virtual COM port	*/
	for ( i = 0; i < sizeof(test_str); i++ )
	{
		test_str[i] = tolower( test_str[i] );
	}

	if ( strstr( test_str, "usb" ) )
	{
		lastbackslash = strrchr( dev_name, '\\' );
		if ( !lastbackslash )
		{
			_snprintf( m_strBuf, sizeof(m_strBuf),
					"No backslash found in USB device name, skipping preparation ...\r\n" );
			m_strText += m_strBuf;
			return;
		}

		com_name = lastbackslash + 1;

		_snprintf( m_strBuf, sizeof(m_strBuf),
				"Preparing USB device on virtual port %s ...\r\n",
				com_name );
		m_strText += m_strBuf;
	}
	else
	{
		/*	not connected via USB, no further preparation necessary	*/
		return;
	}

	/*	open port and get handle	*/
	_snprintf( port_str, sizeof(port_str), "\\\\.\\%s", com_name );

	h_dev = CreateFile(
			port_str,
			GENERIC_READ | GENERIC_WRITE,
			0,								// exclusive access
			NULL,							// no security attributes
			OPEN_EXISTING,
			0,								// or FILE_FLAG_OVERLAPPED
			NULL );
	if ( h_dev == INVALID_HANDLE_VALUE )
	{
		_snprintf( m_strBuf, sizeof(m_strBuf),
				"CreateFile() failed with error 0x%x.\r\n", GetLastError() );
		m_strText += m_strBuf;
		return;
	}

	/*	get current port parameters	*/
	if ( !GetCommState( h_dev, &dcb ) )
	{
		_snprintf( m_strBuf, sizeof(m_strBuf),
				"GetCommState() failed with error 0x%x.\r\n", GetLastError() );
		m_strText += m_strBuf;
		goto exit_prepare_device_port;
	}

	/*	change those port parameters to our needs	*/
	dcb.BaudRate		= CBR_115200;
	dcb.ByteSize		= 8;
	dcb.Parity			= NOPARITY;
	dcb.StopBits		= ONESTOPBIT;
	dcb.fOutxCtsFlow	= false;
	dcb.fOutxDsrFlow	= false;
	dcb.fDtrControl		= DTR_CONTROL_DISABLE;
	dcb.fRtsControl		= RTS_CONTROL_DISABLE;
	dcb.fDsrSensitivity	= false;
	dcb.fParity			= TRUE;
	dcb.fBinary			= TRUE;

	if ( !SetCommState( h_dev, &dcb ) )
	{
		_snprintf( m_strBuf, sizeof(m_strBuf),
				"SetCommState() failed with error 0x%x.\r\n", GetLastError() );
		m_strText += m_strBuf;
		goto exit_prepare_device_port;
	}

	/*	write some dummy string, this seems to be enough workaround	*/
	if ( !WriteFile( h_dev, "N#.", 3, &bytes_written, NULL ) )
	{
		_snprintf( m_strBuf, sizeof(m_strBuf),
				"WriteFile() failed with error 0x%x.\r\n", GetLastError() );
		m_strText += m_strBuf;
		goto exit_prepare_device_port;
  	}

exit_prepare_device_port:
	/*	close port	*/
	if ( !CloseHandle( h_dev ) )
	{
		_snprintf( m_strBuf, sizeof(m_strBuf),
				"CloseHandle() failed with error 0x%x.\r\n", GetLastError() );
		m_strText += m_strBuf;
		return;
	}
}
You may need to adapt those output message stuff to your needs. ;)

This works for us, but we still believe this is a thing which should be fixed in sam-ba.dll by Atmel!

Return to “SAM-BA”

Who is online

Users browsing this forum: No registered users and 2 guests