In CASE of mystery

in Propeller 1
Dear Forum, I have gone code-blind. What is wrong with below CASE section? - the compiler stops at 64 with "Expected and instruction or variable"
Erlend
PUB Gain(gainSel) | bGain, regbyte
CASE gainSel
128: bGain:= 7 'gain selected - in dB
64: bGain:= 6
32: bGain:= 5
16: bGain:= 4
8: bGain:= 3
4: bGain:= 2
2: bGain:= 1
1: bGain:= 0
OTHER: RETURN FALSE
regByte:= i2c.ReadByteA8(ChipAddr, CTRL1_CRP) & !bGAINselCTRL1 'blank out the old Gain bits
i2c.WriteByteA8(ChipAddr, PWR_CTRL, regByte | bGain) 'write byte with new lower 3 bits representing Gain
Recal 'always do re-cal after
RETURN bGain
Erlend
Comments
CASE gainSel 128: bGain:= 7 'gain selected - in dB 64: bGain:= 6 32: bGain:= 5 16: bGain:= 4 8: bGain:= 3 4: bGain:= 2 2: bGain:= 1 1: bGain:= 0 OTHER: RETURN FALSE regByte:= i2c.ReadByteA8(ChipAddr, CTRL1_CRP) & !bGAINselCTRL1 'blank out the old Gain bits i2c.WriteByteA8(ChipAddr, PWR_CTRL, regByte | bGain) 'write byte with new lower 3 bits representing Gain Recal 'always do re-cal after RETURN bGain
ErlendSince the outcome is a single variable update, I suggest you replace case with this line: (corrected)
bGain := lookdownz(gainSel : 1, 2, 4, 8, 16, 32, 64, 128)
IF gainSel is in the list you'll get 0..7 back, otherwise you'll get 0 -- this is exactly what your case is doing.bGain := ((>|gainSel)-1) #> 0
(other values will get rounded down to the nearest power of two)case gainSel 000..001 : bGain := 0 002..003 : bGain := 1 004..007 : bGain := 2 008..015 : bGain := 3 016..031 : bGain := 4 032..063 : bGain := 5 064..127 : bGain := 6 128 : bGain := 7 other : bGain := 0
That said, there is no upper limit, so you may want to modify like this:bGain := 0 #> >|gainSel-1 <# 7
Warning: If gainSel goes negative, you're always going to get 7 for bGain. You could fix that with:if (gainSel > 0) bGain := 0 #> >|gainSel-1 <# 7 else bGain := 0
I like this solution a lot. I have several of these parameter list situations, and not all of them are regular like this one.
Erlend
bGain := LOOKUP(gainSel : 1, 2, 4, 8, 16, 32, 64, 128) 'convert from desired gain dB to bit numbers to set IF bGain == 0 'if not found, do not write to register RETURN FALSE bGain -= 1 'because I used lookup instead of lookupz regByte:= i2c.ReadByteA8(ChipAddr, CTRL1_CRP) & !bGAINselCTRL1 'blank out the old Gain bits i2c.WriteByteA8(ChipAddr, PWR_CTRL, regByte | bGain) 'write byte with new lower 3 bits representing Gain Recal 'always do re-cal after RETURN bGain
Agree?Now I have read the manual (again) and gotten to know that LOOKUP(Z) takes an index and returns the corresponding number in the list, whereas LOOKDOWN(Z) takes a number and returns its index in the list. I need the latter. Thanks @JonnyMac and @Wuerfel_21
bGain := LOOKDOWN(gainSel : 1, 2, 4, 8, 16, 32, 64, 128) 'convert from desired gain dB to bit numbers to set IF bGain == 0 'if not found, do not write to register RETURN FALSE bGain -= 1 'because I used lookdown instead of lookdownz regByte:= i2c.ReadByteA8(ChipAddr, CTRL1_CRP) & !bGAINselCTRL1 'blank out the old Gain bits i2c.WriteByteA8(ChipAddr, CTRL1_CRP, regByte | bGain) 'write byte with new lower 3 bits representing Gain Recal 'always do re-cal after RETURN gainSel
bSPS := LOOKDOWN(SPSsel : 10, 20, 40, 80, -1, -1, -1, 320) IF bSPS == 0 RETURN FALSE bSPS -= 1
Erlend