|
@@ -1,13 +1,13 @@
|
|
|
-(**
|
|
|
+(**
|
|
|
AUTHOR: Alexey Morozov, HighDim GmbH, 2013-2018
|
|
|
PURPOSE: ActiveCells AXI DMA component driver
|
|
|
*)
|
|
|
-module AcAxiDma;
|
|
|
+MODULE AcAxiDma;
|
|
|
|
|
|
-import
|
|
|
+IMPORT
|
|
|
Channels;
|
|
|
|
|
|
-const
|
|
|
+CONST
|
|
|
CmdSetAddr = 1*2;
|
|
|
CmdSetCount = 2*2;
|
|
|
CmdSetBurstLen = 3*2;
|
|
@@ -16,117 +16,123 @@ const
|
|
|
CmdGetCount = 6*2;
|
|
|
CmdGetPendingFlag = 7*2;
|
|
|
|
|
|
-type
|
|
|
-
|
|
|
- Address = longint;
|
|
|
-
|
|
|
- Controller* = record
|
|
|
- cfgCmd-: port out;
|
|
|
- cfgData-: port out;
|
|
|
- status-: port in;
|
|
|
-
|
|
|
- dataSize-: longint; (** size of one data element in bytes *)
|
|
|
- addr-: Address;
|
|
|
- count-: Address;
|
|
|
- maxBurstLen-: longint;
|
|
|
- burstLen-: longint;
|
|
|
- wrap-: boolean;
|
|
|
-
|
|
|
- transferPending: boolean;
|
|
|
- end;
|
|
|
-
|
|
|
- ReadController* = record(Controller)
|
|
|
- end;
|
|
|
-
|
|
|
- WriteController* = record(Controller)
|
|
|
- end;
|
|
|
-
|
|
|
- procedure InitController*(var ctl: Controller; cfgCmd, cfgData: port out; status: port in; dataSize, maxBurstLen: longint);
|
|
|
- begin
|
|
|
- ctl.cfgCmd := cfgCmd;
|
|
|
- ctl.cfgData := cfgData;
|
|
|
- ctl.status := status;
|
|
|
- ctl.dataSize := dataSize;
|
|
|
- ctl.maxBurstLen := maxBurstLen;
|
|
|
-
|
|
|
- Stop(ctl);
|
|
|
- SetCount(ctl,0);
|
|
|
- SetBurstLen(ctl,maxBurstLen);
|
|
|
- SetWrap(ctl,false);
|
|
|
- end InitController;
|
|
|
-
|
|
|
- procedure SetAddr*(var ctl: Controller; addr: Address);
|
|
|
- begin
|
|
|
- ctl.cfgCmd << CmdSetAddr;
|
|
|
- ctl.cfgData << addr;
|
|
|
- ctl.addr := addr;
|
|
|
- end SetAddr;
|
|
|
-
|
|
|
- procedure SetCount*(var ctl: Controller; count: Address);
|
|
|
- begin
|
|
|
- ctl.cfgCmd << CmdSetCount;
|
|
|
- ctl.cfgData << count;
|
|
|
- ctl.count := count;
|
|
|
- end SetCount;
|
|
|
-
|
|
|
- procedure SetBurstLen*(var ctl: Controller; burstLen: longint);
|
|
|
- var d: longint;
|
|
|
- begin
|
|
|
- d := (burstLen-1) + lsh(burstLen*ctl.dataSize,4);
|
|
|
- ctl.cfgCmd << CmdSetBurstLen;
|
|
|
- ctl.cfgData << d;
|
|
|
- ctl.burstLen := burstLen;
|
|
|
- end SetBurstLen;
|
|
|
-
|
|
|
- procedure SetWrap*(var ctl: Controller; wrap: boolean);
|
|
|
- begin
|
|
|
- ctl.cfgCmd << CmdSetWrapFlag;
|
|
|
- if wrap then ctl.cfgData << 1; else ctl.cfgData << 0; end;
|
|
|
- ctl.wrap := wrap;
|
|
|
- end SetWrap;
|
|
|
-
|
|
|
- procedure Start*(var ctl: Controller);
|
|
|
- begin
|
|
|
- ctl.cfgCmd << 1;
|
|
|
- ctl.cfgData << 0;
|
|
|
- ctl.transferPending := true;
|
|
|
- end Start;
|
|
|
-
|
|
|
- procedure Stop*(var ctl: Controller);
|
|
|
- begin
|
|
|
- ctl.cfgCmd << 0;
|
|
|
- ctl.cfgData << 0;
|
|
|
- ctl.transferPending := false;
|
|
|
- end Stop;
|
|
|
-
|
|
|
- procedure GetCurrentAddr*(var ctl: Controller): Address;
|
|
|
- var addr: Address;
|
|
|
- begin
|
|
|
- ctl.cfgCmd << CmdGetAddr;
|
|
|
- ctl.cfgData << 0;
|
|
|
- addr << ctl.status;
|
|
|
- return addr;
|
|
|
- end GetCurrentAddr;
|
|
|
-
|
|
|
- procedure GetCurrentCount*(var ctl: Controller): Address;
|
|
|
- var count: Address;
|
|
|
- begin
|
|
|
- ctl.cfgCmd << CmdGetCount;
|
|
|
- ctl.cfgData << 0;
|
|
|
- count << ctl.status;
|
|
|
- return count;
|
|
|
- end GetCurrentCount;
|
|
|
-
|
|
|
- procedure TransferPending*(var ctl: Controller): boolean;
|
|
|
- var d: longint;
|
|
|
- begin
|
|
|
- if ctl.transferPending then
|
|
|
- ctl.cfgCmd << CmdGetPendingFlag;
|
|
|
- ctl.cfgData << 0;
|
|
|
- d << ctl.status;
|
|
|
- ctl.transferPending := d mod 2 = 1;
|
|
|
- end;
|
|
|
- return ctl.transferPending;
|
|
|
- end TransferPending;
|
|
|
-
|
|
|
-end AcAxiDma.
|
|
|
+TYPE
|
|
|
+
|
|
|
+ Address* = LONGINT;
|
|
|
+ Size* = LONGINT;
|
|
|
+
|
|
|
+ (**
|
|
|
+ ActiveCells AXI DMA component controller
|
|
|
+ *)
|
|
|
+ Controller* = OBJECT
|
|
|
+ VAR
|
|
|
+ cfgCmd: PORT OUT;
|
|
|
+ cfgData: PORT OUT;
|
|
|
+ status: PORT IN;
|
|
|
+
|
|
|
+ dataSize-: WORD; (** size of one data element in bytes *)
|
|
|
+ addr-: Address; (** DMA transfer starting address *)
|
|
|
+ count-: Size; (** DMA transfer size in number of elements *)
|
|
|
+ maxBurstLen-: WORD; (** maximal burst length in number of elements *)
|
|
|
+ burstLen-: WORD; (** current burst length in number of elements *)
|
|
|
+ wrap-: BOOLEAN; (** TRUE in case of a recurrent transfer *)
|
|
|
+
|
|
|
+ PROCEDURE &InitController*(cfgCmdOut, cfgDataOut: PORT OUT; statusInp: PORT IN; dataSize, maxBurstLen: WORD);
|
|
|
+ BEGIN
|
|
|
+ ASSERT(dataSize > 0);
|
|
|
+ ASSERT(maxBurstLen > 0);
|
|
|
+
|
|
|
+ cfgCmd := cfgCmdOut;
|
|
|
+ cfgData := cfgDataOut;
|
|
|
+ status := statusInp;
|
|
|
+ SELF.dataSize := dataSize;
|
|
|
+ SELF.maxBurstLen := maxBurstLen;
|
|
|
+
|
|
|
+ Stop;
|
|
|
+ SetCount(0);
|
|
|
+ SetBurstLen(maxBurstLen);
|
|
|
+ SetWrap(FALSE);
|
|
|
+ END InitController;
|
|
|
+
|
|
|
+ PROCEDURE SetAddr*(startAddr: Address);
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ cfgCmd << CmdSetAddr;
|
|
|
+ cfgData << startAddr;
|
|
|
+ addr := startAddr;
|
|
|
+ END SetAddr;
|
|
|
+
|
|
|
+ PROCEDURE SetCount*(transferCount: Size);
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ cfgCmd << CmdSetCount;
|
|
|
+ cfgData << transferCount;
|
|
|
+ count := transferCount;
|
|
|
+ END SetCount;
|
|
|
+
|
|
|
+ PROCEDURE SetBurstLen*(len: WORD);
|
|
|
+ VAR d: LONGINT;
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ d := (burstLen-1) + LSH(LONGINT(burstLen)*dataSize,4);
|
|
|
+ cfgCmd << CmdSetBurstLen;
|
|
|
+ cfgData << d;
|
|
|
+ burstLen := len;
|
|
|
+ END SetBurstLen;
|
|
|
+
|
|
|
+ PROCEDURE SetWrap*(enableWrap: BOOLEAN);
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ cfgCmd << CmdSetWrapFlag;
|
|
|
+ IF enableWrap THEN cfgData << 1; ELSE cfgData << 0; END;
|
|
|
+ wrap := enableWrap;
|
|
|
+ END SetWrap;
|
|
|
+
|
|
|
+ PROCEDURE Start*();
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ IF SELF IS WriteController THEN
|
|
|
+ cfgCmd << 0;
|
|
|
+ ELSE
|
|
|
+ cfgCmd << 1;
|
|
|
+ END;
|
|
|
+ cfgData << 1;
|
|
|
+ END Start;
|
|
|
+
|
|
|
+ PROCEDURE Stop*();
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ cfgCmd << 0;
|
|
|
+ cfgData << 0;
|
|
|
+ END Stop;
|
|
|
+
|
|
|
+ PROCEDURE GetCurrentAddr*(): Address;
|
|
|
+ VAR addr: Address;
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ cfgCmd << CmdGetAddr;
|
|
|
+ cfgData << 0;
|
|
|
+ addr << status;
|
|
|
+ RETURN addr;
|
|
|
+ END GetCurrentAddr;
|
|
|
+
|
|
|
+ PROCEDURE GetCurrentCount*(): Address;
|
|
|
+ VAR count: Address;
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ cfgCmd << CmdGetCount;
|
|
|
+ cfgData << 0;
|
|
|
+ count << status;
|
|
|
+ RETURN count;
|
|
|
+ END GetCurrentCount;
|
|
|
+
|
|
|
+ PROCEDURE IsTransferPending*(): BOOLEAN;
|
|
|
+ VAR d: LONGINT;
|
|
|
+ BEGIN{EXCLUSIVE}
|
|
|
+ cfgCmd << CmdGetPendingFlag;
|
|
|
+ cfgData << 0;
|
|
|
+ d << status;
|
|
|
+ RETURN (d MOD 2) = 1;
|
|
|
+ END IsTransferPending;
|
|
|
+
|
|
|
+ END Controller;
|
|
|
+
|
|
|
+ ReadController* = OBJECT(Controller)
|
|
|
+ END ReadController;
|
|
|
+
|
|
|
+ WriteController* = OBJECT(Controller)
|
|
|
+ END WriteController;
|
|
|
+
|
|
|
+END AcAxiDma.
|