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

Dear Boxers,

I’ve got a very strange problem.

http://discourse.midibox.org/t/topic/13345

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](< base_url >/applications/core/interface/file/attachment.php?id=8536)

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.

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:

It aborts the function if error != 0 and returns the value of error. So what you are doing now is ignore the error that apparently happens.

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.

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.

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

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.

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: ?!