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