Here you go all:
http://www.xcore.com/projects/adc-startkit
I have taken the low level code and wrapped it into a task with simple interfaces (trigger, read and a notification for conversion complete).
It triggers and samples all 4 channels each time and can either run continuously at a rate specified by you in microseconds, or converts each time a trigger command is sent.
The way the ADC works on the XS1-A devices is a bit different from a normal MCU (requires I/O trigger for each sample and connects over XMOS links) so the API is designed to abstract that all away.
I invested in lot of code comments in there, so if you want to modify the code to suit your needs, hopefully this will be straightforward.
Most importantly, it works on the startKIT regardless of whether you run over JTAG or boot from FLASH.
More info in adc.h, and the source itself.
How to use the ADC on StartKit?
-
Verified
- XCore Legend
- Posts: 1140
- Joined: Thu May 27, 2010 10:08 am
-
Verified
- XCore Legend
- Posts: 1140
- Joined: Thu May 27, 2010 10:08 am
One other point.. -fxscope is still needed (or you have an xscope.config file in the project with xscope enabled, like the startKIT ADC example does). The reason for this is that it does extra link setup which is needed to get ADC packets across to the XTAG tile to the user tile.
There is no disadvantage to using -fxscope, and many will be using fast printing and/or real-time xscope anyhow which needs this switch, so there's no plan to change this. This ADC library is only for the startKIT and is due to the the special A8-Dev device we use which integrates XTAG. (although you could easily adapt it to run on non-startKIT platforms if you like by removing the link setup stuff)
We also have general libs for non-startKIT use such custom boards, sliceKIT, other boards etc. https://github.com/xcore/sc_a_series_support
or
https://github.com/xcore/sc_u_series_support
There is no disadvantage to using -fxscope, and many will be using fast printing and/or real-time xscope anyhow which needs this switch, so there's no plan to change this. This ADC library is only for the startKIT and is due to the the special A8-Dev device we use which integrates XTAG. (although you could easily adapt it to run on non-startKIT platforms if you like by removing the link setup stuff)
We also have general libs for non-startKIT use such custom boards, sliceKIT, other boards etc. https://github.com/xcore/sc_a_series_support
or
https://github.com/xcore/sc_u_series_support
-
- XCore Legend
- Posts: 1274
- Joined: Thu Dec 10, 2009 10:20 pm
It would be good to add this to github/xcore perhaps to the existing Startkit examples.
regards
Al
regards
Al
-
Verified
- XCore Legend
- Posts: 1140
- Joined: Thu May 27, 2010 10:08 am
Agree - it should be part of the basic examples for sure. ADC is essential in many projects!
We will do this shortly.
We will do this shortly.
-
Verified
- XCore Legend
- Posts: 1140
- Joined: Thu May 27, 2010 10:08 am
Done..
Have separated it out into a module (startkit_adc) for inclusion in your own app and an example app showing how to use it.
You can find it in the community tab (search for ADC) at the bottom left of the GUI, or clone it from https://github.com/xcore/sw_startkit_examples
Enjoy....
Have separated it out into a module (startkit_adc) for inclusion in your own app and an example app showing how to use it.
You can find it in the community tab (search for ADC) at the bottom left of the GUI, or clone it from https://github.com/xcore/sw_startkit_examples
Enjoy....
-
- XCore Legend
- Posts: 1274
- Joined: Thu Dec 10, 2009 10:20 pm
In the ADC server task first select you have:
Could this also be written more intuitively this way:
i.e. using a state guard rather than an if, also is this any more efficient?
Code: Select all
case i_adc.trigger(): //Start ADC state machine via interface method call
if (adc_state == 0){
adc_sample <: 1; //Send first rising edge to trigger ADC
t_trig_state :> trig_pulse_time;//Grab current time
trig_pulse_time += ADC_TRIG_DELAY;//Setup trigger time for next edge (falling)
adc_state = 1; //Start trigger state machine
}
else ;
break;
Code: Select all
case !adc_state => i_adc.trigger(): //Start ADC state machine via interface method call
adc_sample <: 1; //Send first rising edge to trigger ADC
t_trig_state :> trig_pulse_time; //Grab current time
trig_pulse_time += ADC_TRIG_DELAY; //Setup trigger time for next edge (falling)
adc_state = 1; //Start trigger state machine
break;
-
Verified
- XCore Legend
- Posts: 1140
- Joined: Thu May 27, 2010 10:08 am
Guarded event cases are a fantastic way of describing state machines and steering the transitions (and just add a few cycles before setting up the events to test for the guard), however in this case I always wanted i_adc.trigger() to respond (not block) to the client. Hence I put the test in the body of the case.
This way i_adc.trigger() doesn't ever block, and effectively just ignores the request if already in progress.
I thought this was more like how an MCU ADC works.
Open to changing this if a different behaviour makes more sense.
This way i_adc.trigger() doesn't ever block, and effectively just ignores the request if already in progress.
I thought this was more like how an MCU ADC works.
Open to changing this if a different behaviour makes more sense.
-
- XCore Legend
- Posts: 1274
- Joined: Thu Dec 10, 2009 10:20 pm
Ok thanks I should have studied you code a little deeper, it makes sense now.
-
- New User
- Posts: 3
- Joined: Thu Sep 05, 2013 2:20 pm
Code: Select all
void sk_init_adc_network(void) {
unsigned data;
read_node_config_reg(tile[0], 0x87, data);
if (data == 0) {
write_node_config_reg(tile[0], 0x85, 0xC0002004); // open
write_node_config_reg(tile[0], 0x85, 0xC1002004); // and say hello
Is the "tile[0]" the same as the "adc_tile" in the line bellow:
startkit_adc.xc:36 write_periph_32(adc_tile, 2, 0x0, 1, data); //Enable Ch 0
I'm also looking for docs for write_periph_32 function.
Regards,
Marcin
-
Verified
- XCore Legend
- Posts: 1140
- Joined: Thu May 27, 2010 10:08 am
[quote]
Code: Select all
void sk_init_adc_network(void) {
unsigned data;
read_node_config_reg(tile[0], 0x87, data);
if (data == 0) {
write_node_config_reg(tile[0], 0x85, 0xC0002004); // open
write_node_config_reg(tile[0], 0x85, 0xC1002004); // and say hello
Is the "tile[0]" the same as the "adc_tile" in the line bellow:
startkit_adc.xc:36 write_periph_32(adc_tile, 2, 0x0, 1, data); //Enable Ch 0[/quote]
No - the code at the top (write_node_config) is setting up the links on the processor tile, so they can then talk to the peripheral tile (where the ADC is). This stuff is normally hidden in XC programming. The tile definitions are in the .xn file.
The write_periph_32(adc_tile... actually writes the remote register (in the adc/peripheral tile).
[quote]I'm also looking for docs for write_periph_32 function.
[/quote]
both write_node_config and write_periph_32 are deocumented in the xtimecomposer user guide. The link behaviour can be learned about here https://www.xmos.com/published/xsysteml