We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi, i'm developing a firmware for the TUSB3210. It is based on the Code example of Texas, 'Keyboard firmware'. It's originaly for IAR compiler, but i'm translating it to Keil compiler. The simulation is now warking ok, but when i download it to the TUSB it doesn't function in the same way, some variables missed they values into the functions, and so the flow didn't match the one it had in the simulation. For example in the next part of the code:
... volatile BYTE abIEP0Buffer[EP0_MAX_PACKET_SIZE] _at_ 0xFEF8; ... PBYTE pbIEP0Buffer; // A buffer pointer to input end point 0 // Data sent back to host is copied from // this pointed memory location ... void usbSendNextPacketOnIEP0(void) { ... for(bIndex=0; bIndex<bPacketSize; bIndex++) { abIEP0Buffer[bIndex] = *pbIEP0Buffer++; } P2 = abIEP0Buffer[0]; ... }
if i stop the program (with a while(1) for example) inmediatly after assigning the value to Port 2, and then i read the value of P2 when the firmware is running on chip, i read 0x00, different of which i'm expecting based on simulation (ex: 0x12) I suspect it is a problem with a difference in the behavior of variables or pointers in simulation and in chip. What could it be?
Thank you.
Sebastian.
PD: sorry for my english.
Hi Tsuneo, the memory model is the large one (Variables in XDATA) the code rom size is set to compact (2k functions, 64k program). I explicity put the 'xdata' before the variable name but it is still not working. Here i post another piece of code that didn't work on chip as it work in simulation.
#define pbEP0_SETUP_ADDRESS ( (char xdata *)0xFF00) // setup packet code tDEVICE_REQUEST_COMPARE tUsbRequestList[] = { // SET ENDPOINT FEATURE USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT, USB_REQ_SET_FEATURE, FEATURE_ENDPOINT_STALL,0x00, 0xff,0x00, 0x00,0x00, 0xf7,&usbSetEndpointHalt, // CLEAR ENDPOINT FEATURE USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT, USB_REQ_CLEAR_FEATURE, FEATURE_ENDPOINT_STALL,0x00, 0xff,0x00, 0x00,0x00, 0xf7,&usbClearEndpointHalt, ... //It has more entries. } VOID usbDecodeAndProcessUsbRequest(VOID) { BYTE bMask,bResult,bTemp; BYTE *pbUsbRequestList; // save code space P0 |= 0x01; // We initialize the pbUsbRequestList pointer to the beginning of the // tUsbRequestList[] so that we can subsequently traverse the table // by incrementing the pbUsbRequestList pointer. pbUsbRequestList = (PBYTE) &tUsbRequestList[0]; // Cycle indefinitely until we've found an entry in the tUsbRequestList[] // table. Since the last entry in the table has a 0x00 mask, we'll // *always* find a match, so this cycle will always exit. while(1) { bResult = 0x00; bMask = 0x80; P0 |= 0x02; // We cycle through fields 0 through 7, which correspond to the 8 fields // in each entry of tUsbRequestList. If the given byte in the packet // we just receive is equal to the corresponding byte in the table, we // set that bit in the result, indicating a byte which matched. Otherwise, // we don't set the bit which means that byte didn't match. for(bTemp = 0; bTemp < 8; bTemp++) { P0 |= 0x04; P1 += 0x01; if(*(pbEP0_SETUP_ADDRESS+bTemp) == *(pbUsbRequestList+bTemp)) bResult |= bMask; bMask = bMask >> 1; } // At this point, bResult holds 8 bits which indicate whether each of the // bytes in the packet matched the corresponding bytes in the tUsbRequestList[] // table. We then AND the mask value in the table with the result so that // we only are comparing the bits required in the mask. If the resulting // value is equal to the mask, that means that all significant bytes match. // This is done since any bit that is clear in the mask is a "don't care", so // the AND makes sure we don't reject a "valid" comparison beause a don't // care bit actually matched. if((*(pbUsbRequestList+bTemp) & bResult) == *(pbUsbRequestList+bTemp)) { P0 |= 0x08; break; } // If we haven't found a matching entry yet, we advenced the pointer to point // to the next entry in the table, and keep looking. pbUsbRequestList += sizeof(tDEVICE_REQUEST_COMPARE); } // We check to see if any more setup packet(s) have been received and, if so, we // anbandon this one to handle the next one. if(bUSBSTA & (USBSTA_SETUP | USBSTA_STPOW) != 0x00) { P0 |= 0x10; return; } // If we've reached this point of the function, we've found the function that should // be called given the current request. So we call it... P0 |= 0x20; ((ptDEVICE_REQUEST_COMPARE)pbUsbRequestList)->pUsbFunction(); }
Ok, the function 'usbDecodeAndProcessUsbRequest()' set the pointer 'pbUsbRequestList' to the beginning of the table 'tUsbRequestList[]' and then it search a match with the packet stored in the location given by 'pbEP0_SETUP_ADDRESS' when it find a match the function jumps to the correct function location showed in the table for the element that has mathed the search. (For example if the first element of the table match, then the jump is to the function 'usbSetEndpointHalt()'. In simulation it works perfectly, but in chip it didn't jump to the correct function location. Running in chip the program enters to the function 'usbDecodeAndProcessUsbRequest()', but then it stay in the while loop and never jumps out (never find a match) like as the pointer never points to the correct position in the table 'tUsbRequestList[]'. In the target options i put or not 'Use on-chip rom/ram' but either didn't work. For C51: level code optimization is 8, Reuse common entry code. Compiler control string : 'LARGE ROM(COMPACT) BROWSE DEBUG OBJECTEXTEND' Ok, a large post, but i search and search and cant find the way to get it working.
Keil is different from IAR in the policy of liker memory assignment.
For IAR, the linker command file precisely defines the address allocation of each segment, either CODE or XDATA.
For KEIL, the possible address range of CODE and XDATA are given on the command line. On the IDE, Options - BL51 Locate - Code Range: 0x0000 - 0x1FFF Options - BL51 Locate - Xdata Range: 0xFD80 - 0xFEEF
Unless you explicitly assign the address to variables and buffers using "_at_", the linker maps the code and variables to this range. Just when you need to fix the address, use "_at_".
buffer_on_xdata_space.c volatile BYTE xdata abOEP0Buffer[EP0_MAX_PACKET_SIZE] _at_ 0xFEF0; volatile BYTE xdata abIEP0Buffer[EP0_MAX_PACKET_SIZE] _at_ 0xFEF8; ... buffer_on_xdata_space.h extern volatile BYTE xdata abOEP0Buffer[]; extern volatile BYTE xdata abIEP0Buffer[];
Also, check the map file (.M51) for the CODE and XDATA address assignment.
TUSB3210 datasheet focus.ti.com/.../tusb3210.pdf 2.1 MCU Memory Map (p12) 2.3 Buffers + I/O RAM Map (p16) "the code rom size is set to compact (2k functions, 64k program)."
I recommend you not to set the code rom size to compact, until the firmware passes the first on-chip run.
As of the above code,
#define SETUP_BUFFER_ADDR 0xFF00 #define SETUP_BYTE( addr ) ( *(BYTE xdata *)(SETUP_BUFFER_ADDR + addr ) ) // setup packet BYTE code * pbUsbRequestList; // save code space ... pbUsbRequestList = tUsbRequestList; ... if( SETUP_BYTE(bTemp) == pbUsbRequestList[bTemp] ) ...
Tsuneo
I believe the problem lies on the address assignment for CODE and/or XDATA. Without above explicit address range, the linker maps objects to the address on which no CODE/ XDATA RAM exists. Then the firmware works on the simulation, but not on the real chip. It will be confirmed on the map (.M51) file.
Hi Tsuneo, the probelm was related as you say to memory assignament. I compiled de firmware using the small memory model (variables in DATA), instead of the large memory model, and with Large Code Rom Size (64K). Explicity putting the requiered variables in XDATA. The problem was resolved in this way. Thank you for your help Tsuneo!
See you.