Initial commit
This commit is contained in:
368
Libs/NanoBlaze/hdl/nanoTest.pas
Normal file
368
Libs/NanoBlaze/hdl/nanoTest.pas
Normal file
@@ -0,0 +1,368 @@
|
||||
{
|
||||
beamer.pas
|
||||
|
||||
The beamer controller polls the UART to get commands and provides the
|
||||
corresponding replies.
|
||||
}
|
||||
|
||||
program BeamerControl;
|
||||
|
||||
{==============================================================================}
|
||||
{ Constants }
|
||||
{==============================================================================}
|
||||
const
|
||||
clockFrequency = 66E6;
|
||||
gpioBaseAddress = $0000;
|
||||
gpioDataOffset = $0000;
|
||||
gpioEnableOffset = $0001;
|
||||
uartBaseAddress = $0010;
|
||||
uartBaudOffset = $0002;
|
||||
uartStatusOffset = $0001;
|
||||
uartDataReady = $0001;
|
||||
uartSending = $0002;
|
||||
uartBaudRate = 1E6;
|
||||
uartBaudCount = clockFrequency / uartBaudRate;
|
||||
uartPollDelay = uartBaudCount / 2;
|
||||
uartTimeout = 10;
|
||||
commandHeader = $AA;
|
||||
commandNack = $00;
|
||||
commandWriteMem = $03;
|
||||
commandReadMem = $04;
|
||||
commandWriteLength = 4;
|
||||
commandReadLength = 2;
|
||||
beamerBaseAddress = $0020;
|
||||
beamerCtlOffset = $0000;
|
||||
beamerSpeedOffset = $0001;
|
||||
beamerCtlInit = $0401;
|
||||
beamerSpeedInit = $0004;
|
||||
commStIdle = $0000;
|
||||
commStGetPacketId = $0001;
|
||||
commStGetCommandId = $0002;
|
||||
commStGetDataLength = $0003;
|
||||
commStGetData = $0004;
|
||||
commStGetChecksum = $0005;
|
||||
commStExecuteCommand = $0006;
|
||||
commStSendHeader = $0007;
|
||||
commStSendPacketId = $0008;
|
||||
commStSendCommandId = $0009;
|
||||
commStSendDataLength = $000A;
|
||||
commStSendData = $000B;
|
||||
commStSendChecksum = $000C;
|
||||
|
||||
{==============================================================================}
|
||||
{ Variables }
|
||||
{==============================================================================}
|
||||
var
|
||||
communicationState : word;
|
||||
uartByte: uint8;
|
||||
|
||||
{==============================================================================}
|
||||
{ Procedures and functions }
|
||||
{==============================================================================}
|
||||
|
||||
{============================================================================}
|
||||
{ Register-level functions }
|
||||
{============================================================================}
|
||||
|
||||
{----------------------------------------------------------------------------}
|
||||
{ Registers initializations }
|
||||
{----------------------------------------------------------------------------}
|
||||
procedure initRegisters;
|
||||
const
|
||||
gpioValue = $AA;
|
||||
gpioEnablemask = $0F;
|
||||
begin
|
||||
{ initialize GPIO }
|
||||
mem[gpioBaseAddress+gpioDataOffset] := gpioValue;
|
||||
mem[gpioBaseAddress+gpioEnableOffset] := gpioEnablemask;
|
||||
{ initialize UART }
|
||||
mem[uartBaseAddress+uartBaudOffset] := uartBaudCount;
|
||||
{ initialize beamer peripheral }
|
||||
mem[beamerBaseAddress+beamerCtlOffset] := beamerCtlInit;
|
||||
mem[beamerBaseAddress+beamerSpeedOffset] := beamerSpeedInit;
|
||||
end;
|
||||
|
||||
{----------------------------------------------------------------------------}
|
||||
{ Get byte from serial port with timeout }
|
||||
{----------------------------------------------------------------------------}
|
||||
function getSerialPortByte(var uartByte: uint8) : word;
|
||||
var
|
||||
dataReady: uint8;
|
||||
pollCount: word;
|
||||
begin
|
||||
{ poll until data byte available or timeout occured}
|
||||
pollCount := uartPollDelay;
|
||||
dataReady := 0;
|
||||
while dataReady = 0 do
|
||||
begin
|
||||
{ read status register }
|
||||
dataReady := mem[uartBaseAddress+uartStatusOffset] and uartDataReady;
|
||||
{ spend time in order not to overcharge the AHB bus }
|
||||
if dataReady = 0 then
|
||||
begin
|
||||
{ check for timeout }
|
||||
pollCount := pollCount -1;
|
||||
if pollCount = 0 then
|
||||
dataReady := $FF;
|
||||
{ spend time in order not to overcharge the system bus }
|
||||
for index := 1 to uartPollDelay do
|
||||
noOperation;
|
||||
end;
|
||||
end;
|
||||
{ function return }
|
||||
if dataReady = $FF then
|
||||
{ return timeout }
|
||||
getSerialPortByte := 1;
|
||||
else
|
||||
{ read data register and return it }
|
||||
begin
|
||||
uartByte := mem[uartBaseAddress];
|
||||
getSerialPortByte := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
{----------------------------------------------------------------------------}
|
||||
{ Send byte to serial port with timeout }
|
||||
{----------------------------------------------------------------------------}
|
||||
function sendSerialPort(var uartByte : uint8) : word;
|
||||
var
|
||||
dataReady: uint8;
|
||||
statusByte: uint8;
|
||||
pollCount: word;
|
||||
begin
|
||||
{ poll until ready to send }
|
||||
pollCount := uartPollDelay;
|
||||
statusByte := mem[uartBaseAddress+uartStatusOffset] and uartSending;
|
||||
while statusByte = 0 do
|
||||
begin
|
||||
{ check for timeout }
|
||||
pollCount := pollCount -1;
|
||||
if pollCount = 0 then
|
||||
dataReady := $FF;
|
||||
{ spend time in order not to overcharge the system bus }
|
||||
for index := 1 to uartPollDelay do
|
||||
noOperation;
|
||||
{ read status register }
|
||||
statusByte := mem[uartBaseAddress+uartStatusOffset] and uartSending;
|
||||
end;
|
||||
{ function return }
|
||||
if dataReady = $FF then
|
||||
{ return timeout }
|
||||
sendSerialPort := 1;
|
||||
else
|
||||
{ write data register and return it }
|
||||
begin
|
||||
mem[uartBaseAddress] := uartByte;
|
||||
sendSerialPort := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
{============================================================================}
|
||||
{ Communication state machine }
|
||||
{============================================================================}
|
||||
procedure updateStateMachine(
|
||||
var communicationState : word;
|
||||
var uartByte: uint8
|
||||
);
|
||||
var
|
||||
communicationNextState : word;
|
||||
uartStatus: word;
|
||||
packetId, commandId : uint8;
|
||||
checksum : uint8;
|
||||
dataLength, dataCount, data1, data2, data3, data4 : uint8;
|
||||
memAddress, memData : word;
|
||||
begin
|
||||
{ idle }
|
||||
if communicationState = commStIdle then
|
||||
begin
|
||||
uartStatus := getSerialPortByte(var uartByte: uint8);
|
||||
if (uartStatus = 0) and (uartByte = commandHeader) then
|
||||
begin
|
||||
checksum := uartByte;
|
||||
communicationNextState := commStGetPacketId;
|
||||
end;
|
||||
end;
|
||||
{ get packet id }
|
||||
else if communicationState = commStGetPacketId then
|
||||
begin
|
||||
uartStatus := getSerialPortByte(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
packetId := uartByte;
|
||||
checksum := checksum + uartByte;
|
||||
communicationNextState := commStGetCommandId;
|
||||
end;
|
||||
end;
|
||||
{ get command id }
|
||||
else if communicationState = commStGetCommandId then
|
||||
begin
|
||||
uartStatus := getSerialPortByte(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
commandId := uartByte;
|
||||
checksum := checksum + uartByte;
|
||||
communicationNextState := commStGetDataLength;
|
||||
end;
|
||||
end;
|
||||
{ get data length }
|
||||
else if communicationState = commStGetDataLength then
|
||||
begin
|
||||
uartStatus := getSerialPortByte(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
dataLength := uartByte;
|
||||
checksum := checksum + uartByte;
|
||||
dataCount := dataLength;
|
||||
communicationNextState := commStGetData;
|
||||
end;
|
||||
end;
|
||||
{ get data }
|
||||
else if communicationState = commStGetData then
|
||||
begin
|
||||
uartStatus := getSerialPortByte(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
data1 := data2;
|
||||
data2 := data3;
|
||||
data3 := data4;
|
||||
data4 := uartByte;
|
||||
checksum := checksum + uartByte;
|
||||
dataCount := dataCount-1;
|
||||
if dataCount = 0 then
|
||||
communicationNextState := commStGetChecksum;
|
||||
end;
|
||||
end;
|
||||
{ get checksum }
|
||||
else if communicationState = commStGetChecksum then
|
||||
begin
|
||||
uartStatus := getSerialPortByte(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
if uartByte = checksum then
|
||||
communicationState := commStExecuteCommand;
|
||||
else
|
||||
begin
|
||||
commandId := commandNack;
|
||||
dataLength := 0;
|
||||
communicationNextState := commStSendHeader;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{ execute command }
|
||||
else if communicationState = commStExecuteCommand then
|
||||
begin
|
||||
if (commandId = commandWriteMem) and (dataLength = commandWriteLength) then
|
||||
begin
|
||||
memAddress := data1 + (data2 shl 8);
|
||||
memData := data3 + (data4 shl 8);
|
||||
mem[memAddress] := memData;
|
||||
dataLength := 0;
|
||||
communicationNextState := commStSendHeader;
|
||||
end;
|
||||
else if (commandId = commandReadMem) and (dataLength = commandReadLength) then
|
||||
begin
|
||||
memAddress := data3 + (data4 shl 8);
|
||||
memData := mem[memAddress];
|
||||
dataLength := 2;
|
||||
data1 := memData and $00FF;
|
||||
data2 := memData shr 8;
|
||||
communicationNextState := commStSendHeader;
|
||||
end;
|
||||
else
|
||||
begin
|
||||
commandId := commandNack;
|
||||
dataLength := 0;
|
||||
communicationNextState := commStSendHeader;
|
||||
end;
|
||||
end;
|
||||
{ send header }
|
||||
else if communicationState = commStSendHeader then
|
||||
begin
|
||||
uartByte := commandHeader;
|
||||
uartStatus := sendSerialPort(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
checksum := uartByte;
|
||||
communicationNextState := commStSendPacketId;
|
||||
end;
|
||||
end;
|
||||
{ send packet id }
|
||||
else if communicationState = commStSendPacketId then
|
||||
begin
|
||||
uartByte := packetId;
|
||||
uartStatus := sendSerialPort(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
checksum := checksum + uartByte;
|
||||
communicationNextState := commStSendCommandId;
|
||||
end;
|
||||
end;
|
||||
{ send command id }
|
||||
else if communicationState = commStSendCommandId then
|
||||
begin
|
||||
uartByte := commandId;
|
||||
uartStatus := sendSerialPort(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
checksum := checksum + uartByte;
|
||||
communicationNextState := commStSendDataLength;
|
||||
end;
|
||||
end;
|
||||
{ send data length }
|
||||
else if communicationState = commStSendDataLength then
|
||||
begin
|
||||
uartByte := dataLength;
|
||||
dataCount := dataLength;
|
||||
uartStatus := sendSerialPort(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
checksum := checksum + uartByte;
|
||||
communicationNextState := commStSendData;
|
||||
end;
|
||||
end;
|
||||
{ send data }
|
||||
else if communicationState = commStSendData then
|
||||
begin
|
||||
if dataCount > 0 then
|
||||
begin
|
||||
uartByte := data1;
|
||||
data2 := data1;
|
||||
data3 := data2;
|
||||
data4 := data3;
|
||||
uartStatus := sendSerialPort(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
begin
|
||||
checksum := checksum + uartByte;
|
||||
dataCount := dataCount-1;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
communicationNextState := commStSendChecksum;
|
||||
end;
|
||||
{ send checksum }
|
||||
else if communicationState = commStSendChecksum then
|
||||
begin
|
||||
uartByte := checksum and $00FF;
|
||||
uartStatus := sendSerialPort(var uartByte: uint8);
|
||||
if uartStatus = 0 then
|
||||
communicationNextState := commStIdle;
|
||||
end;
|
||||
{ update state }
|
||||
communicationState := communicationNextState;
|
||||
end;
|
||||
|
||||
{==============================================================================}
|
||||
{ Main program }
|
||||
{==============================================================================}
|
||||
begin
|
||||
{ initialize SoC registers }
|
||||
initRegisters;
|
||||
{ initialize communication state machine }
|
||||
communicationState := commStIdle;
|
||||
{ main loop }
|
||||
while true do begin
|
||||
{ update communication state machine }
|
||||
updateStateMachine(var communicationState : word; var uartByte : uint8);
|
||||
{ check for timeout }
|
||||
end;
|
||||
end.
|
||||
Reference in New Issue
Block a user