Does DEBUG interfere with RLP in anyway?

I’m working on a RLP library for the VS1053 chip (so I could stream data faster). When I test the code with DEBUG, it hangs on Invoke/InvokeEx most of the times. When I test the code without debugging it works every time. What could be the cause?

Thanks

Shouldn’t interfere. I used RLP while debugging and it didn’t hang, not after i fixed all the RLP bugs anyway… :slight_smile:

You might be corrupting ram or messing up interrupts that are used by debug…

Thanks.

This is all the code I use right now. I invoke VsInit function. LPC24xx.h is from [url]http://pyldin.googlecode.com/svn/trunk/pyldin601/te-lpc2478/include/lpc24xx.h[/url]
I don’t use any pointers yet and all the while’s are with timeouts. In DEBUG it hangs, in release (I mean without debugging) it works as it should.


 #include "RLP.h"
 #include "LPC24xx.h"
 #include "Extension.h"

//VS1053 is connected to SSP1 
//DREQ	-	P0.6	(IO33)
//SCK	-	P0.7
//SO	-	P0.8
//SI	-	P0.9
//XDCS	-	p2.1	(IO32)
//RESET	-	P3.18	(IO34)
//XCS	-	P3.30	(IO31)

//#define DREQ (FIO0PIN & (1<<6))
 #define DREQ (RLPext->GPIO.ReadPin(33))

static void VsInitPorts()
{
	RLPext->GPIO.EnableInputMode(33, RLP_GPIO_RESISTOR_DISABLED); //DREQ

	RLPext->GPIO.EnableOutputMode(31, RLP_TRUE); //XCS
	RLPext->GPIO.EnableOutputMode(32, RLP_TRUE); //XDCS
	RLPext->GPIO.EnableOutputMode(34, RLP_TRUE); //RESET
	
	PINSEL0 |= (0x02UL << 14) | (0x02UL << 16) | (0x02UL << 18); //set SCK, SO and SI as SSP1
}

static void VsClearRxFifo()
{
 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
	volatile unsigned char dummy;
	for (unsigned char i=0; i<8; i++)
		dummy = SSP1DR;
 #pragma GCC diagnostic pop
}

void SSP1_Interrupt(void *arg)
{
}

static void VsInitSSP1()
{
	PCONP |= (1 << 10); //make sure power is on for SSP1
	
	//Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0
	SSP1CR0 = 0x07;
	SSP1CPSR = 0x48; //clock prescaler 72 -> 1MHz clock
	VsClearRxFifo();
	
	//Enable SSP1 in master mode, normal operation
	SSP1CR1 = 0x02;
	
	SSP1IMSC = 0; //disable all interrupts
	
	//install SSP1 interrupt
	//RLPext->Interrupt.Install(11, SSP1_Interrupt, (void*)0);
}

 #define TIMEOUT		0xFFFFFF

static unsigned char VsReadWriteByte(unsigned char data)
{
	unsigned int timeout;

	timeout = TIMEOUT;
	while (!(SSP1SR & SSPSR_TNF) && timeout--);
	if (timeout == 0) return 0;

    SSP1DR = data;

	timeout = TIMEOUT;
	while (!(SSP1SR & SSPSR_RNE) && timeout--);
	if (timeout == 0) return 0;

    return SSP1DR;
}

static void VsWriteRegister(unsigned char reg, unsigned short data)
{
	FIO2SET = (1UL << 1); //set XDCS high
	FIO3CLR = (1UL << 30); //set XCS low

	unsigned int timeout = TIMEOUT;
	while (!DREQ && timeout--);
	if (!timeout) return;

	VsReadWriteByte(0x02);
	VsReadWriteByte(reg);
	VsReadWriteByte(data >> 8);
	VsReadWriteByte(data);
	
	FIO3SET = (1UL << 30); //set XCS high
	FIO2CLR = (1UL << 1); //set XDCS low
}

static unsigned short VsReadRegister(unsigned char reg)
{
	VsClearRxFifo();

	FIO2SET = (1UL << 1); //set XDCS high
	FIO3CLR = (1UL << 30); //set XCS low
	
	unsigned int timeout = TIMEOUT;
	while (!DREQ && timeout--);
	if (!timeout) return 0;

	VsReadWriteByte(0x03);
	VsReadWriteByte(reg);
	
	unsigned short result = VsReadWriteByte(0x00) << 8;
	result |= VsReadWriteByte(0x00);

	FIO3SET = (1UL << 30); //set XCS high
	FIO2CLR = (1UL << 1); //set XDCS low
	
	return result;
}

static void VsSoftReset()
{
	VsWriteRegister(0x00, 0x0004); //software reset
	VsWriteRegister(0x00, 0x0802); //allow MPEG I & II, VS1002 native mode
	VsWriteRegister(0x02, 0x0000); //bass and treble controls are off
	VsWriteRegister(0x03, 0xA4E2); //4x multiplier, no addition, 13 MHz => CLKI = 52 MHz
}

int VsInit(unsigned char *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{
	if (argsCount > 1) return 2;

	VsInitPorts(); //init I/O
	VsInitSSP1(); //init SSP1

	FIO3CLR = (1UL << 18); //set reset low
	RLPext->Delay(5000); //wait 5ms
	FIO3SET = (1UL << 18); //set reset high

	return 0;

	VsSoftReset();

	//if there is an argument, it's the plugin to load
	/*if (argsCount == 1)
	{
		int pluginLength = *(int*)args[0];
		unsigned char result = VsLoadPlugin(generalArray, pluginLength);
		if (result != 0) return result;
	}*/

	VsWriteRegister(0x0B, 0x1515); //set volume
	if (VsReadRegister(0x0B) != 0x1515) return 1; 

	return 0;
}

It’s a bit messy.

maybe comment these out, see if it still crash:

	VsInitPorts(); //init I/O
	VsInitSSP1(); //init SSP1

If it runs then add one in, etc…

Also, i might be wrong, but this statement in VsInitPorts() might not have the intended result:

PINSEL0 |= (0x02UL << 14) | (0x02UL << 16) | (0x02UL << 18); //set SCK, SO and SI as SSP1

An OR statement can only turn a bit on, not off, so if the first bit of any of those ports are set, then they will end up with both bits set. If I recall correctly then you must first clear the bits for those ports, then do an OR.

Yes, but I tested with Register.Read on that register and the those bits are 0 when in init. I will also try to clear them out.

I’ll test more when I get home.

Thanks

I stripped down the code to:


static void VsInitPorts()
{
	RLPext->GPIO.EnableInputMode(33, RLP_GPIO_RESISTOR_DISABLED); //DREQ

	RLPext->GPIO.EnableOutputMode(31, RLP_TRUE); //XCS
	RLPext->GPIO.EnableOutputMode(32, RLP_TRUE); //XDCS
	RLPext->GPIO.EnableOutputMode(34, RLP_TRUE); //RESET

	PINSEL0 &= ~((0x03 << 14) | (0x03 << 16) | (0x03 << 19)); //set SCK, SO and SI as GPIO
	PINSEL0 |= (0x02 << 14) | (0x02 << 16) | (0x02 << 18); //set SCK, SO and SI as SSP1
}

int VsInit(unsigned char *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{
	if (argsCount > 1) return 2;

	//init I/O
	VsInitPorts();

	return 0;
}

(also tried without changing PINSEL0 register)

and this is the managed code:


RLP.Unlock(...);
byte[] elf_file = Extension.GetBytes(Extension.BinaryResources.Extension);
RLP.LoadELF(elf_file);
RLP.Procedure VsInit = RLP.GetProcedure(elf_file, "VsInit");
if ((result = VsInit.Invoke()) != 0) throw new Exception("Could not init VS Driver. Reason " + result.ToString());

I put a breakpoint at VsInit.Invoke(), start debugging, step over that line and it freezes. Everything freezes (debugging, etc.), only a reset works. After the reset, it freezes again (not in debugging but I can see that because it doesn’t draw the UI). After the 2nd freeze, if I reset the board everything works well every time no matter what I do (reset from switch, reset power).

I also tried:


static void VsInitPorts()
{
	PINSEL0 &= ~((0x03 << 12) | (0x03 << 14) | (0x03 << 16) | (0x03 << 19)); //set DREQ, SCK, SO and SI as GPIO
	PINSEL0 |= (0x02 << 14) | (0x02 << 16) | (0x02 << 18); //set SCK, SO and SI as SSP1

	PINSEL4 &= ~(0x03 << 2); //set XDCS as GPIO
	PINSEL7 &= ~((0x03 << 4) | (0x03 << 28)); //set RESET and XCS as GPIO

	FIO0DIR &= ~(1<<6); //set DREQ as input
	FIO2DIR |= (1<<1); //set XDCS as output
	FIO3DIR |= (1<<18) | (1<<30); //set RESET and XCS as output
}

but it’s the same behavior. Also tried checking if the pins are reserved and reserving them if not or abort but still freezes.
The only thing that works is commenting the VsInitPorts function call.

This is the makefile I’m using:


OUTFILE=Extension
LINKERSCRIPT = LinkScript.lds

INCL=./include

CC		=arm-none-eabi-gcc
LD		=arm-none-eabi-gcc

CCFLAGS=  -g -mlittle-endian -mcpu=arm7tdmi -std=gnu99 -Wall -I. -I$(INCL)
CCFLAGS+= -mapcs-frame -fno-builtin -g0 -O3

LDFLAGS =-nostartfiles -Wl,--Map -Wl,$(OUTFILE).map
LDFLAGS+=-lc -lgcc -Wl,--omagic
LDFLAGS+=-T $(LINKERSCRIPT)

SRCS=Extension.c
OBJS=$(SRCS:.c=.o)

rebuild: clean all

all: $(OBJS)
	$(LD) $(LDFLAGS) -o $(OUTFILE).elf $(OBJS)
	
%.o: %.c 
	$(CC) -c $(CCFLAGS) $< -o $@ 

clean:
	-rm *.o *.elf *.map

This is the linkscript file:


OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)

MEMORY
{
  SDRAM (wx) : ORIGIN = 0xA0F00000, LENGTH = 0x000FFFFC
}

SECTIONS
{
        . = ALIGN(4);
        .text : 
        { 
        	*(.text)
        }

        . = ALIGN(4);
        .rodata : 
        { 
          *(.rodata )
        }
        
        . = ALIGN(4);
        .data : 
        { 
        	*(.data)
        }

         . = ALIGN(4);
        .bss : 
        {
            __bss_start__ = .;
            *(.bss)
            __bss_end__ = .;
        }

   
}
end = .;  /* define a global symbol marking the end of application RAM */

And the RLP.h file is the same with the EMX lines uncommented.

If anyone can test the exact same code on an EMX, please do.

Thanks

Later edit:
Could the -std=gnu99 flag for the compiler be the issue? I’m away right now and I can’t test it but it hit me when I looked over the Makefile.

Try to call empty functions to check if its not something related to the compiler. I dont know what does the static void definition but it should be something related to not rellocatable code, so it has not to be used.

By the way did you try GHI’s example ? Does it works ?

A static function is accessible only from the module in which is written. This leads to some optimizations from the compiler. I also tried with/without static but it’s the same behavior.
If I comment out VsInitPorts function (or the instructions in the function) and return a number, it works well and I get the returned number in the managed side.

I did some more testing and it’s not related to -std=gnu99 compiler flag.

So here are the latest results:
-when debugging, it sometimes (very often) hangs in the RLP.Invoke/InvokeEx method
-when running without debugging it hangs (not sure if there) the first time after deployment, after that it works fine every time no matter what.

I’m not sure what the cause could be.
Additional info:
-custom heap is set to 4MiB
-I use ExtendedWeakReference, TouchPanel, LCD, ethernet, USB host, SD

I’m back with another weird RLP thing.

Here is the code:


 #define GREEN_ON	FIO3SET = (1 << 26)
 #define GREEN_OFF	FIO3CLR = (1 << 26)
 #define RED_ON		FIO3SET = (1 << 17)
 #define RED_OFF		FIO3CLR = (1 << 17)

void VsTask(void *arg)
{
	RED_ON;

	RLPext->Task.ScheduleTimeOffset(&bufTask, (unsigned int)500000);
		
	RED_OFF;
}

//some invoked RLP function
RLPext->Task.Initialize(&bufTask, VsTask, 0, RLP_FALSE);
RLPext->Task.Schedule(&bufTask);
return 0;


The led goes red and the whole system hangs.

Anyone any suggestion?

Did you uncomment the proper module in RLP.H ?

Are you sure you are using the same version of GHI SDK in both sides, PC and EMX ?

Your last post is exactly the same as GHI’s example so it must work…

Maybe is the o3 flag crashing everything, try removing the optimization !

Yes, the EMX is uncommented.
Yes, it’s the same SDK version on both sides.
If I comment this line (RLPext->Task.ScheduleTimeOffset) it works fine.

Later Edit: Also tried once again without optimisations but still the same result. I have no ideea what is wrong. Also reflashed the firmware, same result (LED turns red and everything hangs).

Later Later Edit: maybe it’s important, when it hangs, the screen clears (white or light gray) and nothing works anymore only a reset (up/down held so it won’t freeze again).

I didn’t read this thread but have you started with the example we provide as is?

Yes, tried the same exact example (only with different pin) and the LED goes on and the system hangs. I think it hangs at ScheduleTimeOffset. Also tried with Schedule and still hangs. If I remove/comment that line it doesn’t hang but the thing is that I need it.

Later Edit: I have the updated SDK (4.1.8?) but was the same behaviour before the update.

How does keil need to be configured to provide elf files for RLP?

I think I figured it out. Is this map file ok? It looks fine to me.


Image Symbol Table

    Local Symbols

    Symbol Name                              Value     Ov Type        Size  Object(Section)

    test.c                                   0x00000000   Number         0  test.o ABSOLUTE
    .text                                    0xa0f00000   Section        0  test.o(.text)
    .data                                    0xa0f7fff0   Section        8  test.o(.data)
    .bss                                     0xa0f7fff8   Section       32  test.o(.bss)

    Global Symbols

    Symbol Name                              Value     Ov Type        Size  Object(Section)

    BuildAttributes$$THM_ISAv1$ARM_ISAv4$S$PE$A:L22$X:L11$S22$IEEE1$IW$USESV6$~STKCKD$USESV7$~SHL$OTIME$EBA8$STANDARDLIB$REQ8$PRES8$EABIv2 0x00000000   Number         0  anon$$obj.o ABSOLUTE
    MyTaskCallback                           0xa0f00000   ARM Code      84  test.o(.text)
    StartLEDBlink                            0xa0f00054   ARM Code     120  test.o(.text)
    pin                                      0xa0f7fff0   Data           4  test.o(.data)
    state                                    0xa0f7fff4   Data           4  test.o(.data)
    myTask1                                  0xa0f7fff8   Data          32  test.o(.bss)

The library reference has complete examples that should work as is. Also, this explains how to use keil GHI Electronics – Where Hardware Meets Software

I moved all the variables declarations to the top of the c file and it seems that it works now. The problem is that it still hangs when I call RLPext->Task.ScheduleTimeOffset from an interrupt handler. Is this a restriction? It hangs in that interrupt and never starts that task.

If it hangs then it is probably not supported that way.