translator: car echo

This commit is contained in:
e5l
2016-08-15 16:55:32 +03:00
parent cb2eb96b64
commit f817fdab69
14 changed files with 157 additions and 69 deletions
+2 -2
View File
@@ -48,7 +48,7 @@ $(CAR_FMW_BIN): $(CAR_FMW_ELF) $(BIN_DIR)
$(OBJ_COPY) -O binary $< $@
$(CAR_FMW_ELF): $(LIB_CAR_HW) $(LIB_KOT)
$(CC) $(CFLAGS) $^ -T stm32_flash.ld -o $@
$(CC) -Os $(CFLAGS) $^ -T stm32_flash.ld -o $@
$(LIB_CAR_HW):
cd $(CAR_HW_DIR) && make
@@ -83,7 +83,7 @@ flash: $(CAR_FMW_BIN)
debug:
-killall st-util
(setsid $(ST_DIR)/st-util 2>/dev/null 1>&2)&
$(GDB) $(CAR_FMW_ELF) -x $(ST_DIR)/../gdb.cmds
$(GDB) $(CAR_FMW_ELF) -tui -x $(ST_DIR)/../gdb.cmds
clean:
rm -rf bin/*
+11
View File
@@ -0,0 +1,11 @@
fun echoUsb() {
led_on()
clear_buffer()
while (true) {
val command = receive_int();
send_int(command)
}
}
+12
View File
@@ -1,8 +1,20 @@
external fun VCP_init()
external fun clear_buffer()
external fun send_int(i: Int)
external fun send_buffer(size: Int, pointer: Int)
external fun receive_int(): Int
external fun receive_buffer(size: Int, pointer: Int)
fun receiveByteArray(): ByteArray {
val result = ByteArray(receive_int())
receive_buffer(result.size, result.data)
return result
}
fun sendByteArray(arr: ByteArray) {
send_buffer(arr.size, arr.data)
}
+1
View File
@@ -4,4 +4,5 @@ fun init() {
engine_init()
leds_init()
VCP_init()
clear_buffer()
}
+22
View File
@@ -7,3 +7,25 @@ val LED_GREEN = 0
val LED_ORANGE = 1
val LED_RED = 2
val LED_BLUE = 3
val BLINK_DURATION: Int = 1000
fun led_on() {
led_set(LED_GREEN, true)
led_set(LED_BLUE, true)
led_set(LED_RED, true)
led_set(LED_ORANGE, true)
}
fun led_off() {
led_set(LED_GREEN, false)
led_set(LED_BLUE, false)
led_set(LED_RED, false)
led_set(LED_ORANGE, false)
}
fun blink() {
led_on()
wait(BLINK_DURATION)
led_off()
}
+12 -11
View File
@@ -1,16 +1,17 @@
//fun writeProto() {
// val msg = DirectionResponse.BuilderDirectionResponse(4242).build()
// val size = msg.getSizeNoTag()
// val buffer = ByteArray(size)
// val outputStream = CodedOutputStream(buffer)
//
// msg.writeTo(outputStream)
// sendByteArray(buffer)
// send_int(0xDDEEFF)
//}
fun writeProto() {
val msg = DirectionResponse.BuilderDirectionResponse(4242).build()
val size = msg.getSizeNoTag()
val buffer = ByteArray(size)
val outputStream = CodedOutputStream(buffer)
msg.writeTo(outputStream)
sendByteArray(buffer)
send_int(0xDDEEFF)
}
val PROGRAM_DURATION: Int = 1000
fun main() {
init()
simpleRoute()
echoUsb()
}
+12 -12
View File
@@ -150,22 +150,22 @@ class CodedInputStream(val buffer: ByteArray) {
// reads varint not larger than 32-bit integer according to protobuf varint-encoding
fun readInt32NoTag(): Int {
var done: Boolean = false
var result: Int = 0
var result: Long = 0
var step: Int = 0
while (!done) {
val byte: Int = inputStream.read().toInt()
result = result or
(
(byte and WireFormat.VARINT_INFO_BITS_MASK)
shl
(WireFormat.VARINT_INFO_BITS_COUNT * step)
)
(byte and WireFormat.VARINT_INFO_BITS_MASK).toLong()
shl
(WireFormat.VARINT_INFO_BITS_COUNT * step)
).toLong()
step++
if ((byte and WireFormat.VARINT_UTIL_BIT_MASK) == 0) {
done = true
}
}
return result
return result.toInt()
}
// reads varint not larger than 64-bit integer according to protobuf varint-encoding
@@ -177,10 +177,10 @@ class CodedInputStream(val buffer: ByteArray) {
val byte: Int = inputStream.read().toInt()
result = result or
(
(byte and WireFormat.VARINT_INFO_BITS_MASK).toLong()
shl
(WireFormat.VARINT_INFO_BITS_COUNT * step)
)
(byte and WireFormat.VARINT_INFO_BITS_MASK).toLong()
shl
(WireFormat.VARINT_INFO_BITS_COUNT * step)
)
step++
if ((byte and WireFormat.VARINT_UTIL_BIT_MASK) == 0 /* || byte == -1 ???? */) {
done = true
@@ -192,13 +192,13 @@ class CodedInputStream(val buffer: ByteArray) {
// reads zig-zag encoded integer not larger than 32-bit long
fun readZigZag32NoTag(): Int {
val value = readInt32NoTag()
return (value shr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number
return (value ushr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number
}
// reads zig-zag encoded integer not larger than 64-bit long
fun readZigZag64NoTag(): Long {
val value = readInt64NoTag()
return (value shr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number
return (value ushr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number
}
// checks if at least one more byte can be read from underlying input stream
+26 -12
View File
@@ -11,7 +11,7 @@ class CodedOutputStream(val buffer: ByteArray) {
fun writeTag(fieldNumber: Int, type: WireType) {
val tag = (fieldNumber shl 3) or type.id
writeInt32NoTag(tag)
writeRawVarint32(tag)
}
fun writeInt32(fieldNumber: Int, value: Int) {
@@ -19,15 +19,24 @@ class CodedOutputStream(val buffer: ByteArray) {
writeInt32NoTag(value)
}
fun writeInt32NoTag(value: Int) {
if (value < 0) { // sign-extend negative values
writeRawVarint64(value.toLong())
return
}
writeRawVarint32(value)
}
// Note that unsigned integer types are stored as their signed counterparts with top bit
// simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all
// methods, writing unsigned ints simply redirect call to corresponding signed-writing method
fun writeUInt32(fieldNumber: Int, value: Int) {
writeInt32(fieldNumber, value)
writeTag(fieldNumber, WireType.VARINT)
writeUInt32NoTag(value)
}
fun writeUInt32NoTag(value: Int) {
writeInt32NoTag(value)
writeRawVarint32(value)
}
fun writeInt64(fieldNumber: Int, value: Long) {
@@ -35,13 +44,18 @@ class CodedOutputStream(val buffer: ByteArray) {
writeInt64NoTag(value)
}
fun writeInt64NoTag(value: Long) {
writeRawVarint64(value)
}
// See notes on unsigned integers implementation above
fun writeUInt64(fieldNumber: Int, value: Long) {
writeInt64(fieldNumber, value)
writeTag(fieldNumber, WireType.VARINT)
writeUInt64NoTag(value)
}
fun writeUInt64NoTag(value: Long) {
writeInt64NoTag(value)
writeRawVarint64(value)
}
fun writeBool(fieldNumber: Int, value: Boolean) {
@@ -50,7 +64,7 @@ class CodedOutputStream(val buffer: ByteArray) {
}
fun writeBoolNoTag(value: Boolean) {
writeInt32NoTag(if (value) 1 else 0)
writeRawVarint32(if (value) 1 else 0)
}
// Writing enums is like writing one int32 number. Caller is responsible for converting enum-object to ordinal
@@ -60,7 +74,7 @@ class CodedOutputStream(val buffer: ByteArray) {
}
fun writeEnumNoTag(value: Int) {
writeInt32NoTag(value)
writeRawVarint32(value)
}
fun writeSInt32(fieldNumber: Int, value: Int) {
@@ -69,7 +83,7 @@ class CodedOutputStream(val buffer: ByteArray) {
}
fun writeSInt32NoTag(value: Int) {
writeInt32NoTag((value shl 1) xor (value shr 31))
writeUInt32NoTag((value shl 1) xor (value shr 31))
}
fun writeSInt64(fieldNumber: Int, value: Long) {
@@ -78,7 +92,7 @@ class CodedOutputStream(val buffer: ByteArray) {
}
fun writeSInt64NoTag(value: Long) {
writeInt64NoTag((value shl 1) xor (value shr 63))
writeUInt64NoTag((value shl 1) xor (value shr 63))
}
fun writeBytes(fieldNumber: Int, value: ByteArray) {
@@ -90,7 +104,7 @@ class CodedOutputStream(val buffer: ByteArray) {
}
fun writeBytesNoTag(value: ByteArray) {
writeInt32NoTag(value.size)
writeRawVarint32(value.size)
output.write(value)
}
@@ -99,7 +113,7 @@ class CodedOutputStream(val buffer: ByteArray) {
* Then she/he can re-use low-level methods for operating with raw values, that are not annotated with Protobuf tags.
*/
fun writeInt32NoTag(value: Int) {
fun writeRawVarint32(value: Int) {
var curValue: Int = value
// we have at most 32 information bits. With overhead of 1 bit per 7 bits we need at most 5 bytes for encoding
@@ -124,7 +138,7 @@ class CodedOutputStream(val buffer: ByteArray) {
output.write(res, 0, resSize)
}
fun writeInt64NoTag(value: Long) {
fun writeRawVarint64(value: Long) {
var curValue: Long = value
// we have at most 64 information bits. With overhead of 1 bit per 7 bits we need at most 10 bytes for encoding
+10 -7
View File
@@ -25,20 +25,20 @@ object WireFormat {
fun getVarint32Size(value: Int): Int {
var curValue = value
var size = 0
while (curValue != 0) {
do {
size += 1
curValue = curValue ushr VARINT_INFO_BITS_COUNT
}
} while (curValue != 0)
return size
}
fun getVarint64Size(value: Long): Int {
var curValue = value
var size = 0
while (curValue != 0L) {
do {
size += 1
curValue = curValue ushr VARINT_INFO_BITS_COUNT
}
}while (curValue != 0L)
return size
}
@@ -51,15 +51,18 @@ object WireFormat {
}
fun getInt32Size(fieldNumber: Int, value: Int): Int {
return getTagSize(fieldNumber, WireType.VARINT) + getVarint32Size(value)
return getTagSize(fieldNumber, WireType.VARINT) + getInt32SizeNoTag(value)
}
fun getInt32SizeNoTag(value: Int): Int {
if (value < 0) {
return getVarint64Size(value.toLong())
}
return getVarint32Size(value)
}
fun getUInt32Size(fieldNumber: Int, value: Int): Int {
return getInt32Size(fieldNumber, value)
return getTagSize(fieldNumber, WireType.VARINT) + getUInt32SizeNoTag(value)
}
fun getUInt32SizeNoTag(value: Int): Int {
@@ -67,7 +70,7 @@ object WireFormat {
}
fun getInt64Size(fieldNumber: Int, value: Long): Int {
return getTagSize(fieldNumber, WireType.VARINT) + getVarint64Size(value)
return getTagSize(fieldNumber, WireType.VARINT) + getUInt64SizeNoTag(value)
}
fun getInt64SizeNoTag(value: Long): Int {
+1 -15
View File
@@ -1,23 +1,9 @@
val PROGRAM_DURATION: Int = 3000
val BLINK_DURATION: Int = 500
fun blink() {
led_set(LED_GREEN, true)
led_set(LED_BLUE, true)
led_set(LED_RED, true)
led_set(LED_ORANGE, true)
wait(BLINK_DURATION)
led_set(LED_GREEN, false)
led_set(LED_BLUE, false)
led_set(LED_RED, false)
led_set(LED_ORANGE, false)
}
fun simpleRoute() {
while (true) {
wait(PROGRAM_DURATION)
blink()
writeProto()
// writeProto()
}
}
+28 -9
View File
@@ -4,37 +4,56 @@
#include <stdbool.h>
#include <usbd_cdc_vcp.h>
#include "memory.h"
void clear_buffer()
{
uint8_t tmp_char;
while (VCP_get_char(&tmp_char));
}
void send_int(int n)
{
int i = 0;
char* buffer = (char*) &n;
char *buffer = (char *) &n;
VCP_put_char(0xAA);
for (; i < sizeof(int); ++i) {
VCP_put_char(buffer[i]);
}
VCP_put_char(0xAA);
}
void send_buffer(int size, int pointer)
{
int i = 0;
char *buffer = (char *) pointer;
send_int(size);
VCP_put_char(0xAA);
char* buffer = (char*) pointer;
for (; i < size; ++i) {
VCP_put_char(buffer[i]);
}
VCP_put_char(0xAA);
}
int receive_int()
{
return 0;
int i = 0;
char buffer[sizeof(int)];
while (i < 4) {
while (!VCP_get_char(&buffer[i]));
i++;
}
return *((int*) buffer);
}
int receive_buffer()
void receive_buffer(int size, int pointer)
{
return 0;
char* buffer = (char*) pointer;
int i = 0;
for (; i < size; ++i) {
while(!VCP_get_char(&buffer[i]));
}
return buffer;
}
+7 -1
View File
@@ -1,7 +1,13 @@
#pragma once
void clear_buffer();
void send_int(int i);
void send_buffer(int size, int pointer);
int receive_int();
int receive_buffer();
void receive_buffer(int size, int pointer);
void set_state(int i);
int get_state();
+3
View File
@@ -0,0 +1,3 @@
#pragma once
extern char* malloc_static(int);
+10
View File
@@ -11,3 +11,13 @@
#include "stm32f4xx_conf.h"
#include "stm32f4xx_it.h"
int state = 0;
void set_state(int i) {
state = i;
}
int get_state() {
return state;
}