[ASM ERROR] Argument out of range (2135 not between 0 and 2047) (0) : Error[126]
When I click "compile" the progress bar gets all the way up to 100% and then it goes from green to red and I get this message at the bottom.
[ASM ERROR] Argument out of range (2135 not between 0 and 2047) (0) : Error[126]
When I click "compile" the progress bar gets all the way up to 100% and then it goes from green to red and I get this message at the bottom.
Since you haven't shown the relevant code fragment, I suspect you are getting an error at a branch instruction that is branching past the 2048 bytes page size.
How do I locate the relevant code fragment?
Post your code. It is easier for experienced members to help you as they might be able to try out the code to see the issue you have.
Sorry. It's pretty long. This is for use with an electronic music effect device - and echo module. It's doing 3 main things. The first is a signal routing/bypass that uses A5, C3, and C5 to turn various JFETs on and off. The second is controlling a digital potentiometer to control the delay time of two delay chips in series. The delay time can be manipulated with either an analog pot which is read at pin A1. The other is by tapping out the tempo on a push button switch connected to A0. The third main thing that this program does is use an interrupt to count the time between tempo taps and translates that into the wiper position on the digital pot. There's a couple other minor things too, like making LEDs blink and such.
The base of this program works just fine. But recently, since production of semiconductors started back up after COVID, the specs of the delay chip I'm using are not as tight anymore. This has required me to add a "calibration" feature to the program. So it's only after adding this calibration feature that I've gotten the error messages.
Code:#config __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF #endconfig ADCON0 = %00000000 ADCON1 = %00110000 ANSEL = %00000110 define ADC_SAMPLEUS 50 define ADC_BITS 8 DEFINE ADC_CLOCK 3 CMCON0 = %00000111 TRISA = %00001111 TRISC = %00000000 ' Set TMR0 interrupt prescaler to 1:32 OPTION_REG = %10000100 ' Set TMR0 configuration and enable PORTB pullups INTCON = %10100000 ' Enable TMR0 interrupts On Interrupt Goto tickint define WRITE_INT 1 ' ' Hardware connection ' =================== CS VAR PORTA.5 SCK VAR PORTC.2 SDI VAR PORTC.1 tempoLED var PORTC.0 tempobutton var PORTA.0 bypassbutton var PORTA.3 bypassLED var PORTC.4 fetA var PORTC.5 fetB var PORTA.4 fetC var PORTC.3 ;pot is on porta.2 an2 ' ' Variables definition ' =================== x var word y var word w var byte z var byte a var byte ' ADC in variable for tempo LED calibration b var byte ' tempo LED calibration variable used in main program c var byte ' ADC in variable for tap calibration d var byte ' tap calibration variable used in main program plusORminus var bit plusORminus1 var bit plusORminus2 var bit plusORminus3 var bit ticks var word LEDcounter var word LEDrate var word trailsmodecounter var word trailsmode var bit xprevious var byte override var bit analogpot var bit footswitch var bit analogpot = 1 footswitch = 0 LEDadj var byte LEDadj1 var byte tapadj var byte tapadj1 var byte calibrationcounter var byte calibrationon var bit ' Calibration check '================================================================ calibrationon = 0 read 1, calibrationcounter if bypassbutton = 0 then 'hold down bypass button on power up to calibrate goto bypassbuttonrelease calibrationon = 1 endif ' ' begin in "bypass" state ' ==================== tempoLED = 0 fetA = 0 fetB = 0 fetC = 1 bypassLED = 0 trailsmode = 0 override = analogpot pause 1000 gosub readpot gosub movepot pause 100 ' MAIN PROGRAM '================================================================= main: gosub potcheck if LEDcounter < 3 then tempoLED = 1 else tempoLED = 0 endif if tempobutton = 0 then if calibrationon = 1 then goto subtractfromcalibrationcounter else goto tempopress endif endif if ticks > 400 then ticks = 300 endif if LEDcounter > LEDrate then LEDcounter = 0 endif if bypassBUTTON = 0 then if calibrationon = 1 then gosub addtocalibrationcounter else gosub bypasspress endif gosub bypassbuttonrelease ENDif goto main potcheck: gosub readpot if abs (xprevious-x) > 4 then override = analogpot gosub movepot endif return readpot: adcin 1,x x = x * 10 x = x/17 'x = 1 max x return movepot: x = x + calibrationcounter CS = 0 shiftout SDI, SCK, 1, [00000000,x] shiftout SDI, SCK, 1, [00010000,x] CS = 1 x = x - calibrationcounter if override = analogpot then 'checks to see if the delay time was set by the pot or switch xprevious = x endif gosub tempoLEDadjust return tempoLEDadjust: ' compensate for TMR0 not being 1:1 with actual delay time if x < 25 then LEDrate = x + 16 elseif x >= 25 and x < 50 then LEDrate = x + 18 elseif x >= 50 and x < 75 then LEDrate = x + 20 elseif x >= 75 and x < 95 then LEDrate = x + 22 'noon to 2 o'clock elseif x >= 95 and x < 130 then LEDrate = x + 24 '2 o'clock to 3 o'clock elseif x > 130 then LEDrate = x + 26 '3 o'clock to FTCW endif return tempopress: if ticks >= 180 then ' if longer than 3 45bpm since last press assume this is first press and start ticks counter over ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 157 and ticks > 60 then ' set delay time on this press based on how much time has elapsed since last press x = ticks - 20 ' compensate for TRM0 being slightly faster than 10ms when tempo is slower than 100bpm gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 60 and ticks > 57 then 'tempo between 100bpm and 110bpm x = ticks - 7 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks < 57 and ticks > 15 then 'tempo faster than 110bpm x = ticks - 15 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks < 180 and ticks > 157 then ' if tap duration is slighlty longer than max delay time, then set to max delay time. x = 157 - 7 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 15 then 'tap too fast x = 3 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif goto main division: ' tap multiplier subroutine div var byte adcin 2, w ' read toggle switch on channel 1 and store in w if w < 51 then ' 1:1 ratio or quarter note x = x endif if w >= 51 and w < 102 then ' 1:1.5 ratio or dotted eigth note lookup x, [1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,5,6,7,7,8,9,10,11,12,13,13,14,15,15,16,16,17,17,17,18,19,19,20,21,22,22,23,_ 24,24,25,25,26,27,28,28,29,30,30,31,33,33,34,35,35,36,37,37,38,38,39,39,40,40,41,42,42,43,44,45,46,47,47,48,49,_ 50,50,51,51,52,52,53,54,54,55,55,56,57,58,58,60,60,61,61,62,63,63,64,65,66,66,66,67,68,69,69,69,70,71,72,72,72,73,74,75,75,75,_ 76,77,77,78,78,79,80,81,82,82,82,82,83,84,84,85,86,86,87,88,89,89,90,91,92,92,92,93,93,94,94], div x = div endif if w >= 102 and w < 153 then '1:2 ratio or eigth note lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,4,5,5,6,6,7,7,8,8,8,9,10,11,11,12,13,14,14,15,_ 15,15,16,16,16,17,17,18,18,19,19,20,20,21,22,22,23,23,23,24,24,25,25,25,26,26,27,27,28,28,29,29,30,31,32,33,33,34,34,35,35,36,36,_ 37,37,38,39,39,39,40,40,41,42,42,42,43,43,44,44,45,45,46,46,46,47,47,48,48,48,49,49,50,50,51,51,52,53,53,53,54,54,54,55,55,55,57,_ 57,58,58,58,58,60,60,60,60,62,62,62,62,4,64,64,64,66,66,66,66,68,68,68,68], div x = div endif if w >= 153 and w < 204 then '1:3 ratio (triplets) lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,4,_ 4,4,5,5,5,5,6,6,7,7,7,8,8,9,9,10,10,11,11,12,12,12,13,13,13,14,14,14,15,15,15,16,16,16,17,17,17,17,17,18,18,19,19,_ 20,20,20,21,21,21,22,22,22,23,23,23,24,24,24,25,25,25,26,26,26,26,27,27,27,27,27,28,28,28,29,29,30,30,30,31,31,32,33,33,33,34,_ 34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40], div x = div endif if w > 204 then ' 1:4 ratio or 16th note lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,_ 3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,9,9,9,10,10,11,11,12,12,12,12,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,_ 17,17,17,17,17,17,18,18,18,18,19,19,19,19,20,20,21,21,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,25,25,25,25,25,25,26,26,26,_ 27,27], div x = div endif return tempobuttonrelease: ' debounce subroutine for tempo button returnTOpotCounter var word returnTOpotCounter = 0 tempoLED = 1 do until returnTOpotCounter >= 200 if tempobutton = 1 then exit pause 10 pause 10 pause 10 ' pause 30ms. Break up into 10ms to not interfer with interrupt timer returnTOpotCounter = returnTOpotCounter + 3 loop tempoLED = 0 pause 10 pause 10 pause 10 if returnTOpotCounter >= 200 then gosub returnTOpot endif return returnTOpot: gosub readpot gosub movepot onORoff var bit onORoff = bypassLED m var byte for m = 1 to 5 bypassLED = 1 pause 200 bypassLED = 0 pause 200 next m bypassLED = onORoff return bypasspress: pause 10 pause 10 trailsmodecounter = 0 ' waits to see if you want to switch between normal or trails mode do until trailsmodecounter = 200 if bypassbutton = 1 then exit pause 10 trailsmodecounter = trailsmodecounter + 1 loop if trailsmodecounter = 200 then goto trailmodechange endif if trailsmode = 1 then gosub trailsbypass elseif trailsmode = 0 then gosub normalbypass endif return trailmodechange: ' subroutine that occurs when bypass button is held long enough to change between normal or trails mode if trailsmode = 1 then trailsmode = 0 elseif trailsmode = 0 then trailsmode = 1 endif for z = 1 to 5 tempoLED = 1 pause 200 tempoLED = 0 pause 200 next z goto main normalbypass: ' subroutine for normal bypass if bypassLED = 0 then fetA = 1 fetB = 1 fetC = 0 bypassLED = 1 elseif bypassLED = 1 then fetA = 0 fetB = 0 fetC = 1 bypassLED = 0 endif return trailsbypass: 'subroutine for trails bypass if bypassLED = 0 then fetA = 1 fetB = 1 fetC = 0 bypassLED = 1 elseif bypassLED = 1 then fetA = 0 fetB = 1 fetC = 1 bypassLED = 0 endif return bypassbuttonrelease: ' debounce subroutine when bypass button is pressed do until bypassbutton = 1 pause 10 pause 10 pause 10 loop return addtocalibrationcounter: bypassbuttoncounter var word bypassbuttoncounter = 0 do until bypassbutton = 1 pause 10 pause 10 pause 10 bypassbuttoncounter = bypassbuttoncounter + 1 loop if bypassbuttoncounter > 200 then write 1, calibrationcounter calibrationon = 0 else calibrationcounter = calibrationcounter + 1 endif return subtractfromcalibrationcounter: calibrationcounter = calibrationcounter - 1 do until tempobutton = 1 pause 10 pause 10 pause 10 loop return Disable ' Disable interrupts during interrupt handler tickint: ' Interrupt routine to handle each timer tick ticks = ticks + 1 LEDcounter = LEDcounter + 1 tiexit: INTCON.2 = 0 ' Reset timer interrupt flag Resume enable end
the most vital info is missing , what pic chip ?
Warning I'm not a teacher
Duh. Sorry. I'm a pretty much a newb and it's been at least a year since I've used PBP. It took me like 2 days to figure everything that was going on here, and I was the one that wrote it.
I'm using the PC16F684
If it helps, here's link to the schematic http://byocelectronics.com/echoroyalschematic.pdf
I'm using the PIC16F684. The previous version of this code worked just fine when the PT2399 delay chip had a very precise delay time, but they have become inconsistent which causes the tap tempo feature to be slightly out of sync with the delay time. I'm trying to add a "calibration" feature to sync the actual delay time with the tap tempo by adding or subracting postions on the digital potentiometer.
I've reposted the code and highlighted the parts that have been added or modified in blue. Here's a link to the schematic http://byocelectronics.com/echoroyalschematic.pdf The idea is that if the user is holding down SW2 during power up, it will go into "calibration mode". SW2 should now add 1 movement on the digital pot and SW1 should remove one movement. Holding down SW2 for 3 seconds should WRITE calibrationcounter to memory and return to normal function.
I forgot to mention the VR6 "tap multiplier" function, in case you're wondering what all the weird lookup tables are there for. This is a feature commonly requested by guitar players when using a delay/echo effect. It's used with the tap tempo. It sets the delay time so that the echoes will beat at straight quarter note, dotted eighth note, triplet, or 16th intervals and the user only needs to tap out a straight quarter note beat.
Code:#config __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF #endconfig ADCON0 = %00000000 ADCON1 = %00110000 ANSEL = %00000110 define ADC_SAMPLEUS 50 define ADC_BITS 8 DEFINE ADC_CLOCK 3 CMCON0 = %00000111 TRISA = %00001111 TRISC = %00000000 ' Set TMR0 interrupt prescaler to 1:32 OPTION_REG = %10000100 ' Set TMR0 configuration and enable PORTB pullups INTCON = %10100000 ' Enable TMR0 interrupts On Interrupt Goto tickint define WRITE_INT 1 ' ' Hardware connection ' =================== CS VAR PORTA.5 SCK VAR PORTC.2 SDI VAR PORTC.1 tempoLED var PORTC.0 tempobutton var PORTA.0 bypassbutton var PORTA.3 bypassLED var PORTC.4 fetA var PORTC.5 fetB var PORTA.4 fetC var PORTC.3 ;pot is on porta.2 an2 ' ' Variables definition ' =================== x var word y var word w var byte z var byte a var byte ' ADC in variable for tempo LED calibration b var byte ' tempo LED calibration variable used in main program c var byte ' ADC in variable for tap calibration d var byte ' tap calibration variable used in main program plusORminus var bit plusORminus1 var bit plusORminus2 var bit plusORminus3 var bit ticks var word LEDcounter var word LEDrate var word trailsmodecounter var word trailsmode var bit xprevious var byte override var bit analogpot var bit footswitch var bit analogpot = 1 footswitch = 0 LEDadj var byte LEDadj1 var byte tapadj var byte tapadj1 var byte calibrationcounter var byte calibrationon var bit ' Calibration check '================================================================ calibrationon = 0 read 1, calibrationcounter if bypassbutton = 0 then 'hold down bypass button on power up to calibrate goto bypassbuttonrelease calibrationon = 1 endif ' ' begin in "bypass" state ' ==================== tempoLED = 0 fetA = 0 fetB = 0 fetC = 1 bypassLED = 0 trailsmode = 0 override = analogpot pause 1000 gosub readpot gosub movepot pause 100 ' MAIN PROGRAM '================================================================= main: gosub potcheck if LEDcounter < 3 then tempoLED = 1 else tempoLED = 0 endif if tempobutton = 0 then if calibrationon = 1 then goto subtractfromcalibrationcounter else goto tempopress endif endif if ticks > 400 then ticks = 300 endif if LEDcounter > LEDrate then LEDcounter = 0 endif if bypassBUTTON = 0 then if calibrationon = 1 then gosub addtocalibrationcounter else gosub bypasspress endif gosub bypassbuttonrelease ENDif goto main potcheck: gosub readpot if abs (xprevious-x) > 4 then override = analogpot gosub movepot endif return readpot: adcin 1,x x = x * 10 x = x/17 'x = 1 max x return movepot: x = x + calibrationcounter CS = 0 shiftout SDI, SCK, 1, [00000000,x] shiftout SDI, SCK, 1, [00010000,x] CS = 1 x = x - calibrationcounter if override = analogpot then 'checks to see if the delay time was set by the pot or switch xprevious = x endif gosub tempoLEDadjust return tempoLEDadjust: ' compensate for TMR0 not being 1:1 with actual delay time if x < 25 then LEDrate = x + 16 elseif x >= 25 and x < 50 then LEDrate = x + 18 elseif x >= 50 and x < 75 then LEDrate = x + 20 elseif x >= 75 and x < 95 then LEDrate = x + 22 'noon to 2 o'clock elseif x >= 95 and x < 130 then LEDrate = x + 24 '2 o'clock to 3 o'clock elseif x > 130 then LEDrate = x + 26 '3 o'clock to FTCW endif return tempopress: if ticks >= 180 then ' if longer than 3 45bpm since last press assume this is first press and start ticks counter over ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 157 and ticks > 60 then ' set delay time on this press based on how much time has elapsed since last press x = ticks - 20 ' compensate for TRM0 being slightly faster than 10ms when tempo is slower than 100bpm gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 60 and ticks > 57 then 'tempo between 100bpm and 110bpm x = ticks - 7 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks < 57 and ticks > 15 then 'tempo faster than 110bpm x = ticks - 15 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks < 180 and ticks > 157 then ' if tap duration is slighlty longer than max delay time, then set to max delay time. x = 157 - 7 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 15 then 'tap too fast x = 3 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif goto main division: ' tap multiplier subroutine div var byte adcin 2, w ' read toggle switch on channel 1 and store in w if w < 51 then ' 1:1 ratio or quarter note x = x endif if w >= 51 and w < 102 then ' 1:1.5 ratio or dotted eigth note lookup x, [1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,5,6,7,7,8,9,10,11,12,13,13,14,15,15,16,16,17,17,17,18,19,19,20,21,22,22,23,_ 24,24,25,25,26,27,28,28,29,30,30,31,33,33,34,35,35,36,37,37,38,38,39,39,40,40,41,42,42,43,44,45,46,47,47,48,49,_ 50,50,51,51,52,52,53,54,54,55,55,56,57,58,58,60,60,61,61,62,63,63,64,65,66,66,66,67,68,69,69,69,70,71,72,72,72,73,74,75,75,75,_ 76,77,77,78,78,79,80,81,82,82,82,82,83,84,84,85,86,86,87,88,89,89,90,91,92,92,92,93,93,94,94], div x = div endif if w >= 102 and w < 153 then '1:2 ratio or eigth note lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,4,5,5,6,6,7,7,8,8,8,9,10,11,11,12,13,14,14,15,_ 15,15,16,16,16,17,17,18,18,19,19,20,20,21,22,22,23,23,23,24,24,25,25,25,26,26,27,27,28,28,29,29,30,31,32,33,33,34,34,35,35,36,36,_ 37,37,38,39,39,39,40,40,41,42,42,42,43,43,44,44,45,45,46,46,46,47,47,48,48,48,49,49,50,50,51,51,52,53,53,53,54,54,54,55,55,55,57,_ 57,58,58,58,58,60,60,60,60,62,62,62,62,4,64,64,64,66,66,66,66,68,68,68,68], div x = div endif if w >= 153 and w < 204 then '1:3 ratio (triplets) lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,4,_ 4,4,5,5,5,5,6,6,7,7,7,8,8,9,9,10,10,11,11,12,12,12,13,13,13,14,14,14,15,15,15,16,16,16,17,17,17,17,17,18,18,19,19,_ 20,20,20,21,21,21,22,22,22,23,23,23,24,24,24,25,25,25,26,26,26,26,27,27,27,27,27,28,28,28,29,29,30,30,30,31,31,32,33,33,33,34,_ 34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40], div x = div endif if w > 204 then ' 1:4 ratio or 16th note lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,_ 3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,9,9,9,10,10,11,11,12,12,12,12,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,_ 17,17,17,17,17,17,18,18,18,18,19,19,19,19,20,20,21,21,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,25,25,25,25,25,25,26,26,26,_ 27,27], div x = div endif return tempobuttonrelease: ' debounce subroutine for tempo button returnTOpotCounter var word returnTOpotCounter = 0 tempoLED = 1 do until returnTOpotCounter >= 200 if tempobutton = 1 then exit pause 10 pause 10 pause 10 ' pause 30ms. Break up into 10ms to not interfer with interrupt timer returnTOpotCounter = returnTOpotCounter + 3 loop tempoLED = 0 pause 10 pause 10 pause 10 if returnTOpotCounter >= 200 then gosub returnTOpot endif return returnTOpot: gosub readpot gosub movepot onORoff var bit onORoff = bypassLED m var byte for m = 1 to 5 bypassLED = 1 pause 200 bypassLED = 0 pause 200 next m bypassLED = onORoff return bypasspress: pause 10 pause 10 trailsmodecounter = 0 ' waits to see if you want to switch between normal or trails mode do until trailsmodecounter = 200 if bypassbutton = 1 then exit pause 10 trailsmodecounter = trailsmodecounter + 1 loop if trailsmodecounter = 200 then goto trailmodechange endif if trailsmode = 1 then gosub trailsbypass elseif trailsmode = 0 then gosub normalbypass endif return trailmodechange: ' subroutine that occurs when bypass button is held long enough to change between normal or trails mode if trailsmode = 1 then trailsmode = 0 elseif trailsmode = 0 then trailsmode = 1 endif for z = 1 to 5 tempoLED = 1 pause 200 tempoLED = 0 pause 200 next z goto main normalbypass: ' subroutine for normal bypass if bypassLED = 0 then fetA = 1 fetB = 1 fetC = 0 bypassLED = 1 elseif bypassLED = 1 then fetA = 0 fetB = 0 fetC = 1 bypassLED = 0 endif return trailsbypass: 'subroutine for trails bypass if bypassLED = 0 then fetA = 1 fetB = 1 fetC = 0 bypassLED = 1 elseif bypassLED = 1 then fetA = 0 fetB = 1 fetC = 1 bypassLED = 0 endif return bypassbuttonrelease: ' debounce subroutine when bypass button is pressed do until bypassbutton = 1 pause 10 pause 10 pause 10 loop return addtocalibrationcounter: bypassbuttoncounter var word bypassbuttoncounter = 0 do until bypassbutton = 1 pause 10 pause 10 pause 10 bypassbuttoncounter = bypassbuttoncounter + 1 loop if bypassbuttoncounter > 200 then write 1, calibrationcounter calibrationon = 0 else calibrationcounter = calibrationcounter + 1 endif return subtractfromcalibrationcounter: calibrationcounter = calibrationcounter - 1 do until tempobutton = 1 pause 10 pause 10 pause 10 loop return Disable ' Disable interrupts during interrupt handler tickint: ' Interrupt routine to handle each timer tick ticks = ticks + 1 LEDcounter = LEDcounter + 1 tiexit: INTCON.2 = 0 ' Reset timer interrupt flag Resume enable end
Last edited by keithv; - 9th December 2021 at 23:03.
i should have asked what version of pbp also , not that it matters in this case the problem is that the code will no longer fit in the chipI'm using the PIC16F684
you need to trim the code down or get a bigger chip
Warning I'm not a teacher
typo ?
Code:if w >= 102 and w < 153 then '1:2 ratio or eigth note lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,4,5,5,6,6,7,7,8,8,8,9,10,11,11,12,13,14,14,15,_ 15,15,16,16,16,17,17,18,18,19,19,20,20,21,22,22,23,23,23,24,24,25,25,25,26,26,27,27,28,28,29,29,30,31,32,33,33,34,34,35,35,36,36,_ 37,37,38,39,39,39,40,40,41,42,42,42,43,43,44,44,45,45,46,46,46,47,47,48,48,48,49,49,50,50,51,51,52,53,53,53,54,54,54,55,55,55,57,_ 57,58,58,58,58,60,60,60,60,62,62,62,62,4,64,64,64,66,66,66,66,68,68,68,68], div x = div endif
Last edited by richard; - 9th December 2021 at 23:28.
Warning I'm not a teacher
you only get it if it's an ok compilecan't find it now.
Warning I'm not a teacher
A lot has transpired while I was asleep in my TimeZone. I think you found your answer.
you can always replace pbp's highly inefficient lookups with asm tables for byte sized data
just make sure the index will not to exceed the table's number of entries
this is a slightly incomplete and untested example of asm table
since your table data never exceeds 7 bits a packed 14 bit "DA" table could be used also
halving the data size yet again [see my packed fonts for ssd1306 etc ] an unpacking routine
is simple and quick
Code:#config __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF #endconfig ADCON0 = %00000000 ADCON1 = %00110000 ANSEL = %00000110 define ADC_SAMPLEUS 50 define ADC_BITS 8 DEFINE ADC_CLOCK 3 CMCON0 = %00000111 TRISA = %00001111 TRISC = %00000000 ' Set TMR0 interrupt prescaler to 1:32 OPTION_REG = %10000100 ' Set TMR0 configuration and enable PORTB pullups INTCON = %10100000 ' Enable TMR0 interrupts On Interrupt Goto tickint define WRITE_INT 1 ' ' Hardware connection ' =================== CS VAR PORTA.5 SCK VAR PORTC.2 SDI VAR PORTC.1 tempoLED var PORTC.0 tempobutton var PORTA.0 bypassbutton var PORTA.3 bypassLED var PORTC.4 fetA var PORTC.5 fetB var PORTA.4 fetC var PORTC.3 ;pot is on porta.2 an2 ' ' Variables definition ' =================== LU_TMP var word temporary storage for tables x var word y var word w var byte z var byte a var byte ' ADC in variable for tempo LED calibration b var byte ' tempo LED calibration variable used in main program c var byte ' ADC in variable for tap calibration d var byte ' tap calibration variable used in main program plusORminus var bit plusORminus1 var bit plusORminus2 var bit plusORminus3 var bit ticks var word LEDcounter var word LEDrate var word trailsmodecounter var word trailsmode var bit xprevious var byte override var bit analogpot var bit footswitch var bit analogpot = 1 footswitch = 0 LEDadj var byte LEDadj1 var byte tapadj var byte tapadj1 var byte calibrationcounter var byte calibrationon var bit ' Calibration check '================================================================ calibrationon = 0 read 1, calibrationcounter if bypassbutton = 0 then 'hold down bypass button on power up to calibrate goto bypassbuttonrelease calibrationon = 1 endif ' ' begin in "bypass" state ' ==================== tempoLED = 0 fetA = 0 fetB = 0 fetC = 1 bypassLED = 0 trailsmode = 0 override = analogpot pause 1000 gosub readpot gosub movepot pause 100 ' MAIN PROGRAM '================================================================= main: gosub potcheck if LEDcounter < 3 then tempoLED = 1 else tempoLED = 0 endif if tempobutton = 0 then if calibrationon = 1 then goto subtractfromcalibrationcounter else goto tempopress endif endif if ticks > 400 then ticks = 300 endif if LEDcounter > LEDrate then LEDcounter = 0 endif if bypassBUTTON = 0 then if calibrationon = 1 then gosub addtocalibrationcounter else gosub bypasspress endif gosub bypassbuttonrelease ENDif goto main potcheck: gosub readpot if abs (xprevious-x) > 4 then override = analogpot gosub movepot endif return readpot: adcin 1,x x = x * 10 x = x/17 'x = 1 max x return movepot: x = x + calibrationcounter CS = 0 shiftout SDI, SCK, 1, [00000000,x] shiftout SDI, SCK, 1, [00010000,x] CS = 1 x = x - calibrationcounter if override = analogpot then 'checks to see if the delay time was set by the pot or switch xprevious = x endif gosub tempoLEDadjust return tempoLEDadjust: ' compensate for TMR0 not being 1:1 with actual delay time if x < 25 then LEDrate = x + 16 elseif x >= 25 and x < 50 then LEDrate = x + 18 elseif x >= 50 and x < 75 then LEDrate = x + 20 elseif x >= 75 and x < 95 then LEDrate = x + 22 'noon to 2 o'clock elseif x >= 95 and x < 130 then LEDrate = x + 24 '2 o'clock to 3 o'clock elseif x > 130 then LEDrate = x + 26 '3 o'clock to FTCW endif return tempopress: if ticks >= 180 then ' if longer than 3 45bpm since last press assume this is first press and start ticks counter over ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 157 and ticks > 60 then ' set delay time on this press based on how much time has elapsed since last press x = ticks - 20 ' compensate for TRM0 being slightly faster than 10ms when tempo is slower than 100bpm gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 60 and ticks > 57 then 'tempo between 100bpm and 110bpm x = ticks - 7 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks < 57 and ticks > 15 then 'tempo faster than 110bpm x = ticks - 15 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks < 180 and ticks > 157 then ' if tap duration is slighlty longer than max delay time, then set to max delay time. x = 157 - 7 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif if ticks <= 15 then 'tap too fast x = 3 gosub division override = footswitch gosub movepot ticks = 0 gosub tempobuttonrelease goto main endif goto main division: ' tap multiplier subroutine div var byte adcin 2, w ' read toggle switch on channel 1 and store in w if w < 51 then ' 1:1 ratio or quarter note x = x endif if w >= 51 and w < 102 then ' 1:1.5 ratio or dotted eigth note call lu1 @ MOVE?AB _x endif if w >= 102 and w < 153 then '1:2 ratio or eighth note call lu2 @ MOVE?AB _x endif if w >= 153 and w < 204 then '1:3 ratio (triplets) lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,4,_ 4,4,5,5,5,5,6,6,7,7,7,8,8,9,9,10,10,11,11,12,12,12,13,13,13,14,14,14,15,15,15,16,16,16,17,17,17,17,17,18,18,19,19,_ 20,20,20,21,21,21,22,22,22,23,23,23,24,24,24,25,25,25,26,26,26,26,27,27,27,27,27,28,28,28,29,29,30,30,30,31,31,32,33,33,33,34,_ 34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40], div x = div endif if w > 204 then ' 1:4 ratio or 16th note lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,_ 3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,9,9,9,10,10,11,11,12,12,12,12,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,_ 17,17,17,17,17,17,18,18,18,18,19,19,19,19,20,20,21,21,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,25,25,25,25,25,25,26,26,26,_ 27,27], div x = div endif return tempobuttonrelease: ' debounce subroutine for tempo button returnTOpotCounter var word returnTOpotCounter = 0 tempoLED = 1 do until returnTOpotCounter >= 200 if tempobutton = 1 then exit pause 10 pause 10 pause 10 ' pause 30ms. Break up into 10ms to not interfer with interrupt timer returnTOpotCounter = returnTOpotCounter + 3 loop tempoLED = 0 pause 10 pause 10 pause 10 if returnTOpotCounter >= 200 then gosub returnTOpot endif return returnTOpot: gosub readpot gosub movepot onORoff var bit onORoff = bypassLED m var byte for m = 1 to 5 bypassLED = 1 pause 200 bypassLED = 0 pause 200 next m bypassLED = onORoff return bypasspress: pause 10 pause 10 trailsmodecounter = 0 ' waits to see if you want to switch between normal or trails mode do until trailsmodecounter = 200 if bypassbutton = 1 then exit pause 10 trailsmodecounter = trailsmodecounter + 1 loop if trailsmodecounter = 200 then goto trailmodechange endif if trailsmode = 1 then gosub trailsbypass elseif trailsmode = 0 then gosub normalbypass endif return trailmodechange: ' subroutine that occurs when bypass button is held long enough to change between normal or trails mode if trailsmode = 1 then trailsmode = 0 elseif trailsmode = 0 then trailsmode = 1 endif for z = 1 to 5 tempoLED = 1 pause 200 tempoLED = 0 pause 200 next z goto main normalbypass: ' subroutine for normal bypass if bypassLED = 0 then fetA = 1 fetB = 1 fetC = 0 bypassLED = 1 elseif bypassLED = 1 then fetA = 0 fetB = 0 fetC = 1 bypassLED = 0 endif return trailsbypass: 'subroutine for trails bypass if bypassLED = 0 then fetA = 1 fetB = 1 fetC = 0 bypassLED = 1 elseif bypassLED = 1 then fetA = 0 fetB = 1 fetC = 1 bypassLED = 0 endif return bypassbuttonrelease: ' debounce subroutine when bypass button is pressed do until bypassbutton = 1 pause 10 pause 10 pause 10 loop return addtocalibrationcounter: bypassbuttoncounter var word bypassbuttoncounter = 0 do until bypassbutton = 1 pause 10 pause 10 pause 10 bypassbuttoncounter = bypassbuttoncounter + 1 loop if bypassbuttoncounter > 200 then write 1, calibrationcounter calibrationon = 0 else calibrationcounter = calibrationcounter + 1 endif return subtractfromcalibrationcounter: calibrationcounter = calibrationcounter - 1 do until tempobutton = 1 pause 10 pause 10 pause 10 loop return Disable ' Disable interrupts during interrupt handler tickint: ' Interrupt routine to handle each timer tick ticks = ticks + 1 LEDcounter = LEDcounter + 1 tiexit: INTCON.2 = 0 ' Reset timer interrupt flag Resume enable end lu1: asm ; ok for pic 16 or 18 MOVE?BA _x ; x is the index watch its size BANKSEL _LU_TMP BCF STATUS,C ifdef TBLPTRL RLCF WREG,F endif CLRF _LU_TMP+1 addlw low(lu1_t) movwf _LU_TMP ifdef TBLPTRL RLCF _LU_TMP+1,w else RLF _LU_TMP+1,w endif BANKSEL 0 addlw high(lu1_t ) movwf PCLATH movf _LU_TMP,w movwf PCL lu1_t ;start of table data RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 2 RETLW 2 RETLW 2 RETLW 3 RETLW 3 RETLW 4 RETLW 5 RETLW 6 RETLW 7 RETLW 7 RETLW 8 RETLW 9 RETLW 10 RETLW 11 RETLW 12 RETLW 13 RETLW 13 RETLW 14 RETLW 15 RETLW 15 RETLW 16 RETLW 16 RETLW 17 RETLW 17 RETLW 17 RETLW 18 RETLW 19 RETLW 19 RETLW 20 RETLW 21 RETLW 22 RETLW 22 RETLW 23 RETLW 24 RETLW 24 RETLW 25 RETLW 25 RETLW 26 RETLW 27 RETLW 28 RETLW 28 RETLW 29 RETLW 30 RETLW 30 RETLW 31 RETLW 33 RETLW 33 RETLW 34 RETLW 35 RETLW 35 RETLW 36 RETLW 37 RETLW 37 RETLW 38 RETLW 38 RETLW 39 RETLW 39 RETLW 40 RETLW 40 RETLW 41 RETLW 42 RETLW 42 RETLW 43 RETLW 44 RETLW 45 RETLW 46 RETLW 47 RETLW 47 RETLW 48 RETLW 49 RETLW 50 RETLW 50 RETLW 51 RETLW 51 RETLW 52 RETLW 52 RETLW 53 RETLW 54 RETLW 54 RETLW 55 RETLW 55 RETLW 56 RETLW 57 RETLW 58 RETLW 58 RETLW 60 RETLW 60 RETLW 61 RETLW 61 RETLW 62 RETLW 63 RETLW 63 RETLW 64 RETLW 65 RETLW 66 RETLW 66 RETLW 66 RETLW 67 RETLW 68 RETLW 69 RETLW 69 RETLW 69 RETLW 70 RETLW 71 RETLW 72 RETLW 72 RETLW 72 RETLW 73 RETLW 74 RETLW 75 RETLW 75 RETLW 75 RETLW 76 RETLW 77 RETLW 77 RETLW 78 RETLW 78 RETLW 79 RETLW 80 RETLW 81 RETLW 82 RETLW 82 RETLW 82 RETLW 82 RETLW 83 RETLW 84 RETLW 84 RETLW 85 RETLW 86 RETLW 86 RETLW 87 RETLW 88 RETLW 89 RETLW 89 RETLW 90 RETLW 91 RETLW 92 RETLW 92 RETLW 92 RETLW 93 RETLW 93 RETLW 94 RETLW 94 ENDasm lu2: asm MOVE?BA _x BANKSEL _LU_TMP BCF STATUS,C ifdef TBLPTRL RLCF WREG,F endif CLRF _LU_TMP+1 addlw low(lu2_t) movwf _LU_TMP ifdef TBLPTRL RLCF _LU_TMP+1,w else RLF _LU_TMP+1,w endif BANKSEL 0 addlw high(lu2_t ) movwf PCLATH movf _LU_TMP,w movwf PCL lu2_t RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 RETLW 1 ETC ETC ETC ..............................
Warning I'm not a teacher
Thank you very much for that lesson, Richard. I really need to work on learning ASM.
I checked the amount of flash used on the previous version. It's at exactly 2k words with the inefficient PBP look up tables. The 16F684 has 2048 words, so I'm assuming the new modification added 135 words based on the error msg. Is switching the look up tables to ASM going to free up enough space?
Switching to a 16F1xxx chip would obviously solve the problem, as they have more flash and they are actually cheaper! The 16F1613 for example is almost $1.25ea. less. I have to upgrade my version of PBP, but it will pay for itself pretty quickly. So I think I'm going to do that regardless of whether or not I can cram it all into a 16F684. The most practical solution to my real problem is to make R44 an internal trimpot, but that will have to wait till the next production run of PCBs.
easily , the one i completed saved 15 words at least all four would get another 30 or 40 i expectIs switching the look up tables to ASM going to free up enough space?
replacing your readpot routine with this gets another 40 by eliminating that costly divide
Code:readpot: adcin 1,x x=x*/151 '*************** return
Last edited by richard; - 10th December 2021 at 21:54. Reason: chopped a chunk of code out messed up figures
Warning I'm not a teacher
One other thing I notice is that the tables mostly have 152 members , x is always between 0 and 150 as far as i can see
the second table had 153 members , typo ?
Warning I'm not a teacher
Yep. That was a typo. Thanks for catching that.
Thanks so much for helping me with this. Sorry for not getting back sooner. I was out for two weeks with Covid and then I got sidetracked by a bunch of year-end stuff. Anyhow...The program doesn't work because of some mistake I made in the new calibration routine. But I did swap out the look up tables with your new ASM tables in the original "verified" program and they work perfectly. And saved 25 words!
So now I've got to work on the calibration routine. I should be able to make it work in 47 words. After setting it aside for a while, I think I'm going to start over and come at it from a different angle.
Bookmarks