Jump to content

task time : parsing, writing


julienvoirin

Recommended Posts

Hello Boxers !

I am coding an application in C that request a dump of 100 patches from a synth

Each patch is sent every 132ms, one after another

Patch is 275 bytes. Only 134 bytes are useful to describe the patch, the rest is checksum and sysex tag

A sysex parser has been developed and works good with ONE patch

the 134 bytes are then written onto Bankstick

I've tried an automated algoryhtm to directly write the 100x134 bytes in Bankstick but PIC reset : it goes too fast.

So, i'd like to measure the time that does each task

According to ucapps website, writing the banksick takes 30 ms (3 pages of 64 bytes)

But what about the rest ?

/////////////////////////////////////////////////////////////////////////////

//  see: http://wolzow.mindworks.ee/analog/m1k-midi-spec.htm

//  edit buffer received f0 10 06 01 <patch num> <patch data> <checksum> f7

//

//  xx yy   data, sent nybblewise:

//          a data byte dd is sent as xx=dd&0x0F; yy=(dd>>4)&0x0F

//  cc      checksum:

//          the sum of the original data bytes dd, masked with 0x7F.

/////////////////////////////////////////////////////////////////////////////

// faire une boucle avec k = 0 .. 99 ; à chaq tour de boucle on ecrit le patch

// à l'adresse k

/////////////////////////////////////////////////////////////////////////////

// this functin doesn't work : Matrix1000 dumps too fast to write

// only the 1st patch is saved, 2nd is buggy, the rest is out

/////////////////////////////////////////////////////////////////////////////

void MIDI_HandleBankDump(unsigned char byte)

{

    //appelle une sorte de "handle edit buffer"

	unsigned char program_received; // will be used to write is K

	static unsigned char editbufferstatus;

	static unsigned char firstnibble;

	static unsigned char ebparam;

	static unsigned char lsb;

	static unsigned char bytecount;


	unsigned char error = 0;

	unsigned char checksum = 0;


if(program_received < 99)

{


    switch(editbufferstatus)

    {

        case 0:

            if(byte == 0xf0) //premier byte envoyé par m1000

                editbufferstatus = 1;

            else

                editbufferstatus = 0;

            break;


        case 1:

            if(byte == 0x10) ///2eme byte envoyé par m1000, mfg

                editbufferstatus = 2;

            else

                editbufferstatus = 0;

            break;


        case 2:

            if(byte == 0x06) ///3eme byte, correspond à "M1000/M6", code machine

                editbufferstatus = 3;

            else

                editbufferstatus = 0;

            break;


        case 3:

			if(byte == 0x01)

                editbufferstatus = 4; ///single patch data

            else

                editbufferstatus = 0;

            break;


        case 4:

            if(byte == program_received) // notice patch number (0-99)

            {

                editbufferstatus = 5;

                lsb = 1;

                ebparam = 0;

				program_received = byte;

            }

            else{

                editbufferstatus = 0;

            }

            break;


        case 5: // voice data

			if(ebparam < 134) // 134 = number of voice parameter bytes

			{

				if(lsb == 1) // first nibble, least significant byte

				{

					firstnibble = (byte & 0x0f);

					lsb = 0;

				}

				else // second nibble, most significant byte

				{

					EditBuffer[ebparam] = (byte << 4) + firstnibble;

					EditBufferOrig[ebparam] = (byte << 4) + firstnibble;

					lsb = 1; // reset

					ebparam++;

				}

			}

			else // status 6 checksum skip to 7

			{

				editbufferstatus = 7;

				checksum = byte;

			}


            break;


		case 7: // sysex end

			if(byte == 0xF7){

				editbufferstatus = 0;

				UpdateDinStates();

				Write_Patch_To_BS(uBS_uBank, program_received); // write received patch

				program_received ++; // ready for next patch

			}

			else{

				error = byte;

				editbufferstatus = 0;

			}

            break;

		}


	}

	else{

	MIDI_ReceivingBank = 0; // tag "end of receiving a bank"


#if DEBUG

		MIOS_LCD_CursorSet(0xc0 +8); MIOS_LCD_PrintCString("finished !"); MIOS_LCD_MessageStart(TMP_MSG);

#endif	

	}

}


////////////////////////////////////////////////////////////////////////////////////////

// Receiving a whole bank, patch one by one : reboot PIC ! too much received data at once

//////////////////////////////////////////////////////////////////////////////////////////

void MIDI_RequestPatch_onebyone(unsigned char bank, unsigned char ubank)

{

	unsigned char k;


	MIDI_SendPatchBank(bank);


	while( k < 99){

		ProgramNumberReq = k;

		MIDI_SendPatchProgram( k);

		MIOS_Delay(10);

		MIDI_RequestEditBuffer(k);

		MIOS_Delay(60);

		Write_Patch_To_BS(ubank, k);

		MIOS_Delay(130);

		//program_request_1b1++;

		k++;

	}


#if DEBUG

	MIOS_LCD_CursorSet(0xc0 +8); MIOS_LCD_PrintCString("finished !"); MIOS_LCD_MessageStart(TMP_MSG);

#endif

}
/////////////////////////////////////////////////////////////////////////////

// This function returns a byte from patch structure in RAM

/////////////////////////////////////////////////////////////////////////////

unsigned char PATCH_ReadByte(unsigned char addr)

{

	return patch_structure[addr];

}


/////////////////////////////////////////////////////////////////////////////

// This function writes a byte into patch structure in RAM

/////////////////////////////////////////////////////////////////////////////

void PATCH_WriteByte(unsigned char addr, unsigned char byte)

{

	patch_structure[addr] = byte;

}



/////////////////////////////////////////////////////////

// This function read a patch stored into BS

// This function loads the patch structure from EEPROM/BankStick

// Returns != 0 if Load failed (e.g. BankStick not connected)

////////////////////////////////////////////////////////

unsigned char PATCH_Load(unsigned char bank, unsigned char patch)

{

	unsigned char i;


#if PATCH_USE_BANKSTICK

	// determine offset depending on patch number

	unsigned int offset = (patch << 7) + 7; // default : patch << 8

	unsigned char error = 0;


	// select BankStick

	MIOS_BANKSTICK_CtrlSet(bank & 0x07);


	// use 64byte page load functions for faster access

	for(i=0; i<3; ++i)

		error = MIOS_BANKSTICK_ReadPage(offset + i*0x40, (char *)(patch_structure + i*0x40)) ;


		#if DEBUG

			if (error == 0x02){

				MIOS_LCD_CursorSet(20+11); MIOS_LCD_PrintCString("no BS"); MIOS_LCD_PrintHex2(error); MIOS_LCD_MessageStart(TMP_MSG);

			}else{

				MIOS_LCD_CursorSet(20+11); MIOS_LCD_PrintCString("error"); MIOS_LCD_PrintHex2(error); MIOS_LCD_MessageStart(TMP_MSG);

			}


		MIOS_LCD_CursorSet(0xc0 +11); MIOS_LCD_PrintCString("_LoadBS"); MIOS_LCD_MessageStart(TMP_MSG);

		#endif

#else

	// ignore patch and bank

	// use 64byte page load functions for faster access

	for(i=0; i<3; ++i)

		MIOS_EEPROM_ReadPage(i*0x40, (char *)(patch_structure + i*0x40));


		#if DEBUG

			MIOS_LCD_CursorSet(0xc0 +11);	MIOS_LCD_PrintCString("_LoadEE");	MIOS_LCD_MessageStart(TMP_MSG);

		#endif


#endif


	return 0;

}



//////////////////////////////////////////////////////////////////////////////////////////////////////

// This function stores the patch structure into EEPROM/BankStick

// Returns != 0 if Store failed (e.g. BankStick not connected)

///////////////////////////////////////////////////////////////////////////////////////////////////////

unsigned char PATCH_Store(unsigned char bank, unsigned char patch)

{

	unsigned char i;


#if PATCH_USE_BANKSTICK

	// determine offset depending on patch number

	unsigned int offset =  (patch << 7) + 7 ; // default : offset = patch << 8

	unsigned char error = 0;


	// select BankStick

	MIOS_BANKSTICK_CtrlSet(bank & 0x07);


	// use 64byte page write functions for faster access

	for(i=0; i<3; ++i)

		error = MIOS_BANKSTICK_WritePage(offset + i*0x40, (char *)(patch_structure + i*0x40)) ;


		#if DEBUG

		if (error == 0x02){

			MIOS_LCD_CursorSet(20+11); MIOS_LCD_PrintCString("no BS"); MIOS_LCD_PrintHex2(error); MIOS_LCD_MessageStart(TMP_MSG);

		}else{

			MIOS_LCD_CursorSet(20+11); MIOS_LCD_PrintCString("error"); MIOS_LCD_PrintHex2(error); MIOS_LCD_MessageStart(TMP_MSG);

		}	

		MIOS_LCD_CursorSet(0xc0 +11);	MIOS_LCD_PrintCString("_StoreBS"); MIOS_LCD_MessageStart(TMP_MSG);

		#endif	

#else

	// ignore patch and bank

	// use 64byte page write functions for faster access

	for(i=0; i<3; ++i)

		MIOS_EEPROM_WritePage(i*0x40, (char *)(patch_structure + i*0x40));


		#if DEBUG

			MIOS_LCD_CursorSet(0xc0 +11);	MIOS_LCD_PrintCString("_StoreEE"); MIOS_LCD_MessageStart(TMP_MSG);

		#endif


#endif


	return 0;



}



/////////////////////////////////////////////////////////////////////////////

/// read a patch from a BS

/////////////////////////////////////////////////////////////////////////////

void Read_Patch_From_BS(unsigned char bank, unsigned char patch)

{	

	unsigned char j;

	PATCH_Load(bank, patch);

	for (j=0; j<134; j++){

		EditBuffer[j] = patch_structure[j];

		}


#if DEBUG

	MIOS_LCD_CursorSet(0xc0); MIOS_LCD_PrintCString("Read_Patch"); MIOS_LCD_MessageStart(TMP_MSG);

#endif

}


/////////////////////////////////////////////////////////////////////////////

/// write a patch to a BS

/////////////////////////////////////////////////////////////////////////////

void Write_Patch_To_BS(unsigned char bank, unsigned char patch)

{	

	unsigned char j;

	for (j=0; j<134; j++){

		patch_structure[j] = EditBuffer[j]; // ok ça marche :)

		}

	PATCH_Store(bank, patch);


#if DEBUG

	MIOS_LCD_CursorSet(0xc0); MIOS_LCD_PrintCString("Write_Patch"); MIOS_LCD_MessageStart(TMP_MSG);

#endif

}

Thanks in advance if you 've some trick

Best regards

Julien

Edited by julienvoirin
Link to comment
Share on other sites

Since you are using a PIC, you will need a scope for accurate measurements, because all timer resources are allocated.

However, your PIC doesn't reset because the output is too fast, but because the watchdog won't be serviced (-> see datasheet for details)

You have to execute the clrwdt instruction at least once per second, e.g. you could execute it whenever a new patch will be sent.

On a MBHP_CORE_STM32 you could use the MIOS32_STOPWATCH functions.

Best Regards, Thorsten.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...