c++/rgb-assembler/rgb-assembler.cpp
author František Kučera <franta-hg@frantovo.cz>
Fri, 22 Dec 2017 16:21:10 +0100
changeset 13 2a4b8b3abe14
parent 12 1ecfa42ca0d2
child 14 2ab3d7282249
permissions -rw-r--r--
documentation + LED position
     1 #include <cstdlib>
     2 #include <iostream>
     3 #include <wchar.h>
     4 #include <locale.h>
     5 #include <cstring>
     6 
     7 #include <chrono>
     8 #include <thread>
     9 
    10 using namespace std;
    11 
    12 typedef uint16_t address_t;
    13 typedef uint8_t command_t;
    14 typedef uint8_t sleep_t;
    15 typedef uint8_t color_t;
    16 typedef uint8_t led_t;
    17 
    18 // TODO: strong typedefs http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/strong_typedef.html ?
    19 
    20 const address_t MEMORY_SIZE = 1024;
    21 
    22 /**
    23  * Skip to the given address.
    24  * parameter: address_t
    25  */
    26 const command_t CMD_GOTO = 0x70;
    27 
    28 /**
    29  * Wait given time in ms.
    30  * parameter: sleep_t
    31  */
    32 const command_t CMD_SLEEP = 0xFF;
    33 
    34 /**
    35  * Set RGB LED color.
    36  * parameter: led_t LED number
    37  * parameter: color_t red
    38  * parameter: color_t green
    39  * parameter: color_t blue
    40  */
    41 const command_t CMD_COLOR = 0xAA;
    42 
    43 /**
    44  * Stop program.
    45  */
    46 const command_t CMD_END = 0xED;
    47 
    48 /**
    49  * Placeholder for unsupported command.
    50  * Just for testing.
    51  */
    52 const command_t CMD_INVALID = 0x1;
    53 
    54 /**
    55  * Reads data on given position in memory and increments the index (position).
    56  */
    57 template<typename T> T read(command_t * memory, address_t &index) {
    58 	// TODO: for addresses: map higher memory to static hardcoded areas or peripherals
    59 	// TODO: sizeof (command_t) != 1 ?
    60 	T * value = reinterpret_cast<T*> (memory + index);
    61 	index += sizeof (*value) / sizeof (command_t);
    62 	return *value;
    63 }
    64 
    65 /**
    66  * Writes data to given position in memory and increments the index (position).
    67  */
    68 template<typename T> void write(command_t * memory, address_t &index, const T value) {
    69 	// TODO: sizeof (command_t) != 1 ?
    70 	// T * m = (T*) (memory + index);
    71 	T * m = reinterpret_cast<T*> (memory + index);
    72 	*m = value;
    73 	index += sizeof (value) / sizeof (command_t);
    74 }
    75 
    76 int main(int argc, char* argv[]) {
    77 
    78 	setlocale(LC_ALL, "");
    79 
    80 	command_t * memory = (command_t*) malloc(MEMORY_SIZE);
    81 
    82 	{
    83 		address_t a = 0;
    84 		write<command_t>(memory, a, CMD_SLEEP);
    85 		write<sleep_t>(memory, a, 255);
    86 		write<command_t>(memory, a, CMD_SLEEP);
    87 		write<sleep_t>(memory, a, 10);
    88 		write<command_t>(memory, a, CMD_SLEEP);
    89 		write<sleep_t>(memory, a, 255);
    90 		write<command_t>(memory, a, CMD_GOTO);
    91 		write<address_t>(memory, a, a + 4);
    92 		write<command_t>(memory, a, CMD_INVALID);
    93 		write<command_t>(memory, a, CMD_INVALID);
    94 		write<command_t>(memory, a, CMD_SLEEP);
    95 		write<sleep_t>(memory, a, 255);
    96 		write<command_t>(memory, a, CMD_COLOR);
    97 		write<led_t>(memory, a, 23);
    98 		write<color_t>(memory, a, 0);
    99 		write<color_t>(memory, a, 200);
   100 		write<color_t>(memory, a, 255);
   101 		write<command_t>(memory, a, CMD_END);
   102 	}
   103 
   104 	for (address_t i = 0; i < MEMORY_SIZE;) {
   105 		wprintf(L"command %*d = ", 4, i);
   106 		command_t ch = read<command_t>(memory, i);
   107 		wprintf(L"%02X  ", ch);
   108 
   109 		switch (ch) {
   110 			case CMD_GOTO:
   111 			{
   112 				i = read<address_t>(memory, i);
   113 				wprintf(L"GOTO %*d\n", 5, i);
   114 				break;
   115 			}
   116 			case CMD_SLEEP:
   117 			{
   118 				sleep_t delay = read<sleep_t>(memory, i);
   119 				wprintf(L"SLEEP %*d ms\n", 4, delay);
   120 				this_thread::sleep_for(chrono::milliseconds(delay));
   121 				break;
   122 			}
   123 			case CMD_COLOR:
   124 			{
   125 				led_t led = read<led_t>(memory, i);
   126 				color_t r = read<color_t>(memory, i);
   127 				color_t g = read<color_t>(memory, i);
   128 				color_t b = read<color_t>(memory, i);
   129 				wprintf(L"COLOR  %02X %02X %02X → %d\n", r, g, b, led);
   130 				break;
   131 			}
   132 			case CMD_END:
   133 			{
   134 				wprintf(L"END\n");
   135 				i = MEMORY_SIZE;
   136 				break;
   137 			}
   138 			default:
   139 			{
   140 				wprintf(L"invalid command\n");
   141 			}
   142 		}
   143 
   144 	}
   145 
   146 	free(memory);
   147 	memory = nullptr;
   148 	wprintf(L"all done\n");
   149 	return 0;
   150 }
   151