Jump to content

Recommended Posts

Posted (edited)

#include "gfx.h"
#include "stm32f4xx.h"
#include "tetris.h"
#include "ch.h"
#include "hal.h"
#include "gfxconf.h"


#define MY_AUDIO_CHANNEL                0                               /* Use channel 0 */
#define MY_PLAY_FILE                    "test.mp3"

GHandle ghImage1;
font_t          font;
GFILE           *f;
char            *errmsg;
uint32_t        toplay;
uint32_t        len;
GDataBuffer     *pd;

static void createWidgets(void) {
    GWidgetInit wi;

    // Apply some default values for GWIN
    gwinWidgetClearInit(&wi);
    wi.g.show = TRUE;

    // create the first image widget
    wi.g.x = 10; wi.g.y = 10; wi.g.width = 420; wi.g.height = 280;
    ghImage1 = gwinImageCreate(0, &wi.g);
    gwinImageOpenFile(ghImage1, "panda.bmp");
 }
/*
 * SDIO configuration.
 */
static const SDCConfig sdccfg = {
  0
};


void Delay(long i);

/*
 * This is a periodic thread that does absolutely nothing except flashing
 * a LED.
 */
static WORKING_AREA(waThread1, 2048);

static msg_t AudioThread(void *arg){
   if (!gfxBufferAlloc(4, 512)) {
      errmsg = "Err: No Memory";
      goto theend;
   }

    repeatplay:
        // Open the wave file
        if (!(f = gfileOpen(MY_PLAY_FILE, "r"))) {
            errmsg = "Err: Open MP3";
            goto theend;
        }

        // Initialise the audio output device - bitrate is ignored
        if (!gaudioPlayInit(MY_AUDIO_CHANNEL, 22000, GAUDIO_PLAY_FORMAT_FILE)) {
            errmsg = "Err: Bad format/freq";
            goto theend;
        }

        // Play the file
        gdispDrawString(0, gdispGetHeight()/2, "Playing...", font, Yellow);
        toplay = gfileGetSize(f);
        while(toplay) {
            // Get a buffer to put the data into
            pd = gfxBufferGet(TIME_INFINITE);       // This should never fail as we are waiting forever

            // How much data can we put in
            len = toplay > pd->size ? pd->size : toplay;
            pd->len = len;
            toplay -= len;

            // Read the data
            if (gfileRead(f, pd+1, len) != len) {
                errmsg = "Err: Read fail";
                goto theend;
            }

            gaudioPlay(pd);
        }
        gfileClose(f);

        // Wait for the play to finish
        gaudioPlayWait(TIME_INFINITE);
        gdispDrawString(0, gdispGetHeight()/2+10, "Done", font, Green);

        // Repeat the whole thing
        gfxSleepMilliseconds(1500);
        gdispClear(Black);
        goto repeatplay;

        // The end
    theend:
        if (errmsg)
            gdispDrawString(0, gdispGetHeight()/2, errmsg, font, Red);


}

static msg_t BlinkerThread(void *arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  palSetPadMode(GPIOC, 2, PAL_MODE_OUTPUT_PUSHPULL);
  while (TRUE) {
    palSetPad(GPIOC, 2);       /* Orange.  */
    chThdSleepMilliseconds(500);
    palClearPad(GPIOC, 2);     /* Orange.  */
    chThdSleepMilliseconds(500);
  }
}

int main(void)
{
  bool_t exitThread = FALSE;
  halInit();
  chSysInit();
  gaudioPlayInit(0,441000,GAUDIO_PLAY_FORMAT_FILE);
  gfxInit();
  font = gdispOpenFont("*");
  gwinSetDefaultFont(gdispOpenFont("UI2"));
  gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);

	sdcObjectInit(&SDCD1);
	sdcStart(&SDCD1, &sdccfg);
	sdcConnect(&SDCD1);
	createWidgets();
	gfxThreadCreate(NULL, 4096*10, NORMAL_PRIORITY, AudioThread, (void*)&exitThread);

	    while(TRUE)
	        gfxSleepMilliseconds(1000);


Hi, i can call either create Widgets or gfxThreadcreate, but when i use both nothing or something random is happening, sometimes just a scratchy sound, sometimes a part of the picture is visible. These are snippets of some example code of ugfx.

Edited by cheater
Posted

I can see a couple of problems that may (or may not) be the cause.

 

1/ gfxInit should be the very first call. It must occur before the gaudioPlayInit.

2/ unless you have turned off operating system init in your gfxconf.h there is no need to call halinit and chinit as gfxinit will call them for you.

3/ The stack size (4096 x 10) you are specifying for the audio thread seems overly big. This is probably running you out of heap space causing all sorts of strange problems.

4/ the number of buffers specified for audio buffering with gfxBufferAlloc seems a bit small/few depending on your cpu speed etc.

5/ note that PLAY_FORMAT_FILE is only available on a vs1053 audio chip because the codec itself implements it.

6/ check you are not running out of file descriptors. By default only three are enabled. It can be increased by a setting in your gfxconf.h

 

I hope one of those hints help.

Posted (edited)

the error occurs when 

gfileOpen(MY_PLAY_FILE, "r")))

is called. but only if createwidget is called. the audio module runs without it

it must have something todo with the gwinImageOpenFile call, after that i cant open it

kind regards

cheater

Edited by cheater
Posted

As @inmarket mentioned in his post the number of file descriptors is limited. It might be that you need to increase that limit depending on how many files you want to have opened simultaneously. The corresponding setting is GFILE_MAX_GFILES.

Other than that it will be most likely a memory issue. Please check the points listed by @inmarket. All of them.

Posted (edited)

hi, ich added #define GFX_USE_OS_CHIBIOS        TRUE and 

#define GFILE_MAX_GFILES                             30

 

 

/*
 * Copyright (c) 2015 Joel Bodenmann aka Tectu <joel@unormal.org>
 * Copyright (c) 2015 Andrew Hannam aka inmarket
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of the <organization> nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This program was originally contributed by community member "Fleck" as
 * the winning entry in the December 2014 demo competition.
 *
 * Some minor changes have been made by the uGFX maintainers.
 */

#include "calibration.h"
#include "gui.h"
#include "stm32f4xx.h"
#include "tetris.h"
#include "ch.h"
#include "hal.h"
#include "gfxconf.h"




#define MY_AUDIO_CHANNEL                0                               /* Use channel 0 */
#define MY_PLAY_FILE                    "test.mp3"
static gdispImage myImage;
GHandle ghImage1;
font_t          font;
GFILE           *f;
char            *errmsg;
uint32_t        toplay;
uint32_t        len;
GDataBuffer     *pd;

static void createWidgets(void) {
    coord_t swidth, sheight;

    swidth = gdispGetWidth();
    sheight = gdispGetHeight();
    // Set up IO for our image
    gdispImageOpenFile(&myImage, "Logo klein.bmp");
    gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0);
    gdispImageClose(&myImage);
 }
/*
 * SDIO configuration.
 */
static const SDCConfig sdccfg = {
  0
};


void Delay(long i);

/*
 * This is a periodic thread that does absolutely nothing except flashing
 * a LED.
 */
static WORKING_AREA(waThread1, 2048);

static msg_t AudioThread(void *arg){
   if (!gfxBufferAlloc(16, 1024)) {
      errmsg = "Err: No Memory";
      goto theend;
   }

    repeatplay:
        // Open the wave file
        if (!(f = gfileOpen(MY_PLAY_FILE, "r"))) {
            errmsg = "Err: Open MP3";
            goto theend;
        }

        // Initialise the audio output device - bitrate is ignored
        if (!gaudioPlayInit(MY_AUDIO_CHANNEL, 22000, GAUDIO_PLAY_FORMAT_FILE)) {
            errmsg = "Err: Bad format/freq";
            goto theend;
        }

        // Play the file
        gdispDrawString(0, gdispGetHeight()/2, "Playing...", font, Yellow);
        toplay = gfileGetSize(f);
        while(toplay) {
            // Get a buffer to put the data into
            pd = gfxBufferGet(TIME_INFINITE);       // This should never fail as we are waiting forever

            // How much data can we put in
            len = toplay > pd->size ? pd->size : toplay;
            pd->len = len;
            toplay -= len;

            // Read the data
            if (gfileRead(f, pd+1, len) != len) {
                errmsg = "Err: Read fail";
                goto theend;
            }

            gaudioPlay(pd);
        }
        gfileClose(f);

        // Wait for the play to finish
        gaudioPlayWait(TIME_INFINITE);
        gdispDrawString(0, gdispGetHeight()/2+10, "Done", font, Green);

        // Repeat the whole thing
        gfxSleepMilliseconds(1500);
        gdispClear(Black);
        goto repeatplay;

        // The end
    theend:
        if (errmsg)
            gdispDrawString(0, gdispGetHeight()/2, errmsg, font, Red);


}

static msg_t BlinkerThread(void *arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  palSetPadMode(GPIOC, 2, PAL_MODE_OUTPUT_PUSHPULL);
  while (TRUE) {
    palSetPad(GPIOC, 2);       /* Orange.  */
    chThdSleepMilliseconds(500);
    palClearPad(GPIOC, 2);     /* Orange.  */
    chThdSleepMilliseconds(500);
  }
}

int main(void)
{
  gfxInit();
  bool_t exitThread = FALSE;


  gaudioPlayInit(0,441000,GAUDIO_PLAY_FORMAT_FILE);

  gdispSetBacklight(100);
  gdispSetContrast(100);
  font = gdispOpenFont("*");
  gwinSetDefaultFont(gdispOpenFont("UI2"));
  gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);

	//tetrisInit();
	/*
	   */


    //RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // Clock für Port D aktivieren
    //GPIOD->MODER = 0x55000000; // Pin 12..15 als Ausgang deklarieren
	/*
    palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);         // CS.
    palSetPad(GPIOB, 11);
    palSetPadMode(GPIOC, 11, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);         // CS.
	palSetPad(GPIOC, 11);


	palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);            // SCK.
	palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(5));                                       // MISO.
	palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);            // MOSI.

*/
	/*palSetPadMode(GPIOC, 8, PAL_STM32_ALTERNATE(12) | PAL_STM32_PUDR_PULLUP | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); //DAT0
	palSetPadMode(GPIOC, 9, PAL_STM32_ALTERNATE(12) | PAL_STM32_PUDR_PULLUP | PAL_STM32_OTYPE_PUSHPULL); //DAT1
	palSetPadMode(GPIOC, 10,PAL_STM32_ALTERNATE(12) | PAL_STM32_PUDR_PULLUP | PAL_STM32_OTYPE_PUSHPULL); //DAT2
	palSetPadMode(GPIOC, 11,PAL_STM32_ALTERNATE(12) | PAL_STM32_PUDR_PULLUP | PAL_STM32_OTYPE_PUSHPULL); //DAT3
	palSetPadMode(GPIOC, 12,PAL_STM32_ALTERNATE(12) | PAL_STM32_OSPEED_MID2 | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); //CLK
	palSetPadMode(GPIOD, 2, PAL_STM32_ALTERNATE(12) | PAL_STM32_PUDR_PULLUP | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); //CMD*/


	sdcObjectInit(&SDCD1);
	sdcStart(&SDCD1, &sdccfg);
	sdcConnect(&SDCD1);
	//createWidgets();
	gfxThreadCreate(NULL, 1024, NORMAL_PRIORITY, AudioThread, (void*)&exitThread);

    geventListenerInit(&glistener);
    gwinAttachListener(&glistener);

    guiCreate();

	//mmcObjectInit(&MMCD1);
	//mmcStart(&MMCD1, &mmccfg);

	    // Allocate audio buffers - 4 x 512 byte buffers.
	    //  You may need to increase this for slower cpu's.
	    //  You may be able to decrease this for low latency operating systems.

    while (1) {
      gfxSleepMilliseconds(500);
      guiEventLoop();
    }

	/*while (TRUE) {

		// Start a new game
		// Will return when game is over
		tetrisStart();

		gfxSleepMilliseconds(10000);
		GPIOD->BSRR=0;

        GPIOD->BSRRH = 0x0000F000; // Alle LED's aus
        Delay(1000000);
        GPIOD->BSRRL = 0x0001000; // LED 1 ein
        Delay(1000000);
        GPIOD->BSRRL = 0x0002000; // LED 2 ein
        Delay(1000000);
        GPIOD->BSRRL = 0x0004000; // LED 3 ein
        Delay(1000000);
        GPIOD->BSRRL = 0x0008000; // LED 4 ein
        Delay(1000000);
	}*/
}



// Delay für Verzögerungen
void Delay(long i)
{
    volatile long iZ = i;
    while (iZ--);
}

my main file looks like the following now, but the error is still there on gFileOpen

 

i recognized the next strange thing, all demos run a way slower than in your videos:

https://youtu.be/mmRZkh_GtEI

and there as no code from me, simply the demo from you!

kind regards

cheater

 

Edited by cheater
misspelling
  • 2 months later...
Posted

push, please help me!

 

if i use the gfileOpen function after a gwinShow call it wont work. the file discriptor gives me an error an the gwinShow will abort (probably it has something to to with the error from gfileopen)

Posted
On 7/1/2016 at 08:12, cheater said:

i recognized the next strange thing, all demos run a way slower than in your videos:

https://youtu.be/mmRZkh_GtEI

and there as no code from me, simply the demo from you!

There are two very likely causes to this:

  • You don't have your FPU enabled. The shown demo is a very floating point intensive demo.
  • Your clocks are not setup correctly (eg. your CPU runs way slower than it could/should).

 

3 hours ago, cheater said:

if i use the gfileOpen function after a gwinShow call it wont work. the file discriptor gives me an error an the gwinShow will abort (probably it has something to to with the error from gfileopen)

That strongly suggests an out-of-memory situation. I'd recommend you to step through the code to figure out why gfileOpen() fails.

All in all you might want to ensure that all things you want to do work independently first. Eg: Try to create a project that doesn't do anything but playing your MP3. Once that works, create a project that doesn't do anything but implementing the GUI. Once that works, add all the other stuff (eg. peripherals and what not) and ensure that that works. At the end throw everything together step-by-step so you know exactly where and when something stops working.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...