Jump to content

SysEx : OK if EEPROM, troobleshoot if Bankstick [SOLVED]


julienvoirin

Recommended Posts

Dear Boxers,

I've got a very strange problem.

I've enhanced a custom by JackChaos to control Oberheim Matrix 1000.

Jackchaos uses the internal memory of the matrix to store the patch. I did change so that I can store patches into banksticks.

Each patch is an SysEx array of 275 bytes. It starts with the classic F0 and end with F7. The data are described in EditBuffer, 134 bytes, then controlled by a checksum.

If I compile my code using EEPROM, everything works as expected. The only drawback is that i can only store one patch, internal PIC EEPROM is too small.

// 0: use EEPROM, 1: use BankStick as patch storage :: WORK w/ EEPROM :)

#define PATCH_USE_BANKSTICK  0
By expected i mean : get the patch from the matrix, store it is PIC memory, power off the hardware, then power on and recall the patch by transmiting a sysex which is complete : F0 10 06 0d 00 <EditBuffer> checksum F7 If I compile using BankStick, it works too so long I haven't power on (reboot) the controller. If I power off/on, then it doesnt do the bitshift by 4 :
  // transmit the parameter value

        MIOS_MIDI_TxBufferPut(EditBuffer[i] & 0x0f);

        MIOS_MIDI_TxBufferPut((EditBuffer[i] >> 4) & 0x0f);
the bitshifting is always 00, obvious it shouldn't be :wacko: You will easily understand that it's annoying, as the bankstick are supposed to be ROM, not RAM. Sending EditBuffer :
/////////////////////////////////////////////////////////////////////////////

//  Send the edit buffer

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

void SendEditBuffer()

{

    unsigned char i;

    unsigned char checksum = 0;


	MIOS_MIDI_InterfaceSet(device);// set IIC interface

    MIOS_MIDI_BeginStream();

	MIOS_MIDI_TxBufferPut(0xf0); // begin sysex header

	MIOS_MIDI_TxBufferPut(0x10); // mfg

	MIOS_MIDI_TxBufferPut(0x06); // device

	MIOS_MIDI_TxBufferPut(0x0d); // voice data to edit buffer 0x0d

	MIOS_MIDI_TxBufferPut(0x00); // zero


#if sysex_format_oberheim

    // 134 patch bytes

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

    {

		// transmit the parameter value

        MIOS_MIDI_TxBufferPut(EditBuffer[i] & 0x0f);

        MIOS_MIDI_TxBufferPut((EditBuffer[i] >> 4) & 0x0f);


		checksum += EditBuffer[i] ;


    }

# else

// other checksum version (relative to TK Sysex management two nibbles)

	// 134 patch bytes

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

    {

        // transmit the parameter value

        MIOS_MIDI_TxBufferPut(EditBuffer[i] & 0x0f);

		checksum += EditBuffer[i] & 0x0f;

        MIOS_MIDI_TxBufferPut(EditBuffer[i] >> 4);

		checksum += EditBuffer[i] >> 4;

    }

#endif

    MIOS_MIDI_TxBufferPut(checksum & 0x7f);

    MIOS_MIDI_TxBufferPut(0xf7);

	MIOS_MIDI_EndStream();

	MIOS_MIDI_InterfaceAutoSet(); // switch back to default interface


#if DEBUG

    // debug

		MIOS_LCD_CursorSet(20);

        MIOS_LCD_PrintCString("CSUM:");

        MIOS_LCD_PrintHex2(checksum);

		MIOS_LCD_MessageStart(156);

#endif


}


 
the memo.h, defining the functins to store into bankstick/eeprom
/////////////////////////////////////////////////////////////////////////////

// global definitions

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


// 0: use EEPROM, 1: use BankStick as patch storage :: WORK w/ EEPROM :)

#define PATCH_USE_BANKSTICK  0

#define DEBUG 1 // 0: no debug, 1: debug


in memo.c (directly inspired by an example of TK for sysex in mios 8bits):


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

// 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 << 8;

	unsigned char error;


	// select BankStick

	MIOS_BANKSTICK_CtrlSet(bank & 0x07);


	// use 64byte page load functions for faster access

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

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

			return error;

	if (error){

		MIOS_LCD_CursorSet(10); MIOS_LCD_PrintCString("error"); MIOS_LCD_MessageStart(128);

	}

		#if DEBUG

			MIOS_LCD_CursorSet(20); MIOS_LCD_PrintCString("Patch_LoadBS"); MIOS_LCD_MessageStart(128);

		#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(20);	MIOS_LCD_PrintCString("Patch_LoadEE");	MIOS_LCD_MessageStart(128);

		#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 << 8 ; // default : offset = patch << 8

	unsigned char error;


	// select BankStick

	MIOS_BANKSTICK_CtrlSet(bank & 0x07);


	// use 64byte page write functions for faster access

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

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

			return error;

	if (error){

		MIOS_LCD_CursorSet(10); MIOS_LCD_PrintCString("error"); MIOS_LCD_MessageStart(128);

	}

		#if DEBUG

			MIOS_LCD_CursorSet(20);	MIOS_LCD_PrintCString("Patch_StoreBS"); MIOS_LCD_MessageStart(128);

		#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(20);	MIOS_LCD_PrintCString("Patch_StoreEE"); MIOS_LCD_MessageStart(128);

		#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(128);

#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(128);

#endif

}


And finally an extract of the UI :
switch (SoftPanel.Button)

        {


            case DIN_PAGE:

                SoftPanel.Page = SOFT_PAGE2;

				break;


            case SOFT_EDIT_5: // patch set

                Read_Patch_From_BS(uBS_uBank, uBS_uPatch); // to get EditBuffer[i]

                //MIDI_SendPatchBank(uBS_uBank); // set bnk and program for 'single patch data'

				//MIDI_SendPatchProgram(uBS_uPatch);

				//SendSinglePatchData(uBS_uPatch); // the newly stored sound will be recalled into edit buffer

				SendEditBuffer(); /// change edit buffer


				SoftPanel.Selected_MatrixBus = MMOD_BUS1;

				break;


            case SOFT_EDIT_4: // save

				Write_Patch_To_BS(uBS_uBank, uBS_uPatch);

				break;


			case SOFT_EDIT_3: // request editbuffer

				MIDI_SendPatchBank(BankNumber);

				MIDI_SendPatchProgram(ProgramNumber);

				MIDI_RequestSinglePatch(ProgramNumber);

				//MIDI_RequestEditBuffer(ProgramNumber);

			break;


So nothing very exotic, as newbee in Code, i've understood everything. :tongue: The only thing that borrow me is :
#if PATCH_USE_BANKSTICK

        // determine offset depending on patch number

        unsigned int offset = patch << 8 ; // default : offset = patch << 8

        unsigned char error;

I don't understand why shifting by 8 ??

I link (at least i've tried but seems to fail) the full sources, but beware, it is a very huge program !

If somebody has an idea , I would be plenty respectful to this personne :sweat:

Best regards

Julien

MatrixBoxSource_JV_beta v0.33.zip

Edited by julienvoirin
Link to comment
Share on other sites

I really tried to understand what your problem is, but I honestly can't. So I'll try to tackle each part individually, maybe that helps.

If I compile using BankStick, it works too so long I haven't power on (reboot) the controller. If I power off/on, then it doesnt do the bitshift by 4 :

  // transmit the parameter value
MIOS_MIDI_TxBufferPut(EditBuffer[i] & 0x0f);
MIOS_MIDI_TxBufferPut((EditBuffer[i] >> 4) & 0x0f);[/code] the bitshifting is always 00, obvious it shouldn't be :wacko: Um. EditBuffer is basically a sysex stream if I understand you correctly. That means that each byte can only have 7 bits. "EditBuffer[i] & 0x0f" will give you the lower 4 bits, "(EditBuffer[i] >> 4) & 0x0f" will give you the upper nibble with the MSB always being 0. Depending on how the 134 bytes are encoded into the SysEx stream, this behaviour is absolutely correct. Each real byte is most likely split across 2 midi bytes, each one holding one nibble (4 bits) of the real data. That would mean that the high nibble is always 0.
You will easily understand that it's annoying, as the bankstick are supposed to be ROM, not RAM.
The bankstick is RAM not ROM.
The only thing that borrow me is :
[code]#if PATCH_USE_BANKSTICK
// determine offset depending on patch number
unsigned int offset = patch << 8 ; // default : offset = patch << 8
unsigned char error;

I don't understand why shifting by 8 ??

That's easy to explain. "Offset" is the address the data will be written to on the bankstick. Since each patch is ~256 bytes the first patch gets written to address 0, the 2nd to 256, the third to 512... So if you shift the patch number left by 8 bits, it's the same as multiplying it with 256. Which means it translates the patch number to the memory address.

Hope that helps.

Link to comment
Share on other sites

Problem solved !!!

thanks Nils for your details, it did help to remember me "if you don't understand this code line, don't use it !!"

I am a bit dummy :ike:

I removed

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

                        return error;

and it solved my problem !!!

If somebody knows what 'return error' is supposed to do, I would be less dummy :yes:

Edited by julienvoirin
Link to comment
Share on other sites

ahhhhhh OK :thumbsup:

the error is 0x40. Do you know where i can find something about Bankstick error definitions ? I didn't find anything relative to 40h ; only 00h, 01h and 02h are mentioned both on website nor MIOS svn sources.

There is an error in the SysEx string outputted but as it doesn't affect the sound, it isn't a problem. It seems being a problem relative to the 8 first bytes of EditBuffer[0 .. 7] that code the program name. As the Matrix 1000 firmware doesn't store those patchnames (it stores 134 bytes into 96 bytes if i well remember), it doesn't stress me.

Link to comment
Share on other sites

MIOS_BANKSTICK_WritePage will never return 0x40, only 0x00..0x02 (0x00 on success)

It seems that you are using a corrupted C compiler version - which one exactly?

Please type "sdcc --version"

It should return:


SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.8.0 #5117 (Mar 23 2008) (Mac OS X i386)
[/code]

(-> 2.8.0)

Best Regards, Thorsten.

Link to comment
Share on other sites

euhh :ermm:

MacBook-de-Julien-VOIRIN:~ julienvoirin$ sdcc --version

SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.8.0 #5117 (Mar 23 2008) (Mac OS X i386)

MacBook-de-Julien-VOIRIN:~ julienvoirin$ 
We both agree that PrintHex2 is OK ?
MIOS_LCD_CursorSet(20+11); MIOS_LCD_PrintCString("error"); MIOS_LCD_PrintHex2(error); MIOS_LCD_MessageStart(TMP_MSG);

Respectful regards

btw : all those code examples and small applications are a delight for newbie programmer like me, a bit like virtual "Lego" bricks

Link to comment
Share on other sites

Last time you had such strange issues it was related to a private modification in your repository.

So, something is inconsistent again...

You could find out all changes with the "svn diff" command, e.g. "svn diff $MIOS_PATH"

Best Regards, Thorsten.

Link to comment
Share on other sites

Bingo ! thanks :flowers:

in GM5 app :

// ==========================================================================

 unsigned char EEPROM_CONTENT_Write(void) __wparam

 {

-  unsigned char error = 0;

-  unsigned char addr;

-  unsigned char *ptr;

-  unsigned char addr_dscr_interface;

-  unsigned char addr_dscr_endpoints;

-

-  // determine pointer to interface descriptor

-  addr_dscr_interface = USBDSC_CFG[0];

-  if( USBDSC_CFG[addr_dscr_interface+1] != DSCR_INTRFC )

-    return 0x40;// interface descriptor at wrong position

-  addr_dscr_interface += ((unsigned char)USBDSC_CFG&0xff);

-

-  // determine pointer to endpoint descriptor

-  addr_dscr_endpoints=0;

-  for(addr=0; addr<0xff;) {

-    if( USBDSC_CFG[addr+1] == DSCR_ENDPNT ) {

-      addr_dscr_endpoints = addr;

-      break;

-    }

-    addr += USBDSC_CFG[addr+0];

-  }

-  

-  if( !addr_dscr_endpoints ) {

-    return 0x41; // endpoint descriptor not found

-  }

-  addr_dscr_endpoints += ((unsigned char)USBDSC_CFG&0xff);

-

-

-  // ensure that verify mode is enabled

-  MIOS_BOX_CFG1.BS_DIS_VERIFY=0;

-

-  // select CS#0, block0

-  MIOS_BOX_CFG1.BS_A=0;

-

edit : bold in code snippet not possible :getlost:

But .. I don't understand the link between the 2 things : it shouldn't have a relationship :twitch: ?!

Edited by julienvoirin
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...