Search This Blog

Dec 3, 2012

USB CDC command verifier test


1.       Run USB 2.0 Command Verifier

·         It display below message, we need choose second host controller.

But when we select it USB mouse and keyboard lose control, we need find PS2 mouse and then we can continue testing.
·         It opens window like below, we click on Run button, but get error.



Screen clipping taken: 12/3/2012 4:56 PM
 The reason is We have a Card reader socket in LCD monitor, so that is a mass storage device which is not allowed by USB CV.  Disable USB Mass Storage Device in Device Manager.

·         And then we run it again, and select our device VID=10c4, PID=A002



Screen clipping taken: 12/3/2012 4:57 PM
·         Here is the result, we passed most of tests, but failure with item "Halt Endpoint Test".



Screen clipping taken: 12/3/2012 5:00 PM
·         Description of Halt Endpoint Test failed.
Halt Endpoint Test  Failed
INFO  Start time: Mon Dec 03 16:58:38 2012
INFO  Testing Interface number : 0 Alternate setting : 0
WARNING  SetInterface with interface number : 0 failed.
INFO  Testing EndPoint type : Interrupt, Address : 81
INFO  Endpoint is currently not halted
ERROR  Endpoint could not be halted
INFO Cleared endpoint halt
FAIL (1.2.91) A device that has Bulk/Interrupt endpoints must support the Halt Endpoint request on those endpoints.
INFO  Testing Interface number : 1 Alternate setting : 0
WARNING  SetInterface with interface number : 1 failed.
INFO  Testing EndPoint type : Bulk, Address : 3
INFO  Endpoint is currently not halted
ERROR  Endpoint could not be halted
INFO  Cleared endpoint halt
FAIL  (1.2.91) A device that has Bulk/Interrupt endpoints must support the Halt Endpoint request on those endpoints.
INFO  Testing EndPoint type : Bulk, Address : 82
INFO   Endpoint is currently not halted
ERROR  Endpoint could not be halted
INFO  Cleared endpoint halt
FAIL  (1.2.91) A device that has Bulk/Interrupt endpoints must support the Halt Endpoint request on those endpoints.
INFO  Stop time: Mon Dec 03 16:58:55 2012
INFO  Duration: 17 seconds.
INFO  Stopping Test [ Halt Endpoint Test (Configuration Index 0): Number of: Fails (3); Aborts (0); Warnings (2) ]

2.       Analysis.
·         Capture USB data during "Halt Endpoint Test" from Ellisys USB protocol explorer. We know USB CV execute two command. Since the protocol analyzer communicate with PC through USB interface, and CV run, the USB driver was replaced, USB protocol software won't work. We have to setup USB protocol analyzer software in another PC.
·         First it execute SetFeature() to halt endpoint  and then GetStatus to learn whether endpoint halt. From the log, I can see that GetStatusreports that Endpoint doesn't halted.


Screen clipping taken: 12/3/2012 7:25 PM
3.       Check code.
In GetStatus() function we see below code.
   CurrentStatus = Endpoint_IsStalled();
Check Endpoint_IsStalled(),
if(Endpoint_GetEndpointDirection()== ENDPOINT_DIR_IN)
{
status = USB_EPn(usb_ep_selected)->EPCONTROL.ISTSTLI;
}
else
{
status = USB_EPn(usb_ep_selected)->EPCONTROL.OSTSTLI;
}
We should not judge endpoint stall status by those two bit, but instead of below code.
if(Endpoint_GetEndpointDirection()== ENDPOINT_DIR_IN)
{
status = USB_EPn(usb_ep_selected)->EPCONTROL.ISDSTL;
}
else
{
status = USB_EPn(usb_ep_selected)->EPCONTROL.OSDSTL;
}

4.       Verify
Run USB CV again, we pass the "Halt Endpoint Test"

Nov 9, 2012

Porting FreeRTOS to SiM3U167 Cortex M3



Porting FreeRTOS to SiM3U167 Cortex M3
     RTOS is just an application which can execute difference function base on different trigger conditions, something like system ticket, interrupt, and message queue.etc. And also need protect some share resource would be accessed by difference function, or we call it task at one time.
      For Arm Cortex M3, there two popular RTOS, one it uC/OSII, the other one is FreeRtos. We pickup FreeRTOS as our target since it free and open source.  The poring procedure is pretty easy, let start it.

1.       Get Latest FreeRtos 7.3.0 source code.

Go to http://www.freertos.org/, and download it to your PC, extract it. We can see directory structure like below.
\FreeRTOS
\FreeRTOS-Plus
\readme.txt
Just go through the directory, there are a lot of difference platform support codes. We need Cortex M3 and GCC. So here are the resources we need.
\FreeRTOS\Source\*.*
\FreeRTOS\Source\include\*.*
\FreeRTOS\Source\portable\GCC\ARM\CM3\*.*
\FreeRTOS\Source\portable\MemMang\heap_4.c
And one head file needed, FreeRTOSConfig.h
I just choose \FreeRTOS\Demo\CORTEX_LM3S811_GCC\ FreeRTOSConfig.h, and copy it into \FreeRTOS\Source\include\

2.       Prepare our RTOS directory.

a)      Created a directory “FreeRTOSV7.3.0”.
b)      Copy a Blinky example code as code base and copy startup file in it.Exclude original startup file from project.
c)       Copy FreeRTOS directory into this directory.
d)      The directory structure now looks like this
\FreeRTOS\Source\*.*
\FreeRTOS\Source\include\*.*
\FreeRTOS\Source\portable\GCC\ARM\CM3\*.*
\FreeRTOS\Source\portable\MemMang\heap_4.c
\src\*.*
\src\generated\*.*

3.       Precistion32 environment setting and interrupt handler functions modification.

Include paths looks like this:
"${workspace_loc:/sim3u1xx_FreeRtos/src}"
"${workspace_loc:/sim3u1xx_FreeRtos/src/generated}"
"${workspace_loc:/sim3u1xx_FreeRtos/FreeRTOS/Source/include}"
"${workspace_loc:/sim3u1xx_FreeRtos/FreeRTOS/Source/portable/GCC/ARM_CM3}"
"${SI32_PATH}/si32Hal/sim3u1xx"
"${SI32_PATH}/si32Hal/SI32_Modules"
"${SI32_PATH}/si32Hal/CPU"
Open start up file src\startup_sim3u1xx_p32.c, changed three handler functions. In vector table “void (* const g_pfnVectors[])(void)”,
a)       Change SVCall handler to “vPortSVCHandler”
b)       Change PendSV handler to “xPortPendSVHandler”
c)        Change SysTick handler to “xPortSysTickHandler”

4.        Added task test code in main.c

void task1(void * parameters)
{
       uint32_t count = 0;
       const portCHAR *pcPassMessage = "PASS";
       while(1)
       {
              if(SI32_PBSTD_A_read_pin(SI32_PBSTD_2, 8)==0)
              {
                     printf("Task1 running %d\n",count++);
                     xQueueSend( xLEDQueue, &pcPassMessage, portMAX_DELAY );
              }
       }
}

void task2(void * parameters)
{
       uint32_t count = 0;
       while(1)
       {
              printf("Task2 running %d\n",count++);
              vTaskDelay( 1000 );
       }
}

void task3(void * parameters)
{
       uint32_t count = 0;
       portCHAR *pcMessage;
       while(1)
       {
              /* Wait for a message to arrive. */
              xQueueReceive( xLEDQueue, &pcMessage, portMAX_DELAY );
              SI32_PBSTD_A_toggle_pins(SI32_PBSTD_2,0xc00);
              printf("Task3 running %d  %s\n",count++,pcMessage);
       }
}

int main()
{

   while(SI32_PBSTD_A_read_pin(SI32_PBSTD_2, 8) == 0);
   // Enter the default operating mode for this application (gModes.c)
   gModes_enter_my_default_mode();

   // Print a starting message
   printf("hello world\n");
       /* Create the queue used to pass message to vPrintTask. */
   xLEDQueue = xQueueCreate( 3, sizeof( portCHAR * ) );

   xTaskCreate( task1, "task1", 200, NULL, 1, NULL );
   xTaskCreate( task2, "task2", 200, NULL, 2, NULL );
   xTaskCreate( task3, "task3", 200, NULL, 2, NULL );

       /* Start the scheduler running the tasks and co-routines just created. */
   vTaskStartScheduler();

   while(1);
   // Loop forever...
}

5.       Run the code,

We can task output from serial view window.
hello world
Task2 running 0
Task2 running 1
If we press SW2(PB2.8), we can see task1 and task3 active and output message
Task1 running 0
Task3 running 0  PASS
Task1 running 1
Task3 running 1  PASS

6.       Source code

We can get source code from https://github.com/MarkDing/sim3u1xx_FreeRtos


Oct 25, 2012

USB debug adapter SWD connect with Arm Cortex M3 failure analysis

   There is an issue reported from customer that Silabs USB debug adapter (UDA) cannot
connect with SiM3U1xx MCU card board. When they try to download code into MCU under
preceistion32 IDE, it got below message.

“Error message: 02: Failed on connect: Em(04). Cannot provide power to DAP bus. Emu(0):
Conn&Reset. Was: None. DpID: 2BA01477. Info: UDA000C5EFB”

Once new chip been programmed and UDA cannot connect with MCU any more.

What could cause the connection failure? Normally, set system clock incorrectly or put MCU
into low power mode will cause such issue. So I suggest customer to use si32FlashUtility to erase
internal flash. "si32FlashUtility.exe -r 1 -e 2". In startup code, there is 500ms delay which allows
UDA take control of MCU, and then si32FlashUtility.exe can erase the wrong firmware inside
flash. But things not go smooth. Customer replied that it doesn’t work and error message out:
“ADI_STTUS_API_NOT_CONNECTED_TO_TARGET”. There is weird thing and asked customer
sends their board and source code to me.

Investigating:


Customer’s code Analysis:


I start testing on my board with customer’s code at first. I added back door code to prevent
unexpected situation. Add check GPIO status at beginning of main function.

#include
void check_gpio()
{
SI32_CLKCTRL_A_enable_apb_to_modules_0(SI32_CLKCTRL_0,SI32_CLKCTRL_A_APBCLKG0_P
B0);
while(SI32_PBSTD_A_read_pin(SI32_PBSTD_2,8) == 0);
SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_2, 0x00000C00);
SI32_PBSTD_A_write_pins_low(SI32_PBSTD_2, 0x00000C00);
SI32_PBCFG_A_enable_crossbar_1(SI32_PBCFG_0);
}

And we also have 500ms delay in Systeminit function by default.

void SystemInit(void)
{
// To disable the pin reset delay described below, make sure the preprocessor
// symbol si32HalOption_disable_pin_reset_delay is defined by your toolchain.
# if !defined(si32HalOption_disable_pin_reset_delay)
// If the reset pin was the source of the last reset, delay for 500 msec.
// Firmware can disable the debug port by inadvertantly setting the AHB
// clock source to a disabled clock. If this happens too quickly after a
// reset, it is not possible for a debug agent to gain control and thus
// not possible to reprogram the on-chip flash. Adding a delay here gives
// a debug agent sufficient time to connect.
if ((SI32_RSTSRC_0->RESETFLAG.PINRF == 1)
&& (SI32_RSTSRC_0->RESETFLAG.PORRF == 0)
&& (SI32_RSTSRC_0->RESETFLAG.VMONRF == 0))

SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;

// Wait for the count down to complete
while (0 == (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)) {}

// Set the SysTick timer to reset values
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;

}
# endif

// invoke the application's system initialization.
mySystemInit();

}

Run the code and I can see connect failure happened, same as customer’s issue. I ran
"si32FlashUtility.exe -r 1 -e 2", it can erase firmware from internal flash. I just check customer’s
code. I found the reason cause connection failure. They try to make system clock configuration
change to external CMOS. But the setting of the XTAL2 pin is wrong. It set it as analog mode
instead of digital input. So when switch system clock to external CMOS, the MCU hang. And also
ETM enabled by customer. It is not necessary. I just comment out the system clock modification
part. And UDA can connect with MCU card board.

Customer’s board analysis:


But customer’s board cannot be recovered by "si32FlashUtility.exe -r 1 -e 2", what happens
with customer’s board? First, I need to confirm whether customer’s code contains 500ms delay.
This is default routine in SDK. And since customer’s code set ETM enable, this setting will draw
down ETM pin, those pins are high when I press RESET pin. So I can compare RESET and ETM
pin to know whether 500ms delay was executed. And the result shows no 500ms delay at all.
That is why si32FlashUtility cannot erase firmware. I have measure timing of the code execution.
It only takes dozens micro seconds to run from power on to system clock modification part.
I checked si32FlashUtility, it issue reset action on RESET pin, and 4ms later, and it start to
communicate with MCU, the communication period about 50mS. So that insufficient to take
control from MCU.

Solution:


Make sure add back door code in project. Include long delay and GPIO checking.

Oct 19, 2012

With openpyxl for python3 to access excel 2007


Goal:

    We want to transfer the data from the data sheet to the Excel files, which we call Alias files.  We will use the Alias files to automatically generate documentation, code, and IDE support.

Example:

Here’s the SFR definition for ADC0CF from the data sheet.

Here is the same information entered into the Excel File:

Special Notes from the SFR definition
10) The SFR address and page information does not need to be stored in the Excel file.   When we generate documentation and IDE support files, the addresses will come from a different file.
11) The SFR Definition number is not stored in the Excel file.
12) We have a special mechanism for documenting functions in the Description field.  For now, you can simply do an approximation of the equation in the text.
Special Notes from the Excel file
13) Module Name.  Choose any name that is short and appropriate for now.  Use names similar to the corresponding 32-bit peripheral if available.
14) Offset.  In the Excel file, each register must have a unique offset.  Start at 0x00 and increment by 1 for each register.
15)   In this example, the reset value for the AD0SC bits is 11111b, so the reset value is 31, which gets entered into each row.

Consideration:

From above requirements, we can see that is hard work with copy and paste by hand. We need to think about make a code to automatically get peripheral register contents and write into excel files with proper style requirement. However, we can see some fields need human intelligence to name the field. That is Okay, we can leave them there and fill by hand later. And most of fields can be done by code.

Language:

Python is popular in company, so Python3 is our prefer script language.

Parse data sheet:

Since data sheet is PDF file. I have studied background knowledge of python parse PDF file. And finally I found this blog, http://chuckin-py.blogspot.com/2010/03/hacking-pdf-with-python.html. The author planed to do similar thing as I want. But he found that is hard to achieve it. I didn’t know PDF file even has not table. So I need other file type. And we have .txt file, it is easy to access.  We will have a look in it in detail later.

Access Excel 2007 file

Compared several 3rd party tools, I choose openpyxl since it supports excel 2007 and python Here are the steps to install it in your PC, of course you already installed Python 3.
1.       Get distribut0.6.28
http://pypi.python.org/pypi/distribute
2.       Get openpyxl 1.5.8 for python 3
https://bitbucket.org/hjunes/openpyxl/
3.       Install distribut0.6.28
$ setup.py install
4.       Install openpyxl 1.5.8 for python3
$ setup.py install

Creating Excel file

Excel file requirement:

1.       Two sheets.
2.       Font Calibri, size 11
3.       First row is freeze pane, and Font is “bold”
4.       Each register first row is filled with yellow color

Achievement by openpyxl:

1.       Two sheets.
 wb = Workbook()
 ws = wb.worksheets[0]
 ws.title = 'version'
 ws = wb.create_sheet()
 ws.title = "Base_alias"
2.       Font Calibri, size 11
For excel 2007, default font is Calibri, and default font size is 11.
3.       First row is freeze pane, and Font is “Bold”
 ws._freeze_panes = 'A2'
 ws.cell('%s%s'%(col, 1)).style.font.bold = True
4.       Each register first row is filled with yellow color
ws.cell('%s%s'%(col, row)).style.fill.fill_type = Fill.FILL_SOLID
ws.cell('%s%s'%(col, row)).style.fill.start_color.index = Color.YELLOW
5.       Write data into cell
ws.cell('%s%s'%(col, row)).value = row_data[i]

Parse .txt file

.txt file overlook

Here is the example opened by notepad++ , it looks like:


It is not so regular, isn’t it?

Analysis txt file

The arrow in the snapshot is tab(‘\t’), and CRLF is ‘\n’.
1.       Every  register description start with "SFR Definition"
2.       Register bit type field start with 'Type\t'.
3.       Register bit reset field start with 'Reset\t'
4.       Register description start with 'Bit            Name    Function'
5.       We have several situations in description part.
a.       “7\t”
b.      “7:0\t”
c.       “1x:” and “01:”
d.      Description row
e.      Double “\n” indicates reach end of this register.

Handle data in txt file

With Python3 internal function we can deal with all string relate context.

Source code
https://github.com/MarkDing/Txt2xlsx.git

Oct 11, 2012

Access excel file by Python

    I have a task to extract register data from SOC spec and fill in excel file. I chosen Python script language to do this automatic job. I have found two 3rd party tools xlwt and openpyxl.
    I have tried xlwt, it has well documentation and easier to operation. However, it has two major weakness, first, it only support up to excel 2003; second, it doesn't support Python 3 which is default version in my group. So I turn to Openpyxl, before that, I would like record some information for xlwt which might be useful for other who don't care about those two weakness I mentioned above.

http://www.python-excel.org/

1. xlrd
* http://pypi.python.org/pypi/xlrd
* Version 0.8.0
* c:\python26\python.exe setup.py install

2. xlwt
* http://pypi.python.org/pypi/xlwt
* version 0.7.4
* c:\python26\python.exe setup.py install

3. Sample code
These same code can generate all style I needed in my task.
from xlwt import Workbook, easyxf
from xlwt.Utils import rowcol_to_cell

row0_style = easyxf(
    'font: name Calibri, bold True, height 220;'
    )
reg_row_style = easyxf(
    'pattern: pattern solid, fore_colour yellow;'
    'font: name Calibri, height 220;'
    )
common_style = easyxf(
    'font: name Calibri, height 220;'
    )

row0_data = [
    'Module',
    'Register',
    'Offset',
    'Bit Num',
    'Bit',
    'Bit Access',
    'Bit Field Reset',
    'Enum Name',
    'Enum Value',
    'Special',
    'Short Name',
    'Description',
    ]

w = Workbook()
#sheet1 = w.add_sheet('version')

sheet2= w.add_sheet('Base_alias')
sheet2.panes_frozen = True
sheet2.remove_splits = True
sheet2.horz_split_pos = 1
for col in range(12):
    sheet2.write(0,col,row0_data[col],row0_style)
for col in range(12):
    sheet2.write(1,col,rowcol_to_cell(1,col),reg_row_style)
for col in range(12):
    for row in range(2,80):
        sheet2.write(row,col,rowcol_to_cell(row,col),common_style)
w.save('panes.xls')