Page 2 of 2

Re: Setting the speed of GPIO ports on F10x

Posted: Thu Oct 22, 2015 11:48 am
by Aslund
Hello Giovanni

Sounds great. Definitely something we would consider.

I have one final problem with my program, in regards to my one pin I switch from input to output and back again.

With a multi-meter I can confirm that the pin is set LOW at the beginning of the thread.
When it switches to input the pin in HIGH, I expected it to be LOW as nothing drives the line. The pin is connected to a loose wire not connected anywhere.
When I take the wire and briefly connect it to ground it correctly recognize the input state to be LOW by sending a serial command.
This is followed by changing the port from input to output and set it to LOW. Here I measure no LOW but instead it is HIGH.

Did I miss anything in the process?

Regards
Sebastian

Code: Select all

static THD_FUNCTION(rc1Thread, arg)
{

  (void)arg;

  chRegSetThreadName("RC1 thread");

  msg_t rc1HighMsg = (msg_t)"LOW";

  palClearPad(GPIOA, GPIOA_RC1);
  chThdSleepMilliseconds(10000);
  palSetPadMode(GPIOA, GPIOA_RC1, PAL_MODE_INPUT);

  while (true) {

    if( palReadPad(GPIOA, GPIOA_RC1) == PAL_LOW )
    {
      chThdSleepMilliseconds(5000);
      chMtxLock(&bufferAccess);
      sdWrite(&SD1, (uint8_t*)rc1HighMsg, sizeof(rc1HighMsg));
      chMtxUnlock(&bufferAccess);
      palSetPadMode(GPIOC, GPIOA_RC1, PAL_MODE_OUTPUT_PUSHPULL );
      palClearPad(GPIOA, GPIOA_RC1);
      chThdSleepMilliseconds(10000);
      palSetPad(GPIOA, GPIOA_RC1);
      palSetPadMode(GPIOA, GPIOA_RC1, PAL_MODE_INPUT);
    }

    chThdSleepMilliseconds(100);

  }
}

Re: Setting the speed of GPIO ports on F10x

Posted: Thu Oct 22, 2015 12:20 pm
by Giovanni
Hi,

You are setting it to high but also setting it as input so the pin is no more driven. You are probably measuring a floating pin at that point.

Is there an external pull up? if so probably you need to use an open drain output there so you would not need to switch mode any more.

Giovanni

Re: Setting the speed of GPIO ports on F10x

Posted: Thu Oct 22, 2015 4:13 pm
by Aslund
Hello Giovanni

A open drain output did the trick, sort of. My problem now is the sleeping times. Somehow I can not make it go lower than 2 ms.
If I remove the sleeps then it turns into pure noise around 0V.

Code: Select all

  while (true) {
    palClearPad(GPIOA, GPIOA_RC1);
    chThdSleepMicroseconds(20);
    palSetPad(GPIOA, GPIOA_RC1);
    chThdSleepMicroseconds(10);
  }


Image

Re: Setting the speed of GPIO ports on F10x

Posted: Thu Oct 22, 2015 4:23 pm
by Giovanni
Hi,

That depends on the system tick resolution in chconf.h. If you are using tickless mode (the default) then the ST frequency can be set even to 1..4 MHz. It is better to keep it as low as possible compatibly with the required resolution.

Giovanni

Re: Setting the speed of GPIO ports on F10x

Posted: Mon Oct 26, 2015 12:28 pm
by Aslund
Hello Giovanni

Thanks for the help so far. I am almost finished but after changing the timer changes I cant make a long timeout. Is it due to the resolution?

My code is:

Code: Select all

static THD_FUNCTION(rc1Thread, arg)
{

  (void)arg;

  chRegSetThreadName("RC1 thread");
  //systime_t rc1Rate;

  palClearPad(GPIOA, GPIOA_RC1);
  chThdSleepMicroseconds(40);
  palSetPad(GPIOA, GPIOA_RC1);
  chThdSleepMicroseconds(40);

  while (true) {

    if( palReadPad(GPIOA, GPIOA_RC1) == PAL_LOW )
    {
      spiAcquireBus(&SPID1);
      spiStart(&SPID1, &spiCfg);
      spiSelect(&SPID1);
      spiExchange(&SPID1, sizeof(txBuffer),
                  txBuffer, rxBuffer);
      sdWrite(&SD1, rxBuffer, sizeof(rxBuffer));
      spiUnselect(&SPID1);
      spiReleaseBus(&SPID1);
      chThdSleepMilliseconds(1000);
      palClearPad(GPIOA, GPIOA_RC1);
      chThdSleepMicroseconds(40);
      palSetPad(GPIOA, GPIOA_RC1);
      chThdSleepMicroseconds(40);
    }
    else
    {
      chThdSleepMicroseconds(1000);
    }
  }
}


And my chconf.h is:

Code: Select all

/**
 * @brief   System time counter resolution.
 * @note    Allowed values are 16 or 32 bits.
 */
#define CH_CFG_ST_RESOLUTION                16

/**
 * @brief   System tick frequency.
 * @details Frequency of the system timer that drives the system ticks. This
 *          setting also defines the system tick time unit.
 */
#define CH_CFG_ST_FREQUENCY                 1000000

/**
 * @brief   Time delta constant for the tick-less mode.
 * @note    If this value is zero then the system uses the classic
 *          periodic tick. This value represents the minimum number
 *          of ticks that is safe to specify in a timeout directive.
 *          The value one is not valid, timeouts are rounded up to
 *          this value.
 */
#define CH_CFG_ST_TIMEDELTA                 2


I cant change to 32-bit mode in tickless since it says that TIM2 does not support 32-bit mode.
I have tried to disable tickless mode and set the resolution to 32-bit but then the program does not run properly.

My chconf.h file:

Code: Select all

/**
 * @brief   System time counter resolution.
 * @note    Allowed values are 16 or 32 bits.
 */
#define CH_CFG_ST_RESOLUTION                32

/**
 * @brief   System tick frequency.
 * @details Frequency of the system timer that drives the system ticks. This
 *          setting also defines the system tick time unit.
 */
#define CH_CFG_ST_FREQUENCY                 1000000

/**
 * @brief   Time delta constant for the tick-less mode.
 * @note    If this value is zero then the system uses the classic
 *          periodic tick. This value represents the minimum number
 *          of ticks that is safe to specify in a timeout directive.
 *          The value one is not valid, timeouts are rounded up to
 *          this value.
 */
#define CH_CFG_ST_TIMEDELTA                 0


When I run this program:

Code: Select all

  while(1)
  {
    palClearPad(GPIOA, GPIOA_RC1);
    chThdSleepMicroseconds(50);
    palSetPad(GPIOA, GPIOA_RC1);
    chThdSleepMicroseconds(100);
  }


Then my oscilloscope gives the following response:
Image

Regards
Sebastian

Re: Setting the speed of GPIO ports on F10x

Posted: Mon Oct 26, 2015 1:27 pm
by Giovanni
Hi,

The problem is that F1 does not have 32 bits timers, newer STM32s have that. You have to balance resolution with tick frequency.

Note that you make your own sleep functions that calls chThdSleep() repeatedly and have arbitrary large intervals, it would not be fully tickless but interrupts count would still be very low.

Giovanni

Re: Setting the speed of GPIO ports on F10x

Posted: Mon Oct 26, 2015 5:28 pm
by Aslund
Hello Giovanni

Seems like the easiest thing to do.
But is it not possible to run without the tickless mode?

Even with 16 bit resolution I can not run without the tickless mode.

Code: Select all

/**
 * @brief   System time counter resolution.
 * @note    Allowed values are 16 or 32 bits.
 */
#define CH_CFG_ST_RESOLUTION                16

/**
 * @brief   System tick frequency.
 * @details Frequency of the system timer that drives the system ticks. This
 *          setting also defines the system tick time unit.
 */
#define CH_CFG_ST_FREQUENCY                 1000000

/**
 * @brief   Time delta constant for the tick-less mode.
 * @note    If this value is zero then the system uses the classic
 *          periodic tick. This value represents the minimum number
 *          of ticks that is safe to specify in a timeout directive.
 *          The value one is not valid, timeouts are rounded up to
 *          this value.
 */
#define CH_CFG_ST_TIMEDELTA                 0


With this configuration I get the same response on my oscilloscope as in my previous post.
I am therefore thinking that my response is not tied to the resolution of the timer ( except in tickless mode ) but to some fault when running without the tickless mode.

Regards
Sebastian

Re: Setting the speed of GPIO ports on F10x

Posted: Mon Oct 26, 2015 7:00 pm
by Giovanni
Of course you can, set CH_CFG_ST_TIMEDELTA to zero and put resolution to 32 bits, of course this means that the possible frequency is much lower, 1000Hz recommended, 10kHz as maximum.

Giovanni