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!
Passing a tileref to C function Topic is solved
-
- Junior Member
- Posts: 6
- Joined: Wed Sep 14, 2016 2:55 pm
-
- XCore Addict
- Posts: 169
- Joined: Fri Oct 23, 2015 10:23 am
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
'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
-
- Junior Member
- Posts: 6
- Joined: Wed Sep 14, 2016 2:55 pm
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:
Sylvan
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
-
- Junior Member
- Posts: 6
- Joined: Wed Sep 14, 2016 2:55 pm
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
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
-
- XCore Addict
- Posts: 169
- Joined: Fri Oct 23, 2015 10:23 am
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:
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;
}
-
- Junior Member
- Posts: 6
- Joined: Wed Sep 14, 2016 2:55 pm
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
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
-
- XCore Addict
- Posts: 169
- Joined: Fri Oct 23, 2015 10:23 am
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
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
-
- XCore Addict
- Posts: 230
- Joined: Wed Mar 10, 2010 12:46 pm
Hi sylvan,
I found a work-around that seemed to work for me. I created an assembly function in a file called convert.S:
And then in my xc file I declare the prototype and use it like this:
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
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;
}
-
- XCore Addict
- Posts: 169
- Joined: Fri Oct 23, 2015 10:23 am
Hi sylvan,
You can cast to a 2 byte type in an unsafe region
But casting to a 4byte type will cause a compiler error at present.
Robert
You can cast to a 2 byte type in an unsafe region
Code: Select all
unsafe int convertTileRef(tileref t) {
return (short)t;
}
Robert
-
- Junior Member
- Posts: 6
- Joined: Wed Sep 14, 2016 2:55 pm
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
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