translator: car echo
This commit is contained in:
+2
-2
@@ -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/*
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
fun echoUsb() {
|
||||
led_on()
|
||||
|
||||
clear_buffer()
|
||||
while (true) {
|
||||
val command = receive_int();
|
||||
send_int(command)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -4,4 +4,5 @@ fun init() {
|
||||
engine_init()
|
||||
leds_init()
|
||||
VCP_init()
|
||||
clear_buffer()
|
||||
}
|
||||
|
||||
@@ -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
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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()
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
extern char* malloc_static(int);
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user