Hallo
ich schicke die tage ein passendes Programm.
Gruß wom
Hallo,
anbei ein Demo. Der I2C-Soft scheint zu arbeiten, nicht so der TWI. Im demo ist der Test für TWI nicht aktiv, sonst hängt das Programm. Mittlerweile machen die xmega nicht so richtig Spaß. Einige Teile machen hier mehr Probleme wie die AtMega.
program MINI3_X1T;
{$WG}
Device = xmega256A3BU;
{$BOOTRST $20000} {Reset Jump to $20000}
//{$BootApplication} // $20000
Define_Fuses
Override_Fuses;
NoteBook = D;
COMport = USB;
ProgMode = PDI;
LockBits0 = [BLBB0, BLBB1, LB0, LB1]; // protect boot and app against read back
FuseBits0 = [];
FuseBits1 = [];
FuseBits2 = [BootRst]; // mandatory !!
FuseBits5 = [BODACT0, BodLevel0, BodLevel1, BodLevel2];
Import SysTick,WatchDog, SerPortD0, SerPortE0, SerPortF0, SerPortC0;
Import UserPort,TWI_E , TickTimer, ADC_A, I2Cport;
Import SerPortCDC;
//From System Import Processes, Tasks;
From System Import Float,LongWord,Traps;
Define
// XMega USB must use the internal 32MHz OSC. So the system must use the 2MHz OSC
OSCtype = int2MHz,
PLLmul = 16, // bei int2MHz und PLLmul 10 = 20MHz
prescB = 1,
prescC = 1;
SysTick = 10, User; // msec
StackSize = $0128, iData;
FrameSize = $0128, iData;
WatchDog = msec2000; {2048msec}
USBmanufact = 'EcoTron'; // max 31 bytes
USBprodName = 'Serial CDC-USB'; // "
USBpid = $05FE;
USBvid = $BCDE;
USBprodRel = 203;
USBcurrent = 100;
SerPortCDC = TimeOut;
RxBufferCDC = 64, iData;
TxBufferCDC = 64, iData;
{----------------------------- init AD-Wandler -----------------------------}
ADCrefA = REF100;
ADCprescA = 128,12;
ADCchansA = [0..2];
I2Cport = PortC;
I2Cdat = 0;
I2Cclk = 1, 255;
TWIprescE = TWI_BR400;
UserPort = 65535;
{ RTC-CPU-Uhr intern }
TickTimer = Timer_C0; // use Timer_C0 and no PortPin
// RS485
SerPortC0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlC0 = PortD, 4, positive;
RxBufferC0 = 40, iData;
TxBufferC0 = 100, iData;
// RS485
SerPortD0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlD0 = PortD, 4, positive;
RxBufferD0 = 40, iData;
TxBufferD0 = 100, iData;
// RS485
SerPortE0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlE0 = PortE, 4, positive;
RxBufferE0 = 40, iData;
TxBufferE0 = 100, iData;
// RS485
SerPortF0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlF0 = PortF, 1, positive;
RxBufferF0 = 40, iData;
TxBufferF0 = 100, iData;
Uses uXmega_CDC;
Implementation
{$IDATA}
{------------------------------------------------------------------------------}
{ Type Declarations }
Type
{--------------------------------------------------------------}
{ Const Declarations }
Const
// this constant must be the same as in the Main app
DownLoaderID : word = $1234; // mandatory constant
cMonTage : Array [1..12] Of Byte = (31,28,31,30,31,30,31,31,30,31,30,31);
{--------------------------------------------------------------}
{ Var Declarations }
Var
Timer1 : SysTimer;
StopSysTic : Boolean;
PollLED [@PortR,1] : Bit; // Poll-LED
SysLED [@PortR,0] : Bit; // Poll-LED
ADIn : Word;
USBOk[@pinB,3] : Bit;
USBOffline : Boolean;
{$UDATA}
var
uTemp_15Min : Array [0..32767] Of Word;
{$IDATA}
{$NoSave} // standard register save is sufficient
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Interrupt TCD0_INTOVF;
begin
ASM: CALL System.$INTERRUPT_SYSTICK_USER;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure onTickTimer; // onTickTimer(SaveAllRegs);SaveAllRegs not necessary here
begin
ASM: CALL System.$INTERRUPT_SYSTICK_USER;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
{$NoSave} // standard register save is sufficient
(* for a UserDevice the following 3 function must be implemented *)
UserDevice UsrDevIni;
begin
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
UserDevice UsrDevInp (adr : word) : byte;
var
ERR,IC : Byte;
EEByte : Byte;
begin
EnableInts($87);
IC:=$50; // mandory for USB_ControlJob
If Adr>=32768 Then Inc(IC); EndIf;
If TWIOutE(IC,adr) Then
Err:=50;
Repeat
Dec(Err);
Until TWIInpE(IC,EEByte) Or (Err=0);
If Err=0 Then Return($ff); Else Return(EEByte); EndIf;
EndIf;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
UserDevice UsrDevOut (adr : word; outp : byte);
var
ERR,IC : Byte;
begin
EnableInts($87); // mandory for USB_ControlJob
IC:=$50; // mandory for USB_ControlJob
If Adr>=32768 Then Inc(IC); EndIf;
If TWIOutE(IC,adr,outp) Then
Err:=50;
Repeat
Dec(Err);
Until (TWIStatE(IC)) Or (Err=0);
EndIf;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure OnSysTick;
Begin
// Dec(I2CTiOut);
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure WriteUSB(xASCII:String[240]);
Begin
If CDCportValid Then
FlushBuffer(TxBufferCDC);
Write(SerOutCDC,xASCII);
uDelay(100);
EndIf;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure WriteLnUSB(xASCII:String[240]);
Begin
If CDCportValid Then
FlushBuffer(TxBufferCDC);
WriteLn(SerOutCDC,xASCII);
uDelay(100);
EndIf;
End;
{--------------------------------------------------------------}
{ Initialisieren der CPU }
{--------------------------------------------------------------}
Procedure InitPorts;
Begin
DDRR := DDRR Or %00000011; // Output=1 Input=0
DDRA := DDRA And %11111000; // Output=1 Input=0
PollLED:=True;
SysLED :=False;
End;
{--------------------------------------------------------------}
{ Init System und Ports }
{ Ports DDR = Output=1 Input=0 }
{--------------------------------------------------------------}
Procedure InitSystem;
Begin
InitPorts;
WatchDogStart;
End;
{==============================================================================}
{--------------------------------------------------------------------}
{--------------------------------------------------------------------}
Procedure RTCtickDate;
Begin
WriteLnUSB('RTCtickDate');
End;
{--------------------------------------------------------------------}
{--------------------------------------------------------------------}
Procedure RTCtickHour;
Begin
WriteLnUSB('RTCtickHour');
End;
{--------------------------------------------------------------------}
{--------------------------------------------------------------------}
Procedure RTCtickMinute;
Begin
WriteLnUSB('RTCtickMinute');
End;
{--------------------------------------------------------------------}
{--------------------------------------------------------------------}
Procedure RTCtickSecond;
begin
End;
{==============================================================================}
Procedure PollSystem;
Var
xFL : Float;
ASCII : String[40];
Begin
PollLED:=True;
ADIn:=GetAdcA(1);
xFL:=Float(ADIn);
ASCII:=FloatToStr(xFL);
WriteLnUSB(ASCII+' - '+IntToStr(ADIn));
PollLED:=False;
End;
(*------------------------------------------------------------------*)
(*------------------------------------------------------------------*)
Procedure I2CUST_SoftOn;
Const
PCF8574AP : Byte = $38;
Var
IOX,x,xUST,xKanal : Byte;
Bool : Boolean;
Begin
WatchDogTrig;
xUST:=0;
xKanal:=0;
WriteLnUSB('I2CUST_SoftOn');
Repeat
If I2CStat(PCF8574AP+xUST) Then
Bool:=I2COut(PCF8574AP+xUST,$FF);
Else
WriteLnUSB(ByteToStr(xUST)+' offline');
EndIf;
Inc(xUST);
Until xUST=8;
xUST:=0;
Repeat
IOX:=$FF;
If I2CStat(PCF8574AP+xUST) Then
For x:=0 to 3 Do
SetBit (IOX,x,False);
Bool:=I2COut(PCF8574AP+xUST,IOX);
mDelay(250);
EndFor;
Else
WriteLnUSB(ByteToStr(xUST)+' offline');
EndIf;
Inc(xUST);
Until xUST=8;
End;
Procedure TestTWI;
Var
x,y : Word;
Begin
WriteLnUSB(' Test TWI ');
x:=0;
Repeat
// uTemp_15Min[x]:=x;
Inc(x);
Until x>255;
WatchDogTrig;
x:=0;
Repeat
// y:=uTemp_15Min[x];
If y<>x Then
WatchDogTrig;
WriteLnUSB(' Fehler ');
EndIf;
Inc(x);
Until x>255;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitSystem;
SysLED:=True;
EnableInts($87); // mandory for USB_ControlJob
TickTimerTime(10000); // 10000usec = 10msec
TickTimerStart;
USBOffline:=True;
PollLED:=False;
SetSysTimer(Timer1,100);
StopSysTic:=False;
loop
If USBOk Then
SysLED:=False;
If USBOffline Then
CDCopenPort; // Open&Connect CDC Port
USBOffline:=False;
SysLED:=True;
EndIf;
Else
SysLED:=True;
System_Reset;
EndIf;
If IsSysTimerZero(Timer1) Then
SetSysTimer(Timer1,100);
WatchDogTrig;
I2CUST_SoftOn;
PollSystem;
// TestTWI;
EndIf;
endloop;
CDCclosePort;
end.
ich schicke die tage ein passendes Programm.
Gruß wom
Hallo,
anbei ein Demo. Der I2C-Soft scheint zu arbeiten, nicht so der TWI. Im demo ist der Test für TWI nicht aktiv, sonst hängt das Programm. Mittlerweile machen die xmega nicht so richtig Spaß. Einige Teile machen hier mehr Probleme wie die AtMega.
Code
program MINI3_X1T;
{$WG}
Device = xmega256A3BU;
{$BOOTRST $20000} {Reset Jump to $20000}
//{$BootApplication} // $20000
Define_Fuses
Override_Fuses;
NoteBook = D;
COMport = USB;
ProgMode = PDI;
LockBits0 = [BLBB0, BLBB1, LB0, LB1]; // protect boot and app against read back
FuseBits0 = [];
FuseBits1 = [];
FuseBits2 = [BootRst]; // mandatory !!
FuseBits5 = [BODACT0, BodLevel0, BodLevel1, BodLevel2];
Import SysTick,WatchDog, SerPortD0, SerPortE0, SerPortF0, SerPortC0;
Import UserPort,TWI_E , TickTimer, ADC_A, I2Cport;
Import SerPortCDC;
//From System Import Processes, Tasks;
From System Import Float,LongWord,Traps;
Define
// XMega USB must use the internal 32MHz OSC. So the system must use the 2MHz OSC
OSCtype = int2MHz,
PLLmul = 16, // bei int2MHz und PLLmul 10 = 20MHz
prescB = 1,
prescC = 1;
SysTick = 10, User; // msec
StackSize = $0128, iData;
FrameSize = $0128, iData;
WatchDog = msec2000; {2048msec}
USBmanufact = 'EcoTron'; // max 31 bytes
USBprodName = 'Serial CDC-USB'; // "
USBpid = $05FE;
USBvid = $BCDE;
USBprodRel = 203;
USBcurrent = 100;
SerPortCDC = TimeOut;
RxBufferCDC = 64, iData;
TxBufferCDC = 64, iData;
{----------------------------- init AD-Wandler -----------------------------}
ADCrefA = REF100;
ADCprescA = 128,12;
ADCchansA = [0..2];
I2Cport = PortC;
I2Cdat = 0;
I2Cclk = 1, 255;
TWIprescE = TWI_BR400;
UserPort = 65535;
{ RTC-CPU-Uhr intern }
TickTimer = Timer_C0; // use Timer_C0 and no PortPin
// RS485
SerPortC0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlC0 = PortD, 4, positive;
RxBufferC0 = 40, iData;
TxBufferC0 = 100, iData;
// RS485
SerPortD0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlD0 = PortD, 4, positive;
RxBufferD0 = 40, iData;
TxBufferD0 = 100, iData;
// RS485
SerPortE0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlE0 = PortE, 4, positive;
RxBufferE0 = 40, iData;
TxBufferE0 = 100, iData;
// RS485
SerPortF0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlF0 = PortF, 1, positive;
RxBufferF0 = 40, iData;
TxBufferF0 = 100, iData;
Uses uXmega_CDC;
Implementation
{$IDATA}
{------------------------------------------------------------------------------}
{ Type Declarations }
Type
{--------------------------------------------------------------}
{ Const Declarations }
Const
// this constant must be the same as in the Main app
DownLoaderID : word = $1234; // mandatory constant
cMonTage : Array [1..12] Of Byte = (31,28,31,30,31,30,31,31,30,31,30,31);
{--------------------------------------------------------------}
{ Var Declarations }
Var
Timer1 : SysTimer;
StopSysTic : Boolean;
PollLED [@PortR,1] : Bit; // Poll-LED
SysLED [@PortR,0] : Bit; // Poll-LED
ADIn : Word;
USBOk[@pinB,3] : Bit;
USBOffline : Boolean;
{$UDATA}
var
uTemp_15Min : Array [0..32767] Of Word;
{$IDATA}
{$NoSave} // standard register save is sufficient
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Interrupt TCD0_INTOVF;
begin
ASM: CALL System.$INTERRUPT_SYSTICK_USER;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure onTickTimer; // onTickTimer(SaveAllRegs);SaveAllRegs not necessary here
begin
ASM: CALL System.$INTERRUPT_SYSTICK_USER;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
{$NoSave} // standard register save is sufficient
(* for a UserDevice the following 3 function must be implemented *)
UserDevice UsrDevIni;
begin
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
UserDevice UsrDevInp (adr : word) : byte;
var
ERR,IC : Byte;
EEByte : Byte;
begin
EnableInts($87);
IC:=$50; // mandory for USB_ControlJob
If Adr>=32768 Then Inc(IC); EndIf;
If TWIOutE(IC,adr) Then
Err:=50;
Repeat
Dec(Err);
Until TWIInpE(IC,EEByte) Or (Err=0);
If Err=0 Then Return($ff); Else Return(EEByte); EndIf;
EndIf;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
UserDevice UsrDevOut (adr : word; outp : byte);
var
ERR,IC : Byte;
begin
EnableInts($87); // mandory for USB_ControlJob
IC:=$50; // mandory for USB_ControlJob
If Adr>=32768 Then Inc(IC); EndIf;
If TWIOutE(IC,adr,outp) Then
Err:=50;
Repeat
Dec(Err);
Until (TWIStatE(IC)) Or (Err=0);
EndIf;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure OnSysTick;
Begin
// Dec(I2CTiOut);
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure WriteUSB(xASCII:String[240]);
Begin
If CDCportValid Then
FlushBuffer(TxBufferCDC);
Write(SerOutCDC,xASCII);
uDelay(100);
EndIf;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure WriteLnUSB(xASCII:String[240]);
Begin
If CDCportValid Then
FlushBuffer(TxBufferCDC);
WriteLn(SerOutCDC,xASCII);
uDelay(100);
EndIf;
End;
{--------------------------------------------------------------}
{ Initialisieren der CPU }
{--------------------------------------------------------------}
Procedure InitPorts;
Begin
DDRR := DDRR Or %00000011; // Output=1 Input=0
DDRA := DDRA And %11111000; // Output=1 Input=0
PollLED:=True;
SysLED :=False;
End;
{--------------------------------------------------------------}
{ Init System und Ports }
{ Ports DDR = Output=1 Input=0 }
{--------------------------------------------------------------}
Procedure InitSystem;
Begin
InitPorts;
WatchDogStart;
End;
{==============================================================================}
{--------------------------------------------------------------------}
{--------------------------------------------------------------------}
Procedure RTCtickDate;
Begin
WriteLnUSB('RTCtickDate');
End;
{--------------------------------------------------------------------}
{--------------------------------------------------------------------}
Procedure RTCtickHour;
Begin
WriteLnUSB('RTCtickHour');
End;
{--------------------------------------------------------------------}
{--------------------------------------------------------------------}
Procedure RTCtickMinute;
Begin
WriteLnUSB('RTCtickMinute');
End;
{--------------------------------------------------------------------}
{--------------------------------------------------------------------}
Procedure RTCtickSecond;
begin
End;
{==============================================================================}
Procedure PollSystem;
Var
xFL : Float;
ASCII : String[40];
Begin
PollLED:=True;
ADIn:=GetAdcA(1);
xFL:=Float(ADIn);
ASCII:=FloatToStr(xFL);
WriteLnUSB(ASCII+' - '+IntToStr(ADIn));
PollLED:=False;
End;
(*------------------------------------------------------------------*)
(*------------------------------------------------------------------*)
Procedure I2CUST_SoftOn;
Const
PCF8574AP : Byte = $38;
Var
IOX,x,xUST,xKanal : Byte;
Bool : Boolean;
Begin
WatchDogTrig;
xUST:=0;
xKanal:=0;
WriteLnUSB('I2CUST_SoftOn');
Repeat
If I2CStat(PCF8574AP+xUST) Then
Bool:=I2COut(PCF8574AP+xUST,$FF);
Else
WriteLnUSB(ByteToStr(xUST)+' offline');
EndIf;
Inc(xUST);
Until xUST=8;
xUST:=0;
Repeat
IOX:=$FF;
If I2CStat(PCF8574AP+xUST) Then
For x:=0 to 3 Do
SetBit (IOX,x,False);
Bool:=I2COut(PCF8574AP+xUST,IOX);
mDelay(250);
EndFor;
Else
WriteLnUSB(ByteToStr(xUST)+' offline');
EndIf;
Inc(xUST);
Until xUST=8;
End;
Procedure TestTWI;
Var
x,y : Word;
Begin
WriteLnUSB(' Test TWI ');
x:=0;
Repeat
// uTemp_15Min[x]:=x;
Inc(x);
Until x>255;
WatchDogTrig;
x:=0;
Repeat
// y:=uTemp_15Min[x];
If y<>x Then
WatchDogTrig;
WriteLnUSB(' Fehler ');
EndIf;
Inc(x);
Until x>255;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitSystem;
SysLED:=True;
EnableInts($87); // mandory for USB_ControlJob
TickTimerTime(10000); // 10000usec = 10msec
TickTimerStart;
USBOffline:=True;
PollLED:=False;
SetSysTimer(Timer1,100);
StopSysTic:=False;
loop
If USBOk Then
SysLED:=False;
If USBOffline Then
CDCopenPort; // Open&Connect CDC Port
USBOffline:=False;
SysLED:=True;
EndIf;
Else
SysLED:=True;
System_Reset;
EndIf;
If IsSysTimerZero(Timer1) Then
SetSysTimer(Timer1,100);
WatchDogTrig;
I2CUST_SoftOn;
PollSystem;
// TestTWI;
EndIf;
endloop;
CDCclosePort;
end.