Passing a tileref to C function Topic is solved

Technical questions regarding the XTC tools and programming with XMOS.
sylvan
Junior Member
Posts: 6
Joined: Wed Sep 14, 2016 2:55 pm

Passing a tileref to C function

Post by sylvan »

Hello!

I'm in the process of refactoring lib_usb so that xud() and endpoint0() can be passed a tileref so that I may run multiple USB interfaces within the same .xn. Endpoint0() is in 'C' so I'm trying to figure out how to pass a tileref into it. xccompat.h doesn't address tileref types.

Any ideas?

Thanks!


View Solution
robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post by robertxmos »

Hi Sylvan,

'tileref' is a 2 byte opaque type, thus you could cast it via an 'int16_t' for passing around.
Should you wish to look under the lid, you may be surprised to see that '0' is valid and even more surprised to see that '-1' is a 'null tileref' (unlike all other null types).
This null oddity is an historic artefact come about because the implementation used tileref as a subscript... but as it is an opaque type the implementation may change in the future.

Robert
sylvan
Junior Member
Posts: 6
Joined: Wed Sep 14, 2016 2:55 pm

Post by sylvan »

Thanks! That's good info. I initially tried to cast but got a compiler error about not being able to cast resource types. I ultimately solved it by doing the following:

Code: Select all

#ifdef __XC__
void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl,
	       chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctr, client interface i_dfu dfuInterface, tileref usb_tile_ref);
#else
void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl,
	       chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctr, client interface i_dfu dfuInterface, unsigned usb_tile_ref);
#endif
Sylvan
sylvan
Junior Member
Posts: 6
Joined: Wed Sep 14, 2016 2:55 pm

Post by sylvan »

Actually, the above didn't solve it. After I waded through the rest of my compiler errors it fails on link.

You said I can cast a tileref to an int16_t. tileref is a resource type, no? How do I get around the compiler restriction of casting resource types?

Thanks,

Sylvan
robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post by robertxmos »

Hmmm, yes, the compiler wishes to stay clear of such dodgy dealings.

Can you explain further how you are going to use the tileref from C (should have asked this first).

There is always the inline assembler - assuming there is a symbol for what you are after:

Code: Select all

#include <platform.h>
int main() {
  int i;
  asm volatile( "add %0, %1, 0" : "=r" (i) : "r" (tile[1]) );
  return i;
}
sylvan
Junior Member
Posts: 6
Joined: Wed Sep 14, 2016 2:55 pm

Post by sylvan »

Thanks, Robert.

lib_usb out of the box is hardcoded via a macro to use a specific tileref that points to the usb node (it defaults to 'usb_tile'. This is fine for a system with only one USB interface. However, I have two in this system. Therefore, I'm attempting to modify lib_usb to be able to pass a tileref to it.

The two initial functions needed to start the stack up are xud(...) and Endpoint0(...). Endpoint0(...) is a 'C' function and calls other processes that need a tileref so I need to pass it in.

I'm really surprised it isn't making it across the linker since it works with every other resource type by way of xccompat.h.

tileref is the only type not handled in xccompat.h!

Sylvan
robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post by robertxmos »

Hi Sylvan,
tileref is quite different to the other resources, I'll have to dig a lot deeper before I can help further.
Sorry for the delay.
Robert
peter
XCore Addict
Posts: 230
Joined: Wed Mar 10, 2010 12:46 pm

Post by peter »

Hi sylvan,

I found a work-around that seemed to work for me. I created an assembly function in a file called convert.S:

Code: Select all

    .text
    .cc_top convert.function
    .globl    convert
    .type    convert,@function

    .align 4
convert:
    retsp 0

.tmp_convert:
    .size    convert, .tmp_convert-convert
    .align    4
    .cc_bottom convert.function

    .set    convert.nstackwords,0
    .globl    convert.nstackwords
    .set    convert.maxcores,1
    .globl    convert.maxcores
    .set    convert.maxtimers,0
    .globl    convert.maxtimers
    .set    convert.maxchanends,0
    .globl    convert.maxchanends
And then in my xc file I declare the prototype and use it like this:

Code: Select all

int convert(tileref t);

void print(tileref t) {
  int i = convert(t);
  debug_printf("%x\n", i);
}

int main() {
  print(tile[0]);
  return 0;
}

robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post by robertxmos »

Hi sylvan,

You can cast to a 2 byte type in an unsafe region

Code: Select all

unsafe int convertTileRef(tileref t) {
  return (short)t;
}
But casting to a 4byte type will cause a compiler error at present.

Robert
sylvan
Junior Member
Posts: 6
Joined: Wed Sep 14, 2016 2:55 pm

Post by sylvan »

Thanks for looking into this Robert and Peter!

The key to this was pairing 'unsafe' with the cast of the tileref to a signed short.

I now have a working lib_usb which can be passed a tileref to any usb node in the design!

Sylvan