hubmartin / WS2812B_STM32F3

WS2812 DMA library with low RAM needs. Up to 16 paralel outputs and thousands of LEDs on each of them
MIT License
60 stars 15 forks source link

problem compiling with the new HAL library release. #3

Closed jacobrejin closed 4 years ago

jacobrejin commented 6 years ago

most of the functions used in the program are not recognized . but when i use the scr and Inc files given in the project folder it works. shouldnt the HAL library releases be compatible.

hubmartin commented 6 years ago

Its hard to say. Which newer version do you use? Which function calls are not recognized?

jacobrejin commented 6 years ago

void DMA_TransferCompleteHandler(DMA_HandleTypeDef DmaHandle); void DMA_TransferHalfHandler(DMA_HandleTypeDef DmaHandle); compiler does not recognize DMA_HandleTypeDef??

jacobrejin commented 6 years ago

i think the problem is with the pointer DmaHandle i referred the STM32F103xB document and found that they have used hdma. ca this be the issue? There is another warning showing unused parameter *DmaHandle

jacobrejin commented 6 years ago

even if change the DmaHandle to hdma the compiler still shows this warning: ../src/ws2812b.c:269:49: warning: unused parameter 'hdma' [-Wunused-parameter] void DMA_TransferHalfHandler(DMA_HandleTypeDef hdma)

there is also another Warning: n file included from ../src/visEffect.c:18:0: ../include/ws2812b.h:90:13: warning: 'ws2812b_set_pixel' declared 'static' but never defined [-Wunused-function] static void ws2812b_set_pixel(uint8_t row, uint16_t column, uint8_t red, uint8_t green, uint8_t blue);

this is the last warning: ../src/ws2812b.c: In function 'ws2812b_set_pixel': ../include/ws2812b.h:84:36: warning: initialization discards 'volatile' qualifier from pointer target type [-Wdiscarded-qualifiers]

define BITBAND_SRAM(address, bit) ( (__IO uint32_t ) (RAM_BB_BASE + (((uint32_t)address) - RAM_BASE) 32 + (bit) * 4))

                                ^

../src/ws2812b.c:458:22: note: in expansion of macro 'BITBAND_SRAM' uint32_t *bitBand = BITBAND_SRAM(&ws2812bDmaBitBuffer[(calcCol)], row);

As these are warnings the compiler still compiles and give an output .hex file. when i upload it to stm32F103c8t6 nothing happens to the connected Led strip. I have the strips data pin connected to PC14 i have changed the necessary #defines

define WS2812B_PORT GPIOC

define WS2812B_PINS GPIO_PIN_14

define WS2812B_NUMBER_OF_LEDS 30

// Number of output LED strips. Each has its own buffer.

define WS2812_BUFFER_COUNT 2

had a doubt what does the "WS2812_BUFFER_COUNT 2" this do ? what is this define for?

hubmartin commented 6 years ago

There will be warnings, the code is not clean.

WS2812_BUFFER_COUNT 2 defines how many GPIO pins on a SINGLE port is connected to the WS2812B LEDs. If you connect one LED strip on PA0 and other on PA1, then the value should be 2

jacobrejin commented 6 years ago

But u have used 4 strips in parallel and then too used a WS2812_BUFFER_COUNT 2. ???? WHY??

jacobrejin commented 6 years ago

i found the problem i guess. stm32f103xx does not support mem2peripheral dma transfer. instead i will have to use mem2mem DMA with destination address that of GPIOx ODR register. how can i achieve this??

hubmartin commented 6 years ago

The code outputs data on 2 output pins for 2 LED strips. Where do you see mention of 4 led strips? Maybe the readme was taken from the F4 project. WS2812_BUFFER_COUNT defines how many outputs you use. You can even assign many outputs the same framebuffer and it will output the same data to all of them. https://github.com/hubmartin/ws2812b_stm32F3/blob/master/src/ws2812b/ws2812b.h#L69

F103 supports all combinations of memory & peripheral transfer http://www.st.com/content/ccc/resource/technical/document/application_note/47/41/32/e8/6f/42/43/bd/CD00160362.pdf/files/CD00160362.pdf/jcr:content/translations/en.CD00160362.pdf

As I said. You can send me your code/project and I check that with oscilloscope/logic analyzer. I've troubleshooted a lot of WS2812B glitches so we can quickly find what is wrong.

jacobrejin commented 6 years ago

Ok I'll snet u the code. I'm current at my native place I'll sent it once I reach home. Thank you for the help.

jacobrejin commented 6 years ago

i have attached my code. its created in eclipse IDE WS2812b_with_given.zip

jacobrejin commented 6 years ago

hey!!

hubmartin commented 6 years ago

hey, I do not have time right now, I'll take a look at the code later. Thanks.

hubmartin commented 6 years ago

I've checked the most important bits which are:

see Table 78. Summary of DMA1 requests for each channel The channels 2 (up), 5(cc1) and 7(cc2) are ok.

Here do you don't enable GPIOB clock int the ws2812b.h file // GPIO enable command #define WS2812B_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() // LED output port

define WS2812B_PORT GPIOB

// LED output pins

define WS2812B_PINS (GPIO_PIN_0 | GPIO_PIN_1)

Do you have debugger and oscilloscope? You have to check that DMA half and full interrupts are working fine. Try to define GPIO debug outputs LED4_PORT and LED5_PORT, or put a breakpoint to the DMA half/full handlers.

Other issue could be ,that F103 DMA1 could not write to GPIO. For example if you look on STM32F4 reference manual "Figure 23. System implementation of the two DMA controllers STM32F401xB/C and STM32F401xD/E) then you see that only DMA2 can write to AHB2, where the GPIO is placed. But in F103 Figure 1. System architecture (low-, medium-, XL-density devices) it seems that both DMAs can access APB2, thus all the GPIOs.

Try that GPIO clock enable and let me know the results.

jacobrejin commented 6 years ago

Thank you. the clock was not enabled. sorry for the whole hassle. I will try to implement it and if any problem comes up ill ask. again thank you

jacobrejin commented 6 years ago

does changing the clock setting effect the timer events

tim_period = SystemCoreClock / 800000; // 0,125us period (10 times lower the 1,25us period to have fixed math below) uint32_t cc1 = (10 tim_period) / 36; uint32_t cc2 = (10 tim_period) / 15;

my clock speed is 72Mhz as I am using USB CDC to transfer LED data from PC.

jacobrejin commented 6 years ago

can u explain to me in a bit detail about the above doubt.

hubmartin commented 6 years ago

As long as the SystemCoreClock is 72000000 then everything should be fine. If not, make sure you call System Core Clock update function.

jacobrejin commented 6 years ago

I am very sorry. but correcting the port to PORTB did not make it work. it was some random color that was being displayed when i moved the data cable and not the stm32 was driving it. can u check the code again for me.

jacobrejin commented 6 years ago

tried running the debug in eclipse and found that the in the function visHandle() the if(ws2812b.transferComplete) is never turned true it just keep looping over and over. void visHandle() { if(ws2812b.transferComplete) { // Update your framebuffer here or swap buffers visHandle2(); // Signal that buffer is changed and transfer new data ws2812b.startTransfer = 1; ws2812b_handle(); } }

which means void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) is never called

hubmartin commented 6 years ago

It is initially set in https://github.com/hubmartin/ws2812b_stm32F3/blob/master/src/ws2812b/ws2812b.c#L545 which is called from visInit() and then enabled again after DMA transfer is done. I try to test it, hovewer I have no F103 CPU other than deubggers od ST-link so it will take a week until I find a time to find and prepare the hardware.

jacobrejin commented 6 years ago

Thank you for ur precious time. : ) I'll wait for another week. Just to let u know , I am done with the whole processing part which sends the led frame data to stm32 through USB CDC.

Another problem was that I put a breakpoint in the DMAtransfercomplete callback function and it is never triggered while debugging. Could that be a problem.

In the file ws2812b.c the DMA IRQ handlers for channel 2 and 5 were commented out Only IRQ for channel 7 was enabled.

jacobrejin commented 6 years ago

any luck

hubmartin commented 6 years ago

Not yet, sorry.

On Thu, 2 Aug 2018 at 13:11, jacobrejin notifications@github.com wrote:

any luck

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/hubmartin/ws2812b_stm32F3/issues/3#issuecomment-409891411, or mute the thread https://github.com/notifications/unsubscribe-auth/AAeWPNEeUfgiYdUlGWW0VgKntb_e0ZN9ks5uMt55gaJpZM4UKH2U .

jacobrejin commented 6 years ago

aything??

hubmartin commented 6 years ago

Got it running.

img_20180825_115224

The issue was that the F1xx HAL library, or the new version HAL libraries at general clear the user function callbacks when you call HAL_DMA_Init(). So i just swaped those lines to:

    // TIM2 CC2 event
        ......
    dmaCC2.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    dmaCC2.Instance = DMA1_Channel7;

    // DMA_INIT clears the callbacks, call it first
    HAL_DMA_Init(&dmaCC2);

    // Then set the callbacks
    dmaCC2.XferCpltCallback  = DMA_TransferCompleteHandler;
    dmaCC2.XferHalfCpltCallback = DMA_TransferHalfHandler;
    //dmaUpdate.XferErrorCallback = TransferError;

    HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
    HAL_DMA_Start_IT(&dmaCC2, (uint32_t)WS2812_IO_Low, (uint32_t)&WS2812B_PORT->BSRR, BUFFER_SIZE);

....

I changed the output pins in the project to PA2, PA3 so I could test that on the ST-link hardware. Don't forget to change it back to you pins (WS2812B_PORT, WS2812B_PINS), set the WS2812B_GPIO_CLK_ENABLE() define correctly and in visInit() set channels to the pin numbers ws2812b.item[0].channel = 2; // for PA2.

Could I use your example code and create a new repository with F103 support? Are you ok with that? So others can use that. Now the lib could support F0,F1 (+F2), F3, F4 lines. Great. WS2812b_STM32F103_fixed_jacobrejin.zip

jacobrejin commented 6 years ago

Thank you so much 💯 👍

Could I use your example code and create a new repository with F103 support

yes please. i struggled a lot to get it working. let others get it easily

jacobrejin commented 6 years ago

I am working a processing application which would allow us to display videos just like octoWs2812b once done ill post it

hubmartin commented 6 years ago

Thanks for details. I wanted to ask later about the usage of my library. I studied other libraries how they work before I wrote mine. However I did not tested them. Can you please in short tell me what libraries did you try, some comparison and why did you choosed LowMEM ws2812b library? Thanks a lot.

jacobrejin commented 6 years ago

one of my main issue was that, if I want get a large WS2812B display working with OctoWS2811 we would need a Teensy 3.0(65K SRAM) board which costs almost 11.65$ which can only drive 1000 leds. on the contrary STM32F103(20K SRAM) which had almost the same spec costs 1.85$ with shipping on aliexpress.

my goal was to create a library similar to OctoWS2811 but using cheap STM32F103 uC which can drive as many leds as possible.

DMA > SPI/I2S peripheral : The limitation of this method, as u said is that it can only support upto 4 parallel strips.

DMA > TIMer Output compare register & TIMer > DMA > GPIO : although it can drive multiple LED's but the memory requirement is very heavy.

lets just say i want to drive 2400 leds using your TIMer > DMA > GPIO in which each new frame data is received after the DMA transfer, I would require 14.4K of SRAM. Of which 7.2K would be for led Frame data and another 7.2K for pre-computed data. As You Said in your website

This is where your LowMEM ws2812b library shines. I can use the entire 14.4K of SRAM for new LED data ie 4800 leds using a STM32F103 uC which only has 20K of SRAM.

But the limiting factor while using your LowMEM ws2812b is not the SRAM size. its the Frame rate that can be achieved . if we are driving 2400 leds ( by a method in which each new frame data is received after the DMA transfer) it would take almost 50ms to transfer the LED data from processing to STM32F103 using USB CDC and another 10ms to transfer the data to the LEDs using DMA. That is a total of 60ms which is ----> 16fps( in theory )

if we drive 1200 LEDs we could 32fps and so on.

even if we are able to drive 500 leds it would be great since we are saving a lot as compared to the price of a single teensy

hubmartin commented 6 years ago

Thanks for details. I did some basic calculations comparing other libraries, but I never pushed my lowMEM library to the edge. Sounds like I should investigate that not just on the paper but also in reality and find out the real memory usage.

Jeriomas commented 4 years ago

Good day. Have bad english, sorry. I think I have a problem with void DMA_TransferHalfHandler(DMA_HandleTypeDef DmaHandle); Then I fliash project without cubemix code generator its ok working. After I generate code with cubemix, PORTC generate periodes 1.25us, but reset pulse no and always ws2812b.transferComplete = 0; Then I debug DmaHandles: void DMA_TransferCompleteHandler(DMA_HandleTypeDef DmaHandle); void DMA_TransferHalfHandler(DMA_HandleTypeDef *DmaHandle); In it leds not on. Can you help?

Jeriomas commented 4 years ago

I experence write *hdma

void DMA_TransferCompleteHandler(DMA_HandleTypeDef hdma); void DMA_TransferHalfHandler(DMA_HandleTypeDef hdma);

Compiling ok, but problem does not improve.

Jeriomas commented 4 years ago

CPU STM32F407ZG

hubmartin commented 4 years ago

Have you tried F4 port which is specifically for F407? Please start a new thread there. https://github.com/hubmartin/WS2812B_STM32F4