Initial commit
This commit is contained in:
		
							
								
								
									
										315
									
								
								06-07-08-09-SystemOnChip/SystemOnChip/hdl/beamer.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								06-07-08-09-SystemOnChip/SystemOnChip/hdl/beamer.pas
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,315 @@ | ||||
| { | ||||
|   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; | ||||
|     commandHeader       = $AA; | ||||
|     commandNack         = $00; | ||||
|     commandWriteMem     = $03; | ||||
|     commandReadMem      = $04; | ||||
|     commandWriteLength  = 4; | ||||
|     commandReadLength   = 2; | ||||
|     beamerBaseAddress   = $0020; | ||||
|     beamerCtlOffset       = $0000; | ||||
|     beamerSpeedOffset     = $0001; | ||||
|     beamerCtlInit         = $0401; | ||||
|     beamerSpeedInit       = $0004; | ||||
|  | ||||
| {==============================================================================} | ||||
| { Variables                                                                    } | ||||
| {==============================================================================} | ||||
|   var | ||||
|     packetId, commandId, errorId: uint8; | ||||
|     memoryAddress, memoryData: word; | ||||
|  | ||||
| {==============================================================================} | ||||
| { Procedures and functions                                                     } | ||||
| {==============================================================================} | ||||
|  | ||||
|   {============================================================================} | ||||
|   { Register-level accesses                                                    } | ||||
|   {============================================================================} | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Registers initializations                                                  } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   procedure initRegisters; | ||||
|   begin | ||||
|                                                              { initialize GPIO } | ||||
|     mem[gpioBaseAddress+gpioDataOffset] := $AA; | ||||
|     mem[gpioBaseAddress+gpioEnableOffset] := $0F; | ||||
|                                                              { initialize UART } | ||||
|     mem[uartBaseAddress+uartBaudOffset] := uartBaudCount; | ||||
|                                                 { initialize beamer peripheral } | ||||
|     mem[beamerBaseAddress+beamerCtlOffset] := beamerCtlInit; | ||||
|     mem[beamerBaseAddress+beamerSpeedOffset] := beamerSpeedInit; | ||||
|   end; | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Get byte from serial port                                                  } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   procedure getSerialPortByte : uint8; | ||||
|     var | ||||
|       uartByte: uint8; | ||||
|   begin | ||||
|                                               { poll until data byte available } | ||||
|     uartByte := 0; | ||||
|     while uartByte = 0 do | ||||
|       begin | ||||
|                            { spend time in order not to overcharge the AHB bus } | ||||
|         for index := 1 to uartpollDelay do | ||||
|           noOperation; | ||||
|                                                         { read status register } | ||||
|         uartByte := mem[uartBaseAddress+uartStatusOffset] and uartDataReady; | ||||
|       end; | ||||
|                                             { read data register and return it } | ||||
|     getSerialPortByte := mem[uartBaseAddress]; | ||||
|   end; | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Send byte to serial port                                                   } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   procedure sendSerialPort(uartByte : uint8); | ||||
|     var | ||||
|       statusByte: uint8; | ||||
|   begin | ||||
|                                                     { poll until ready to send } | ||||
|     statusByte := mem[uartBaseAddress+uartStatusOffset] and uartSending; | ||||
|     while statusByte = 0 do | ||||
|       begin | ||||
|                            { spend time in order not to overcharge the AHB bus } | ||||
|         for index := 1 to uartpollDelay do | ||||
|           noOperation; | ||||
|                                                         { read status register } | ||||
|         statusByte := mem[uartBaseAddress+uartStatusOffset] and uartSending; | ||||
|       end; | ||||
|                                                          { write data register } | ||||
|     mem[uartBaseAddress] := uartByte; | ||||
|   end; | ||||
|  | ||||
|   {============================================================================} | ||||
|   { Communication protocol                                                     } | ||||
|   {============================================================================} | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Get command                                                                } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   function getCommand( | ||||
|     var packetId, commandId, commandLength : uint8; | ||||
|     var memoryAddress, memoryData : word | ||||
|   ) : uint8; | ||||
|     var | ||||
|       uartData: uint8; | ||||
|       checksum: word; | ||||
|   begin | ||||
|                                                  { wait for new command header } | ||||
|     uartData := 0; | ||||
|     while uartData <> commandHeader do | ||||
|       uartData := getSerialPortByte; | ||||
|     checksum := uartData; | ||||
|                                                                { get packet id } | ||||
|     packetId := getSerialPortByte; | ||||
|     checksum := checksum + packetId; | ||||
|                                                                  { get command } | ||||
|     commandId := getSerialPortByte; | ||||
|     checksum := checksum + commandId; | ||||
|                                                       { process known commands } | ||||
|     if (commandId = commandWriteMem) or (commandId = commandReadMem) then | ||||
|       begin | ||||
|                                                           { get command length } | ||||
|         commandLength := getSerialPortByte; | ||||
|         checksum := checksum + commandLength; | ||||
|                                                        { check command lengths } | ||||
|         if (commandId = commandWriteMem) and (commandLength <> commandWriteLength) then | ||||
|           getCommand := 1; | ||||
|         else if (commandId = commandReadMem) and (commandLength <> commandReadLength) then | ||||
|           getCommand := 1; | ||||
|         else | ||||
|           begin | ||||
|                                                                  { get address } | ||||
|             memoryAddress := getSerialPortByte; | ||||
|             checksum := checksum + memoryAddress; | ||||
|             memoryAddress := (memoryAddress shl 8) + getSerialPortByte; | ||||
|             checksum := checksum + memoryAddress; | ||||
|                                                                     { get data } | ||||
|             if commandId = commandReadMem then | ||||
|               begin | ||||
|                 memoryData := getSerialPortByte; | ||||
|                 checksum := checksum + memoryData; | ||||
|                 memoryData := (memoryData shl 8) + getSerialPortByte; | ||||
|                 checksum := checksum + memoryData; | ||||
|               end; | ||||
|                                                       { get and verify checksum} | ||||
|             if getSerialPortByte = (checksum and $00FF) then | ||||
|               getCommand := 0; | ||||
|             else | ||||
|               getCommand := 1; | ||||
|           end; | ||||
|       end; | ||||
|     else | ||||
|       getCommand := 1; | ||||
|   end; | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Send NACK                                                                  } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   function sendNegativeAcknowledge(packetId : uint8); | ||||
|     var | ||||
|       uartData: uint8; | ||||
|       checksum: word; | ||||
|   begin | ||||
|                                                           { send packet header } | ||||
|     uartData := $AA; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := uartData; | ||||
|                                                               { send packet id } | ||||
|     uartData := packetId; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                              { send command id } | ||||
|     uartData := commandNack; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                           { send packet length } | ||||
|     uartData := 0; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                                { send checksum } | ||||
|     uartData := checksum and $00FF; | ||||
|     sendSerialPort(uartData); | ||||
|   end; | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Send ACK                                                                  } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   function sendAcknowledge(packetId, commandId : uint8); | ||||
|     var | ||||
|       uartData: uint8; | ||||
|       checksum: word; | ||||
|   begin | ||||
|                                                           { send packet header } | ||||
|     uartData := $AA; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := uartData; | ||||
|                                                               { send packet id } | ||||
|     uartData := packetId; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                              { send command id } | ||||
|     uartData := commandId; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                           { send packet length } | ||||
|     uartData := 0; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                                { send checksum } | ||||
|     uartData := checksum and $00FF; | ||||
|     sendSerialPort(uartData); | ||||
|   end; | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Send READ_MEM reply                                                                  } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   function sendReadAnswer(packetId : uint8; memoryData: word); | ||||
|     var | ||||
|       uartData: uint8; | ||||
|       checksum: word; | ||||
|   begin | ||||
|                                                           { send packet header } | ||||
|     uartData := $AA; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := uartData; | ||||
|                                                               { send packet id } | ||||
|     uartData := packetId; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                              { send command id } | ||||
|     uartData := commandReadMem; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                           { send packet length } | ||||
|     uartData := 2; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                                { send data low } | ||||
|     uartData := memoryData and $00FF; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                               { send data high } | ||||
|     uartData := memoryData shr 8; | ||||
|     sendSerialPort(uartData); | ||||
|     checksum := checksum + uartData; | ||||
|                                                                { send checksum } | ||||
|     uartData := checksum and $00FF; | ||||
|     sendSerialPort(uartData); | ||||
|   end; | ||||
|  | ||||
| {==============================================================================} | ||||
| { Main program                                                                 } | ||||
| {==============================================================================} | ||||
| begin | ||||
|                                                     { initialize SoC registers } | ||||
|   initRegisters; | ||||
|                                                                    { main loop } | ||||
|   while true do begin | ||||
|                                                            { get a new command } | ||||
|     errorId := getCommand(packetId, commandId, memoryAddress, memoryData); | ||||
|                                                              { process command } | ||||
|     if errorId = 0 then | ||||
|       begin | ||||
|                                                        { process write command } | ||||
|         if commandId = commandWriteMem then | ||||
|           begin | ||||
|             mem[memoryAddress] := memoryData; | ||||
|             sendAcknowledge(packetId, commandId); | ||||
|           end; | ||||
|                                                         { process read command } | ||||
|         else if commandId = commandReadMem then | ||||
|           begin | ||||
|             memoryData := mem[memoryAddress]; | ||||
|             sendReadAnswer(packetId, memoryData); | ||||
|           end; | ||||
|                                                     { reply to unknown command } | ||||
|         else | ||||
|           sendNegativeAcknowledge(packetId); | ||||
|       end; | ||||
|                                      { negative acknowledge on reception error } | ||||
|     else | ||||
|       sendNegativeAcknowledge(packetId); | ||||
|   end; | ||||
| end. | ||||
|  | ||||
| { | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; register definitions | ||||
|                 ;   s0, s1: used for INPUT and OUTPUT operations | ||||
|                 ;   S2: returns UART data byte | ||||
|                 ;   S3: uart protocol checksum | ||||
|                 ;   S4: uart protocol packet id | ||||
|                 ;   S5: uart protocol command id | ||||
|                 ;   S6: uart protocol address | ||||
|                 ;   S7: uart protocol data | ||||
|                 ;   S8: copy of UART data byte for debug | ||||
|                 ;--------------------------------------------------------------- | ||||
| } | ||||
		Reference in New Issue
	
	Block a user