• Welcome to Andy's Workshop Forums. Please login or sign up.
 
May 23, 2024, 06:59:49 am

News:

SMF - Just Installed!


Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - mhel

1
stm32plus C++ library / Re: stm32f103C8 & timers
February 26, 2017, 02:07:03 pm
Hello all,

I'm revisiting this post just to make an update. I have managed to get a working input capture using a pair of timer channels as required capturing pwm input
instead of just a regular input capture. It's much simpler but limited to channel pairs. I use this to capture pwm from an RC receiver. I'm posting it here so googlers may find it.


#ifndef PWMINPUTCAPTURE_H_
#define PWMINPUTCAPTURE_H_

#include "config/stm32plus.h"
#include "config/timer.h"
#include "config/timing.h"

using namespace stm32plus;

/**
* PWM input capture mode on Timers 4 & 3.
*
* PWM input capture uses Timer channel pairs 1 & 2 to capture the signal
* on a single input . Duty cycle is captured on channel 1 and pulse width
* is captured on channel 2.
*
* Timer4 Channel1 is on PB6
* Timer3 Channel1 in on PA6
*
*/

class PWMInputCapture {

  protected:

    /**
     * Declare a type for our input timer.
     */
        typedef TimerChannel1Feature<            // we're going to use channel 1
                TimerChannelICRisingEdgeFeature, // we'll capture rising edge
                TimerChannelICDirectTiFeature,   // direct connection
                TimerChannelICPreScaler1Feature, // prescaler of 1
                TimerChannelICFilterFeature<0>   // no filter
        > ch1Features;
        typedef TimerChannel2Feature<            // we're going to use channel 2
                TimerChanneICFallingEdgeFeature, // we'll capture falling edge
                TimerChannelICDirectTiFeature,   // direct connection
                TimerChannelICPreScaler1Feature, // prescaler of 1
                TimerChannelICFilterFeature<0>   // no filter
        > ch2Features;

        typedef Timer4<
            Timer4InternalClockFeature,         // we'll need this for the frequency calculation
            ch1Features,
            ch2Features,
            Timer4InterruptFeature,           // we want to use interrupts
            Timer4GpioFeature<                // we want to read something from GPIO
              TIMER_REMAP_NONE,               // the GPIO input will not be remapped
              TIM4_CH1_IN                     // we will read channel 1 from GPIO PB6
            >,
            TimerSlaveFeature<
                TIM_TS_TI1FP1,
                TIM_SlaveMode_Reset
                >,
            TimerResetMasterFeature
          > TimerInput1;

        typedef Timer3<
            Timer3InternalClockFeature,         // we'll need this for the frequency calculation
            ch1Features,
            ch2Features,
            Timer3InterruptFeature,           // we want to use interrupts
            Timer3GpioFeature<                // we want to read something from GPIO
              TIMER_REMAP_NONE,               // the GPIO input will not be remapped
              TIM3_CH1_IN                     // we will read channel 1 from GPIO PA6
            >,
            TimerSlaveFeature<
                TIM_TS_TI1FP1,
                TIM_SlaveMode_Reset
                >,
            TimerResetMasterFeature
          > TimerInput2;

    /*
     * The timer needs to be a class member so we can see it from the callback
     */

    TimerInput1 *_TimerInput1;
    TimerInput2 *_TimerInput2;



  public:

    /* These does not have to be an array if only interested in one of the captured value */
    volatile uint16_t _steerCapture[2];
    volatile uint16_t _throttleCapture[2];

    void initialize() {

        /*
         * Declare a new instance of the input capture timer.
         */

        _TimerInput1=new TimerInput1;
        _TimerInput2=new TimerInput2;

        /* Timer4 runs at 36Mhz on APB1
         * This sets up a free running timer that ticks at 1MHz
         */

        _TimerInput1->setTimeBaseByFrequency(1000000, 0xFFFF, TIM_CounterMode_Up);
        _TimerInput2->setTimeBaseByFrequency(1000000, 0xFFFF, TIM_CounterMode_Up);

        /*
         * Insert our subscribtion of the capture interrupts generated by the input timer
         */

        _TimerInput1->TimerInterruptEventSender.insertSubscriber(
            TimerInterruptEventSourceSlot::bind(this,&PWMInputCapture::onSteerInterrupt)
          );
        _TimerInput2->TimerInterruptEventSender.insertSubscriber(
            TimerInterruptEventSourceSlot::bind(this,&PWMInputCapture::onThrottleInterrupt)
          );


        /* Select the TIM4 Input Trigger: TI1FP1 */
//        TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1);
        _TimerInput1->enableSlaveFeature();

        /* Select the slave Mode: Reset Mode */
//        TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
//        TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);
        _TimerInput1->enableMasterFeature();

        /* Select the TIM3 Input Trigger: TI1FP1 */
//        TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
        _TimerInput2->enableSlaveFeature();

        /* Select the slave Mode: Reset Mode */
//        TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
//        TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
        _TimerInput1->enableMasterFeature();

        /*
         * Enable channel 1 interrupts on Timer inputs.
         */

        _TimerInput1->enableInterrupts(TIM_IT_CC1);
        _TimerInput2->enableInterrupts(TIM_IT_CC1);

        /*
         * Enable timers to start the action
         */
        _TimerInput1->enablePeripheral();
        _TimerInput2->enablePeripheral();

    } // Iniatilize


    /*
     * Interrupt callback function. This is called when the input capture
     * event is fired
     */
        void onSteerInterrupt(TimerEventType tet, uint8_t /* timerNumber */) {
            if (tet == TimerEventType::EVENT_COMPARE1) {

                // store the current capture time
//                _steerCapture[0] = TIM_GetCapture1(TIM4); // Period
//                _steerCapture[1] = TIM_GetCapture2(TIM4); // Duty/Width
//                _steerCapture[0] = _TimerInput1->ch1Features::getCapture();
                _steerCapture[1] = _TimerInput1->ch2Features::getCapture();
            }
        } // onInterrupt
    /*
     * Interrupt callback function. This is called when the input capture
     * event is fired
     */
        void onThrottleInterrupt(TimerEventType tet, uint8_t /* timerNumber */) {
            if (tet == TimerEventType::EVENT_COMPARE1) {

                // store the current capture time
//                _throttleCapture[0] = TIM_GetCapture1(TIM3); // Period
//                _throttleCapture[1] = TIM_GetCapture2(TIM3); // Duty/Width
//                  _throttleCapture[0] = _TimerInput2->ch1Features::getCapture();
                  _throttleCapture[1] = _TimerInput2->ch2Features::getCapture();
            }
        } // onInterrupt
}; //

#endif /* PWMInputCapture_H_ */
2
stm32plus C++ library / STM32F446
December 04, 2016, 10:16:58 am
Hi,

So I got me a nucleo board with stm32f446RE and I didn't realize
it's not supported by stm32plus yet. How would I go about adding support
for it? stm32plus seems to be using stdperipheral library v1.4 and support for
f446 is only available with the new 1.8.

thanks.
3
Hi All,

So I managed to revive my discovery-board. I wanted to buy a new one but it gotten expensive.
I remember buying mine for about $20CAD, and all I ever did was blink a LED.I just bought the chip and winged it. It's not easy but a chipquick helps a lot, as I didn't want
to take a chance damaging the board like the last time I made a similar attempt that ended up me throwing the board out of disappointment  :-[ (It's kind of an expensive hobby).

I tried using the stm32f103 and did not realize I couldn't just port the codes from f4. And it would take me more time to figure out how I to utilize
the EXTI instead of the input capture. I probably would try to use a lower series like the F303 , because the F4 is way overkill for my purpose.
I've read some smarties did it on an AVR and PIC.

Anyhow, I'd like to thank Andy again for the libraries and the examples. I tried to do it in C because a lot of info I found on other forums uses it,
but I keep coming back to stm32plus,I even tried stm32duino. Even though I'm still learning c++ with very little knowledge of C (which is kind of obvious with what I've posted so far).


Below is what I've come up with, well it's a Frankentstein's version of what I've gathered. I've learnt about two types of controlling h-bridges.
One is called locked antiphase (google can help here) and the other is sign magnitude, where basically one needs a pin for PWM and another for Direction,
where lock antiphase uses a single PWM pin. I've tried both because my h-bridge supports it. A Cytron MD10C. I like  the locked antiphase because it drives smooth, but I'm afraid of the runaway motor in case of crash, I settled for the sign magnitude.
The downside is, changing direction causes jerks, and I've read some other complicated tricks to solve it and it's out of reach of my current understanding.
If anyone knows how I can ease in and ease out when changing direction that would be great. The code below works, my logic is messy but it's functional.
Some newbies like me would still probably appreciate it  ::)
The attached is based on the input capture example I didn't change all the comments. (code reach the maximum 2000 characters)

4
stm32plus C++ library / Re: stm32f103C8 & timers
June 14, 2016, 06:45:42 pm
Hi All,
After a lot of searching, I just found out that the input capture on both edges is not possible with this chip.
I may have to change strategy, or get another chip that can do both edge so as to ease the learning process.
5
stm32plus C++ library / Re: stm32f103C8 & timers
June 11, 2016, 11:50:38 am
Ok this is somewhat odd I think.

This setup somehow enables CC3S instead of CC4S.

        /**
         * Declare a type for our input timer.
         */
        typedef TimerChannel1Feature<
                TimerChannelICBothEdgesFeature,
                TimerChannelICDirectTiFeature,
//            TimerChannelICPreScaler1Feature,
                TimerChannelICFilterFeature<0>
        > ch1Features;

        typedef TimerChannel2Feature<
                TimerChannelICBothEdgesFeature,
                TimerChannelICDirectTiFeature,
//            TimerChannelICPreScaler1Feature,
                TimerChannelICFilterFeature<0>
        > ch2Features;

        typedef TimerChannel3Feature<
                TimerChannelICBothEdgesFeature,
                TimerChannelICDirectTiFeature,
//            TimerChannelICPreScaler1Feature,
                TimerChannelICFilterFeature<0>
        > ch3Features;

        typedef Timer4<
                Timer4InternalClockFeature, // we'll need this for the frequency calculation
                ch1Features,
                ch2Features,
                ch3Features,
                Timer4InterruptFeature, // we want to use interrupts
                Timer4GpioFeature<    // we want to read something from GPIO
                        TIMER_REMAP_NONE, // the GPIO input wil not be re-mapped
                        TIM4_CH1_IN, // we will read channel 1 from GPIO PB6
                        TIM4_CH2_IN,              // Channel 2 on GPIO PB7
                        TIM4_CH3_IN              // Channel 2 on GPIO PB8
                >
        > MyInputTimer;


Maybe the mistake is staring me in the face and I couldn't see it.
6
stm32plus C++ library / Re: stm32f103C8 & timers
June 11, 2016, 11:27:46 am
Reading a bit more, I just found out the Timers used as PWM relies on the ARR for frequency,
so it's not really smart testing my inputcapture clock using the same principle. :-[
7
stm32plus C++ library / Re: stm32f103C8 & timers
June 11, 2016, 07:49:38 am
(I was typing and it timed out, I wasn't able to login until browser restart clearing cookies didn't fix it)

I kind of figured out the clocking scheme by using the clock configuration from cubemx.
[img=http://s33.postimg.org/jpt561xej/Screenshot_06112016_08_40_48_AM.jpg]

This is my setup

            Timer3<
                    Timer3InternalClockFeature, // clocked from the internal clock
                    TimerChannel1Feature<>,     // we're going to use channel 1
                    TimerChannel2Feature<>,     // we're going to use channel 2
                    Timer3GpioFeature<          // we want to output something to GPIO
                            TIMER_REMAP_NONE,   // the GPIO output will not (cannot for this timer) be remapped
                            TIM3_CH1_OUT,       // we will output channel 1 to GPIO (PA6)
                            TIM3_CH2_OUT        // we will output channel 1 to GPIO (PA7)
                    >
            > outputTimer;

...snipped timebase initialization here....

            outputTimer.TimerChannel1Feature<>::initCompareForPwmOutput(50);
            outputTimer.TimerChannel2Feature<>::initCompareForPwmOutput(50);


This setup however produce the correct frequency:

            outputTimer.setTimeBaseByFrequency(10000000, 10 - 1);

But if I used this initialization I only have 10 counts to play with in the ARR when I capture.
(Note that I'm only testing this setup to check the frequency, I'm actually using the timer4 for the input capture.)
From what I gather I need a free running timer that ticks at 1us, so the captured value of 1000 would equal to 1ms which
is ideal for ease of calculation with the servo pulses of 1 to 2 milliseconds.

So the prescaler of 71 should scale my timer clock to 1Mhz, similarly or exactly the same as the stm32f4 with a prescaler of 167.
What I can't figure out yet is the ARR. Why is it with the F4 I can use the maximum size 65535 for counting, but I can't with the F103?

I should mention that all other stuff (that I needed) seems to be working as expected. I have usart1 working, the capture interrupt.
I could capture but  the result is not what is expected, that's why I believed that my clocking setup might be wrong.

Thanks.


8
Yeah, I paid a premium for mine if I compare it to those less than $5 board, but I got it in 3 days. The chip itself is about $9CAD at Digikey.
I was afraid if I order from far East it will take 2 weeks minimum and my vacation time will be over. And there's looming postal worker strike here.
9
stm32plus C++ library / stm32f103C8 & timers
June 10, 2016, 08:14:10 am
Hi All,

So I got this medium density stm32f103 72Mhz, and I managed to get something compiled. I used Debug_f1hd_72_8 build, but changed the memory settings
as mentioned in the readme of stm32++. There's a directory f1md but no build configuration for it, it seems identical to the content of f1hd_72_8

I'm using timer3 and timer4 (both 16bit) which according to the clock tree from the docs is connected to APB1, if I'm not mistaken it should be using 36MHz since the APB1 is divided by 1.
Why is the output of this:
timer3.getClock()
is 72MHz?

I setup my input timer the way I did with stm32f4-discovery board.

            _myInputTimer->initialiseTimeBase(
                    0xFFFF,             // Auto-reload
                    72-1,             // Prescaler
                    0,                  // Division
                    TIM_CounterMode_Up  // Counting up
            );

but no go.

I set it up to output instead and measure (with my newly scrounge oscope).

            outputTimer.initialiseTimeBase(
                    0xFFFF,             // Auto-reload
                    72-1,             // Prescaler
                    0,                  // Division
                    TIM_CounterMode_Up  // Counting up
                    );


Now I'm quite new on using an oscilloscope but the magic button :D that says measure frequency says I'm getting 15Hz

It's more likely that I'm misunderstanding the timer setup hence this post.  What settings should I be looking for?

EDIT1:
So I played with SMT32CubeMX, and found out that with PCLK1 is 36MHz but the Timer clock is 72MHz with x2 multiplier as configured in System.c
Still not sure why on stm32f4 the same setup works as expected, but not on this stm32f103.
10
So my discovery board is busted. I got me a couple of these stm32f103 since stm32f4 is overkill for what I want to do, and I don't want to wait long so I got it sort of locally.
I'm having timer trouble. I'll start a new thread for it.
11
Thanks,
I may have busted my input pins, the board freezes everytime I turn the RC receiver on, I must have shorted something when I hook up the hbridge.
I'll post back if it still works if I remap the pins.
Thanks again.
12
Thanks for the reply.

So I already have the duty cycle captured between rising and falling edges.
What I can't figure out yet (with my limited understanding) is how can I turn
the pulse width to value between 0:100 so could pass it to setDutyCyle().
Knowing that my 100% is 2300 and my 0% is 700.
( I almost think that it should be a simple math, but I can't even pretend I know what I'm doing :-) )
13
Hi All,

I made some more progress :-)
It's still has a glitch, it might be an overflow or likely a mistake.
Now how do I convert the captured pulse width to pwm duty cycle to drive my hbridge?

I'm posting it here for the google warriors like me.

class TimerInputCaptureTest {

  protected:

    /**
     * Declare a type for our input timer.
         */
        typedef TimerChannel1Feature<
                TimerChannelICBothEdgesFeature,
                TimerChannelICDirectTiFeature,
//            TimerChannelICPreScaler1Feature,
                TimerChannelICFilterFeature<0>
        > T1Features;

        typedef TimerChannel2Feature<
                TimerChannelICBothEdgesFeature,
                TimerChannelICDirectTiFeature,
//            TimerChannelICPreScaler1Feature,
                TimerChannelICFilterFeature<0>
        > T2Features;

       typedef Timer3<
               Timer3InternalClockFeature, // we'll need this for the frequency calculation
               T1Features,
               T2Features,
               Timer3InterruptFeature, // we want to use interrupts
               Timer3GpioFeature<    // we want to read something from GPIO
                  TIMER_REMAP_FULL, // the GPIO input will be re-mapped
                  TIM3_CH1_IN, // we will read channel 1 from GPIO PC6
                  TIM3_CH2_IN              // Channel 2 on GPIO PC7
                      >
        > MyInputTimer;

       /*
        * The timer needs to be a class member so we can see it from the callback
        */

       MyInputTimer *_myInputTimer;


    volatile uint8_t _indexCH1;
    volatile uint8_t _indexCH2;
    volatile uint32_t _captureCH1[2];
    volatile uint32_t _captureCH2[2];
    volatile uint32_t _ch1Out;
    volatile uint32_t _ch2Out;
    volatile uint32_t _duty1;
    volatile uint32_t _duty2;


    GpioE<DefaultDigitalOutputFeature<7> > LED;
  public:

    void run() {

      /*
       * Declare a USART1 object. Note that an alternative Usart1_Remap object is available
       * if your application demands that you use the alternate pins for USART1
       */

//      Usart1<> usart1(57600);
        Usart2_Remap1<> usart2(9600);

      /*
       * We'll use an output stream for sending to the port instead of using the
       * send(uint8_t) method on the usart object
       */

      UsartPollingOutputStream outputStream(usart2);

      /*
       * We'll use Timer 1 to generate a PWM signal on its channel 1.
       * The signal will be output on PA1
       */


      Timer1<
        Timer1InternalClockFeature,     // clocked from the internal clock
        TimerChannel1Feature<>,         // we're going to use channel 1
        Timer1GpioFeature<              // we want to output something to GPIO
          TIMER_REMAP_FULL,             // the GPIO output will not (cannot for this timer) be remapped
          TIM1_CH1_OUT                  // we will output channel 1 to GPIO (PA1)
        >
      > outputTimer;

      /*
       * Set the output timer to 1MHz with a reload frequency of 20Khz (1MHz/50).
       */


      outputTimer.setTimeBaseByFrequency(1000000,50-1);

      /* Timer runs at 168Mhz with reload frequency of 20Khz */
      // (((SystemCoreClock / 1000000) / 2) - 1)

      /*
       * Initialise the output channel for PWM output with a duty cycle of 50%. This will
       * give us a nice square wave for the input capture channel to sample.
       */

      outputTimer.initCompareForPwmOutput(50);

      /*
       * Declare a new instance of the input capture timer.
       */

      _myInputTimer=new MyInputTimer;


//      _myInputTimer->setTimeBaseByFrequency(4000000,4-1);

      /* Timer3 runs at 84Mhz on APB1
       * This sets up a free running timer that ticks at 1MHz
       */

//      (uint16_t) (((SystemCoreClock / 1000000) / 2) - 1); // Shooting for 1 MHz, (1us)
        _myInputTimer->initialiseTimeBase(0xFFFF,                 // Auto-reload
                                            84-1,                 // Prescaler
                                            0,                    // Division
                                            TIM_CounterMode_Up    // Counting up
                                           );

     /*
       * Insert our subscribtion of the capture interrupts generated by the input timer
       */

      _myInputTimer->TimerInterruptEventSender.insertSubscriber(
          TimerInterruptEventSourceSlot::bind(this,&TimerInputCaptureTest::onInterrupt)
        );


      /*
       * Reset the variables used to hold the state
       */

      _indexCH1=0;
      _indexCH2=0;
//      _capturingNextFrequency=true;


      _captureCH1[0] = 0;
      _captureCH2[1] = 0;
      _ch1Out = 0;
      _ch2Out = 0;
      _duty1 = 0;
      _duty2 = 0;

      /*
       * Enable channel 4 interrupts on Timer 3.
       */

            _myInputTimer->clearPendingInterruptsFlag(0xFF);
            _myInputTimer->enableInterrupts(TIM_IT_CC1 | TIM_IT_CC2);


      /*
       * Enable both timers to start the action
       */

      outputTimer.enablePeripheral();
      _myInputTimer->enablePeripheral();


            for (;;) {

                char buf1[15];

                LED[7].reset();

                if ( (_captureCH1[1] - _captureCH1[0]) > 700) {

                    if ( (_captureCH1[1] - _captureCH1[0]) < 2300)
                    _ch1Out = _captureCH1[1] - _captureCH1[0];

                }
                    _captureCH1[0] = _captureCH1[1];

                if ((_captureCH2[1] - _captureCH2[0]) > 700) {

                    if ( (_captureCH2[1] - _captureCH2[0]) < 2300)
                    _ch2Out = _captureCH2[1] - _captureCH2[0];

                }
                     _captureCH2[0] = _captureCH2[1];

                StringUtil::modp_uitoa10(_ch1Out, buf1);
                outputStream << buf1 << " Ch1Out ";
                StringUtil::modp_uitoa10(_ch2Out, buf1);
                outputStream << buf1 << " Ch2Out\r\n";

                MillisecondTimer::delay(500);
                LED[7].set();

            }
    }


    /*
     * Interrupt callback function. This is called when the input capture
     * event is fired
     */

        void onInterrupt(TimerEventType tet, uint8_t /* timerNumber */) {


            if (tet == TimerEventType::EVENT_COMPARE1) {

                _captureCH1[_indexCH1] = _myInputTimer->T1Features::getCapture();

                if (_indexCH1++ == 1) {

                    _indexCH1 = 0;
                }

            }

            if (tet == TimerEventType::EVENT_COMPARE2) {

                _captureCH2[_indexCH2] = _myInputTimer->T2Features::getCapture();

                if (_indexCH2++ == 1) {

                    _indexCH2 = 0;
                }
            }
//            if (tet == TimerEventType::EVENT_COMPARE3) {
//
//            }
        }
};


Edit1: Fixed the glitch by clamping the capture...courtesy of google ofcourse...well I'm a DuckDuckGo user...so credit where credit is due. Thanks DuckDuckGo :-)
(Still needs help converting the capture to PWM out.)
14
I'm making progress...sort of. I can't seem to clear timer interrupt. It fires but it doesn't get cleared.
At-least that's what the gnu-arm register plugin says.
I'm calling this at the start of initialization before enabling the timer just to see if the flags are cleared, but it doesn't clear all.
CC1F,CC10F remains.

_myInputTimer->clearPendingInterruptsFlag(0xFF);


15
Hi All,

I'm trying to capture PWM signal from an RC servo receiver  but I'm having a hard time configuring the timer for input.
I change the example to use Timer3 CH1 on Port C6. At the moment I'm just trying to capture 1 channel but will be using 3 onced I get one running.

    typedef Timer3<
        Timer3InternalClockFeature,         // we'll need this for the frequency calculation
//        TimerInternalTriggerClockFeature<TIM_TS_TI1FP1>,
        TimerChannel1Feature<               // we're going to use channel 1
            TimerChannelICBothEdgesFeature,    // both edge trigger
            TimerChannelICDirectTiFeature,    // direct connection
            TimerChannelICPreScaler1Feature,  // prescaler of 1
            TimerChannelICFilterFeature<0>    // no filter
        >,
        Timer3InterruptFeature,           // we want to use interrupts
        Timer3GpioFeature<                // we want to read something from GPIO
          TIMER_REMAP_FULL,               // the GPIO input will be re-mapped
          TIM3_CH1_IN                     // we will read channel 1 from GPIO PC6
        >
      >MyInputTimer;


Some other examples I found suggests that I should set these:

  /* Select the TIM3 Input Trigger: TI1FP1 */
  TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

What am I missing with the timer configuration?
Better yet, if anyone has an example of capturing servo pwm from an RC receiver
it woulbe be greatly appreciated.

edit:
Forgot to mention I'm using the current lib from git.