{###########################################################################}

procedure SendSR;
//Sende MP3switchState an den 4094 oder Ausgangsport

begin
  if MP3isOn then
    b_ExtOnMP3Power:= high;
  else
    b_ExtOnMP3Power:= low;
  endif;
  MP3switchTemp := MP3State OR SwitchState;
  asm;
    cbi  DDS.DDSOutPort, DDS.b_SCLK
    LDS _ACCA, DDS.MP3switchTemp;
    ldi  _ACCB, 8

    DDS.srloop1:
    LSL  _ACCA
    brcs DDS.datahigh1
    cbi  DDS.DDSOutPort, DDS.b_SDATA
    rjmp DDS.dataset1
    DDS.datahigh1:
    sbi  DDS.DDSOutPort, DDS.b_SDATA
    DDS.dataset1:
    nop
    sbi  DDS.DDSOutPort, DDS.b_SCLK
    nop
    cbi  DDS.DDSOutPort, DDS.b_SCLK
    dec _ACCB
    BRNE  DDS.srloop1

    LDS _ACCA, DDS.LevelByteHi;
    ldi  _ACCB, 8

    DDS.srloop2:
    LSL  _ACCA
    brcs DDS.datahigh2
    cbi  DDS.DDSOutPort, DDS.b_SDATA
    rjmp DDS.dataset2
    DDS.datahigh2:
    sbi  DDS.DDSOutPort, DDS.b_SDATA
    DDS.dataset2:
    nop
    sbi  DDS.DDSOutPort, DDS.b_SCLK
    nop
    cbi  DDS.DDSOutPort, DDS.b_SCLK
    dec _ACCB
    BRNE  DDS.srloop2

    LDS _ACCA, DDS.LevelByteLo         ; LSB Level zuletzt
    ldi  _ACCB, 8

    DDS.srloop3:
    LSL  _ACCA
    brcs DDS.datahigh3
    cbi  DDS.DDSOutPort, DDS.b_SDATA
    rjmp DDS.dataset3
    DDS.datahigh3:
    sbi  DDS.DDSOutPort, DDS.b_SDATA
    DDS.dataset3:
    nop
    sbi  DDS.DDSOutPort, DDS.b_SCLK
    nop
    cbi  DDS.DDSOutPort, DDS.b_SCLK
    dec _ACCB
    BRNE  DDS.srloop3

    sbi  DDS.DDSOutPort, DDS.b_STROBE
    nop
    nop
    cbi  DDS.DDSOutPort, DDS.b_STROBE
    sbi  DDS.DDSOutPort, DDS.b_SCLK
  endasm;
end;

{AD9833 DDS functions }
procedure SendDDS;  //Sende ein Wort an den DDS-Chip

begin
  asm;
    sbi  DDS.DDSOutPort, DDS.b_SCLK
    lds  _ACCA, DDS.dss_cmd+1
    cbi  DDS.DDSOutPort, DDS.b_FSYNC

    ldi  _ACCB, 8

    DDS.ddsloop1:    ; höherwertiges Byte rausschieben
    sbrc _ACCA,7 // Bit high?
    sbi  DDS.ControlBitPort, DDS.b_SDATAOUT
    cbi  DDS.ControlBitPort, DDS.b_SCLK
    lsl  _ACCA
    cbi  DDS.ControlBitPort, DDS.b_SDATAOUT
    sbi  DDS.ControlBitPort, DDS.b_SCLK
    dec _ACCB
    brne  DDS.ddsloop1

    lds  _ACCA, DDS.dss_cmd
    ldi  _ACCB, 8

    DDS.dssloop2:    ; niederwertiges Byte rausschieben
    sbrc _ACCA,7 // Bit high?
    sbi  DDS.ControlBitPort, DDS.b_SDATAOUT
    cbi  DDS.ControlBitPort, DDS.b_SCLK
    lsl  _ACCA
    cbi  DDS.ControlBitPort, DDS.b_SDATAOUT
    sbi  DDS.ControlBitPort, DDS.b_SCLK
    dec _ACCB
    brne  DDS.dssloop2

    sbi  DDS.DDSOutPort, DDS.b_FSYNC
  endasm;
end;

{###########################################################################}

//DDS-Funktionen

procedure SetLevelDDS;
//Pegelsteller und Relais setzen, AktuelleFrequenz einstellen
var
  acc : LongInt;
  freqHi, freqLo : word;
  LevelInt: Integer;
  AttnSwLevel:Integer;
begin
//Pegel einstellen, Relais und MP3-Power setzen
  SwitchState:=0;

  if Level < 100 then  // unter 100 mV DA-Pegel wieder full Scale, 4095 Digits
    LevelInt:=integer(Level*40+0.5);
    b_AttnSw:= high;  //Relais für Abschwächer auf 1/40
  else
    LevelInt:=Integer(Level+0.5);  // Runden auf Ganzzahl
    b_AttnSw:= low;
  endif;

  case Wave of
    c_sinw :
      wave_cmd:= c_ddssinecmd;
      |
    c_triw :
      wave_cmd:= c_ddstrianglecmd;
      |
    c_squw,c_logic :
      wave_cmd:= c_ddssquarecmd;
      b_SquareSw:= high;
      if wave= c_logic then
        b_LogicSw:= high;
      endif;
      |
{    c_dc :
      wave_cmd:= c_ddsresetcmd; // Aus für  c_off und Audio
      b_LogicSw:= high;  // Offset erzwingen
      |
}
  else
    wave_cmd:= c_ddsresetcmd; // Aus für  c_off und Audio
  endcase;

  b_LEDpwr:=high;  // zusätzliche LEDs default aus
  b_LEDsym:=high;
  case Outputmode of
    c_symo:
      b_LEDsym:=low;
      LevelInt:=LevelInt div 2;
      |
    c_pwro:
      b_LEDpwr:=low; // PowerAmp-LED an
      b_PwrSw:=high; // PowerAmp-Relais
      |
    c_psymo:
      b_LEDsym:=low;
      b_LEDpwr:=low;  // zusätzliche LEDs default aus
      b_PwrSw:=high; // PowerAmp-Relais
      LevelInt:=LevelInt div 2;
     |
  endcase;

  LevelByteHi:=hi(LevelInt);
  LevelByteLo:=lo(LevelInt);
  
//MP3Power wird in SendSR eingefügt
  SendSR; //Pegel und Relais setzen


//DSS-AktuelleFrequenz einstellen
  DDSfrequ:= 0;
  FreqStr:= longtostr(AktuelleFrequenz : 8:'0'); // mit führenden Nullen
  for i := 0 to 7 do                //Einzelne Stellen aufaddieren
    k:= byte(FreqStr[i+1])-48;
    acc:= gettable(fhz, i);
    DDSfrequ:= DDSfrequ + (acc*longint(k));
  endfor;
  dss_cmd:= loword(DDSfrequ) AND %0011111111111111;
  dss_cmd:= dss_cmd OR %0100000000000000;
  SendDDS;
  DDSfrequ:= DDSfrequ shl 2;
  dss_cmd:= hiword(DDSfrequ) AND %0011111111111111;
  dss_cmd:= dss_cmd OR %0100000000000000;
  SendDDS;
  dss_cmd:= wave_cmd;
  SendDDS;
end;

