Jump to content

Push Button Handling


robinfawell
 Share

Recommended Posts

Dear Thorsten

Button Handlers for Organ

The push buttons on the console are all momentary action.  Nearly all have integral LED's of various colours.

Sysex Buttons

The majority are associated with triggering the stored Sysex messages.There are 7 groups. There are 2 keyboards.  Each of these have 3 groups each (Flutes, Mutations and Reeds).  There is also a pedal group.

Only one instrument from each group ie only 1 Flute, 1 Mutation and 1 Reed may be selected.

If a selection was made from each group then 7 instruments would sound.

The numbers of instruments in each group varies from 1 to 7.

(1) Sysex Button behaviour

Assume that there are 3 instruments in a group A, B and C. Also assume initially that no selections have been made.

Select B.  The Sysex Message B would be triggered, this will be transmitted followed immediately by either 2 or 3 CC Midi Messages to the sound module. The LED in Button B would be illuminated.

Select A. The Sysex file A would be sent as above and a new sound would be available. LED A would light and LED B would be extinguished.

Select A again. This would cause the "Group Cancel" Sysex message to be sent.  LED A would extingish and therefore all LED's in this group would be out.

Only one LED may be lit at any time otherwise all are out.

This is a form of Radio Button I suppose.

(2) Reset and Panic Button Behaviour

These are not toggled.  They are leading edge triggered. The Sysex messages are sent each time the momentary Push buttons are pressed. The Reset Sysex should also be sent on Power Up.

(3) Mute / (Restore) Button Behaviour

There are 4 of these.

Assume initially that they are in the Restore state.  The integral LED will be "Out"

Press Mute Push Button.  The Mute Sysex message will be sent to the Sound Module. The LED will be "On".

Press button again.  The Restore Sysex message will be sent and the LED will be "Out"

(4) Coupler, Tremelo and Sub Octave Button behaviour

There are 7 of these.  In this case no Sysex messages are sent. Either Double Note on / Note Off messages are sent triggered from the keyboards or CC messages are sent.  In all cases

the LED's toggle.

General Comment

I assume that the Midio 128.ini file will need to be modified. Also the Midio_DIN.inc file will need changes.

Where and how do I store the  table which will include the Name Location and Length of the stored Sysex Files/

I am out of my depth here. Please help.

Best Regards  Robin

PS.  I hate to complicate this query but I should add that I will need to store up to 10 different setups of the stops and 10 fader values .   This my have a bearing on how the button handling can be achieved.

Link to comment
Share on other sites

Dear Thorsten

I have spent a few hours looking at the sequencer files Seq_buttons.inc main.asm. and seq_led.inc

I am a complete novice in the use of assembler, however I have retained a small knowledge of digital logic design from about 30 years ago.

To help me understand MPASM I have purchased (not recently) two books on the subject one by John Morton PIC Your  Personal Introductory Course, and Embedded Design PIC 18F452 Microcontroller by John Peatman.

Queries

Seq_buttons.inc

Page 1 Refers to a file CS_MENU_DIN_TABLE in "cs_menu_io_tables"  I cannot find this.  Maybe it is called by another name.

I have tried using the books mentioned above to find out the meaning of

xorlw      (DEFAULT_GP_DIN_SR0 - 1) << 3

I understand the xorlw.  However (DEFAULT_GP_DIN_SR0 - 1) << 3 is not understood.

I believe that there are 2 GP shift registers. (8 bits each) SR0 equivalent to SR#7 and SR1 to SR#10;  this was from:-

From Main.asm   Some menus are provide the possibility to use 16 "general purpose" buttons

; Define the two shift registers which are assigned to this function here:

; (valid numbers: 1-16)

#define DEFAULT_GP_DIN_SR0      7      ; first GP DIN shift register assigned to SR#7

#define DEFAULT_GP_DIN_SR1      10      ; second GP DIN shift register assigned to SR#10

Is (DEFAULT_GP_DIN_SR0 - 1)   7 -1 = 6 ?

<< 3 Does this mean Shift Binary value 3 places left?

I am trying to relate the Input Pins to the GP Buttons and the Left, Right,Scrub etc. buttons.

Please confirm that GP Buttons are nothing to do with Left, Right,Scrub etc.

To gain a an understanding of the button handler should I concentrate on the GP Buttons  or the Left, Right,Scrub etc. Buttons or both?

Thanks Robin

Link to comment
Share on other sites

Hi Robin,

I am a complete novice in the use of assembler, however I have retained a small knowledge of digital logic design from about 30 years ago.

don't give up!

I know that it isn't so easy to understand the implementation since the code is very compact and spreaded over different files. For MIDIbox SEQ it wasn't my intention to write a simple example, but to bring as much as possible features into the endproduct.

To help me understand MPASM I have purchased (not recently) two books on the subject one by John Morton PIC Your  Personal Introductory Course, and Embedded Design PIC 18F452 Microcontroller by John Peatman.

Would you like to write a review about these books in the MIDIbox Wiki? (http://wiki.midibox.org) - I think that for other people it could be helpful to know if these books give enough informations to work on MIOS applications.

Page 1 Refers to a file CS_MENU_DIN_TABLE in "cs_menu_io_tables"  I cannot find this.  Maybe it is called by another name.

You are right, the table is called "SEQ_IO_TABLE_DIN" and located in "mios_tables.inc" - I will correct this comment in the next release.

I have tried using the books mentioned above to find out the meaning of

xorlw      (DEFAULT_GP_DIN_SR0 - 1) << 3

I understand the xorlw.  However (DEFAULT_GP_DIN_SR0 - 1) << 3 is not understood.

The equation at the right side creates a constant ("literal") value.

I believe that there are 2 GP shift registers. (8 bits each) SR0 equivalent to SR#7 and SR1 to SR#10;  this was from:-

Is (DEFAULT_GP_DIN_SR0 - 1)   7 -1 = 6 ?

<< 3 Does this mean Shift Binary value 3 places left?

exactly!

The first 3 bits are addressing the pins of the shift register

I am trying to relate the Input Pins to the GP Buttons and the Left, Right,Scrub etc. buttons.

Please confirm that GP Buttons are nothing to do with Left, Right,Scrub etc.

correct. "GP" means "general purpose" buttons, they have different functions depending on the menu which is currently active. Most code of the GP buttons/LEDs can be found in seq_gp.inc and in various cs_m_*.inc files

To gain a an understanding of the button handler should I concentrate on the GP Buttons  or the Left, Right,Scrub etc. Buttons or both?

GP is possibly not so interesting for your use case.

Especially interesting could be the track and the layer buttons, since these are very special "radio buttons". Description about the behaviour:

Use these buttons to select the track(s) which should be edited.

The track buttons behave like "radio buttons" if only one is pressed so that you can quickly change between the tracks views. It's also possible to select multiple tracks by holding one, and pushing the additional track buttons - in this case every parameter change will be done not only on one, but on all selected tracks.

In pattern and song mode these buttons are used to select the pattern group (1-4).

Best Regards, Thorsten.

Link to comment
Share on other sites

Dear Thorsten

I have spent many hours trying to understand the seq_buttons.inc and seq_leds.inc.  Unfortunately, I do not understand the control functions of the sequencer and this makes things seem very difficult.  However, I am sure I've gained some knowledge.

I think that my requirements are much simpler.  I have 7 button groups which behave the same.

Each button operates in a radio button manner. Except that there is no cancel button. This is achieved by a repeat or "toggle" of the last button pressed (in this group).

I require a shift register LED_PATTERN_ (1-7) for each group with 8 inputs (not all will be used).

There will be another Register LAST_INPUT_STATE_(1-7) for each group.  I will need a statement in the app_defines.h file.

I will need a routine that examines the button number to determine which of the 7 LAST_INPUT_STATE registers  should be used. I am not sure how to organise this.

Then......

     movf MIOS_PARAMETER1, W ; get button No

     cpfseq LAST_INPUT_STATE   ; checks for 2nd press of button in this group

2ND_PRESS_ROUTINE_(1-7) ; There will be 7 of these

     call MIOS_HLP_GETBITORMASK ; provides appropriate pattern of LED Group                  movwf LED_PATTERN (1-7)

     ....

     ....

     ;send this input Sysex message

     

2ND_PRESS_ROUTINE_(1-7)

     clrf LED_PATTERN_(1-7)

     ....

     ....

     ;send the Group(1-7) Cancel Sysex message.

I am not sure how the LED Patterns will be sent to the DOUT's.

I know that there are lots of code missing.  However I will appreciate your comments.

Regards Robin

     

Link to comment
Share on other sites

Robin, I took at look at what you are trying to do to see how it would affect the use of switch matrix. Do you want to turn LEDs on and off using DOUT? If so you should stick with MIDIO128 because Switch Matrix uses the DOUT in a way that may make it an input only device.

I don't really grasp why you are dealing with the buttons the way you are. What are you planning to use for sound modules? Do they really respond to SysEx rather than ProgramChange to change instruments?

You include some functions like couplers that would be handled by a relay in a pipe organ. Once you start doing things like having the MIDIbox produce multiple Note Messages from a single key, you are starting to make an organ relay with the MIDIbox.

Are you trying to avoid using a PC? A PC costs about the same as a hardware sound module but can be more flexible. Virtual organ programs in the PC can provide the relay function.

Does the budget preclude using a commercial product such as Opus Two? A real organ relay will give you much more flexibility than your proposal appears to offer.

Link to comment
Share on other sites

Dear Jim

Here are the anwers to your questions.

Do you want to turn LEDs on and off using DOUT? If so you should stick with MIDIO128 because Switch Matrix uses the DOUT in a way that may make it an input only device.

Yes, I need to do that because I am using momentary action Push buttons with integral LED's. The LED will confirm that a given stop or control has been selected. However I would imagine that the system would allow further DOUT modules to be used outside of the Scan Matrix needs.

I don't really grasp why you are dealing with the buttons the way you are. What are you planning to use for sound modules?

I have purchased the Roland Sound Module SC8850 that is recommended.  The button action behaviour is determined by the needs of the Sound Module.

Do they really respond to SysEx rather than ProgramChange to change instruments?

Yes, all the organ stops are set up by Sysex messages.  The stops are complex layered sounds.

You include some functions like couplers that would be handled by a relay in a pipe organ. Once you start doing things like having the MIDIbox produce multiple Note Messages from a single key, you are starting to make an organ relay with the MIDIbox.

Coupling manuals is a fairly simple concept.  All that happens is that the keyboard Midi Note On and Off messages are  duplicated and the Midi Channel changed on the second message. The Pedal sub Octave does the same but transposes the note by one octave.

Are you trying to avoid using a PC?

The SCPOP organ original design is PC based.  However my organ will be used in a church by organists.  I decided that it would better to avoid a Monitor , keyboards and a mouse.  I have the therefore decided to try to make a non PC version of the SCPOP.  

Does the budget preclude using a commercial product such as Opus Two? A real organ relay will give you much more flexibility than your proposal appears to offer.

Most of my decisions spring from the basic one to copy the SCPOP organ see http://www.scpop.de/

Regards Robin

Link to comment
Share on other sites

However I would imagine that the system would allow further DOUT modules to be used outside of the Scan Matrix needs.
DOUT is a long serial shift register. Multiple modules just extend the register. All the output comes from one pin on the PIC. I think Thorsten loads a single low going bit in the shift register and then just shifts it one position to scan successive columns in his second example which is the really fast scan and which I am working from. That would mess up the DOUT for any other use.

I think his first example used logic that was closer to the MIDIO128 where the whole DOUT was sent every millisecond. That should allow a mix of switch matrix and unrelated outputs. But it would take up to 16 milliseconds to capture an input change if you used 16 columns. That's too long.

If one is clever enough there is probably a way to get fast scanning and unrelated outputs. I'm not the one, at least not now. Seems that you have plenty to do without changing to the switch matrix.

Coupling manuals is a fairly simple concept.
True, but I don't think anything in MIDIbox can handle that yet. I think you have a significant new feature that you will have to add. Perhaps you can do something where you couple by setting a flag that causes the button presses to be replicated appropriately after the scan of the DIN and before the search for changes. I was going to say after the search for changes but you should allow for the possibility of a coupler being added or removed without any other change.
Link to comment
Share on other sites

Dear Thorsten or anyone else.

Please ignore my message Reply #4.

I am studying the Midio128_Din.inc file in detail because I hope that it can be modified together with Midio128_Dout.inc etc to give me what I want.

What is the function of Midio_Base and Midio_CFG0??  When are they set and do they change?

I also am having difficulty with the following, from the Midio_fsr.inc

The text in Green shows my comments.

This function returns a FSR0 pointer to the button value depending on

;;  MIDIO_CURRENT_DIN

;; --------------------------------------------------------------------------

MIDIO_FSR_DINValue

     ;; (status of 8 buttons stored in a SR register)

     SET_BSR      MIDIO_BASE ; needed for indirect addressing

lfsr      FSR0, MIDIO_DIN_VALUES_SR0 ; assume that initially this is 0x000.  This is 12 bit address.

rrf      MIDIO_CURRENT_DIN, W, BANKED ;(A) copy current din into WREG, shift R       into WREG      

rrf      WREG, F ; (B) copy WREG into F = current din, shift  R

rrf      WREG, W ; © copy WREG into WREG, shift R

andlw      0x07 ; (D) mask last 3 bits WREG, result into WREG

addwf      FSR0L, F ; (E) add WREG to low address of FSR0

Assume that current din = b,0101,0111 =0x57

After (A) this becomes    = b,   010,1011      into W

After (B) this becomes    = b,       1,0101  into Curr Din

After © this becomes    = b,       1,0101 into W

After (D) this becomes    = b,               101 into  W

After (E) this becomes     = b,0000,0101 into  FSR0L

This assumes that initially FSR0L was 0x00

I still do not understand  the logic of the above.  Please check my working.

When are the values set for MIDIO_DIN_VALUES_SR0 ?

Regards Robin

Link to comment
Share on other sites

Robin,

Here is my interpretation of what is happening

This function returns a FSR0 pointer to the button value depending on

;;  MIDIO_CURRENT_DIN

;; ------------------------------------------------------------------------ --

MIDIO_FSR_DINValue

;; (status of 8 buttons stored in a SR register)

SET_BSR MIDIO_BASE ; needed for indirect addressing

lfsr FSR0, MIDIO_DIN_VALUES_SR0

; The above will result in FSR0 = 0x090. This is defined by the following statement( in app_defines.h):

     ;; button values (packed)

MIDIO_DIN_VALUES_SR0      EQU      0x090

rrf MIDIO_CURRENT_DIN, W, BANKED ;(A) copy current din into WREG, Rotate R into WREG  

rrf WREG, F ; (B) copy WREG into F = itself (=WREG), Rotate  R

rrf WREG, W ; © copy WREG into WREG, Rotate R

andlw 0x07 ; (D) mask last 3 bits WREG, result into WREG

addwf FSR0L, F ; (E) add WREG to low address of FSR0

Assume that current din = b,0101,0111 =0x57

After (A) this becomes    = b,  0010,1011 into W (the instr is Rotate through Carry)

After (B) this becomes    = b,  1001,0101 into W  

After © this becomes    = b,  1100,1010 into W

After (D) this becomes    = b,  0000,0010 into W

After (E) this becomes    = b,  1001,0010 into  FSR0L

This routine will give you an address to 8 registers 0x090 - 0x97 depending on the current DIN

Per S

Link to comment
Share on other sites

  • 5 months later...

Dear Thorsten

After a long time away from my organ project I hope to make some progress during the winter months.

Button Handler

I propose modifying the Midio_Din.inc file of Midio_128 for the second core module.  (The first core will be used with two keyboards of 62 notes)

The jump table currently has 3 modes. I propose to add 7 further Radio Group Modes. This should allow another 5 modes for other button behaviours. I believe that I may need to use the 4 byte version of the Jumptable, please confirm or not.

This will allow me to store the last Din number for each of the 7 Radio Button Groups.  You may recall that I need to send a Group Cancel Sysex message when the Input button is pressed twice.

I will need to retain the Midio_Din_Toggle mode because I have 32 Pedal Din Numbers to send the Midi Note On/Off messages.

How do I associate the Din numbers with the Din Modes?  I think that this is through the Presets.inc files, perhaps?

Thanking you in advance

Robin

Link to comment
Share on other sites

Hi Robin,

the 4byte jumptable macro is only required if you are using 32-bit instructions like "goto". So long you are using "rgoto" (an instruction which allocates 16-bit=2 bytes), the JUMPTABLE_2BYTES macro is sufficient.

Please use JUMPTABLE_2BYTES (number-of-entries) instead of JUMPTABLE_2BYTES_UNSECURE (like the the firmware), otherwise you have to take care that the jumptable index never exceeds the table

In "midio_presets.inc" you will find the "MIDIO_Presets_DIN_MODES" label, thereafter some table entries for the modes. Note that the mode is encoded in a special form (to save memory). Each hex-digit stands for one DIN pin, this means that up to 16 modes (0..F) are possible

Best Regards, Thorsten.

Link to comment
Share on other sites

Dear TK

Here are some first attempts on the button handler.  This shows the changes in Red and my questions and comments in blue.

I have some need of help on how to proceed.

Regards Robin

;; in difference to other MIDIboxes the MIDIO128 stores the mode in a 4-bit field

call MIDIO_BANK_Read

;; select nibble

SET_BSR MIDIO_BASE

btfsc MIDIO_CURRENT_DIN, 0, BANKED

swapf WREG, W

andlw 0x03

JUMPTABLE_2BYTES_0xFF ; Is this correct?

rgoto MIDIO_DIN_OnOff

rgoto MIDIO_DIN_OnOnly

rgoto MIDIO_DIN_Toggle

rgoto MIDIO_DIN_RADGRP1

rgoto MIDIO_DIN_RADGRP2

rgoto MIDIO_DIN_RADGRP3

rgoto MIDIO_DIN_RADGRP4

rgoto MIDIO_DIN_RADGRP5

rgoto MIDIO_DIN_RADGRP6

rgoto MIDIO_DIN_RADGRP7

;; rgoto MIDIO_DIN_Spare11

;; rgoto MIDIO_DIN_Spare12

;; rgoto MIDIO_DIN_Spare13

;; rgoto MIDIO_DIN_Spare14

;; rgoto MIDIO_DIN_Spare15

;; rgoto MIDIO_DIN_Spare16

;; (DIN value stored in TMP1)

MIDIO_DIN_OnOff

;; save status of DIN

rcall MIDIO_DIN_Hlp_SaveStat

rgoto MIDIO_DIN_Send

;; (DIN value stored in TMP1)

MIDIO_DIN_OnOnly

;; save status of DIN

rcall MIDIO_DIN_Hlp_SaveStat

;; when on: send DIN value defined in dump

;; when off: send nothing

IFSET TMP1, 0, rgoto MIDIO_DIN_DontSend

rgoto MIDIO_DIN_Send

;; (DIN value stored in TMP1)

MIDIO_DIN_Toggle

;; when on: toggle between 0x00 and the DIN value defined in dump

;; when off: send nothing

IFSET TMP1, 0, rgoto MIDIO_DIN_NotifyChangeEnd

;; toggle appr. bit in DIN_VALUE register

call MIDIO_FSR_DINValue

SET_BSR MIDIO_BASE

movf MIDIO_CURRENT_DIN, W, BANKED

call MIOS_HLP_GetBitORMask

xorwf INDF0, F

MIDIO_DIN_RADGRP1

;; check whether current Din number is equal to group 1 Last Din ;; Number.  If not prepare to send relevant sysex. If so prepare to send Radio Group 1 Cancel Sysex.

SET_BSR MIDIO_BASE

movf MIDIO_CURRENT_DIN, W, BANKED

cpfseq MIDIO_LAST_DIN_RADGRP1

rgoto MIDIO_DIN_SYSEX_TABLE_ADDR_Pointer

rgoto MIDIO_RADGRP1_CANC_TABLE_ADDR_Pointer

I want to make a table that hold the Bankstick Number, Bankstick (HL) Addresses and Counts (HL) for my Sysex files and Group_Sysex_Cancel_files. I need to construct pointers from MIDIO_CURRENT_DIN and the 7 MIDIO_LAST_DIN_RADGRP( ).

This table would store the table details in TMP(123) and Parameter (12) variables.

There are about 35 Current Din Sysex files and 7 Group Cancel Sysex files.

I need to set Last Din RadGrp1 to Midio Current Din if cpfseq not equal.

MIDIO_DIN_RADGRP2

;; duplicate program above substituting RADGRP2

MIDIO_DIN_RADGRP3

;; duplicate program above substituting RADGRP3

MIDIO_DIN_RADGRP4

;; duplicate program above substituting RADGRP4

MIDIO_DIN_RADGRP5

;; duplicate program above substituting RADGRP5

MIDIO_DIN_RADGRP6

;; duplicate program above substituting RADGRP6

MIDIO_DIN_RADGRP7

;; duplicate program above substituting RADGRP7

; MIDIO_DIN_Spare11

; MIDIO_DIN_Spare12

; MIDIO_DIN_Spare13

; MIDIO_DIN_Spare14

; MIDIO_DIN_Spare15

; MIDIO_DIN_Spare16

;; rgoto MIDIO_DIN_Send

MIDIO_DIN_Send

Link to comment
Share on other sites

Hi Robin,

to the JUMPTABLE macro: this is the right syntax: JUMPTABLE_2BYTES 10 ; entries

change "andlw 0x03" by "andlw 0x0f" before the macro

Table: you want to store 5 bytes per table entry. It's important to know about this assembler bug: it's not possible to create table entries with an odd size - the assembler will fill it to an even number (so that a table entry will contain 6 bytes instead of 5). In order to make this more clear, I suggest the use of 6 bytes per entry. Or better: 3 16-bit words. Here an example:



;; --------------------------------------------------------------------------
;; In: index (table entry number) in WREG
;; Out: BankStick Address in MIOS_PARAMETER[12],
;;      Dump Size in TMP[12],
;;      BankStick number in TMP3
;; --------------------------------------------------------------------------
BANKSTICK_DUMP_Get
mullw 6 ; each entry has a size of 6 bytes
;; result of multiplication in PROD[LH]

;; add offset to base address of table (16-bit addition)
;; copy result to TBLPTR[LH]
movlw (BANKSTICK_DUMP_TABLE & 0xff)
addwf PRODL, W
movwf TBLPTRL
movlw (BANKSTICK_DUMP_TABLE >> 8) & 0xff
addwfc PRODH, W
movwf TBLPTRH

;; first entry: bankstick number
tblrd*+
movff TABLAT, TMP3

;; second entry: dummy, not used
tblrd*+

;; next two entries: bankstick address to dump
tblrd*+
movff TABLAT, MIOS_PARAMETER1
tblrd*+
movff TABLAT, MIOS_PARAMETER2

;; last two entries: counter
tblrd*+
movff TABLAT, TMP1
tblrd*+
movff TABLAT, TMP2

return


;; the table
BANKSTICK_DUMP_TABLE
;;      BS Nr    Addr    Offs
dw 0x0000, 0x1000, 0x1000
dw 0x0000, 0x2000, 0x1000
dw 0x0001, 0x1000, 0x1000
dw 0x0001, 0x2000, 0x1000
[/code]

(not tested!)

Best Regards, Thorsten.

Link to comment
Share on other sites

Dear Thorsten

Thanks for  Bankstick _Dump_Get.

I think that I understand the code. There are a few supplementary questions .

BANKSTICK_DUMP_TABLE

I assume that I will need to define  its base location. In which*.inc file?

Also connected to the above,  how do I show that the table addresses have been used or reserved?.  Is this by entering the BS No,  Addresses and Count in the table or some other method?  Again in which*.inc document?

Are there reasons why a given table should be located in either BS, EEprom or  Flash?

How do you keep a check or display which memory locations are used.

Regards Robin

PS Can I use Serges Tool to upload the data?

Link to comment
Share on other sites

Hi Robin,

such tables can be stored everywhere in the flash memory, so you could also save it in the same file like the code which accesses it, or you can create a new file which contains all your own stuff.

Note that the tblrd*+ method I demonstrated here works only when the table is located in program flash. Storing the table in EEPROM or BankStick requires the appr. MIOS_*_*Read* Funktions

To check the allocated memory locations I'm normaly looking at the end of main.lst where the "memory usage map" can be found.

Serge's Tool: which data do you mean exactly?

Best Regards, Thorsten.

Link to comment
Share on other sites

Dear Thorsten

I have read your comments on where to store the table.

I have completed the coding to include the revised jumptable which now includes my radio button  groups and a further mode (an On only Sysex mode).  I have added the BANKSTICK_DUMP_Get kindly provided by you.

The data table you say can be added to the revised Din.inc.  This table has about 40 entries of 12 bytes. Do I just add it anywhere in the Din.inc file? Do I need to record the existence of BANKSTICK_DUMP_TABLE elsewhere in MIDIO_128, ie in App defines h?.  Do I need to have a specific starting address?

I had a question about Serge's Tools.  I was not thinking clearly.  The data table will, of course, be entered in the Midio 128 files. (In my case I will use Din.inc).

Regards Robin

Link to comment
Share on other sites

Hi Robin,

you are making things more complicated then they are... you don't need a specific address for the table, and you can put it into the assembler code where you want - once you are using a label (BANKSTICK_DUMP_TABLE) it will get automatically a reference which can be used in the code (-> TABLE_ADDR BANKSTICK_DUMP_TABLE). It must only be ensured that the table is not located within a function. Means: you have to make sure that the PIC never executes the data of the table (so, never do a "goto BANKSTICK_DUMP_TABLE"). Normaly I'm putting tables at the end of an .inc file, the function above the able must end with a "return" or a "goto"/"rgoto"

Best Regards, Thorsten.

Link to comment
Share on other sites

  • 2 weeks later...

Dear Thorsten

I have revised the Din.inc file for Midio_128.  This includes the code including the Table containing the addresses and counts for the Sysex messages stored in EEprom.  I believe that this should enable me to send the appropriate Sysex messages on Mdi Out.

I have shown my modifications in Red.  Please check the program for errors.  There is a fair amount of repetitive code!

I do appreciate that this is a major task for you!  and I really appreciate your help.

;; in difference to other MIDIboxes the MIDIO128 stores the mode in a 4-bit field
	call	MIDIO_BANK_Read
	;; select nibble
	SET_BSR	MIDIO_BASE
	btfsc	MIDIO_CURRENT_DIN, 0, BANKED
	swapf	WREG, W
	andlw	0x0[color=Red]F
	JUMPTABLE_2BYTES_0x0B ;[/color]
	rgoto	MIDIO_DIN_OnOff
	rgoto	MIDIO_DIN_OnOnly
	rgoto	MIDIO_DIN_Toggle
	[color=Red]rgoto	MIDIO_DIN_RADGRP1
	rgoto	MIDIO_DIN_RADGRP2
	rgoto	MIDIO_DIN_RADGRP3
	rgoto	MIDIO_DIN_RADGRP4
	rgoto	MIDIO_DIN_RADGRP5
	rgoto	MIDIO_DIN_RADGRP6
	rgoto	MIDIO_DIN_RADGRP7
rgoto	MIDIO_DIN_Sysex_OnOnly[/color]

	;; (DIN value stored in TMP1)
MIDIO_DIN_OnOff
	;; save status of DIN
	rcall	MIDIO_DIN_Hlp_SaveStat
	rgoto	MIDIO_DIN_Send

	;; (DIN value stored in TMP1)
MIDIO_DIN_OnOnly
	;; save status of DIN
	rcall	MIDIO_DIN_Hlp_SaveStat

	;; when on: send DIN value defined in dump
	;; when off: send nothing
	IFSET	TMP1, 0, rgoto MIDIO_DIN_DontSend
	rgoto	MIDIO_DIN_Send

	;; (DIN value stored in TMP1)
MIDIO_DIN_Toggle
	;; when on: toggle between 0x00 and the DIN value defined in dump
	;; when off: send nothing
	IFSET	TMP1, 0, rgoto MIDIO_DIN_NotifyChangeEnd

	;; toggle appr. bit in DIN_VALUE register
	call	MIDIO_FSR_DINValue
	SET_BSR	MIDIO_BASE
	movf	MIDIO_CURRENT_DIN, W, BANKED
	call	MIOS_HLP_GetBitORMask
	xorwf	INDF0, F

[color=Red]MIDIO_DIN_RADGRP1
;; checks whether current Din number is equal to this RADGRP Last Din Number.  If not, send Din No Sysex. If so get table entry No of this RADGRP Cancel Sysex.

SET_BSR	MIDIO_BASE
	movf		MIDIO_CURRENT_DIN, W, BANKED
	cpfseq	MIDIO_LAST_DIN_RADGRP1
	rgoto		MIDIO_BANKSTICK_DUMP_GET
	movlw		0x22; Table entry No of RADGRP1 Cancel
	rgoto		MIDIO_BANKSTICK_DUMP_GET

 MIDIO_DIN_RADGRP2
;;Same comments as under MIDIO_DIN_RADGRP1 Label

SET_BSR	MIDIO_BASE
	movf		MIDIO_CURRENT_DIN, W, BANKED
	cpfseq	MIDIO_LAST_DIN_RADGRP2
	rgoto		MIDIO_BANKSTICK_DUMP_GET
	movlw		0x23; This is the table entry No of RADGRP2 Cancel
	rgoto		MIDIO_BANKSTICK_DUMP_GET

MIDIO_DIN_RADGRP3
;;Same comments as under MIDIO_DIN_RADGRP1 Label

SET_BSR	MIDIO_BASE
	movf		MIDIO_CURRENT_DIN, W, BANKED
	cpfseq	MIDIO_LAST_DIN_RADGRP3
	rgoto		MIDIO_BANKSTICK_DUMP_GET
	movlw		0x24; This is the table entry No of RADGRP3 Cancel
	rgoto		MIDIO_BANKSTICK_DUMP_GET

MIDIO_DIN_RADGRP4
;;Same comments as under MIDIO_DIN_RADGRP1 Label

SET_BSR	MIDIO_BASE
	movf		MIDIO_CURRENT_DIN, W, BANKED
	cpfseq	MIDIO_LAST_DIN_RADGRP4
	rgoto		MIDIO_BANKSTICK_DUMP_GET
	movlw		0x25; This is the table entry No of RADGRP4 Cancel
	rgoto		MIDIO_BANKSTICK_DUMP_GET

MIDIO_DIN_RADGRP5
;;Same comments as under MIDIO_DIN_RADGRP1 Label

SET_BSR	MIDIO_BASE
	movf		MIDIO_CURRENT_DIN, W, BANKED
	cpfseq	MIDIO_LAST_DIN_RADGRP5
	rgoto		MIDIO_BANKSTICK_DUMP_GET
	movlw		0x26; This is the table entry No of RADGRP5 Cancel
	rgoto		MIDIO_BANKSTICK_DUMP_GET

MIDIO_DIN_RADGRP6
;;Same comments as under MIDIO_DIN_RADGRP1 Label

SET_BSR	MIDIO_BASE
	movf		MIDIO_CURRENT_DIN, W, BANKED
	cpfseq	MIDIO_LAST_DIN_RADGRP6
	rgoto		MIDIO_BANKSTICK_DUMP_GET
	movlw		0x27; This is the table entry No of RADGRP6 Cancel
	rgoto		MIDIO_BANKSTICK_DUMP_GET


MIDIO_DIN_RADGRP7
;;Same comments as under MIDIO_DIN_RADGRP1 Label

SET_BSR	MIDIO_BASE
	movf		MIDIO_CURRENT_DIN, W, BANKED
	cpfseq	MIDIO_LAST_DIN_RADGRP7
	rgoto		MIDIO_BANKSTICK_DUMP_GET
	movlw		0x28; This is the table entry No of RADGRP7 Cancel
	rgoto		MIDIO_BANKSTICK_DUMP_GET

MIDIO_DIN_Sysex_OnOnly
	;; sends Reset, Tremelo(S&F), (No Radio Group cancels are sent)
SET_BSR	MIDIO_BASE
	movf		MIDIO_CURRENT_DIN, W, BANKED
	clrwdt ;; Reset count 16470 X .000320 = 5.2 secs
		;;Trem[FS] count both 2756 X .000320 = 0.9 secs	

	rgoto		MIDIO_BANKSTICK_DUMP_GET


;;----------------------------------------------------------------------
;;IN:		Index (Table Entry Number) in WREG
;;OUT: 	Bankstick Address in MIOS_PARAMETER [12]
		Dump Size (Count) in TMP [12]		
		Bankstick Number in TMP3
;;----------------------------------------------------------------------

MIDIO_BANKSTICK_DUMP_GET
Mullw 6 ; the addresses jump in increments of 6 bytes 
;; result of multiplication is in PROD[HL]
;; Add Offset to base address of table 16 bit addition)
;; copy result to TBLPTR[HL]
movlw (BANKSTICK_DUMP_TABLE & 0xFF)
addwf PRODL, W
movwf TBLPTRL
movlw (BANKSTICK_DUMP_TABLE >>8) & 0xFF
addwfc PRODH, W
mvwf TBLPTRH

;; First Entry: Bankstick Number
tblrd*+
movff	TABLAT, TMP3

;; Second Entry: dummy, not used
tblrd*+

;; Third & Fourth Entry: Bankstick Address
tblrd*+
movff	TABLAT, MIOS_PARAMETER1

tblrd*+
movff	TABLAT, MIOS_PARAMETER2

;; Fifth & Sixth Entry; Count
tblrd*+
movff	TABLAT, TMP1

tblrd*+
movff	TABLAT, TMP2
return

call SYSEX_Send_Block
SYSEX_SendBlock
	Movf	TMP3,W
	Call MIOS_BANKSTICK_CtrlSet
SYSEX_SendBlockLoop
	Call	MIOS_BANKSTICK_Read ;; Expects Addr in MIOS_PARAMETER[12], ;;read byte from BS
Call MIOS_MIDI_TxBufferPut
	;; Decrement 16 bit loop counter, loop until counter is zero
	decf	TMP1,	F	
skpc
decf TMP2,	F
bc 	SYSEX_SendBlockLoop
return




BANKSTICK_DUMP_TABLE
;;BS No  	Addr  	Count

0x0000,	0x0000,	0x04CA,
0x0000,	0x04CA,	0x02F4,
0x0000,	0x07BE,	0x02F4,
0x0000,	0x0AB2,	0x04CA,
0x0000,	0x0F7C,	0x02F4,
0x0000,	0x1270,	0x0490,
0x0001,	0x0000,	0x04CA,
0x0001,	0x04CA,	0x0574,
0x0001,	0x0A3E,	0x03A0,
0x0001,	0x0DDE,	0x04CA,
0x0001,	0x12A8,	0x03A0,
0x0001,	0x1648,	0x03A0,
0x0001,	0x19E8,	0x02F4,
0x0001	0x1CDC,	0x04CA,
0x0001,	0x21A6,	0x04CA,
0x0001,	0x2670,	0x04CA,
0x0001,	0x2B3A,	0x03A0,
0x0001,	0x2EDA,	0x04CA,
0x0001,	0x33A4,	0x0574,
0x0001,	0x3918,	0x0574,

0x0002,	0x0000,	0x04D4,
0x0002,	0x04D4,	0x04D4,
0x0002,	0x09A8,	0x04D4,
0x0002,	0x0E7C,	0x09A8,
0x0002,	0x1824,	0x04D4,
0x0002,	0x1CF8,	0x04D4,
0x0002,	0x21CC,	0x04D4,

0x0003,	0x0000,	0x0AC4,
0x0003,	0x0AC4,	0x0AC4,
0x0003,	0x1588,	0x4056,
0x0003,	0x55DE,	0x01E0,
0x0003,	0x57BE,	0x032C,
0x0003,	0x5AEA,	0x028C,
0x0003,	0x5D76,	0x01E0,
0x0003,	0x5F56,	0x0218,
0x0003,	0x616E,	0x03A0,
0x0003,	0x650E,	0x02AC,


[/color]		


	;; 	rgoto	MIDIO_DIN_Send


MIDIO_DIN_Send
	;; send event

Regards Robin

Link to comment
Share on other sites

Hi Robin,

from that what I can see I can only presume that you need to change your workflow.

I can see a lot of syntax errors which will (normaly) be reported by the assembler (take a look into the main.err file), they need to be fixed first, the assembler will tell you faster what is wrong (in principle) then I ;-)

Second problem I see: since you are trying to implement the whole thing without validating changes step by step, there is a high chance that you will have a lot of trouble to debug the application if nothing works (e.g. if the application crashes). Try to begin with simple extensions and check if your changes are working like expected. Thereafter start to enhance the code in little steps, always check the effects. This will prevent a lot of frustration

Best Regards, Thorsten.

Link to comment
Share on other sites

Hi Robin,

I never really used the simulator, it's mostly more effort then debugging in-system - a valuable debugging help is the use of the MIDI interface in conjunction with a MIDI-Monitor (MIDI-Ox). You can send out common MIDI events (or SysEx streams) to protocol what happens with your code.

Example: in order to notify that a certain parts of the code have been executed, you could send out program changes with a continuous number (I call this the "checkpoint method"). Example:


;; some code..
;; ...

;; checkpoint #1 reached
movlw 0xc0
call MIOS_MIDI_TxBufferPut
movlw 0x00
call MIOS_MIDI_TxBufferPut

;; some code..
;; ...

;; checkpoint #2 reached
movlw 0xc0
call MIOS_MIDI_TxBufferPut
movlw 0x01
call MIOS_MIDI_TxBufferPut
[/code] the content of variables can also be sent via MIDI. Here I'm normaly using SysEx streams --- but take care, the bytes within a SysEx stream must be limited to 7-bit!
[code]
;; send MIOS_PARAMETER[12]
movlw 0xf0 ; begin SysEx
call MIOS_MIDI_TxBufferPut
movf MIOS_PARAMETER1, W
andlw 0x7f ; MIOS_PARAMETER1 & 0x7f
call MIOS_MIDI_TxBufferPut
movf MIOS_PARAMETER2, W
andlw 0x7f ; MIOS_PARAMETER2 & 0x7f
call MIOS_MIDI_TxBufferPut
movf MIOS_PARAMETER3, W
andlw 0x7f ; MIOS_PARAMETER3 & 0x7f
call MIOS_MIDI_TxBufferPut
movlw 0xf7 ; end SysEx
call MIOS_MIDI_TxBufferPut
if the full resolution (8-bit) is required, then you have to send the high- and low nibble seperately:

;; send MIOS_PARAMETER[12]
movlw 0xf0 ; begin SysEx
call MIOS_MIDI_TxBufferPut
swapf MIOS_PARAMETER1, W
andlw 0x0f ; send upper nipple of MIOS_PARAMETER1
call MIOS_MIDI_TxBufferPut
movf MIOS_PARAMETER1, W
andlw 0x0f ; send lower nipple of MIOS_PARAMETER1
call MIOS_MIDI_TxBufferPut
movlw 0xf7 ; end SysEx
call MIOS_MIDI_TxBufferPut
[/code]

[b]Important:[/b]: MIOS_MIDI_* modifies the BSR, this means: if you are doing BANKED transfer, then BSR has to be restored after the MIDI events have been sent

Best Regards, Thorsten.

Link to comment
Share on other sites

Dear Thorsten

Thanks for the tips on checking the revised program.

I have now corrected the syntax errors using MPLAB and have used the checkpoint method on a couple of points in your program (Not my changes) just to see what happens. It works!

I am uncertain when and how I should deal with BANKED transfers.  I know that BSR means Bank Select Register and that is used for non Access addressing.  I need to determine which entry points need the code you have detailed and how to recognise when there is a need to restore BRS.

How do you restore BSR?

Regards Robin

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...
 Share

×
×
  • Create New...