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