Using startKIT ADC and Flash in the same application

All technical discussions and projects around startKIT
User avatar
alfanick
Member
Posts: 12
Joined: Sat Jun 21, 2014 8:01 pm
Contact:

Using startKIT ADC and Flash in the same application

Postby alfanick » Wed Jul 09, 2014 10:05 am

Hello again,
my project uses ADC (via module_startkit_adc) and I would love to use builtin SPI memory in the same app (using flashlib). Both ADC and flashlib work as presumed when used separately.
On startkit ADC_SAMPLE trigger port is connected to 1A so as MISO of the flash memory.
XC compiler makes an error about using ports in two statements.
I wonder if there is any hack to make it work? I.e. to stop compiler of checking this port - I can make sure in my code, that ADC isn't triggered when flash memory is used.

Amadeusz
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Postby Folknology » Wed Jul 09, 2014 10:30 am

Take a look at moveable ports and reconfigure port, there is a thread discussing this for another SPI application

BTW Xmos folk, this doesn't seem to be covered in the new XMOS Programming Guide, it would be nice if this can be added.

regards
Al
User avatar
alfanick
Member
Posts: 12
Joined: Sat Jun 21, 2014 8:01 pm
Contact:

Postby alfanick » Wed Jul 09, 2014 10:31 am

Folknology wrote:Take a look at moveable ports and reconfigure port, there is a thread discussing this for another SPI application

BTW Xmos folk, this doesn't seem to be covered in the new XMOS Programming Guide, it would be nice if this can be added.

regards
Al


Thank you!
User avatar
alfanick
Member
Posts: 12
Joined: Sat Jun 21, 2014 8:01 pm
Contact:

Postby alfanick » Fri Jul 11, 2014 3:49 pm

I'm afraid I still need some help. What I did, I changed code of module_startkit_adc to use port pointer as trigger and added some code.

The code for reconfiguring port from MISO (in port:8) to ADC trigger (out port) is implemented as below:

Code: Select all

      case i_adc.trigger_from_miso(in buffered port:8 * movable miso):
        adc_sample = reconfigure_port(move(miso), out port);

        if (!initialized) {
          init_adc_periph(c_adc);                 //Setup the ADC
          initialized = 1;
        }
        break;

      case i_adc.miso_from_trigger() -> in buffered port:8 * movable miso:
        miso = reconfigure_port(move(adc_sample), in buffered port:8);
        break;

No problems there, no crashes - code works (I guess).

However, still I cannot use it. Another XC safety feature disallows me to use flash_memory structure in code below (short version - whole code at https://github.com/alfanick/2-wheeler-h ... ication.xc):

Code: Select all

config_flash_port flash_memory = {
  PORT_SPI_MISO,
  PORT_SPI_SS,
  PORT_SPI_CLK,
  PORT_SPI_MOSI,
  XS1_CLKBLK_2
};

[[combinable]]
void balancer_communication(...) {

  in buffered port:8 * movable miso = &flash_memory.spiMISO;
  sensors.release_adc(move(miso));

  // ...

  miso = sensors.acquire_adc();
  config_open(flash_memory);
 
  // ...
}

// Note: config_flash_port is typedef to fl_SPIPorts from flashlib
//      config_open is wrapper around fl_connectToDevice


XC compiler hides flash_memory from the scope in line where flash_memory.spiMISO is assigned to pointer. So even that port is properly configured, I cannot use flash_memory structure... I cannot modify libflash because its API is "as is".

My dear XC experts, is there another way of doing what I tried to do?

Best wishes
Amadeusz
User avatar
davelacey
Experienced Member
Posts: 104
Joined: Fri Dec 11, 2009 8:29 pm

Postby davelacey » Mon Jul 14, 2014 2:53 pm

Hi,
It's hard in xC to dynamically move pointers to ports in structures at the moment. I think the best bet is to replace movable with unsafe in this case.

https://www.xmos.com/node/17653?page=25#unsafe-pointers

In this way, you can extract an unsafe pointer to the port out of the flash_memory structure and pass it to the other task.

Code: Select all

  in buffered port:8 * unsafe miso;
  unsafe {
    miso = (in buffered port:8 * unsafe) &flash_memory.spiMISO;
  }
  sensors.release_adc(miso);

  // ...

  miso = sensors.acquire_adc();
 

  config_open(flash_memory);
 
  // ...


Using unsafe means that your code is not guaranteed free of race conditions by construction (you have to just reason that your code is ok) but allows you more freedom for dynamic manipulation of data/resources.

Dave
User avatar
alfanick
Member
Posts: 12
Joined: Sat Jun 21, 2014 8:01 pm
Contact:

Postby alfanick » Mon Jul 14, 2014 3:53 pm

Thank you for answer.
I tried to use unsafe pointers already, I'm stuck on reconfigure_port if used. It requires using movable pointers and I cannot cast unsafe pointer to movable one, because casting pointers of resource types are forbidden...
I guess the answer is to use some assembler command which does what reconfigure_port does, bypassing movable pointer requirement. However, I'm no expert on Xmos assembly. :)

Amadeusz
User avatar
davelacey
Experienced Member
Posts: 104
Joined: Fri Dec 11, 2009 8:29 pm

Postby davelacey » Mon Jul 14, 2014 4:57 pm

alfanick wrote:Thank you for answer.
I tried to use unsafe pointers already, I'm stuck on reconfigure_port if used. It requires using movable pointers and I cannot cast unsafe pointer to movable one, because casting pointers of resource types are forbidden...
I guess the answer is to use some assembler command which does what reconfigure_port does, bypassing movable pointer requirement. However, I'm no expert on Xmos assembly. :)

Amadeusz


I think that would be quite hard. I was imagining you would change the sensor interface to take unsafe pointers as well.
User avatar
alfanick
Member
Posts: 12
Joined: Sat Jun 21, 2014 8:01 pm
Contact:

Postby alfanick » Mon Jul 14, 2014 5:01 pm

davelacey wrote:
alfanick wrote:Thank you for answer.
I tried to use unsafe pointers already, I'm stuck on reconfigure_port if used. It requires using movable pointers and I cannot cast unsafe pointer to movable one, because casting pointers of resource types are forbidden...
I guess the answer is to use some assembler command which does what reconfigure_port does, bypassing movable pointer requirement. However, I'm no expert on Xmos assembly. :)

Amadeusz


I think that would be quite hard. I was imagining you would change the sensor interface to take unsafe pointers as well.


Yep, I've made everything to use unsafe pointers - builtin XS1 macro reconfigure_port (which is alias to __reconfigure_port) fails to work on not movable pointers.
I have to use reconfigure_port to change port function from in (flash miso) to out (adc trigger) - communication acquires and releases adc port (as in https://github.com/alfanick/2-wheeler-h ... ion.xc#L35) through safety/sensors (as in https://github.com/alfanick/2-wheeler-h ... ety.xc#L79) which manages adc module (as in https://github.com/alfanick/startkit_ex ... dc.xc#L140).
I know it may seem bit complicated, but it makes code structure quite logical. Anyway, even if all the code for adc and flash would be moved to one file, the problem of movable pointers on structures or unsafe pointers and reconfigure_port will stay.
User avatar
davelacey
Experienced Member
Posts: 104
Joined: Fri Dec 11, 2009 8:29 pm

Postby davelacey » Mon Jul 14, 2014 6:50 pm

alfanick wrote:Yep, I've made everything to use unsafe pointers - builtin XS1 macro reconfigure_port (which is alias to __reconfigure_port) fails to work on not movable pointers.


Oops. I misread your last post, sorry. Reconfigure port is just for movable but you can get the same effect by casting an unsafe pointer and then using the set_port_use_on function which resets the port to a new mode. So these functions should do the trick:

Code: Select all

unsafe
in buffered port:8 * unsafe unsafe_reconfigure_to_buffered(in port * unsafe p)
{
  in buffered port:8 * unsafe p_reconf = (in buffered port:8 * unsafe) p;
  set_port_use_on(*p_reconf);
  return p_reconf;
}

unsafe
in port * unsafe unsafe_reconfigure_from_buffered(in buffered port:8  * unsafe p)
{
  in port * unsafe p_reconf = (in port * unsafe) p;
  set_port_use_on(*p_reconf);
  return p_reconf;
}
User avatar
alfanick
Member
Posts: 12
Joined: Sat Jun 21, 2014 8:01 pm
Contact:

Postby alfanick » Wed Jul 16, 2014 6:35 pm

Thank you Dave,
after all got it working with your code (and some refactoring within mine) :)

Amadeusz

Who is online

Users browsing this forum: No registered users and 9 guests