CLS
OPTION EXPLICIT
OPTION DEFAULT NONE
OPTION BASE 0
OPTION AUTORUN ON
CONST ERRORLOGENTRIES = 10
CPU 80
CONST C.FOREGROUND = RGB(white)
CONST C.BACKGROUND = RGB(BLACK)
Const C.TEXT = RGB(192,192,192)
CONST C.ERROR = RGB(RED)
CONST C.BUTTON = RGB(BLUE)
CONST C.FREQ = RGB(WHITE)
CONST C.WARNING = RGB(YELLOW)
CONST C.BUTTONHIGHLIGHT = RGB(64,64,255)
CONST C.BUTTONFADE = RGB(64,64,64)
CONST C.FOREGROUNDFADE =RGB(GRAY)
CONST amRadio = 0, fmRadio = 1, dabRadio = 2
CONST amMin = 520, amMax = 1710, amDeltaLarge = 9
CONST fmMin = 76000, fmMax = 108000, fmDeltaLarge = 100
CONST dabMin = 168000, dabMax = 240000, dabDeltaLarge = 100
CONST audioAnalog = &H8001
CONST audioDigital = &H8002
CONST mainPage = 1, standbyButton = 2, settingsPage = 3
CONST muting = 4
CONST volumeControl = 5
CONST channelInfo = 6
CONST curName = 7
CONST curFreqGUI = 8, curFreqUnits = 9, curFreqDown = 10, curFreqUp = 11, curServDown = 12, curServUp = 13
CONST SNR = 40, SNRUnits = 41
CONST SS = 42, SSUnits = 43
CONST curFreqUpUp = 44, curFreqDownDown = 45
CONST curFreqSeekUp=48  ,curFreqSeekDown=49
CONST trackInfo = 46, trackFrame=47
CONST radioModeAM = 14, radioModeFM = 15, radioModeDAB = 16
CONST ch0Button = 17
CONST forceMono = 50
CONST quietMode = 51
CONST FMStereoICON =52
CONST saveSettings = 57
CONST setBacklightMax =58, setBacklightMin=59, setBacklightDelay=60
CONST setBacklightMaxT =61, setBacklightMinT=62, setBacklightDelayT=63
CONST curLocaleGUI=64, curLocaleName=65
CONST errorLogSpinbox=66, errorLogCaption=67, errorLogError=68
CONST copySDtoFlashGUI =69
CONST analogDigitalSelect=70
CONST stereoSwap=71
CONST speakerGain=72, speakerGainText=73
CONST RESETPIN = 74
const IC2RST = 61
const IC2IFM = 60
const IC2CSB = 59
CONST IRRPIN = 99
CONST HPSWPIN = 14
CONST IC6MUTE = 0
CONST IC6NORMAL = 1
CONST IC6REVERSE =2
CONST IC6EXTERNAL =3
CONST IC6BIT0=25
CONST IC6BIT1=24
CONST IC4SD = 68
CONST IC4UP = 67
CONST IC4DN = 66
VariableInit
GuiSetup
LoadFromFlash
if curMode <> amRadio AND curMode <> fmRadio AND curMode <> dabRadio THEN curMode=amRadio
if (curMode=dabRadio) and (curChannelSelected>-1) THEN flagDABserviceChange=1
GUI HIDE ALL
newChannelSelected=curChannelSelected
if curChannelSelected>=0 and curChannelSelected<=7 then
SwitchToChannel(curChannelSelected)
ENDIF
InitSplashScreen(C.FOREGROUND)
Si4689ControlsFlash()
TEXT 0,479,"Starting WM8804              ","LB",5,1,C.FOREGROUND,C.BACKGROUND
SetupIO()
Print "Reset and Power UP"
PAUSE 500
GUI INTERRUPT HandleTouchDown, HandleTouchUp
SETTICK 300, TickInterrupt
IR DevCode, KeyCode, IR_Int
infoText=""
newChannelSelected=curChannelSelected
newMode=curMode
newFreq=curFreq
SwitchToChannel(curChannelSelected)
curChannelSelected=-1
curMode=-1
curFreq=-1
DO
if curChannelSelected <> newChannelSelected THEN
BlankRDSstrings
curChannelSelected=newChannelSelected
SwitchToChannel(curChannelSelected)
for i = 0 to 7
if i=curChannelSelected THEN
GUI BCOLOUR C.BUTTONHIGHLIGHT,ch0Button+i
ELSE
GUI BCOLOUR C.BUTTON,ch0Button+i
ENDIF
NEXT i
ENDIF
if newMode <> curMode THEN
curMode=newMode
BlankRDSstrings
SetRadioMode(curMode)
GUI ENABLE ALL
endIF
if (flagFreqChange >0) and (newMode = curMode) THEN
BlankRDSstrings
newFreq=CtrlVal(curFreqGUI)
flagFreqChange=0
ZEnforceTuningBounds
CtrlVal(curFreqGUI)=newFreq
ENDIF
if (newFreq <> curFreq) and (newMode = curMode)THEN
BlankRDSstrings
ZenforceTuningBounds
curFreq=newFreq
SetRadioFrequency(curFreq)
ENDIF
if flagSeekUp >0 THEN
flagSeekDown=0
FreqSeekUp
ENDIF
if flagSeekDown >0 THEN
flagSeekUp=0
FreqSeekDown
ENDIF
IF (flagDABserviceChange  >0) AND (flagFreqChange =0) and (newMode = curMode) THEN
if CTRLVAL(curName)<> "Checking service" THEN
tempDABname$=CTRLVAL(curName)
CTRLVAL(curName)="Checking service"
ENDIF
CurDABService =newDABService
curDABServiceID=newDABServiceID
curDABComponentID=newDABComponentID
Print CurDABService;"/";NumDABServices
StartDigitalService(curDABServiceID,curDABComponentID)
if NumDABServices > 0 then
flagDABserviceChange=0
CTRLVAL(curName)=tempDABname$
ENDIF
ENDIF
if flagUpdateMute  >0 THEN
UpdateMute
flagUpdateMute=0
ENDIF
if flagUpdateVolume>0 THEN
UpdateVolume
flagUpdateVolume=0
ENDIF
IF analogDigitalChangeFlag>0 THEN
SetProperty(&H0800, analogDigitalFlag)
SetRadioFrequency(curFreq)
analogDigitalChangeFlag=0
ENDIF
if countScroll>len(infotext) +7 THEN
countScroll=0
ENDIF
if numEntryInProgress >0 then
stemp="     IR Entry:"+right$("      "+numEntryString,6)+"kHz"
if stemp <> CtrlVal(trackInfo) AND editBoxDisplayed=0 THEN CtrlVal(trackInfo)=stemp
ELSE
if quietModeFlag=0 THEN
if curMode = fmRadio  THEN
QueryFMRDS
ENDIF
IF curMode = dabRadio THEN
GetDABProgramInfo
ENDIF
UpdateRadioStats
if len(infotext) < 30 THEN
newInfoText=infotext
ELSE
countTemp=countScroll-6
if countTemp<0 THEN countTemp=0
newInfoText= MID$(infotext,countTemp+1,30)
ENDIF
if newInfoText <> CtrlVal(trackInfo) AND editBoxDisplayed=0 THEN CtrlVal(trackInfo)=newInfoText
ELSE
if CtrlVal(trackInfo)<>"Unavailable in Quiet Mode" then CtrlVal(trackInfo)="Unavailable in Quiet Mode"
if CTRLVAL(SNR) <> "---" then CTRLVAL(SNR) = "---"
if CTRLVAL(SS) <> "---" then CTRLVAL(SS) = "---"
if CtrlVal(FMStereoICON)<>"-" then CtrlVal(FMStereoICON)= "-"
ENDIF
ENDIF
IF FMMonoFlagChange>0 THEN
SetFMMono(FMMonoFlag)
FMMonoFlagChange=0
ENDIF
IF pin(IC4SD)=1 THEN
if speakerGainSet > CtrlVal(speakerGain) THEN
PULSEIC4DOWN
speakerGainSet=speakerGainSet-1
ENDIF
if speakerGainSet < CtrlVal(speakerGain) THEN
PULSEIC4UP
speakerGainSet=speakerGainSet+1
ENDIF
ENDIF
if (stereoSwapSet<> CtrlVal(stereoSwap)) and  (PIN(IC6BIT1)+ PIN(IC6BIT0)) = 1 THEN
IF CtrlVal(stereoSwap)= 0 THEN
SetIC6(IC6NORMAL)
stereoSwapSet=0
ELSE
SetIC6(IC6REVERSE)
stereoSwapSet=1
ENDIF
ENDIF
IF copySDtoFlashFlag >0 THEN copySDtoFlash
if CheckHeadphone()=0 THEN
SpeakerOutput(1)
if (analogDigitalFlag=audioAnalog) and (CtrlVal(analogDigitalSelect)=1) THEN
analogDigitalFlag=audioDigital
analogDigitalChangeFlag=1
ENDIF
ELSE
SpeakerOutput(0)
if analogDigitalFlag=audioDigital THEN
analogDigitalFlag=audioAnalog
analogDigitalChangeFlag=1
ENDIF
ENDIF
IF standbyFlag=1 then
PRINT "Going into standby, next touch will reset and restart."
BACKLIGHT 0
CLS
SetIC6(IC6MUTE)
SpeakerOutput(0)
PIN(IC2RST) = 0
GUI DISABLE ALL
pause 100
standbyFlag=2
DO
Loop
ENDIF
pause 100
Loop
END
SUB PULSEIC4UP
PRINT "IC4 gain up"
PIN(IC4UP)=0
PAUSE 40
PIN(IC4UP)=1
PAUSE 40
END SUB
SUB PULSEIC4DOWN
PRINT "IC4 gain down"
PIN(IC4DN)=0
PAUSE 40
PIN(IC4DN)=1
PAUSE 40
END SUB
SUB SetFMMono(n as INTEGER)
if curMode=fmRadio then
IF n>0 then
SetProperty &H3704,&H403F
SetProperty &H3700,&H7877
ELSE
SetProperty &H3704,&H180f
SetProperty &H3700,&H2010
ENDIF
ENDIF
END SUB
FUNCTION CheckHeadphone() AS INTEGER
if PIN(HPSWPIN)=0 THEN
hpCounter=hpCounter+1
ELSE
hpCounter=hpCounter-1
ENDIF
IF hpCounter<0 THEN hpCounter=0: hpState=0
IF hpCounter>3 THEN hpCounter=3: hpState=1
CheckHeadphone=hpState
END FUNCTION
SUB SetIC6(n As INTEGER)
SETPIN IC6BIT1, DOUT
SETPIN IC6BIT0, DOUT
SELECT CASE n
CASE IC6MUTE
PIN(IC6BIT1) = 0
PIN(IC6BIT0) = 0
PRINT "Audio set to mute"
CASE IC6NORMAL
PIN(IC6BIT1) = 0
PIN(IC6BIT0) = 1
PRINT "Audio set to Si4689 stereo normal"
CASE IC6REVERSE
PIN(IC6BIT1) = 1
PIN(IC6BIT0) = 0
PRINT "Audio set to Si4689 stereo reverse"
CASE IC6EXTERNAL
PIN(IC6BIT1) = 1
PIN(IC6BIT0) = 1
PRINT "Audio set to AUX"
END SELECT
END SUB
SUB TickInterrupt
LOCAL INTEGER k,b
if editBoxDisplayed = 0 THEN countScroll=countScroll+1
countBacklight=countBacklight+1
k=countBacklight-(delayBacklight*10)\3
b=maxBacklight
if k>0 and k<6 THEN b= (minBacklight-maxBacklight)*k\6+maxBacklight
if k>=6 then b= minBacklight
if editBoxDisplayed >0 THEN b=maxBacklight
BACKLIGHT b
END SUB
SUB softMute(n as integer)
if n = 0 then
for i=0 to CTRLVAL(volumeControl)
SetProperty &H0300,i
pause 3
NEXT i
ELSE
for i= CTRLVAL(volumeControl) to 0 step -1
SetProperty &H0300,i
pause 3
NEXT i
ENDIF
END SUB
SUB UpdateMute
print "setting mute to...",CTRLVAL(muting)
IF CTRLVAL(muting) = 1 THEN
softMute(1)
SetProperty   &H0301, 3
GUI DISABLE volumeControl
GUI FCOLOUR C.FOREGROUNDFADE, volumeControl
GUI BCOLOUR C.BUTTONFADE, volumeControl
ELSE
SetProperty &H0301, 0
softMute(0)
GUI ENABLE volumeControl
GUI FCOLOUR C.FOREGROUND, volumeControl
GUI BCOLOUR C.BUTTON, volumeControl
ENDIF
END SUB
SUB UpdateVolume
print "setting volume to...",CTRLVAL(volumeControl)
SetProperty &H0300,(CTRLVAL(volumeControl) MOD 64)
end SUB
SUB SetRadioFrequency(f as integer)
PRINT "Frequency set to ";f
CtrlVal(curFreqGUI)=f
SELECT CASE curMode
CASE amRadio
CTRLVAL(curName) = "AM "+str$(f)+"kHz"
lastAMfreqInUse=f
CASE fmRadio
CTRLVAL(curName) = "FM "+str$((f\10)/100)+"MHz"
infoText="Waiting for RDS"
BlankRDSstrings
lastFMfreqInUse=f
CASE dabRadio
if flagDABserviceChange =0 then CTRLVAL(curName) ="Scanning services"
lastDABfreqInUse=f
END SELECT
SetRadioFrequencyHW(f)
END SUB
sub ZEnforceTuningBounds
if newFreq < minFreq THEN
print "Enforced at min",minFreq,newFreq
newFreq=minFreq
ENDIF
if newFreq > maxFreq THEN
print "Enforced at max",maxFreq,newFreq
newFreq=maxFreq
ENDIF
end sub
SUB InitSplashScreen(c as INTEGER)
TEXT 400,200,"Silicon Chip", "CM",5,1,c,C.BACKGROUND
TEXT 400,240,"AM, FM and DAB+ Radio", "CM",5,1,c,C.BACKGROUND
TEXT 400,280,"Initializing", "CM",5,1,c,C.BACKGROUND
END SUB
SUB FixChannelButton(ch as integer)
GUI DELETE ch0Button+ch
GUI SETUP 2
FONT 2
GUI BUTTON ch0Button+ch,  channelNames(ch),160*(ch MOD 4)+5,270+(ch\4)*70,150,65,C.FOREGROUND,C.BUTTON
END SUB
SUB VariableInit
DIM INTEGER DevCode, KeyCode
DIM i AS INTEGER
DIM j AS INTEGER
DIM stemp as STRING
DIM INTEGER numEntryInProgress
numEntryInProgress=0
DIM STRING numEntryString
numEntryString=""
DIM initComplete as INTEGER
initComplete=0
DIM standbyFlag as INTEGER
standbyFlag=0
DIM INTEGER FMMonoFlag, FMMonoFlagChange
FMMonoFlag=0
FMMonoFlagChange=0
DIM STRING FMStereoState$
FMStereoState$="M"
DIM quietModeFlag as INTEGER
quietModeFlag=0
DIM STRING errorLogBuffer(ERRORLOGENTRIES) LENGTH 32
for i = 1 to ERRORLOGENTRIES-1
errorLogBuffer(i)="---"
NEXT i
errorLogBuffer(0)="---"
DIM INTEGER errorLogCount
errorLogCount=0
DIM INTEGER stereoSwapSet
stereoSwapSet=0
DIM INTEGER speakerGainSet
speakerGainSet=24
DIM INTEGER editBoxDisplayed
editBoxDisplayed=0
DIM SPIRXBUF%(1028)
DIM INTEGER curBacklight, maxBacklight, minBackLight, delayBacklight, countBacklight
curBacklight=100
maxBacklight=100
minBackLight=100
delayBacklight=5
DIM INTEGER countScroll,lastCountScroll, countTemp
DIM STRING infoText, newInfoText
DIM STRING RDSGroup0Program(4) LENGTH 4
DIM STRING RDSGroup2Info(32) LENGTH 8
DIM INTEGER RDSGroup2AB
BlankRDSstrings
DIM flagFreqChange as INTEGER
flagFreqChange=0
DIM numPadInUse AS INTEGER
numPadInUse=0
dim INTEGER flagUpdateVolume,flagUpdateMute
flagUpdateVolume=1
flagUpdateMute=1
DIM tuningDeltaSmall AS FLOAT
DIM tuningDeltaLarge AS FLOAT
DIM minFreq AS FLOAT
DIM maxFreq AS FLOAT
DIM INTEGER localDabMin, localDabMax
DIM INTEGER localDabMinIndex,localDabMaxIndex
localDabMin=dabmin
localDabMax=dabmax
localDabMinIndex=0
localDabMaxIndex=99
DIM STRING tempDABname$
tempDABname$=""
DIM curMode AS INTEGER, newMode AS INTEGER
DIM curFreq AS INTEGER, newFreq as INTEGER
dim INTEGER curChannelSelected, newChannelSelected
curChannelSelected=-1
DIM STRING channelNames(8) LENGTH 32
DIM INTEGER channelFreqs(8)
DIM INTEGER channelModes(8)
DIM INTEGER channelServices(8)
DIM INTEGER channelComponents(8)
DIM INTEGER curVolumeState, newVolumeState
DIM INTEGER curMuteState, newMuteState
for I = 0 to 7
channelNames(i)="--"+str$(i+1)+"--"
channelFreqs(i)=531
channelModes(i)=amRadio
Next I
curVolumeState=10
curMuteState=0
DIM INTEGER lastAMfreqInUse,lastFMfreqInUse,lastDABfreqInUse,lastDABserviceInUse
DIM INTEGER NumDABFreqs
DIM INTEGER DABFreqs(64)
DIM INTEGER DABFreqIndexInUse,NumDABServices,DABserviceListReady
DABFreqIndexInUse=0
DABserviceListReady=0
DIM INTEGER DABServiceIDs(64)
DIM INTEGER CurDABService,newDABService,flagDABserviceChange
DIM INTEGER curDABServiceID,curDABComponentID,newDABServiceID,newDABComponentID
DIM STRING DABServiceNames(64) LENGTH 18
DIM INTEGER DABComponentIDs(64)
DIM INTEGER lastServiceListVersion
flagDABserviceChange  =0
Dim INTEGER curLocale
DIM STRING localeNameList(3)
localeNameList(0)="Locale:Australia"
localeNameList(1)="Locale:New Zealand"
localeNameList(2)="Locale:Rest of World"
DIM INTEGER copySDtoFlashFlag
copySDtoFlashFlag=0
DIM INTEGER flagSeekUp,flagSeekDown
flagSeekUp=0
flagSeekDown=0
DIM INTEGER hpState, hpCounter
hpState=0
hpCounter=0
DIM INTEGER analogDigitalFlag, analogDigitalChangeFlag
analogDigitalFlag=audioAnalog
analogDigitalChangeFlag=0
END SUB
SUB GuiSetup
LOCAL ch AS INTEGER
GUI SETUP 1
FONT 5
GUI BUTTON mainPage,"Main",10,410,180,65,C.FOREGROUND,C.BUTTON
GUI BUTTON standbyButton,"Standby",210,410,180,65,C.FOREGROUND,C.BUTTON
GUI BUTTON settingsPage,"Config",410,410,180,65,C.FOREGROUND,C.BUTTON
GUI SWITCH analogDigitalSelect,"Dig Out",610,410,180,65,C.FOREGROUND,C.BUTTON
GUI SETUP 5
FONT 5
GUI RADIO radioModeAM,"AM",650,60,20,C.FOREGROUND
GUI RADIO radioModeFM,"FM",650,110,20,C.FOREGROUND
GUI RADIO radioModeDAB,"DAB",650,160,20,C.FOREGROUND
GUI SETUP 2
FONT 5
GUI SWITCH muting,"Mute",645,270,150,65,C.FOREGROUND,C.BUTTON
FONT 2
GUI SPINBOX volumeControl,645,350,150,50,C.FOREGROUND,C.BUTTON,1,0,63
FONT 5
GUI FRAME channelInfo,"Silicon Chip AM FM DAB+ Radio",0,16,799,240,C.FOREGROUND
FONT 5
GUI TEXTBOX curName,80,35,460,50,C.TEXT,C.BACKGROUND
GUI TEXTBOX FMStereoICON,550,35,50,50,C.TEXT,C.BACKGROUND
GUI BUTTON curServDown,"-",20,40,40,40,C.FOREGROUND,C.BUTTON
GUI BUTTON curServUp,"+",560,40,40,40,C.FOREGROUND,C.BUTTON
GUI NUMBERBOX curFreqGUI,190,100,160,50,C.FOREGROUND,C.BUTTON
GUI CAPTION curFreqUnits,"kHz",360,112,"LT",C.FOREGROUND,C.BACKGROUND
GUI BUTTON curFreqDown,"-",140,105,40,40,C.FOREGROUND,C.BUTTON
GUI BUTTON curFreqUp,"+",440,105,40,40,C.FOREGROUND,C.BUTTON
GUI BUTTON curFreqDownDown,"<",90,105,40,40,C.FOREGROUND,C.BUTTON
GUI BUTTON curFreqUpUp,">",490,105,40,40,C.FOREGROUND,C.BUTTON
GUI BUTTON curFreqSeekUp,">>",540,105,60,40,C.FOREGROUND,C.BUTTON
GUI BUTTON curFreqSeekDown,"<<",20,105,60,40,C.FOREGROUND,C.BUTTON
FONT 2
GUI CAPTION SNR,"0.0",120,165,"RT",C.FOREGROUND,C.BACKGROUND
GUI CAPTION SNRUnits,"dB  SNR",120,165,"LT",C.FOREGROUND,C.BACKGROUND
GUI CAPTION SS,"0.0",320,165,"RT",C.FOREGROUND,C.BACKGROUND
GUI CAPTION SSUnits,"dBuV RX Pwr",320,165,"LT",C.FOREGROUND,C.BACKGROUND
FONT 5
GUI FRAME trackFrame,"",20,192,760,50,C.FOREGROUND
GUI CAPTION trackInfo,"awaiting track data...", 35,202,"LT",C.FOREGROUND,C.BACKGROUND
FONT 2
FOR ch = 0 to 7
GUI BUTTON ch0Button+ch,  channelNames(ch),160*(ch MOD 4)+5,270+(ch\4)*70,150,65,C.FOREGROUND,C.BUTTON
NEXT ch
GUI SETUP 4
FONT 5
GUI CHECKBOX forceMono,"Force Mono FM",20,0,40,C.FOREGROUND
GUI CHECKBOX quietMode,"RF Quiet Mode",20,50,40,C.FOREGROUND
GUI BUTTON saveSettings,"Save settings",430,0,360,40,C.FOREGROUND,C.BUTTON
FONT 2
GUI SPINBOX setBacklightMax,20,150,120,40,C.FOREGROUND,C.BUTTON,1,20,100
GUI SPINBOX setBacklightMin,20,200,120,40,C.FOREGROUND,C.BUTTON,1,0,100
GUI SPINBOX setBacklightDelay,20,250,120,40,C.FOREGROUND,C.BUTTON,1,0,60
GUI SPINBOX curLocaleGUI,20,300,120,40,C.FOREGROUND,C.BUTTON,1,0,2
GUI SPINBOX speakerGain,20,350,120,40,C.FOREGROUND,C.BUTTON,1,1,32
GUI SPINBOX errorLogSpinbox,430,50,120,40,C.FOREGROUND,C.BUTTON,1,1,ERRORLOGENTRIES
FONT 5
GUI CAPTION setBacklightMaxT,"B/L maximum", 150,150,"LT",C.FOREGROUND,C.BACKGROUND
GUI CAPTION setBacklightMinT,"B/L minimum", 150,200,"LT",C.FOREGROUND,C.BACKGROUND
GUI CAPTION setBacklightDelayT,"B/L delay", 150,250,"LT",C.FOREGROUND,C.BACKGROUND
GUI CAPTION curLocaleName,"Locale:Australia", 150,300,"LT",C.FOREGROUND,C.BACKGROUND
GUI CAPTION speakerGainText,"Speaker Gain (step)", 150,350,"LT",C.FOREGROUND,C.BACKGROUND
GUI CAPTION errorLogCaption,"No Errors", 550,50,"LT",C.FOREGROUND,C.BACKGROUND
FONT 2
GUI CAPTION errorLogError,errorLogBuffer(0), 440,100,"LT",C.WARNING,C.BACKGROUND
FONT 5
GUI BUTTON copySDtoFlashGUI,"Write Flash",480,200,300,60,C.FOREGROUND,C.BUTTON
GUI CHECKBOX stereoSwap,"Stereo Swap",20,100,40,C.FOREGROUND
END SUB
SUB HandleTouchDown
if standbyFlag=2 THEN doSoftReset
curBacklight=maxBacklight
countBacklight=0
BACKLIGHT maxBacklight
SELECT CASE TOUCH(REF)
CASE quietMode
quietModeFlag=ctrlval(quietMode)
CASE forceMono
FMMonoFlag=ctrlval(forceMono)
FMMonoFlagChange=1
CASE radioModeAm
newMode=amRadio
newChannelSelected=-1
newFreq=lastAMfreqInUse
CASE RadioModeFM
newMode=fmRadio
newChannelSelected=-1
newFreq=lastFMfreqInUse
CASE radioModeDAB
newMode=dabRadio
newChannelSelected=-1
newFreq=lastDABfreqInUse
CASE curFreqDown
newFreq=newFreq-tuningDeltaSmall
newChannelSelected=-1
CASE curFreqUp
newFreq=newFreq+tuningDeltaSmall
newChannelSelected=-1
CASE curFreqDownDown
newFreq=newFreq-tuningDeltaLarge
newChannelSelected=-1
CASE curFreqUpUp
newFreq=newFreq+tuningDeltaLarge
newChannelSelected=-1
CASE curFreqSeekUp
flagSeekUp=1-flagSeekUp
CASE curFreqSeekDown
flagSeekDown=1-flagSeekDown
CASE curServDown
newChannelSelected=-1
IF NumDABServices > 0 THEN
flagDABserviceChange=1
newDABService = (CurDABService + NumDABServices - 1) MOD NumDABServices
newDABServiceID = DABServiceIDs%(newDABService)
newDABComponentID = DABComponentIDs%(newDABService)
print newDABServiceID,newDABComponentID
CTRLVAL(curName) = DABServiceNames$(newDABService)
fixCurName
infoText="Waiting for DAB+ info data"
ENDIF
CASE curServUp
newChannelSelected=-1
IF NumDABServices > 0 THEN
flagDABserviceChange=1
newDABService = (CurDABService + 1) MOD NumDABServices
newDABServiceID = DABServiceIDs%(newDABService)
newDABComponentID = DABComponentIDs%(newDABService)
print newDABServiceID,newDABComponentID
CTRLVAL(curName) = DABServiceNames$(newDABService)
fixCurName
infoText="Waiting for DAB+ info data"
ENDIF
CASE volumeControl
flagUpdateVolume=1
CASE muting
flagUpdateMute=1
CASE mainPage
PAGE 1
PAGE 1,2,5
CASE standbyButton
standbyFlag=1
CASE settingsPage
PAGE 1
PAGE 1,4
CtrlVal(errorLogSpinBox)=1
CtrlVal(errorLogError)=errorLogBuffer(0)
CASE ch0Button TO (ch0Button + 7)
TIMER = 0
CASE saveSettings
SaveToFlash
CASE setBacklightMax
maxBackLight=CtrlVal(setBacklightMax)
CASE setBacklightMin
minBackLight=CtrlVal(setBacklightMin)
CASE setBacklightDelay
delayBacklight=CtrlVal(setBacklightDelay)
CASE curFreqGUI
editBoxDisplayed=1
CASE curLocaleGUI
curLocale=CtrlVal(curLocaleGUI)
CtrlVal(curLocaleName)=localeNameList(curLocale)
CASE errorLogSpinBox
CtrlVal(errorLogError)=errorLogBuffer(CtrlVal(errorLogSpinBox)-1)
CASE copySDtoFlashGUI
copySDtoFlashFlag=1
CASE analogDigitalSelect
if CtrlVal(analogDigitalSelect)=0 THEN
analogDigitalFlag=audioAnalog
ELSE
analogDigitalFlag=audioDigital
ENDIF
analogDigitalChangeFlag=1
END SELECT
END SUB
SUB SaveToFlash
curMuteState=CtrlVal(muting)
curVolumeState=CtrlVal(volumeControl)
FMMonoFlag=CtrlVal(forceMono)
speakerGainSet=CtrlVal(speakerGain)
stereoSwapSet=CtrlVal(stereoSwap)
VAR SAVE curChannelSelected,channelNames(),channelFreqs(),channelModes(),channelServices(),channelComponents()
VAR SAVE curMuteState,curVolumeState
VAR SAVE curMode, curFreq
VAR SAVE lastAMfreqInUse,lastFMfreqInUse,lastDABfreqInUse,lastDABserviceInUse
VAR SAVE maxBacklight, minBackLight, delayBacklight
VAR SAVE curLocale,analogDigitalFlag,FMMonoFlag
VAR SAVE speakerGainSet,stereoSwapSet
Print "VAR saved to flash"
end sub
SUB LoadFromFlash
VAR RESTORE
CtrlVal(forceMono)=FMMonoFlag
CtrlVal(setBacklightMax)=maxBackLight
CtrlVal(setBacklightMin)=minBackLight
CtrlVal(setBacklightDelay)=delayBacklight
CtrlVal(curLocaleGUI)=curLocale
CtrlVal(curLocaleName)=localeNameList(curLocale)
CtrlVal(speakerGain)=speakerGainSet
speakerGainSet=24
CtrlVal(stereoSwap)=stereoSwapSet
BACKLIGHT maxBacklight
for i = 0  to 7
FixChannelButton(i)
NEXT i
CtrlVal(muting)=curMuteState
CtrlVal(volumeControl)=curVolumeState
if analogDigitalFlag=audioAnalog THEN
CtrlVal(analogDigitalSelect)=0
ELSE
CtrlVal(analogDigitalSelect)=1
ENDIF
END SUB
SUB HandleTouchUp
SELECT CASE TOUCH(LASTREF)
CASE ch0Button TO (ch0Button + 7)
ChannelButtonReleased
CASE curFreqGUI
flagFreqChange=1
editBoxDisplayed=0
END SELECT
END SUB
SUB IR_Int
PRINT "IRRX:";DevCode;":";KeyCode
if DevCode = 255 THEN
SELECT CASE KeyCode
CASE 163
IF numEntryInProgress>0 THEN
numEntryInProgress=0
numEntryString =""
ELSE
if standbyFlag=0 then standbyFlag=1
if standbyFlag=2 then doSoftReset
ENDIF
CASE 129
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"1"
ELSE
SwitchToChannel(0)
newChannelSelected=0
ENDIF
CASE 193
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"2"
ELSE
SwitchToChannel(1)
newChannelSelected=1
ENDIF
CASE 131
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"3"
ELSE
SwitchToChannel(2)
newChannelSelected=2
ENDIF
CASE 65
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"4"
ELSE
SwitchToChannel(3)
newChannelSelected=3
ENDIF
CASE 1
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"5"
ELSE
SwitchToChannel(4)
newChannelSelected=4
ENDIF
CASE 3
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"6"
ELSE
SwitchToChannel(5)
newChannelSelected=5
ENDIF
CASE 177
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"7"
ELSE
SwitchToChannel(6)
newChannelSelected=6
ENDIF
CASE 241
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"8"
ELSE
SwitchToChannel(7)
newChannelSelected=7
ENDIF
CASE 179
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"9"
ENDIF
CASE 49
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"0"
ENDIF
CASE 19
if CTRLVAL(volumeControl)<63 then CTRLVAL(volumeControl)=CTRLVAL(volumeControl)+1
flagUpdateVolume=1
CASE 43
if CTRLVAL(volumeControl)>0 then CTRLVAL(volumeControl)=CTRLVAL(volumeControl)-1
flagUpdateVolume=1
CASE 105
if CTRLVAL(muting)=1 then
CTRLVAL(muting)=0
else
CTRLVAL(muting)=1
endif
flagUpdateMute=1
case 147
flagSeekUp=1-flagSeekUp
case 145
flagSeekDown=1-flagSeekDown
CASE 195
SELECT CASE curMode
CASE amRadio
newMode=fmRadio
newChannelSelected=-1
newFreq=lastFMfreqInUse
CASE fmRadio
newMode=dabRadio
newChannelSelected=-1
newFreq=lastDABfreqInUse
CASE dabRadio
newMode=amRadio
newChannelSelected=-1
newFreq=lastAMfreqInUse
END SELECT
CASE 255
if numEntryInProgress>0 THEN
numEntryInProgress=0
newFreq=val(numEntryString)
numEntryString =""
ELSE
numEntryInProgress=1
ENDIF
CASE 104
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"0"
ELSE
if standbyFlag=0 then standbyFlag=1
if standbyFlag=2 then doSoftReset
ENDIF
CASE 48
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"1"
ELSE
SwitchToChannel(0)
newChannelSelected=0
ENDIF
CASE 24
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"2"
ELSE
SwitchToChannel(1)
newChannelSelected=1
ENDIF
CASE 122
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"3"
ELSE
SwitchToChannel(2)
newChannelSelected=2
ENDIF
CASE 16
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"4"
ELSE
SwitchToChannel(3)
newChannelSelected=3
ENDIF
CASE 56
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"5"
ELSE
SwitchToChannel(4)
newChannelSelected=4
ENDIF
CASE 90
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"6"
ELSE
SwitchToChannel(5)
newChannelSelected=5
ENDIF
CASE 66
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"7"
ELSE
SwitchToChannel(6)
newChannelSelected=6
ENDIF
CASE 74
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"8"
ELSE
SwitchToChannel(7)
newChannelSelected=7
ENDIF
CASE 82
IF numEntryInProgress>0 THEN
numEntryString =numEntryString +"9"
ENDIF
CASE 168
if CTRLVAL(volumeControl)<63 then CTRLVAL(volumeControl)=CTRLVAL(volumeControl)+1
flagUpdateVolume=1
CASE 224
if CTRLVAL(volumeControl)>0 then CTRLVAL(volumeControl)=CTRLVAL(volumeControl)-1
flagUpdateVolume=1
CASE 194
if CTRLVAL(muting)=1 then
CTRLVAL(muting)=0
else
CTRLVAL(muting)=1
endif
flagUpdateMute=1
case 226
flagSeekUp=1-flagSeekUp
case 162
flagSeekDown=1-flagSeekDown
CASE 98
SELECT CASE curMode
CASE amRadio
newMode=fmRadio
newChannelSelected=-1
newFreq=lastFMfreqInUse
CASE fmRadio
newMode=dabRadio
newChannelSelected=-1
newFreq=lastDABfreqInUse
CASE dabRadio
newMode=amRadio
newChannelSelected=-1
newFreq=lastAMfreqInUse
END SELECT
CASE 144
if numEntryInProgress>0 THEN
numEntryInProgress=0
newFreq=val(numEntryString)
numEntryString =""
ELSE
numEntryInProgress=1
ENDIF
CASE 176
if numEntryInProgress>0 THEN
numEntryInProgress=0
newFreq=val(numEntryString)
numEntryString =""
ELSE
numEntryInProgress=1
ENDIF
END SELECT
ENDIF
END SUB
SUB ChannelButtonReleased
LOCAL ch as INTEGER
ch = TOUCH(LASTREF) - ch0Button
IF TIMER > 1000 THEN
channelNames(ch) = left$(CTRLVAL(curName),12)
channelFreqs(ch) = CTRLVAL(curFreqGUI)
channelModes(ch) = curMode
PRINT "Saving to channel ";ch+1
GUI DELETE ch0Button+ch
GUI SETUP 2
FONT 2
GUI BUTTON ch0Button+ch, channelNames(ch),160*(ch MOD 4)+5,270+(ch\4)*70,150,65,C.FOREGROUND,C.BUTTON
newChannelSelected=ch
if newMode=dabRadio THEN
channelServices(ch)=newDABServiceID
channelComponents(ch)=newDABComponentID
ENDIF
SaveToFlash
ELSE
SwitchToChannel(ch)
newChannelSelected=ch
ENDIF
TIMER = 0
END SUB
SUB SwitchToChannel(ch AS INTEGER)
if ch >-1 THEN
print "Switching to channel ";ch+1
newMode=channelModes(ch)
newFreq=channelFreqs(ch)
CtrlVal(curName)=channelNames(ch)
if newMode=dabRadio THEN
flagDABserviceChange=1
newDABServiceID = channelServices(ch)
newDABComponentID = channelComponents(ch)
ENDIF
ENDIF
END SUB
SUB Si4689ControlsFlash
SETPIN 92, DIN
SETPIN 91, DIN
SETPIN 90, DIN
SETPIN 88, DIN
END SUB
SUB SetupIO
PIN(RESETPIN) = 0
SETPIN RESETPIN, DOUT
PIN(44) = 0
SETPIN 44, DOUT
ChipSelect(1)
SETPIN 80, DOUT
SPI OPEN 2000000, 0, 8
StartSPDIF()
PIN(21) = 0
SETPIN 21, DOUT
PIN(IC4SD)=1
PIN(IC4UP)=1
PIN(IC4DN)=1
SETPIN IC4SD,DOUT
SETPIN IC4UP,DOUT
SETPIN IC4DN,DOUT
SpeakerOutput(0)
SETPIN HPSWPIN,DIN
END SUB
SUB SpeakerOutput(n as INTEGER)
if n=0 THEN
PIN(IC4SD)=0
speakerGainSet=24
ELSE
PIN(IC4SD)=1
ENDIF
END SUB
SUB ChipSelect (value AS INTEGER)
PIN(80) = value
END SUB
SUB StartSPDIF
LOCAL INTEGER T
T=0
print "starting WM8804"
SPI CLOSE
PIN(IC2RST) = 0
PIN(IC2IFM) = 1
PIN(IC2CSB) = 1
SETPIN IC2RST, DOUT
SETPIN IC2IFM, DOUT
SETPIN IC2CSB, DOUT
PAUSE 1000
PIN(72) = 1
PAUSE 400
PIN(IC2RST) = 1
PAUSE 400
print "Set WM8804 to software mode"
SPI OPEN 2000000, 0, 8
PIN(IC2CSB) = 0
SPI WRITE 2, &H06, &H08
PIN(IC2CSB) = 1
PAUSE 1
PIN(IC2CSB) = 0
SPI WRITE 2, &H03, &HBA
PIN(IC2CSB) = 1
PAUSE 1
PIN(IC2CSB) = 0
SPI WRITE 2, &H04, &H49
PIN(IC2CSB) = 1
PAUSE 1
PIN(IC2CSB) = 0
SPI WRITE 2, &H05, &H0C
PIN(IC2CSB) = 1
PAUSE 1
PIN(IC2CSB) = 0
SPI WRITE 2, &H1E, &H3F
PIN(IC2CSB) = 1
PAUSE 20
PIN(IC2CSB) = 0
SPI WRITE 2, &H1E, &H02
PIN(IC2CSB) = 1
PAUSE 20
PIN(IC2CSB) = 0
SPI WRITE 1, &H80
SPI READ 1, SPIRXBUF%()
PIN(IC2CSB) = 1
print "DEVICEID[7:0]: ", SPIRXBUF%(0)
T= SPIRXBUF%(0)
PIN(IC2CSB) = 0
SPI WRITE 1, &H81
SPI READ 1, SPIRXBUF%()
PIN(IC2CSB) = 1
print "DEVICEID[15:7]: ", SPIRXBUF%(0)
T= T*256+SPIRXBUF%(0)
PAUSE 10
IF T=1416 THEN
PRINT "WM8804 detected"
ELSE
PRINT "WM8804 not detected- no digital audio out available"
ENDIF
PIN(IC2CSB) = 0
SPI WRITE 2, &H1B, &H0A
PIN(IC2CSB) = 1
PAUSE 10
PIN(IC2CSB) = 0
SPI WRITE 2, &H1C, &HCA
PIN(IC2CSB) = 1
IF T=1416 THEN print "WM8804 now in I2S master mode"
PAUSE 10
END SUB
SUB ResetAndPowerUp
ChipSelect(1)
PIN(RESETPIN) = 1
PAUSE 10
PIN(RESETPIN) = 0
PAUSE 10
PIN(RESETPIN) = 1
PAUSE 10
ChipSelect(0)
SPI WRITE 16,&H01,&H00,&H17,&H20,&H00,&HF8,&H24,&H01,&H10,&H10,&H00,&H00,&H00,&H10,&H00,&H00
ChipSelect(1)
PAUSE 10
WaitForCTS()
if (spirxbuf%(0) AND 64) = 64 THEN LogErrorToLog("Power Up Failed")
END SUB
SUB PatchBootLoaderfromMMFflash
LOCAL INTEGER loaderbinAddress
loaderbinAddress=PEEK(CFUNADDR LOADERBIN)
local INTEGER TTIMER
TTIMER=TIMER
LOCAL INTEGER eflag
eflag=0
Issue_LOAD_INIT()
ChipSelect(0)
SPI WRITE 4,&H04,&H00,&H00,&H00
FOR i = 0 TO 4092 step 4
SPI WRITE 4,PEEK(BYTE i+loaderbinAddress),PEEK(BYTE i+loaderbinAddress+1),PEEK(BYTE i+loaderbinAddress+2),PEEK(BYTE i+loaderbinAddress+3)
next i
ChipSelect(1)
WaitForCTS()
IF spirxbuf%(0) <> 128 THEN
print "HOST_LOAD error! 1st pass"
eflag=1
ENDIF
ChipSelect(0)
SPI WRITE 4,&H04,&H00,&H00,&H00
FOR i = 4096 TO 5792 step 4
SPI WRITE 4,PEEK(BYTE i+loaderbinAddress),PEEK(BYTE i+loaderbinAddress+1),PEEK(BYTE i+loaderbinAddress+2),PEEK(BYTE i+loaderbinAddress+3)
next i
ChipSelect(1)
WaitForCTS()
IF spirxbuf%(0) <> 128 THEN
print "HOST_LOAD error! 2nd pass"
eflag=1
ENDIF
print "Bootloader load from flash:";TIMER-TTIMER
PAUSE 10
if eflag>0 then LogErrorToLog("Patch Bootloader error")
END SUB
SUB WaitForCTS
local done AS INTEGER
LOCAL CTScount as INTEGER
CTScount = 0
done = 0
WHILE done = 0
ReadReply(4)
done = spirxbuf%(0) AND 128
CTScount=CTScount+1
if CTScount > 1000 then done = 1: LogErrorToLog("Waiting for CTS timeout")
WEND
END SUB
SUB Issue_LOAD_INIT
ChipSelect(0)
SPI WRITE 2,&H06,&H00
ChipSelect(1)
WaitForCTS()
IF spirxbuf%(0) = 128 THEN
print "LOAD_INIT issued successfully"
ELSE
print "LOAD_INIT failed"
LogErrorToLog("Load Init Failed")
ENDIF
END SUB
SUB ReadReply(length AS INTEGER)
PAUSE 1
ChipSelect(0)
SPI WRITE 1,0
PAUSE 1
SPI READ length, SPIRXBUF%()
ChipSelect(1)
END SUB
SUB Set4689FlashProperties
ChipSelect(0)
SPI WRITE 4, &H05, &H10, &H00, &H00
SPI WRITE 4, &H02, &H00, &H00, &H00
SPI WRITE 4, &H01, &H00, &HB8, &H0B
ChipSelect(1)
WaitForCTS()
END SUB
SUB Boot
print "booting radio..."
ChipSelect(0)
SPI WRITE 2,&H07,&H00
ChipSelect(1)
PAUSE 200
print "booted."
END SUB
SUB SetProperty(prop AS INTEGER, value AS INTEGER)
print "setting property ",prop," to ",value
ChipSelect(0)
SPI WRITE 6,&H13,&H00,(prop MOD 256),(prop \ 256) MOD 256,(value MOD 256),(value \ 256) MOD 256
ChipSelect(1)
PAUSE 50
END SUB
SUB SetRadioMode(m as integer)
GUI DISABLE ALL
softMute(1)
SetIC6(IC6MUTE)
SELECT CASE m
CASE amRadio
Print "Changing to AM"
CtrlVal(radioModeAM)=1
tuningDeltaSmall = 1.0
tuningDeltaLarge = amDeltaLarge
minFreq = amMin
maxFreq = amMax
GUI HIDE curServDown,curServUp,FMStereoICON
GUI SHOW curFreqUp, curFreqUpUp, curFreqDown, curFreqDownDown,SNRUnits
flagDABserviceChange=0
CASE fmRadio
Print "Changing to FM"
CtrlVal(radioModeFM)=1
tuningDeltaSmall = 10.0
tuningDeltaLarge = fmDeltaLarge
minFreq = fmMin
maxFreq = fmMax
GUI HIDE curServDown,curServUp
GUI SHOW curFreqUp, curFreqUpUp, curFreqDown, curFreqDownDown,SNRUnits,FMStereoICON
flagDABserviceChange=0
FMStereoState$="M"
CtrlVal(FMStereoICON)=FMStereoState$
CASE dabRadio
Print "Changing to DAB"
CtrlVal(radioModeDAB)=1
tuningDeltaSmall = 1.0
tuningDeltaLarge = dabDeltaLarge
minFreq = localDabMin
maxFreq = localDabMax
GUI SHOW curServDown,curServUp
GUI HIDE curFreqUp, curFreqUpUp, curFreqDown, curFreqDownDown,SNRUnits,FMStereoICON
END SELECT
if initComplete=0 THEN TEXT 0,479,"Initialising Si4689          ","LB",5,1,C.FOREGROUND,C.BACKGROUND
print "setting radio mode to...",m
ResetAndPowerUp()
print "radio reset, loading firmware..."
if initComplete=0 THEN TEXT 0,479,"Loading bootloader for Si4689","LB",5,1,C.FOREGROUND,C.BACKGROUND
PatchBootLoaderfromMMFflash()
curMode = m
PAUSE 4
if initComplete=0 THEN TEXT 0,479,"Loading firmware for Si4689  ","LB",5,1,C.FOREGROUND,C.BACKGROUND
LoadFirmwareFromFlash(m)
if initComplete=0 THEN TEXT 0,479,"Starting Si4689              ","LB",5,1,C.FOREGROUND,C.BACKGROUND
Boot()
PAUSE 50
SetProperty(&H0800, analogDigitalFlag)
SetFMMono(FMMonoFlag)
PAUSE 50
if initComplete=0 THEN
initComplete=1
CLS C.BACKGROUND
GUI SHOW ALL
PAGE 1
PAGE 1,2,5
if m = dabRadio then
GUI HIDE curFreqUp, curFreqUpUp, curFreqDown, curFreqDownDown,SNRUnits,FMStereoICON
GUI SHOW curServDown,curServUp
ENDIF
if m = fmRadio then
GUI HIDE curServDown,curServUp
GUI SHOW curFreqUp, curFreqUpUp, curFreqDown, curFreqDownDown,SNRUnits,FMStereoICON
ENDIF
if m = amRadio then
GUI HIDE curServDown,curServUp,FMStereoICON
GUI SHOW curFreqUp, curFreqUpUp, curFreqDown, curFreqDownDown,SNRUnits
ENDIF
ENDIF
IF m = dabRadio THEN
PAUSE 100
SetFreqTableFromLocale
minFreq = localDabMin
maxFreq = localDabMax
infoText="Waiting for DAB+ info data"
BlankRDSstrings
ENDIF
if m = fmRadio THEN
SetProperty(&H3C02, &H0001)
SetFMMono(FMMonoFlag)
infoText="Waiting for RDS"
BlankRDSstrings
ENDIF
IF m = amRadio THEN
infoText="Info not available in AM mode"
BlankRDSstrings
ENDIF
IF CtrlVal(stereoSwap)= 0 THEN
SetIC6(IC6NORMAL)
stereoSwapSet=0
ELSE
SetIC6(IC6REVERSE)
stereoSwapSet=1
ENDIF
UpdateMute
UpdateVolume
GUI ENABLE ALL
END SUB
SUB LoadFirmwareFromFlash(mode AS INTEGER)
Issue_LOAD_INIT()
ChipSelect(0)
SPI WRITE 4, &H05, &H00, &H00, &H00
IF mode = fmRadio THEN
print "loading FM radio firwmare from flash..."
SPI WRITE 4, &H00, &H60, &H00, &H00
ENDIF
IF mode = dabRadio THEN
print "loading DAB radio firwmare from flash..."
SPI WRITE 4, &H00, &H20, &H09, &H00
ENDIF
IF mode = amRadio THEN
print "loading AM radio firwmare from flash..."
SPI WRITE 4, &H00, &HE0, &H11, &H00
ENDIF
SPI WRITE 4, &H00, &H00, &H00, &H00
ChipSelect(1)
print "done loading firmware from flash."
WaitForCTS()
if (spirxbuf%(0) AND 64) = 64 THEN LogErrorToLog("Load F/W from Flash Failed")
END SUB
sub LogErrorToLog(e as STRING)
for i = ERRORLOGENTRIES-1 to 1 step -1
errorLogBuffer(i) = errorLogBuffer(i-1)
next i
errorLogBuffer(0)=e
errorLogCount=errorLogCount+1
if errorLogCount>1 THEN
CtrlVal(errorLogCaption)=str$(errorLogCount)+" Errors"
ELSE
CtrlVal(errorLogCaption)=str$(errorLogCount)+" Error"
ENDIF
END SUB
SUB SetRadioFrequencyHW(freq AS FLOAT)
LOCAL INTEGER dabindex
IF curMode = amRadio THEN
print "tuning AM radio to...",freq
ChipSelect(0)
SPI WRITE 2,&H40,&H00
SPI WRITE 1, (INT(freq)) MOD 256
SPI WRITE 1, (INT(freq)) \ 256
SPI WRITE 3,&H00,&H00,&H00
ChipSelect(1)
ENDIF
IF curMode = fmRadio THEN
print "tuning FM radio to...",freq
ChipSelect(0)
SPI WRITE 2,&H30,&H00
SPI WRITE 1, (INT(freq)\10) MOD 256
SPI WRITE 1, (INT(freq)\10) \ 256
SPI WRITE 3,&H00,&H00,&H00
ChipSelect(1)
ENDIF
IF curMode = dabRadio THEN
print "tuning DAB radio to...",freq
dabindex=0
if NumDABFreqs > 0 THEN
for i = 0 to NumDABFreqs-1
if DABFreqs%(i)=freq then dabindex=i
NEXT i
ENDIF
PRINT "Using index ";dabindex;", at ";DABFreqs%(dabindex)
TuneDABFrequency(dabindex);
DABserviceListReady = 0
NumDABServices=0
pause 100
SetProperty(&HB400, &H0007)
ENDIF
END SUB
SUB copySDtoFlash
GUI DELETE copySDtoFlashGUI
FONT 5
GUI SETUP 4
GUI BUTTON copySDtoFlashGUI,"Writing...",430,150,360,40,C.FOREGROUND,C.BUTTON
GUI DISABLE ALL
PIN(RESETPIN) = 0
curMode=-1
MicroMiteControlsFlash()
EraseFlashChip()
WriteFirmwareToFlash()
Si4689ControlsFlash()
GUI DELETE copySDtoFlashGUI
FONT 5
GUI SETUP 4
GUI BUTTON copySDtoFlashGUI,"Write Done",430,150,360,40,C.FOREGROUND,C.BUTTON
copySDtoFlashFlag=0
GUI ENABLE ALL
END SUB
SUB MicroMiteControlsFlash
PIN(92) = 1
SETPIN 92, DOUT
SETPIN 91, DOUT
SETPIN 90, DOUT
SETPIN 88, DIN
END SUB
SUB EraseFlashChip
LOCAL success AS INTEGER
PRINT "erasing flash chip: please wait..."
WriteEnable()
StartSPI2Op()
WriteSPI2Byte(&HC7)
EndSPI2Op()
success = 0
WHILE ReadFlashStatusReg() MOD 256 <> 0
success = success + 1
WEND
IF success > 0 THEN PRINT "flash chip erased" ELSE PRINT "flash chip erase error!"
END SUB
SUB WriteFirmwareToFlash
LOCAL addr AS INTEGER
LOCAL length AS INTEGER
length = 128
print "writing FM radio firmware to flash..."
OPEN "fmhd.bin" FOR INPUT AS #1
addr = 24576
FOR i = 0 TO 4142
WriteFlashChunk(addr, length)
addr = addr + length
NEXT i
CLOSE #1
print "writing DAB radio firmware to flash..."
OPEN "dab.bin" FOR INPUT AS #1
addr = 598016
FOR i = 0 TO 4073
WriteFlashChunk(addr, length)
addr = addr + length
NEXT i
CLOSE #1
print "writing AM radio firmware to flash..."
OPEN "amhd.bin" FOR INPUT AS #1
addr = 1171456
FOR i = 0 TO 4136
WriteFlashChunk(addr, length)
addr = addr + length
NEXT i
CLOSE #1
print "writing Loader firmware to flash, copy 1 at 0x2000"
OPEN "loader.bin" FOR INPUT AS #1
addr = &H2000
FOR i = 0 TO 45
WriteFlashChunk(addr, length)
addr = addr + length
NEXT i
CLOSE #1
print "writing Loader firmware to flash, copy 2 at 0x4000"
OPEN "loader.bin" FOR INPUT AS #1
addr = &H4000
FOR i = 0 TO 45
WriteFlashChunk(addr, length)
addr = addr + length
NEXT i
CLOSE #1
END SUB
SUB WriteFlashChunk(addr AS INTEGER, length AS INTEGER)
LOCAL STRING chunk$,wrCmd$
LOCAL bucket AS INTEGER
LOCAL verify$
chunk$ = INPUT$(length, #1)
IF len(chunk$) < length THEN
chunk$ = chunk$ + string$(length - len(chunk$), 0)
ENDIF
wrCmd$ = CHR$(2) + CHR$((addr \ 65536) MOD 256) + CHR$((addr \ 256) MOD 256) + CHR$(addr MOD 256)
WriteEnable()
StartSPI2Op()
bucket = StringSPI(wrCmd$, 0, 4)
bucket = StringSPI(chunk$, 0, length)
EndSPI2Op()
WHILE ReadFlashStatusReg() MOD 256 <> 0
WEND
verify$ = ReadFlash(addr, LENGTH)
IF verify$ <> chunk$ THEN
print "chunk verify failed!"
FOR j = 1 to length
print HEX$(ASC(MID$(verify$, j, 1)))
NEXT j
ENDIF
END SUB
SUB WriteEnable
StartSPI2Op()
WriteSPI2Byte(&H06)
EndSPI2Op()
END SUB
SUB StartSPI2Op()
PIN(91) = 0
PIN(92) = 0
END SUB
SUB EndSPI2Op()
PIN(91) = 0
PIN(92) = 1
END SUB
SUB WriteSPI2Byte(byte AS INTEGER)
LOCAL INTEGER bucket
bucket = StringSPI(CHR$(BYTE), 0, 1)
END SUB
CFunction StringSPI
00000000
8CA20000 8CCD0000 41606000 11A00054 25ADFFFF 24420001 00822021 008D6821
3C0ABF88 240B0001 3C03BF88 3C0CBF88 80890000 00002821 24060008 31280080
11000005 00000000 8D486630 7D680004 10000004 AD486630 8D486630 7C080004
AD486630 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 8C686030 7D683184 AC686030
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 24C6FFFF 00052840 8D886520 31080002 55000001 34A50001
8C686030 7C083184 AC686030 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 14C0FFC1 00094840 10E00006
00000000 8CE20000 8CE60004 00461025 54400001 A0850000 148DFFB5 24840001
41606020 00001021 03E00008 00001821
End CFunction
FUNCTION ReadFlashStatusReg() AS INTEGER
LOCAL bucket AS INTEGER
LOCAL STRING longstr$
LOCAL regs(2) AS INTEGER
longstr$ = CHR$(5) + CHR$(0)
StartSPI2Op()
bucket = StringSPI(longstr$, 0, 4, 1)
regs(0) = ASC(MID$(longstr$, 2, 1))
EndSPI2Op()
longstr$ = CHR$(53) + CHR$(0)
StartSPI2Op()
bucket = StringSPI(longstr$, 0, 4, 1)
regs(1) = ASC(MID$(longstr$, 2, 1))
EndSPI2Op()
ReadFlashStatusReg = regs(0) + (regs(1) << 8)
END FUNCTION
FUNCTION ReadFlash(addr as integer, numbytes as integer) AS STRING
LOCAL bucket AS INTEGER
LOCAL i as INTEGER
LOCAL STRING longstr$
longstr$ = CHR$(&H0B) + CHR$((addr \ 65536) MOD 256) + CHR$((addr \ 256) MOD 256) + CHR$(addr MOD 256) + CHR$(0)
StartSPI2Op()
bucket = StringSPI(longstr$, 0, 5)
longstr$ = STRING$(numbytes, 0)
bucket = StringSPI(longstr$, 0, numbytes, 1)
ReadFlash = LEFT$(longstr$, numbytes)
EndSPI2Op()
END FUNCTION
SUB UpdateRadioStats
local snrval AS INTEGER
IF curMode = amRadio THEN
SendAmRSQ
ReadReply(22)
CTRLVAL(SNR) = STR$(sint8%(SPIRXBUF%(10)))
CTRLVAL(SS) = STR$(sint8%(SPIRXBUF%(9)))
ENDIF
IF curMode = fmRadio THEN
SendFmRSQ
ReadReply(22)
CTRLVAL(SNR) = STR$(sint8%(SPIRXBUF%(10)))
CTRLVAL(SS) = STR$(sint8%(SPIRXBUF%(9)))
sendFMACF
ReadReply(11)
if ((SPIRXBUF%(8) AND 128) =128) AND ((SPIRXBUF%(5) AND 4)=0) THEN
FMStereoState$="S"
ELSE
FMStereoState$="M"
ENDIF
if CtrlVal(FMStereoICON)<>FMStereoState$ then CtrlVal(FMStereoICON)=FMStereoState$
ENDIF
IF curMode = dabRadio THEN
SendDABDigradStatus
ReadReply(23)
if (SPIRXBUF%(5) mod 2)=0 then CTRLVAL(SNR)="No signal"
if (SPIRXBUF%(5) AND 13)=13 then CTRLVAL(SNR)="Errors   "
if (SPIRXBUF%(5) AND 13)=5 then CTRLVAL(SNR)="Signal OK"
CTRLVAL(SS) = STR$(sint8%(SPIRXBUF%(6)))
if (SPIRXBUF%(5) mod 2)=1 then CheckDigitalEnsemble
ENDIF
END SUB
SUB SendAmRSQ
ChipSelect(0)
SPI WRITE 2,&H42,&H00
ChipSelect(1)
PAUSE 10
END SUB
SUB sendFMACF
ChipSelect(0)
SPI WRITE 2,&H33  ,&H01
ChipSelect(1)
PAUSE 10
END SUB
SUB SendFmRSQ
ChipSelect(0)
SPI WRITE 2,&H32,&H00
ChipSelect(1)
PAUSE 10
END SUB
SUB SendDABDigradStatus
ChipSelect(0)
SPI WRITE 2,&HB2,&H00
ChipSelect(1)
PAUSE 50
END SUB
FUNCTION nop(x AS INTEGER)
nop = x
END FUNCTION
FUNCTION sint8%(x AS INTEGER)
IF x > 127 THEN
sint8% = x - 256
ELSE
sint8% = x
ENDIF
END FUNCTION
SUB QueryFMRDS
ChipSelect(0)
SPI WRITE 2,&H34,&H04
ChipSelect(1)
PAUSE 10
ReadReply(20)
if SPIRXBUF%(10) > 0 THEN
GetFMRDSData
ENDIF
end sub
SUB GetFMRDSData
LOCAL STRING temporary$
LOCAL INTEGER done,nextChar
local INTEGER RDSgroupcode, RDSversion, RDStpValue, RDSptyValue, RDSappValue
LOCAL STRING nextByte
done=0
WHILE done = 0
ChipSelect(0)
SPI WRITE 2,&H34,&H00
ChipSelect(1)
PAUSE 10
ReadReply(20)
if SPIRXBUF%(11)=0 then
RDSgroupcode=(SPIRXBUF%(15)\16) AND 15
RDSversion=(SPIRXBUF%(15)\8) AND 1
RDStpValue=(SPIRXBUF%(15)\4) AND 1
RDSptyValue=((SPIRXBUF%(15)*8) AND 24) + ((SPIRXBUF%(14)\32) AND 7)
RDSappValue=SPIRXBUF%(14) AND 31
select case RDSgroupcode
CASE 0
RDSGroup0Program(RDSappValue and 3)= chr$(PrintFixed(SPIRXBUF%(19)))+chr$(PrintFixed(SPIRXBUF%(18)))
temporary$=RDSGroup0Program(0)+RDSGroup0Program(1)+RDSGroup0Program(2)+RDSGroup0Program(3)
if CtrlVal(curName) <> temporary$ then CtrlVal(curName) = temporary$
CASE 2
RDSGroup2Info(RDSappValue)= chr$(PrintFixed(SPIRXBUF%(17)))+chr$(PrintFixed(SPIRXBUF%(16)))+chr$(PrintFixed(SPIRXBUF%(19)))+chr$(PrintFixed(SPIRXBUF%(18)))
i = RDSappValue and 16
if i <> RDSGroup2AB then
for j = 16-i to 31-i
RDSGroup2Info(j)="    "
NEXT j
RDSGroup2AB=i
ENDIF
END SELECT
ENDIF
if SPIRXBUF%(10) <2 THEN  done =1
WEND
UpdateRDSGroup2Display
end sub
FUNCTION PrintFixed(c as integer) AS INTEGER
if c < 32 then c=32
if c > 126 then c=32
PrintFixed=c
end FUNCTION
sub BlankRDSstrings
FOR i = 0 to 3
RDSGroup0Program(i)="--"
NEXT i
FOR i = 0 to 31
RDSGroup2Info(i)="    "
NEXT i
END SUB
sub PrintRDSstrings
FOR i = 0 to 3
print RDSGroup0Program(i);
NEXT i
print "  ",RDSGroup2AB
FOR i = 0 to 31
print RDSGroup2Info(i);
NEXT i
print
end sub
SUB UpdateRDSGroup2Display
LOCAL STRING newInfoText$
local integer whitespace
newInfoText$=""
whitespace=1
for i = RDSGroup2AB to RDSGroup2AB+15
newInfoText$ = newInfoText$+ RDSGroup2Info(i)
next i
for i = 1 to len(newInfoText$)
if mid$(newInfoText$,i,1) <> " " THEN whitespace=i
next i
newInfoText$=left$(newInfoText$,whitespace)
if infoText <> newInfoText$ then infoText = newInfoText$
END SUB
SUB FreqSeekUp
CtrlVal(curName)="Seeking up"
Print "Seek Up requested"
GUI DISABLE ALL
GUI ENABLE curFreqSeekUp
if curMode = fmRadio THEN fmStartSeek(1)
if curMode = amRadio THEN amStartSeek(1)
if curMode = dabRadio THEN  DABSeek(1)
WHILE flagSeekUp>0
if curMode = fmRadio THEN fmCheckSeekStatus
if curMode = amRadio THEN amCheckSeekStatus
PAUSE 10
WEND
if curMode = fmRadio THEN fmEndSeek
if curMode = amRadio THEN amEndSeek
GUI ENABLE ALL
curFreq=-1
flagSeekUp=0
END SUB
SUB FreqSeekDown
CtrlVal(curName)="Seeking Down"
Print "Seek Down requested"
GUI DISABLE ALL
GUI ENABLE curFreqSeekDown
if curMode = fmRadio THEN fmStartSeek(0)
if curMode = amRadio THEN amStartSeek(0)
if curMode = dabRadio THEN  DABSeek(0)
WHILE flagSeekDown>0
if curMode = fmRadio THEN fmCheckSeekStatus
if curMode = amRadio THEN amCheckSeekStatus
PAUSE 10
WEND
if curMode = fmRadio THEN fmEndSeek
if curMode = amRadio THEN amEndSeek
GUI ENABLE ALL
curFreq=-1
flagSeekDown=0
END SUB
SUB fmStartSeek(seekup as INTEGER)
SetProperty &H3100,fmMin\10
WaitForCTS()
SetProperty &H3101,fmMax\10
WaitForCTS()
SetProperty &H3102,10
WaitForCTS()
SetProperty &H3200,114
WaitForCTS()
SetProperty &H3201,15
WaitForCTS()
SetProperty &H3202,17
WaitForCTS()
SetProperty &H3203,17
WaitForCTS()
SetProperty &H3204,10
WaitForCTS()
ChipSelect(0)
SPI WRITE 6,&H31,&H00,(seekup*2) AND 2,&H00,&H00,&H00
ChipSelect(1)
WaitForCTS()
END SUB
SUB fmCheckSeekStatus
SendFmRSQ
ReadReply(20)
newFreq=SPIRXBUF%(7)*2560+SPIRXBUF%(6)*10
CtrlVal(curFreqGUI)=newFreq
if (SPIRXBUF%(0) and 1) > 0 then
flagSeekUp=0
flagSeekDown=0
fmEndSeek
ENDIF
END SUB
SUB fmEndSeek
ChipSelect(0)
SPI WRITE 2,&H32,&H03
ChipSelect(1)
WaitForCTS()
END SUB
SUB amStartSeek(seekup as INTEGER)
SetProperty &H4100,amMin
WaitForCTS()
SetProperty &H4101,amMax
WaitForCTS()
SetProperty &H4102,1
WaitForCTS()
SetProperty &H4200,75
WaitForCTS()
SetProperty &H4201,8
WaitForCTS()
SetProperty &H4202,35
WaitForCTS()
SetProperty &H4203,40
WaitForCTS()
SetProperty &H4204,10
WaitForCTS()
ChipSelect(0)
SPI WRITE 6,&H41,&H00,(seekup*2) AND 2,&H00,&H00,&H00
ChipSelect(1)
WaitForCTS()
END SUB
SUB amCheckSeekStatus
SendAmRSQ
ReadReply(16)
newFreq=SPIRXBUF%(7)*256+SPIRXBUF%(6)*1
CtrlVal(curFreqGUI)=newFreq
if (SPIRXBUF%(0) and 1) > 0 then
flagSeekUp=0
flagSeekDown=0
amEndSeek
ENDIF
END SUB
SUB amEndSeek
ChipSelect(0)
SPI WRITE 2,&H42,&H03
ChipSelect(1)
WaitForCTS()
END SUB
SUB DABSeek(seekup as INTEGER)
CtrlVal(curName)="--------"
Print "Stepping to next DAB Frequency"
if seekup>0 THEN
DABFreqIndexInUse=DABFreqIndexInUse+1
ELSE
DABFreqIndexInUse=DABFreqIndexInUse-1
ENDIF
if DABFreqIndexInUse>localDabMaxIndex THEN DABFreqIndexInUse=localDabMaxIndex
if DABFreqIndexInUse<localDabMinIndex then DABFreqIndexInUse=localDabMinIndex
if NumDABFreqs=0 THEN
newFreq=localDabMin
ELSE
newFreq=DABFreqs%(DABFreqIndexInUse)
ENDIF
flagSeekUp=0
flagSeekDown=0
infoText="Waiting for DAB+ info data"
end sub
SUB ReadDABFreqTable
LOCAL freq AS INTEGER
print "reading DAB frequency table..."
ChipSelect(0)
SPI WRITE 2, &HB9, &H00
ChipSelect(1)
PAUSE 10
ReadReply(5)
print spirxbuf%(0)
print spirxbuf%(1)
print spirxbuf%(2)
print spirxbuf%(3)
NumDABFreqs = SPIRXBUF%(4)
print "number of DAB freq table entries: ",NumDABFreqs
ReadReply(8 + 4*NumDABFreqs)
FOR i = 0 TO (NumDABFreqs - 1)
freq = SPIRXBUF%(8 + 4*i) + 256 * SPIRXBUF%(8 + 4*i + 1) + 65536 * SPIRXBUF%(8 + 4*i + 2)
DABFreqs%(i) = freq
print "entry ",i,": ",DABFreqs%(i)
NEXT i
END SUB
SUB TuneDABFrequency(entry AS INTEGER)
WriteDABFEConfig()
PAUSE(20)
print "tuning to DAB frequency table entry: ",entry
ChipSelect(0)
SPI WRITE 2,&HB0,&H00
SPI WRITE 1,entry
SPI WRITE 3,&H00,&H00,&H00
ChipSelect(1)
print "done."
END SUB
SUB ParseDigitalServiceList()
local ServiceListSize AS INTEGER
local ptr AS INTEGER
local NumberOfComponents AS INTEGER
local service AS INTEGER
local component AS INTEGER
local serviceLabel AS STRING
local serviceLabelIndex AS INTEGER
ServiceListSize = SPIRXBUF%(4) + 256 * SPIRXBUF%(5)
print "Parsing DAB service list, size in bytes is:", ServiceListSize
ptr = 8
NumDABServices = SPIRXBUF%(ptr)
ptr = ptr + 1
print "Number of Services: ",NumDABServices
ptr = ptr + 3
FOR service = 0 to (NumDABServices - 1)
DABServiceIDs%(service) = SPIRXBUF%(ptr)+256*SPIRXBUF%(ptr+1)+65536*SPIRXBUF%(ptr+2)+16777216*SPIRXBUF%(ptr+3)
print "service ID: ", hex$(DABServiceIDs%(service))
ptr = ptr + 4
ptr = ptr + 1
NumberOfComponents = SPIRXBUF%(ptr) MOD 16
ptr = ptr + 1
print "number of components: ",NumberOfComponents
ptr = ptr + 2
serviceLabel$ = ""
FOR serviceLabelIndex = 0 to 15
serviceLabel$ = serviceLabel$ + CHR$(SPIRXBUF%(ptr))
ptr = ptr + 1
NEXT serviceLabelIndex
DABServiceNames$(service) = serviceLabel
print "service label:",DABServiceNames$(service)
FOR component = 0 to (NumberOfComponents - 1)
DABComponentIDs%(service) = SPIRXBUF%(ptr)+256*SPIRXBUF%(ptr+1)
print "component ID: ", DABComponentIDs%(service)
ptr = ptr + 2
ptr = ptr + 2
NEXT component
NEXT service
END SUB
SUB GetDigitalServiceList
local ServiceListSize AS INTEGER
print "getting digital service list..."
ChipSelect(0)
SPI WRITE 2,&H80,&H00
ChipSelect(1)
PAUSE 1000
ReadReply(6)
print "service list size LSByte: ",SPIRXBUF%(4)
print "service list size MSByte: ",SPIRXBUF%(5)
ServiceListSize = SPIRXBUF%(4) + 256 * SPIRXBUF%(5)
ReadReply(6 + ServiceListSize)
print "done."
END SUB
SUB WriteDABFEConfig
SetProperty(&H1710, &HF8A9)
SetProperty(&H1711, &H01C6)
SetProperty(&H1712, &H0001)
END SUB
SUB DABSettle
LOCAL INTEGER ServiceListVersion
PAUSE(200)
SendDABDigradStatus
ReadReply(23)
IF (SPIRXBUF%(5) MOD 2) = 0 THEN
print "DAB_DIGRAD_STATUS does not report VALID"
RETURN
ENDIF
DABGetEventStatus()
ReadReply(8)
ServiceListVersion=SPIRXBUF%(7)*256+SPIRXBUF%(6)
if ((SPIRXBUF%(5) MOD 2) = 1) THEN
IF  (DABserviceListReady =0) or (lastServiceListVersion <> ServiceListVersion) THEN
GetDigitalServiceList()
DABserviceListReady = 1
ParseDigitalServiceList()
if CTRLVAL(curName) ="Scanning services" then CTRLVAL(curName) ="Services Found"
ENDIF
lastServiceListVersion = ServiceListVersion
ENDIF
END SUB
SUB DABGetEventStatus
ChipSelect(0)
SPI WRITE 2,&HB3,&H01
ChipSelect(1)
PAUSE 50
END SUB
sub CheckDigitalEnsemble
DABSettle
END SUB
SUB StartDigitalService(ServiceID AS INTEGER, ComponentID AS INTEGER)
print "starting digital audio service 0x",hex$(serviceID)
print "serID:",(ServiceID MOD 256),(ServiceID \ 256) MOD 256, (ServiceID \ 65536) MOD 256, (ServiceID \ 16777216) MOD 256
print "cmpID:",(ComponentID MOD 256),(ComponentID \ 256) MOD 256, (ComponentID \ 65536) MOD 256, (ComponentID \ 16777216) MOD 256
ChipSelect(0)
SPI WRITE 4,&H81,&H00,&H00,&H00
SPI WRITE 4,(ServiceID MOD 256),(ServiceID \ 256) MOD 256, (ServiceID \ 65536) MOD 256, (ServiceID \ 16777216) MOD 256
SPI WRITE 4,(ComponentID MOD 256),(ComponentID \ 256) MOD 256, (ComponentID \ 65536) MOD 256, (ComponentID \ 16777216) MOD 256
ChipSelect(1)
PAUSE(50)
ReadReply(4)
FOR i = 0 to 3
print "resp ",i,":",SPIRXBUF%(i)
NEXT i
print "done"
infoText="Waiting for DAB+ info data"
END SUB
SUB SetFreqTableFromLocale
ReadDABFreqTable
localDabMin=dabmin
localDabMax=dabmax
localDabMinIndex=0
localDabMaxIndex=0
if NumDABFreqs>1 THEN localDabMaxIndex=NumDABFreqs-1
if curLocale = 0 THEN
Print "Setting DAB to AU"
localDabMin=202928
localDabMax=211648
END IF
if curLocale = 1 THEN
Print "Setting DAB to NZ"
localDabMin=174928
localDabMax=239200
END IF
if curLocale = 2 THEN
Print "Setting DAB to R.O.W"
END IF
for i = localDabMinIndex to localDabMaxIndex
if localDabMin = DABFreqs%(i) then localDabMinIndex=i
if localDabMax = DABFreqs%(i) then localDabMaxIndex=i
NEXT i
Print "Local Minimum:(";localDabMinIndex;"):"localDabMin
Print "Local Maximum:(";localDabMaxIndex;"):"localDabMax
END SUB
SUB setFreqTable(n as integer)
if n> 48 then n=48
if n< 0 then n=0
ChipSelect(0)
SPI WRITE 4,&HB8,n,&H00,&H00
for i = 0 to n-1
SPI WRITE 4,DABFreqs(n) and 255,(DABFreqs(n)\256) and 255,(DABFreqs(n)\65536) and 255,(DABFreqs(n)\16777216) and 255
next i
ChipSelect(1)
WaitForCTS()
END SUB
SUB GetDABProgramInfo
local payLoadSize AS INTEGER
ChipSelect(0)
SPI WRITE 2,&H84,&H00
ChipSelect(1)
PAUSE 10
ReadReply(280)
payLoadSize=SPIRXBUF%(19)*256+SPIRXBUF%(18)
if payLoadSize>0 THEN
GetDigitalServiceDataPayload(payLoadSize)
ENDIF
END SUB
SUB GetDigitalServiceDataPayload(p as INTEGER)
local STRING temp$
temp$=""
print p
if p > 256 THEN p= 256
if ((SPIRXBUF%(24)=0) or(SPIRXBUF%(24)=128))  and (SPIRXBUF%(25)=0) then
for i = 0 to p-1
if SPIRXBUF%(24+i)>31 then
temp$=temp$+chr$(SPIRXBUF%(24+i))
ENDIF
NEXT i
ENDIF
print "DAB+ data {";len(temp$);"}:";temp$
if len(temp$)>0 THEN infoText=temp$
END SUB
SUB fixCurName
DO WHILE (len(CTRLVAL(curName))>0) and RIGHT$(CTRLVAL(curName),1)=" "
CTRLVAL(curName)=left$(CTRLVAL(curName),LEN(CTRLVAL(curName))-1)
LOOP
END SUB
SUB doSoftReset
WATCHDOG 1
PAUSE 1000
END SUB
CFunction LOADERBIN
00000000
FF000010 00000000 00000000 12345678 00000000 00000000 6CCB84FD 00000001
DEADBEEF 00001648 00000004 00000004 00000000 50200544 00000000 00000000
00000000 00000000 00000000 00000000 00000000 076FCF88 8100006F 5000D800
5000E048 5000E150 50002A00 502867AC 5028656C A0002E00 50002A80 502896A0
FFF0FF0C A0001E00 4FFFFF80 502895E8 50000040 502892F8 50000050 50000060
FFFF0000 00001003 502008A8 502008C8 50200874 502007E0 502009F0 50200660
5000FE00 90200403 502008FC 50286778 50002A50 50002200 501FFFFF 50260000
A0000E00 502897D4 50008E00 A003F300 FFFFEFFF A002BE00 50002534 500027E0
5000E134 5000E130 502860A8 50285198 000FFFFF FFF00000 50286594 5000E050
0000ED0C 0000DEC0 0000C0DE 50286658 5000E000 00000BB7 0000C350 A000BE00
5000E0B0 5028A570 03000000 9FFFFE00 00001000 A00020C0 000F00F3 A00020D0
A00020E0 A00020F0 A0001004 00000800 A000C080 5000E0A8 A000C090 0000FFFF
A000C0F0 A000C010 A000C070 50201544 A000C100 A00010F0 A0001044 A0003100
A0001060 A0001080 A00011F0 00C00000 00400000 00004E20 5028A6A4 C3500000
00008808 0001FFE3 A0001008 EFFC37FF EFFC3FFF A000C0E0 00060000 00040000
A000C110 A000C120 A000C060 00020000 5028A580 02000000 5000E020 50284C50
5000E030 5000E140 A003DE00 000103F7 000103E7 00001017 00001037 81000011
5000E000 030361A8 004B000B 00042002 000040C7 500E0000 00000000 00000000
00000000 4649423C 5244485F 4345535F 0A3E4E54 49422F3C 44485F46 45535F52
3E4E5443 0000000A 21000042 5000E048 8000050A 50200400 21004136 20C03202
15229200 820020C0 98971422 0020C00E C01522B2 22A20020 F01AB714 C6000065
0000FFF6 21004136 20C03202 14223200 C0A03320 23520020 0005521A 420020C0
441B1A23 0C0020C0 321B0C4A 03811E23 30930B32 08E09339 2B452600 26465526
75265065 6085265A 1587980C 6A952664 1597B90C CFA0A26E 811D15A7 1A0C3204
0C0008E0 0002C61A 228203BD E004AD23 0A0C0008 1D004E25 8203BDF0 04AD2B22
060008E0 03BDFFF7 AD242282 0008E004 BDFFF3C6 25228203 08E004AD FFF08600
E0262282 EE460008 272282FF 060008E0 2282FFEC 0008E028 82FFE9C6 08E02922
FFE78600 E02A2282 E5460008 000000FF A2004136 052180A0 0020C032 A0C42292
20C02099 32068100 82C46292 88AC0808 20C01A0C CC229200 C02099A0 62920020
320781CC 08E0DA0C C0EC7C00 22B20020 10BBC0CC B20020C0 F01DCC62 0C004136
3203814A 08E00B0C 41170C00 09313208 32065132 92F2A062 05210805 C0F99C32
22B20020 20BB70CC B20020C0 20C0CC62 9023A200 6010AA40 20C020AA 9063A200
C10111E5 0CC2320A 35EC3789 B250A0A2 0B8104A0 320CC132 A10008E0 0D81320C
320EB132 A20008E0 A0B260A0 320B8104 E0320CC1 0CA10008 320D8132 E0320FB1
0A4C0008 0B814B0C 320CC132 C10008E0 11A13210 3202B132 920020C0 99C08422
2099A010 A10020C0 16C13217 3215D132 F13214E1 62923213 32128184 F2286B82
6BE22B6B 236BD225 A2246BC2 0592266B C0F99C08 22E20020 20EE70CC E20020C0
20C0CC62 9023D200 6010DD40 20C020DD 9063D200 C1321AB1 18A1321C 32199132
92321B81 4A0C5C6A 0C0008E0 3203814A 08E01B0C 00F01D00 81004136 20C03205
D8288200 66348080 0FA50238 00006500 0000F01D 0C006136 3205B115 820020C0
1D31D82B 34808032 0C2E3826 3203814A 08E00B0C 32048100 08E01A0C 3202A100
520020C0 090C166A 0C0020C0 186A921B 0C320381 0008E04A 020CF01D 42D22392
23C2CD23 321EF1D1 0C094CF6 90620CED 0106832D 904E0C00 BF47932E 321F8105
5002B847 AEE22022 3220910F D20020C0 DDE0D82B 0020C010 C2D86BD2 20C0F0A1
D82BA200 C020AAC0 6BA20020 0020C0D8 C09E6952 69520020 0020C096 65966952
0AF10009 890FF232 8105EF57 08E03221 814A0C00 0B0C3203 C80008E0 A201B811
2291D023 9D098D32 F2043D0A FF8002A5 86A0E211 FF40FFEA EAA1E211 0FA0FFEA
00F01D00 81004136 0882320A 471A0C89 2D0C3D68 C03220B1 2BC20020 20CCD098
C20020C0 20C0986B 982B9200 C02099A0 07810020 986B9232 820008E0 23F100A1
0020C032 80201FE2 20C020EE 205FE200 0000F01D 21004136 2481320A 89022232
27322541 20C00EE2 8C243200 C0103380 64320020 00F01D8C 7C004136 32054105
320533B6 0086FDC3 00A03200 820020C0 8080D824 33286634 C220D330 26A103C2
3227B132 1600DC25 20C004BA D824B200 C010BB50 64B20020 C03A0CD8 24920020
2099A0D8 920020C0 F01DD864 B20020C0 BB50D824 0020C010 0CD864B2 0020C07A
A0D82492 20C02099 D8649200 0C320481 0008E01A 1DC1F01D F32CC232 81FF4C16
1A0C3204 1D0008E0 000000F0 B6004136 02821433 FFA0A200 920B98A7 02B20102
0299A702 81151BA7 28A1322A 3229B132 0B99090C 03BD0A99 08E002AD 00F01D00
31004136 05213202 0020C032 20D82222 22803420 0020C011 1D306322 000000F0
0C008136 269387F8 0C60A0A2 320B814B 08E001CD 8101AD00 C1B2320D 0008E010
90904198 8169CCF4 02AD322B 1D0008E0 000000F0 A8004136 201D0C12 6B98A0BA
923205C1 20C00009 982C8200 89F48080 E8BA1BAB 660A0C52 42D90479 26000106
32D90149 AD01BBE7 322CE10B 98A09A20 322DB169 C01099E0 2C820020 1088B080
C0208890 6C820020 A942F880 B8AFDC12 A732C802 190C069B 004622D9 26229800
1C260819 322E8105 0C0008E0 3203814A 08E01B0C 00F01D00 0C004136 3203814A
08E00B0C 31040C00 20C03202 1423B200 20C0BB1B 1463B200 A20020C0 20C01923
14239200 C00539A7 63420020 0020C014 9C1723C2 2212663C C0FFB365 63420020
0020C017 06166342 20C00004 1623D200 B1E57D8C 0020C0FF 0C166342 3203814A
08E01B0C 00F01D00 B6004136 2FA17033 00686532 410002A2 3A163202 023AE606
82371AE6 7816F0CA EFCA9216 B2169916 2BA7F3A0 F0A0C205 D255AAC7 DAD0F4A0
16CD16C0 E0FEA0E2 4E16C0EA FFA0F20D 16C0FAF0 020C113F 0C000506 0DB837E8
C3C2B23B 0016A5FD A20020C0 120C3064 56007BE5 04810082 01A0A232 1D0008E0
37A90CF0 B23BE7B9 65FDC3C2 F7060014 02B3F6FF C1002146 02B23230 0102D202
D011BB80 9BC720BB 0FC2B273 92090282 02F20402 F1C3D205 E20E02C2 CC800D02
20CCE011 800C02E2 CCE011CC 0B02E220 E011CC80 CCD020CC 0602E263 D010AFD2
EE8080DA 20EEF011 F211EE80 EE900A02 03029220 8011FF80 FF8011EE 08028220
9011FF80 FF8020EE 07028220 8011FF80 AFF020FF 00296520 D4860A2D 46120CFF
73B6FFD3 3231E13F F20202D2 DD800102 20DDF011 A22D9DE7 02B20602 11AA8005
B220AAB0 AA800402 20AAB011 800302B2 AAB011AA 003B2520 ABA01B0C 460A2D93
0000FFC3 46120C00 32D1FFC1 0202C232 800102E2 CCE011CC 0F9CD720 0C003365
93ADA01D B9860A2D 000000FF B786120C E5A23BFF B5060017 0202A2FF 800102B2
AAB011AA 00102520 A20020C0 AF063064 FDC3C2FF 0E0C0D0C B20202A2 AA800102
20AAB011 AA40B23B 001E2511 00FFA786 BD006136 7C04CD03 0C32CCFA 0003464D
C208A0D2 C3B2FCC4 0061A204 2F510368 AD01A932 00706505 7A2505AD 41030C00
20C0321D B6D5C800 2146023C 08235600 56F324D2 05AD07CD 16008425 0578FE3A
01ADD28C 81A0C750 5CB83233 08E09CC8 5622F600 503226A1 27B1A0D7 052DC232
65092DD2 3AA0009A 0CAAAC20 C0E5B91B 05F10020 D82F9232 99A00A7C 0020C010
C0D86F92 2FE20020 80380CD8 20C020EE D86FE200 C20004C6 DC16F324 01A0A200
8101A092 E5993204 AD0008E0 00822505 A8FFDB86 A7B28C01 04810916 E01A0C32
01A80008 F01D0A2D BC004136 32345102 26341226 B34C3622 42361237 124701A1
02A18235 92341287 129701A2 02A2A233 B23212A7 12B703A2 04A2C231 0C0312C7
22F01D02 F01D0C05 1D001522 020522F0 1522F01D 22F01D03 F01D0305 1D040522
080522F0 0522F01D 22F01D09 F01D0515 0C004136 81BA4C17 A1B23234 3235D101
E201A2C2 A2F202A2 52B90C03 45160012 01126207 1516224B 551526FF 97442526
15A73B15 2615B72F E71D15C7 15F71415 04A2320B 62439537 F3460C48 055862FF
62FFF1C6 F0460948 084862FF 62FFEEC6 ED460348 643060FF 06035832 4862FFEB
FFE98604 620546F6 E7460248 06070CFF BD67FFE6 32364105 0C04B467 FFE28607
06005862 072DFFE1 0000F01D 0C008136 810B0CDA 61293203 032D5169 043D6178
4DF8C262 E0025D05 31490008 41292169 06BD14AC 01AD2169 F97CC38B 99323381
0008E001 6A1731A8 B851C80B 041BC701 2C46020C 32376100 0C068316 FFA08204
52000522 128701C5 01A0A250 C1001665 0CC23234 0020C008 C2322F91 B0705849
0020C0F5 705949B2 20C041A8 5A49A200 720020C0 20C05B49 5C492200 E505A0A2
20C00044 CC26D200 C0086D07 26E20020 F6EE07CC 070014E5 771BF9EA 1BFFA082
9B934744 68073188 BD61A83B E541C803 20C0001B CC269200 C0086907 26A20020
F6EA07CC C38B21B8 F97CA14B 99323381 0008E011 11C81A0C 020C01B8 B0C0BBC0
0046832A 0C120C00 320381DA 08E01B0C 00F01D00 E5004136 1A0C000E 0C000B65
0013252A A0000DE5 288C7480 F01D020C 0A251A0C 32349100 92322FA1 20C00C09
584A9200 3A651A0C 32379100 B20020C0 6B07CC29 0020C008 07CC29C2 0A65F6EC
F9EA0700 F01D120C A5004136 1A0C0009 0C000625 000DE52A A00008A5 288C7480
F01D020C 04E51A0C 3234C100 C2322F91 20C0090C 5849C200 C0F5B020 49B20020
41A82059 A20020C0 20C05A49 5B492200 33A54A0C 32379100 D20020C0 6D07CC29
0020C008 07CC29E2 03A5F6EE F9EA0700 F01D120C 0C004136 91480C6A 8A20322F
0020C093 49821A0C 00302558 C0323791 29B20020 086B07CC C20020C0 EC07CC29
00F01DF6 21004136 2CB13237 32383132 B0322DC1 20C010B3 8022A200 B010AAC0
20C020AA 8062A200 0CA0C392 0020C058 1B0C1A0C 65584982 20C0002E CC22C200
C0086C07 22D20020 F6ED07CC 220020C0 F01D0003 0C004136 322F8119 920020C0
20C05848 222A0C00 28255948 32379100 B20020C0 6B07CC29 0020C008 07CC29C2
F825F6EC F9EA07FF 0000F01D A1004136 03BD3234 C1040A92 C9CC322F C0030A82
4C820020 C64A0C58 20C00003 584C9200 20C00A0C 5C4CA200 80205A0C 3237D1F5
820020C0 F820594C 0020C041 C05A4CF2 4C220020 322CE15B E0322DF1 20C010E4
802DC200 E010CCF0 20C020CC 806DC200 1D0022A5 000000F0 0C004136 318C5C0B
3981322F E003AD32 3AB10008 323BC132 910020C0 6CB2323C B13A0CA2 A0C2323E
9932A9F2 323DA142 A1004F25 3EB1323F F2A0C232 A1004E65 3EB13240 F2A0C232
A1004DA5 3EB13241 F1A0C232 A5004CE5 42A10006 3243B132 A1004E25 2CB13244
3245C132 A1004B65 47B13246 E57C0C32 48A1004A 0C3B0C32 004A251C B23248A1
0C0C70A0 A1004965 42C83249 0B3247B1 0048A5CC B2324AA1 1C0C73A0 CD0047E5
81DA0C03 4BB1321B 0008E032 1C324CA1 A50C0CCB F01D0046 A1004136 10B1324D
A50C0C32 4EA10045 3243B132 310046E5 13823223 32342120 A1376887 A4B2324F
00A4C200 81004365 A3A23207 0008E0E8 B13250A1 43C13243 00422532 3C324FA1
A50C1C0B 51A10041 0CCB0C32 0040E50C A1001586 53B13252 3254C132 B2003FE5
55C10012 B71A0C32 AAF00B3C 11BBF011 46F6BCB7 1A0C0000 0B325681 0E42929A
E03257A1 DAB20008 41BCB008 B211BBF0 A2C20D42 74B0B000 C020BBC0 53B20020
3258A190 A20020C0 4CA18053 3259B132 D20202C2 E1C00E02 11DD2004 F004C0C0
DDE011EE 20CCD020 1D003925 000000F0 A1004136 3EB1323D 258C0C32 40A10038
323EB132 37658C0C 3241A100 0C323EB1 0036A58C B1323FA1 8C0C323E A10035E5
43B1325A 00376532 0381DA0C E00B0C32 5BB10008 3220A132 B20020C0 5C91886A
0020C032 1D886A92 000000F0 A1004136 47B1325D 650C0C32 4CA10032 325EB132
A5325FC1 02CD0031 7C3260A1 0030E5FB 0C3261A1 651C0C1B F01D0030 A1004136
47B1325D 650C0C32 62A1002F 3247B132 2EA50C0C 324CA100 C1325EB1 2DE53263
3260A100 C280FB7C 20C3C001 A1002CE5 1B0C3261 2C651C0C 00F01D00 61004136
A0823238 0D384780 06AD03BD CD326481 0008E004 0E0C063D 0ECD02DD 390020C0
E9E2E9F2 0020C0D2 C0106242 62E20020 0020C012 C01362E2 62E20020 1562E214
0C3202A1 1AA97649 B20020C0 AA4B1A2A F8071367 C0FF50F2 1B051BF7 4B5DB9CC
C9F03DDD C102E932 42C9323C C03237A1 42B80020 BB0B12E9 B03210C1 20C0F4B0
842A9200 B01099C0 20C02099 921B0C00 0381846A E0DA0C32 F01D0008 C0004136
D2880020 6856E298 0A39560A A20020C0 2A561222 0020C004 881022B2 378BB6F2
20C00888 11628200 1FF8F2F8 E80020C0 1262F2F2 F2E9EE8B D20020C0 CDD21022
0020C0F8 C01062D2 22C20020 917CCC12 20C03265 12629200 A20020C0 1C0C1222
C004EA16 22820020 0020C012 12C84238 20633380 5CC8A0CC A20020C0 03BD1122
C0FFC0A5 22B20020 C0BB3A11 62B20020 0020C011 301222A2 20C0C0AA 1262A200
920020C0 991B1322 920020C0 F01D1362 20C0F01D 1DD2C900 000000F0 C0004136
D2880020 0C0338B6 0CF01D02 320381DA 08E00B0C C0130C00 12A80020 99A70298
0020C009 0B0C22C8 0C833BC0 320381DA 08E01B0C C063CC00 D2980020 C0CB29B6
D2A80020 3AB6120C 1D020C03 00F01DF0 0C004136 920B0CDA 03811522 92991B32
08E01562 A8030C00 1B32B802 B702A9AA 0239013A B80020C0 A19B8C22 EBE5322F
0020C0FF DA0C2239 0C320381 0008E01B 20C03A0C B8D29800 2429F6E2 20C01BAC
1322D200 C20020C0 BCD71422 0020C00E C01322F2 22E20020 F03EF714 A90020C0
0020C0D2 1866D288 0020C015 C01322B2 22920020 B72C0C14 20C00439 C0D2C900
D2D80020 C0102D66 22F20020 1522E214 C0043EF7 D2A90020 0000F01D D1004136
3BE1323A 0020C032 C0A26ED2 12B80020 203237C1 20C0A0DB 982CC200 C0C00A0C
889DC9F4 87BB1B32 0BAD01BB A90020C0 0020C012 02F81288 9F87190C 0020C007
01462299 322FA100 C0FFDF25 22A20020 C0AA1B14 62A20020 00F01D14 40004136
F77C1063 C0307370 02580020 60105570 20C02055 1D025900 000000F0 C0004136
02390020 0000F01D 29006136 AC013911 326631F5 E2322971 C7C210C3 0C079810
26E9AC06 29667F19 A805DD15 8101B811 04CD3267 E10008E0 69C13268 56050C32
11A8FDA5 2AA2190C A2020C27 29A0F8CA D8F01D83 3A0F0C17 E2B6572D 0BFDFF56
B29DCA55 02820004 1B441B00 B2DD1B22 17D90049 A81F1B87 8101B811 69C13267
0008E032 C13268E1 290C3269 1F0C0799 17D90D0C 26000086 661B04BD 0CFFEE46
C607A91A 0F0CFFF9 060C17D8 B6572DEA F8AF568D 661B550B 820002B2 441B0004
2D081B87 D90D0C0E 00040617 191C221B 17D9DD1B 0C059D97 A92A0C1F FFF34607
41004136 0482320A 04848089 C216D816 052C0FAE 6A31023C 3205A132 B20020C0
BBC0D82A 0020C010 C0D86AB2 2A920020 209920D8 920020C0 20C0D86A 88635200
1C320781 0008E0EA 220020C0 07818863 E0EA1C32 A2920008 0020C030 81886392
EA1C3207 920008E0 20C030A3 88639200 1C320781 0008E0EA C0326B91 63920020
32078184 08E0EA1C 326C9100 920020C0 07818463 E0EA1C32 A1920008 0020C030
81886392 EA1C3207 910008E0 2321326D 0020C032 81385292 EA1C3207 910008E0
20C0326E 38529200 1C320781 0008E0EA C03FA392 52920020 32078130 08E0EA1C
1CA19200 920020C0 07812052 E0EA1C32 A1920008 0020C010 81886392 EA1C3207
C00008E0 52520020 32078120 08E0EA1C 08A19200 920020C0 07816852 E0EA1C32
991C0008 920020C0 07815852 2CA1A232 920008E0 A1B28A04 A2A9CC00 20C01BA1
7052A200 B0000206 20C020B9 7052B200 1C320781 0008E0EA 20A1DD7C 0020C032
D0982AC2 20C010CC 986AC200 20C0EB7C 982A9200 C01099B0 6A920020 00F01D98
00000000
End CFunction
