GrumpyOldPizza / ArduinoCore-stm32l0

Arduino Core for STM32L0
125 stars 67 forks source link

Change i2c pins or Wire1 available ? #14

Closed battosai30 closed 6 years ago

battosai30 commented 6 years ago

Hi,

First thanks for your Arduino Core and libraries, it's very powerful !!

I'm trying to play with STM32L082 but in LQFP32 package, which has not PB8 and PB9 for i2c. But as PB7 and PB6 are available, would it be difficult to implement Wire1 on this pin ? Or switch Wire to this pins ? Based on what I understood, almost everything seems ready to do it, it just seems to miss pins definition, but as it's my first time playing with STM32 I don't know if it would be enough ...

Thanks

GrumpyOldPizza commented 6 years ago

Actually this is pretty trivial.

What you need to do is to simply write a new variant. Take a Grasshopper one as an example (and please download the github first, because I just re-arranged the variants).

In variant.cpp there is a g_WireParams, which assigns the pins to Wire. So you'd just put in PB6 & PB7 where appropriate, and perhaps also change the rest of the pins, as you have less.

Are you designing a LoRa board ?

battosai30 commented 6 years ago

Hi,

Thanks for your explanation. Is it the same solution for SPI ? On LQFP32 SPI2 is not accessible so I have to switch to SPI1

I'm designing two boards which are parts of an open source ecosystem I'm building: one based on Murata CMWX1ZZABZ (for LoRa obviously) + SIM33ELA (GNSS) and one with STM32L082 + SIM868 for GSM & GNSS.

When I found your core I found the solution I expected since a long time as I has was looking for low power, memory, RTC and USB capacity so until now, my designs were based on MSP430F5529 and MSP430FR5969+CP2102 (programmed on Energia) but Texas is not as active as ST and it missed some high level library to allow developpement like you did here.

So be sure I will follow your work with attention and I will push my variant on your git as I'm sure it's working well ;)

GrumpyOldPizza commented 6 years ago

SPI1 vs. SPI2 is the same idea, except that then you need to mess with the DMA assignments. STM32L0 really wants DMA on the SPI RX path. DMA_CHANNEL_1 is for ADC, DMA_CHANNEL_2 for DAC. You need one for I2C RX, and two for your primary UART ... If you connect a GNSS, you'd want to have DMA on the UART RX path.

There is a CMWX1ZZABZ + GNSS module already, https://www.tindie.com/products/TleraCorp/cricket-lorawangnss-asset-tracker/. I am not the biggest fan on SIM33ELA (well, MT3333 that is ... there is also Quectel's L96). In any case, connect PPS ... On thing to try (which we had not done) is to use I2C instead of UART.

battosai30 commented 6 years ago

Yes I saw this module, but my ecosystem has it own rules ;)

Why are you not fan on SIM33ELA ? Looking at the specs which are the same, I think it's the same GNSS module in SIM868. I worked with this this modules and I was very satisfied (EASY function is really efficient).

Back to SPI : without talking about SPI1 & SPI2, can you just confirm me that I can use several UARTs + I2C + SPI together ?

Regards

GrumpyOldPizza commented 6 years ago

SIM33ELA. MT3333 has big issues with the proper altitude. Also there is no vertical speed (due to NMEA only). L96 has some additional NMEA sentences to fix that. With EASY, I have no experience. Any pointers to a SIM33ELA breakout to test power ?

BTW, I have there this GNSS class ... The underlying code can deal with SIM33ELA (if I'd spend some time on it again; not sure whether I have not ripped out too much there).

UART + I2C + SPI will work together. You have to balance DMAs though. You want a RX DMA on each UART, on I2C. SPI RX is faster with DMA (no FIFO for SPI ...).

battosai30 commented 6 years ago

No module for SIM33ELA :s they annonce 12µA for RAM retention, which is pretty high for doing that, but 14$ and very tiny ... ublox module are much more expensive. But as I have to check power consumption and possible current leaks, I will test it today or tomorrow, I will tell you chat I measured ;) I tested this module with classic tinyGPS library and it worked like a charm.

How do I select (or deselect) DMA usage ?

battosai30 commented 6 years ago

Hi, sorry I'm late !

Ok so SIM33ELA consumption seems to follow the datasheet (I'm not 100% sure because I'm not sure of my "zero" point but I'm sure it's between 10 and 20µA). The trick to know is that if you enter backup mode, you have to generate a low to high signal on FORCE_ON pin to wake it up. EINT pin seems to drive the stand-by mode but in this mode you can wake it up by uart.

battosai30 commented 6 years ago

Hi, Finally received my batch with STM32L082 LQFN32 + SIM868. So a lot of things are OK for now (USB, Serial2 ...). I succesfully added some I/Os which are not included in any variants (I'm not used with STM32 so I like Mickey in Fantasia ... :) but thanks to your work and high level libraries, it's pretty easy to understand).

Now back to my first problem : change Wire pins. I modified the code but nothing comes out (checked with logic analyser) and the system hangs up on Wire.endTransmission(), exactly here :

Wire.cpp sendTransmission() :

    while (transaction.status == STM32L0_I2C_STATUS_BUSY) {
    armv6m_core_wait();
    }

Here my modifications :

variant.cpp

/*extern const stm32l0_i2c_params_t g_WireParams = {
    STM32L0_I2C_INSTANCE_I2C1,
    STM32L0_I2C_IRQ_PRIORITY,
    STM32L0_DMA_CHANNEL_DMA1_CH7_I2C1_RX,
    STM32L0_DMA_CHANNEL_NONE,
    {
        STM32L0_GPIO_PIN_PB8_I2C1_SCL,
        STM32L0_GPIO_PIN_PB9_I2C1_SDA,
    },
};*/

extern const stm32l0_i2c_params_t g_WireParams = {
    STM32L0_I2C_INSTANCE_I2C1,
    STM32L0_I2C_IRQ_PRIORITY,
    STM32L0_DMA_CHANNEL_DMA1_CH7_I2C1_RX,
    STM32L0_DMA_CHANNEL_NONE,
    {
        STM32L0_GPIO_PIN_PB6_I2C1_SCL,
        STM32L0_GPIO_PIN_PB7_I2C1_SDA,
    },
};

variant.h :

/*
#define PIN_WIRE_SDA         (14u)
#define PIN_WIRE_SCL         (15u)
*/

#define PIN_WIRE_SDA         (4u)
#define PIN_WIRE_SCL         (3u)

Any ideas ?

Regards

battosai30 commented 6 years ago

Ok I finally found the problem : I'm just stupid !! When I created my variant I obsiously created it in board.txt but I simply forgot to edit the variant variable to point to the right variant folder. So I was editing my variant.h but it was still loading the variant.h file from Grasshopper .... With the right config it just work like a charm with the modifications from my previous post.

1 day lost on this mistake ... But at least I much more understand your framework and STM32 family !

Thanks for your help and your work anyway ;)