diff --git a/ports/bare-rpi/Makefile b/ports/bare-rpi/Makefile new file mode 100644 index 00000000000..9782d4bd0e9 --- /dev/null +++ b/ports/bare-rpi/Makefile @@ -0,0 +1,57 @@ +include ../../py/mkenv.mk + +# qstr definitions (must come before including py.mk) +QSTR_DEFS = qstrdefsport.h + +# include py core make definitions +include $(TOP)/py/py.mk + +CROSS_COMPILE = arm-none-eabi- + +OBJCPY=$(CROSS_COMPILE)objcopy +INC += -I. +INC += -I$(TOP) +INC += -I$(BUILD) + +CFLAGS = $(INC) -Wall -std=c99 -nostdlib -marm -mcpu=arm1176jzf-s $(COPT) + +#Debugging/Optimization +ifeq ($(DEBUG), 1) +CFLAGS += -O0 -ggdb +else +CFLAGS += -Os -DNDEBUG +endif + +CCVERSION:=$(shell $(CC) --version | sed 's/[ ]/\n/g' | grep "\." | xargs | awk '{ print $$1 }') +ARMGCCLIBPATH=/usr/lib/gcc/arm-none-eabi/$(CCVERSION) + +LDFLAGS = -nostdlib -T kernel.ld -Map=$@.map --cref +LIBS = -L$(ARMGCCLIBPATH) -lgcc + +SRC_LIB = $(addprefix lib/,\ + libc/string0.c ) + +SRC_C = \ + main.c \ + uart.c \ + gpio.c \ + +SRC_S = \ + start.s + +OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(SRC_LIB:.c=.o)) + +all: $(BUILD)/firmware.img + +list: $(BUILD)/firmware.elf + $(CROSS_COMPILE)objdump -d $(BUILD)/firmware.elf > $(BUILD)/firmware.list + +$(BUILD)/firmware.elf: $(OBJ) + $(ECHO) "LINK $@" + $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS) + $(Q)$(SIZE) $@ + +$(BUILD)/firmware.img: $(BUILD)/firmware.elf + $(OBJCPY) $(BUILD)/firmware.elf -O binary $(BUILD)/firmware.img + +include $(TOP)/py/mkrules.mk diff --git a/ports/bare-rpi/gpio.c b/ports/bare-rpi/gpio.c new file mode 100644 index 00000000000..b3171ec48c9 --- /dev/null +++ b/ports/bare-rpi/gpio.c @@ -0,0 +1,120 @@ +#include "gpio.h" + +volatile pios_gpio_t* const pios_gpio = (volatile pios_gpio_t* const) (PIOS_IO_BASE + PIOS_GPIO_BASE); + +void __attribute__((optimize("O0"))) wait ( int sec ) { + while ( sec > 0 ) { + int counter = 0x400000; + while ( counter > 0 ) + counter--; + sec--; + } +} + +void __attribute__((optimize("O1"))) pios_wasteCycles ( uint32_t cycles ) { + cycles++; + while ( cycles > 0 ) { + cycles--; + } +} + +void pios_gpio_pullBulk ( uint32_t p[2], uint32_t pull ) { + if ( pull == PIOS_GPIO_PULL_UP || + pull == PIOS_GPIO_PULL_DOWN || + pull == PIOS_GPIO_PULL_OFF) { + pios_gpio->pullControlEnable = pull; + pios_wasteCycles ( 150 ); + + pios_gpio->pullControlClock[0] = p[0]; + pios_gpio->pullControlClock[1] = p[1]; + pios_wasteCycles ( 150 ); + + //pios_gpio->pullControlEnable = PIOS_GPIO_PULL_OFF; + pios_gpio->pullControlClock[0] = 0; + pios_gpio->pullControlClock[1] = 0; + } + else { + pios_gpio->pullControlEnable = PIOS_GPIO_PULL_OFF; + } +} + +void pios_gpio_pullControl ( uint32_t pin, uint32_t pull ) { + if ( pin > 53 ) + return; + + uint32_t p[2]={0}; + uint32_t i = 0; + if ( pin > 31 ) { + i++; + pin-=32; + } + + p[i] = (1 << pin); + + pios_gpio_pullBulk ( p, pull ); +} + +uint32_t pios_gpio_read ( uint32_t pin ) { + if ( pin > 53 ) + return PIOS_GPIO_LOW; + + volatile uint32_t* base = &pios_gpio->level[0]; + if ( pin > 31 ) { + base++; + pin -= 32; + } + + uint32_t val = *base; + return ( ((val & (1< 53 ) + return; + + volatile uint32_t* base = &pios_gpio->outputset[0]; + if ( val == PIOS_GPIO_LOW ) { + base = &pios_gpio->outputclear[0]; + } + + if ( pin > 31 ) { + base++; + pin -= 32; + } + (*base) = 1 << pin; +} + +void pios_gpio_pinmode ( uint32_t pin, uint32_t val ) { + if ( val > 7 ) + return; + + if ( pin > 53 ) + return; + + volatile uint32_t *base = &pios_gpio->fn_select[0]; + while ( pin >= 10 ) { + base++; + pin-=10; + } + + uint32_t v = *base; + v &= ~(7 << ((pin<<1) + pin)); /// move the 7 pin*3 times, so it masks the correct bits + v |= (val << ((pin<<1) + pin)); + *base = v; +} + +int pios_gpio_getPinmode ( uint32_t pin ) { + if ( pin > 53 ) + return -1; + + volatile uint32_t *base = &pios_gpio->fn_select[0]; + while ( pin >= 10 ) { + base++; + pin-=10; + } + + uint32_t v = *base; + v = v >> ((pin<<1)+pin) ; + v &= 7; /// move the 7 pin*3 times, so it masks the correct bits + return v; +} diff --git a/ports/bare-rpi/gpio.h b/ports/bare-rpi/gpio.h new file mode 100644 index 00000000000..e6eb17b7c91 --- /dev/null +++ b/ports/bare-rpi/gpio.h @@ -0,0 +1,124 @@ +/** + * \file gpio.h + * \author Stefan Naumann + * \date 26th May 2017 + * \brief interfaces for using the GPIO-connectors on the Raspberry Pi; + * memory map of the registers and some functions for using the basic-features + * of the GPIO-pins + **/ + +#ifndef PIOS_GPIO +#define PIOS_GPIO + +#include + +#define PIOS_IO_BASE 0x20000000 + +/// the base offset address of the GPIO-registers in memory +#define PIOS_GPIO_BASE 0x200000 + +/// constant for the low-signal level of a pin +#define PIOS_GPIO_LOW 0 +/// constant for the high-signal level of a pin +#define PIOS_GPIO_HIGH 1 + +/// the mode INPUT as constant +#define PIOS_GPIO_INPUT 0 +/// the mode OUTPUT as constant +#define PIOS_GPIO_OUTPUT 1 +/// alternative function 0 +#define PIOS_GPIO_ALT0 4 +/// alternative function 1 +#define PIOS_GPIO_ALT1 5 +/// alternative function 2 +#define PIOS_GPIO_ALT2 6 +/// alternative function 3 +#define PIOS_GPIO_ALT3 7 +/// alternative function 4 +#define PIOS_GPIO_ALT4 3 +/// alternative function 5 +#define PIOS_GPIO_ALT5 2 + +/// pull the level up +#define PIOS_GPIO_PULL_UP 2 +/// pull the level down +#define PIOS_GPIO_PULL_DOWN 1 +/// turn the pulling off +#define PIOS_GPIO_PULL_OFF 0 + +/** + * \brief a mapping of the memory-registers of the GPIO-controller + **/ +struct _pios_gpio_t { + uint32_t fn_select[6]; ///< function select registers for the Pins + uint32_t pad1; + uint32_t outputset[2]; ///< registers for setting the levels HIGH + uint32_t pad2; + uint32_t outputclear[2]; ///< registers for setting the levels LOW + uint32_t pad3; + uint32_t level[2]; ///< the levels of the pins for reading + uint32_t pad4; + uint32_t eventDetect[2]; ///< indicates whether an event has occured (whathever is enabled) + uint32_t pad5; + uint32_t risingEdgeDetect[2]; ///< en/disable rising edge for the eventDetect-field + uint32_t pad6; + uint32_t fallingEdgeDetect[2]; ///< en/disable falling edge for the eventDetect + uint32_t pad7; + uint32_t highDetect[2]; ///< en/disable HIGH as event for eventDetect + uint32_t pad8; + uint32_t lowDetect[2]; ///< en/disable LOW as event for eventDetect + uint32_t pad9; + uint32_t asyncRisingEdgeDetect[2]; ///< en/disable rising edge as asynchronous event for eventDetect (i.e. not bound to system clock) + uint32_t pad10; + uint32_t asyncFallingEdgeDetect[2]; ///< en/disable falling edge as asynchronous event for eventDetect (i.e. not bound to system clock) + uint32_t pad11; + uint32_t pullControlEnable; ///< set the pull-mode (i.e. UP, DOWN or OFF) + uint32_t pullControlClock[2]; ///< set pins for pulling (see the manual for the exact algorithm) +} typedef pios_gpio_t; + +/// struct mapping the GPIO-controller-registers +extern volatile pios_gpio_t* const pios_gpio; + +void __attribute__((optimize("O0"))) wait ( int sec ); + +/** + * \brief pull up or down a set of pins + * \param p an array which represents the GPIO-pins and their on-values for pulling + * \param pull the direction for the voltage-pull + * \note this is a lower-level implementation of the pios_gpio_pudControl-function, use that if unsure + **/ +void pios_gpio_pullBulk ( uint32_t p[2], uint32_t pull ); +/** + * \brief pull up or down a specific pin + * \param pin GPIO-Pin + * \param pull the direction for the voltage-pull + **/ +void pios_gpio_pullControl ( uint32_t pin, uint32_t pull ); +/** + * \brief reads the value of the GPIO-pin (set as input) + * \param pin the GPIO pin you want the state of (in [0, 53]) + * \return the state of the GPIO-Pin (i.e. HIGH or LOW-signal level), + * always returns LOW if the input is invalid + **/ +uint32_t pios_gpio_read ( uint32_t pin ); +/** + * \brief writes a value to the GPIO-Pin (i.e. writes 1 to set or 1 to clear) + * \param pin GPIO-Pin + * \param val output-value (1 for on, 0 for off) + **/ +void pios_gpio_write ( uint32_t pin, uint32_t val ); +/** + * \brief sets the PIN into the mode we want + * \param pin GPIO-Pin + * \param val GPIO-Mode + * \return NONE + **/ +void pios_gpio_pinmode ( uint32_t pin, uint32_t val ); +/** + * \brief read the mode of the pin and return it + * \param pin the pin to be read + * \return the current mode of the pin + **/ +int pios_gpio_getPinmode ( uint32_t pin ); + +#endif diff --git a/ports/bare-rpi/kernel.ld b/ports/bare-rpi/kernel.ld new file mode 100644 index 00000000000..c18a498ddc4 --- /dev/null +++ b/ports/bare-rpi/kernel.ld @@ -0,0 +1,14 @@ +SECTIONS { + . = 0x8000; + .init . : { *(.init) } + .text : { *(.text) } + .data : { *(.data) } + .bss : { *(.bss COMMON) } + . = ALIGN(8); + . = . + 0x1000; + heap_start = .; + . = . + 0x800000; + heap_end = .; + . = . + 0x800000; + stack_top = .; +} diff --git a/ports/bare-rpi/main.c b/ports/bare-rpi/main.c new file mode 100644 index 00000000000..ae290e763ec --- /dev/null +++ b/ports/bare-rpi/main.c @@ -0,0 +1,79 @@ +#include +#include +#include + +#include "py/compile.h" +#include "py/runtime.h" +#include "py/repl.h" +#include "py/mperrno.h" +#include "py/gc.h" + +#include "uart.h" +#include "gpio.h" + +extern char heap_end, heap_start; + +void do_str(const char *src, mp_parse_input_kind_t input_kind) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); + qstr source_name = lex->source_name; + mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); + mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true); + mp_call_function_0(module_fun); + nlr_pop(); + } else { + // uncaught exception + mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); + } +} + +int main(int argc, char **argv) { + pios_uart_init(); + pios_uart_puts ("Hello World!\n\r"); + + gc_init ( &heap_start, &heap_end ); + + mp_init(); + do_str("print('Hello World')", MP_PARSE_FILE_INPUT); + do_str("i = 0\nwhile ( i < 10 ) :\n print ( i );\n i=i+1\n", MP_PARSE_FILE_INPUT); + + mp_deinit(); + return 0; +} + +void gc_collect(void) { +} + +void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) { + pios_uart_write ( str, len ); +} + + +mp_lexer_t *mp_lexer_new_from_file(const char *filename) { + mp_raise_OSError(MP_ENOENT); +} + +mp_import_stat_t mp_import_stat(const char *path) { + return MP_IMPORT_STAT_NO_EXIST; +} + +mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); + +void nlr_jump_fail(void *val) { + while (1); +} + +void NORETURN __fatal_error(const char *msg) { + while (1); +} + +#ifndef NDEBUG +void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) { + printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line); + __fatal_error("Assertion failed"); +} +#endif diff --git a/ports/bare-rpi/mpconfigport.h b/ports/bare-rpi/mpconfigport.h new file mode 100644 index 00000000000..515594834be --- /dev/null +++ b/ports/bare-rpi/mpconfigport.h @@ -0,0 +1,74 @@ +#include + +#include "uart.h" + +// options to control how MicroPython is built +#define MICROPY_DEBUG_VERBOSE (0) +#define MICROPY_QSTR_BYTES_IN_HASH (1) +#define MICROPY_ALLOC_PATH_MAX (512) +#define MICROPY_EMIT_X64 (0) +#define MICROPY_EMIT_THUMB (0) +#define MICROPY_EMIT_INLINE_THUMB (0) +#define MICROPY_COMP_MODULE_CONST (0) +#define MICROPY_COMP_CONST (0) +#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0) +#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0) +#define MICROPY_MEM_STATS (0) +#define MICROPY_DEBUG_PRINTERS (1) +#define MICROPY_ENABLE_GC (1) +#define MICROPY_HELPER_REPL (0) +#define MICROPY_HELPER_LEXER_UNIX (0) +#define MICROPY_ENABLE_SOURCE_LINE (1) +#define MICROPY_ENABLE_DOC_STRING (1) +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) +#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) +#define MICROPY_PY_ASYNC_AWAIT (0) +#define MICROPY_PY_BUILTINS_BYTEARRAY (0) +#define MICROPY_PY_BUILTINS_MEMORYVIEW (0) +#define MICROPY_PY_BUILTINS_ENUMERATE (0) +#define MICROPY_PY_BUILTINS_FROZENSET (0) +#define MICROPY_PY_BUILTINS_REVERSED (0) +#define MICROPY_PY_BUILTINS_SET (0) +#define MICROPY_PY_BUILTINS_SLICE (0) +#define MICROPY_PY_BUILTINS_PROPERTY (0) +#define MICROPY_PY___FILE__ (0) +#define MICROPY_PY_GC (0) +#define MICROPY_PY_ARRAY (0) +#define MICROPY_PY_ATTRTUPLE (0) +#define MICROPY_PY_COLLECTIONS (0) +#define MICROPY_PY_MATH (0) +#define MICROPY_PY_CMATH (0) +#define MICROPY_PY_IO (0) +#define MICROPY_PY_STRUCT (0) +#define MICROPY_PY_SYS (0) +#define MICROPY_CPYTHON_COMPAT (0) +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) +#define MICROPY_USE_INTERNAL_PRINTF (1) + +// type definitions for the specific machine + +#define malloc(n) m_malloc(n) +#define free(p) m_free(p) +#define realloc(p, n) m_realloc(p, n) + +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1)) + +#define UINT_FMT "%lu" +#define INT_FMT "%ld" + +typedef int32_t mp_int_t; // must be pointer size +typedef uint32_t mp_uint_t; // must be pointer size +typedef long mp_off_t; + +// dummy print +#define MP_PLAT_PRINT_STRN(str, len) pios_uart_write(str, len) + +#define MICROPY_PORT_BUILTIN_MODULES + +// extra built in names to add to the global namespace +#define MICROPY_PORT_BUILTINS \ + { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) }, + +// We need to provide a declaration/definition of alloca() +#include diff --git a/ports/bare-rpi/mphalport.h b/ports/bare-rpi/mphalport.h new file mode 100644 index 00000000000..4bd8276f349 --- /dev/null +++ b/ports/bare-rpi/mphalport.h @@ -0,0 +1 @@ +// empty file diff --git a/ports/bare-rpi/qstrdefsport.h b/ports/bare-rpi/qstrdefsport.h new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/ports/bare-rpi/qstrdefsport.h @@ -0,0 +1 @@ + diff --git a/ports/bare-rpi/start.s b/ports/bare-rpi/start.s new file mode 100644 index 00000000000..ace00726ed6 --- /dev/null +++ b/ports/bare-rpi/start.s @@ -0,0 +1,17 @@ +.global start +.section .init + +start: + ldr sp, =stack_top + + /// load C15 control register c1-c1,0,0 (c1 Control Register) into r0 + mrc p15, 0, r0, c1, c0, 0 + ldr r1, =0x00400000 /// set bit 22 (U-bit) + orr r0, r1 + mcr p15, 0, r0, c1, c0, 0 + + bl main + +halt: + b halt + diff --git a/ports/bare-rpi/uart.c b/ports/bare-rpi/uart.c new file mode 100644 index 00000000000..128ae669dd8 --- /dev/null +++ b/ports/bare-rpi/uart.c @@ -0,0 +1,159 @@ +#include "uart.h" + +/// will be used as offset with the PBASE-address to get the AUX address +/// in the I/O-device memory section +#define AUX_BASE_ADDR 0x00215000 + +/// system clock for the baudrate calculation +#define PIOS_AUX_SYSCLOCK 250000000 + +/** + * \brief enum type for enumerating the registers of the AUX-peripheral of BCM2835 + * \note see section 2.1.1 in the manual + **/ +enum pios_aux_t { + AUX_IRQ = 0, ///< AUX Interrupt status (for hierarchical source-detection) + AUX_ENABLE = 1, ///< AUX enable (last 3 bits: SPI2, SPI1, UART [2,1,0]) + + AUX_MU_IO = 16, ///< UART I/O Data + AUX_MU_IER = 17, ///< UART IRQ Enable + AUX_MU_IIR = 18, ///< UART IRQ Identify + AUX_MU_LCR = 19, ///< UART Line Control + AUX_MU_MCR = 20, ///< UART Modem Control + AUX_MU_LSR = 21, ///< UART Line Status + AUX_MU_MSR = 22, ///< UART Modem Status + AUX_MU_SCRATCH = 23, ///< UART Scratch ( an extra 8 bit buffer(?) ) + AUX_MU_CNTL = 24, ///< UART Extra Control + AUX_MU_STAT = 25, ///< UART Extra Status + AUX_MU_BAUD = 26, ///< UART Baudrate + + AUX_SPI0_CNTL0 = 32, ///< SPI 0 Control Register 0 + AUX_SPI0_CNTL1 = 33, ///< SPI 0 Control Register 1 + AUX_SPI0_STAT = 34, ///< SPI 0 Status + AUX_SPI0_IO = 35, ///< SPI 0 Data + AUX_SPI0_PEEK = 36, ///< SPI 0 Peek + + AUX_SPI1_CNTL0 = 48, ///< SPI 1 Control Register 0 + AUX_SPI1_CNTL1 = 49, ///< SPI 1 Control Register 1 + AUX_SPI1_STAT = 50, ///< SPI 1 Status + AUX_SPI1_IO = 51, ///< SPI 1 Data + AUX_SPI1_PEEK = 52 ///< SPI 1 Peek +}; + +/// enable bit for the ENABLE-operation +#define AUX_UART ( 1 << 0 ) +/// bit for SPI0 ENABLE-operation +#define AUX_SPI0 ( 1 << 1 ) +/// bit for SPI1 ENABLE-operation +#define AUX_SPI1 ( 1 << 2 ) + +/// bit for finding out whether the Transmitter is idle +#define AUX_TX_IDLE ( 1 << 6 ) +/// can the transmitter-queue receive another byte of data +#define AUX_TX_EMPTY ( 1 << 5 ) +/// is the receiver overrung, i.e. were data lost +#define AUX_RX_OVERRUN ( 1 << 1 ) +/// is there a byte in the receiver-queue? +#define AUX_RX_DATA ( 1 << 0 ) + +/** + * \brief mapping of AUX-registers, use with pios_aux_t as indices + **/ +extern volatile uint32_t* const pios_aux; + +volatile uint32_t* const pios_aux = (volatile uint32_t* const) (PIOS_IO_BASE + AUX_BASE_ADDR); + +void pios_uart_init ( ) { + // set the GPIO-pins into the correct state + pios_aux[AUX_ENABLE] = AUX_UART; + pios_aux[AUX_MU_IER] = 0; + pios_aux[AUX_MU_CNTL] = 0; + pios_aux[AUX_MU_LCR] = 3; // undocumented second bit (?) + pios_aux[AUX_MU_MCR] = 0; + pios_aux[AUX_MU_IER] = 0; + pios_aux[AUX_MU_IIR] = 0xc6; + pios_aux[AUX_MU_BAUD] = 270; + + pios_gpio_pinmode ( 14, PIOS_GPIO_ALT5 ); + pios_gpio_pinmode ( 15, PIOS_GPIO_ALT5 ); + + uint32_t p[2] = { (1<<14)|(1<<15), 0 }; + pios_gpio_pullBulk ( p, PIOS_GPIO_PULL_OFF ); + + pios_aux[AUX_MU_CNTL] = 3; +} + +bool pios_uart_checkPins () { + if ( pios_gpio_getPinmode ( 14 ) == PIOS_GPIO_ALT5 && + pios_gpio_getPinmode ( 15 ) == PIOS_GPIO_ALT5 ) { + return true; + } + return false; +} + +void pios_uart_puts ( const char* str ) { + while ( *str ) { + pios_uart_putchar(*str); + str++; + } +} + +void pios_uart_write ( const char* str, size_t len ) { + for ( int i=0; i> 24); +} +int pios_uart_txQueue () { + return (((0x000f0000) & pios_aux[AUX_MU_STAT]) >> 16); +} diff --git a/ports/bare-rpi/uart.h b/ports/bare-rpi/uart.h new file mode 100644 index 00000000000..63356d7a0b8 --- /dev/null +++ b/ports/bare-rpi/uart.h @@ -0,0 +1,86 @@ +/** + * \file uart.h + * \author Stefan Naumann + * \date 17. May 2017 + * \brief Code for the AUX-miniUART of the Raspberry Pi + **/ + +#ifndef PIOS_UART +#define PIOS_UART + +#include "gpio.h" +#include +#include +#include + +/** + * \brief checks the current function of the UART-GPIO-Pins and returns whether they are correctly set or not + **/ +bool pios_uart_checkPins (); +/** + * \brief initiate the miniUART of the AUX-peripheral + **/ +void pios_uart_init ( ); +/** + * \brief write a string to the UART + * \param[in] str the string to be transmitted + * \param[in] len the length of the string to be sent + **/ +void pios_uart_write ( const char* str, size_t len ); +/** + * \brief read a string of data from the UART-queue + * \param[out] buff the buffer to be written to + * \param[in] len the maximal length of data to be read + **/ +void pios_uart_read ( char* buff, size_t len ); + +/** + * \brief write a single character to the transmitter-queue + * \param[in] c the character to print + **/ +void pios_uart_putchar ( const char c ); +/** + * \brief read a single character from the UART + * \return the single character + **/ +uint32_t pios_uart_getchar ( ); +/** + * \brief set a specific baudrate to the UART + * \param[in] baud the wanted baudrate + **/ +void pios_uart_setBaud ( uint32_t baud ); +/** + * \brief set the data-size of the uart (7 or 8 bit) + * \param[in] size the data-size of the characters in bits + **/ +void pios_uart_setDataSize ( int size ); +/** + * \brief print a string to the uart + * \param[in] str the string to be transmitted + **/ +void pios_uart_puts ( const char* str ); + +/** + * \brief is the receiver-queue ready? + **/ +bool pios_uart_rxReady (); +/** + * \brief is the transmitter-queue ready? + **/ +bool pios_uart_txReady (); + +/** + * \brief get the receiver-queue-state + **/ +int pios_uart_rxQueue (); +/** + * \brief get the transmitter-queue-state + **/ +int pios_uart_txQueue (); + +/** + * \brief wait until the transmitter is idle again, i.e. sent it's complete queue + **/ +void pios_uart_flush (); + +#endif