From 02431f006669785afdf8e12ef1e91e06cb6318b4 Mon Sep 17 00:00:00 2001 From: Bert Lange Date: Fri, 18 Jul 2014 14:45:17 +0200 Subject: change: to minimal zpu system --- mig_test/software/libhal/Makefile | 31 ++++++ mig_test/software/libhal/common.c | 203 +++++++++++++++++++++++++++++++++++ mig_test/software/libhal/hw.c | 28 +++++ mig_test/software/libhal/include.mak | 16 +++ mig_test/software/libhal/timer.c | 132 +++++++++++++++++++++++ mig_test/software/libhal/uart.c | 56 ++++++++++ mig_test/software/libhal/vga.c | 67 ++++++++++++ 7 files changed, 533 insertions(+) create mode 100644 mig_test/software/libhal/Makefile create mode 100644 mig_test/software/libhal/common.c create mode 100644 mig_test/software/libhal/hw.c create mode 100644 mig_test/software/libhal/include.mak create mode 100644 mig_test/software/libhal/timer.c create mode 100644 mig_test/software/libhal/uart.c create mode 100644 mig_test/software/libhal/vga.c (limited to 'mig_test/software/libhal') diff --git a/mig_test/software/libhal/Makefile b/mig_test/software/libhal/Makefile new file mode 100644 index 0000000..fe149c1 --- /dev/null +++ b/mig_test/software/libhal/Makefile @@ -0,0 +1,31 @@ +# +# $HeadURL: https://svn.fzd.de/repo/concast/FWF_Projects/FWKE/hw_sp605/bsp_zpuahb/software/libhal/Makefile $ +# $Date$ +# $Author$ +# $Revision$ +# + +DIR=.. +include include.mak + + +C_FILES=hw.c common.c timer.c uart.c vga.c +OBJECTS=hw.o common.o timer.o uart.o vga.o +INCLUDES=../include/peripherie.h + + +all: libhal.a + + +libhal.a: $(OBJECTS) $(INCLUDES) + $(AR) clr libhal.a $(OBJECTS) + $(RANLIB) libhal.a + + +%.o: %.c $(INCLUDES) + $(CC) -c -o $@ $< $(CFLAGS) + + +clean: + rm -f *.o + rm -f libhal.a diff --git a/mig_test/software/libhal/common.c b/mig_test/software/libhal/common.c new file mode 100644 index 0000000..941c7e4 --- /dev/null +++ b/mig_test/software/libhal/common.c @@ -0,0 +1,203 @@ +/* + * $HeadURL: https://svn.fzd.de/repo/concast/FWF_Projects/FWF_Internals/FPGA/hw_sp605/bsp_zpuahb/software/libhal/common.c $ + * $Date$ + * $Author$ + * $Revision$ + */ + + +#include +#include // utoa, dtostrf (actually not implemented) + +//////////////////////////////////////// +// common stuff + + +// libgloss/zpu/syscalls.c work with inbyte and outbyte +char putchar( char c) +{ + return stdout( c); +} + + + +void putstr(const char *s) +{ + while (*s) + putchar( *s++); +} + + +/* + print data in binary format + prepend 0b + parameter: dataType - number of bits +*/ +void putbin( unsigned char dataType, unsigned long data) +{ + unsigned char i, temp; + char dataString[] = "0b "; + + for(i=dataType; i>0; i--) + { + temp = data % 2; + dataString [i+1] = temp + 0x30; + data = data/2; + } + putstr( dataString); +} + + +// http://asalt-vehicle.googlecode.com/svn› trunk› src› uart.c +unsigned char puthex( unsigned char dataType, unsigned long data) +{ + unsigned char count = 8; // number of chars + unsigned char i; + unsigned char temp; + char dataString[] = " "; + + // dataType = bit width + if (dataType == 4) count = 1; + if (dataType == 8) count = 2; + if (dataType == 16) count = 4; + + for(i=count; i>0; i--) + { + temp = data % 16; + if (temp<10) dataString [i-1] = temp + 0x30; + else dataString [i-1] = (temp - 10) + 0x41; + + data = data/16; + } + dataString[count] = '\0'; + putstr( dataString); + + return count; // return length +} + + + +// http://www.mikrocontroller.net/articles/FAQ#itoa.28.29 +unsigned char itoa( long z, char* Buffer ) +{ + int i = 0; + int j; + char tmp; + unsigned u; // In u bearbeiten wir den Absolutbetrag von z. + + // ist die Zahl negativ? + // gleich mal ein - hinterlassen und die Zahl positiv machen + if( z < 0 ) { + Buffer[0] = '-'; + Buffer++; + // -INT_MIN ist idR. größer als INT_MAX und nicht mehr + // als int darstellbar! Man muss daher bei der Bildung + // des Absolutbetrages aufpassen. + u = ( (unsigned)-(z+1) ) + 1; + } + else { + u = (unsigned)z; + } + // die einzelnen Stellen der Zahl berechnen + do { + Buffer[i++] = '0' + u % 10; + u /= 10; + } while( u > 0 ); + + // den String in sich spiegeln + for( j = 0; j < i / 2; ++j ) { + tmp = Buffer[j]; + Buffer[j] = Buffer[i-j-1]; + Buffer[i-j-1] = tmp; + } + Buffer[i] = '\0'; + // Laengenkorrektur wg. Vorzeichen + if (z < 0) + i++; + return i; // BLa: Laenge des Buffers zurueckgeben +} + +unsigned char utoa( unsigned long i, char *p) +{ + unsigned char length; + + length = 0; + do { + *--p = '0' + i % 10; + i /= 10; + length++; + } while (i > 0); + return length; +} + + +unsigned char putuint( unsigned long data) +{ + char str[20]; + unsigned char length; + + length = utoa( data, str); + putstr( str); + return length; +} + + +unsigned char putint( long data) +{ + char str[20]; + unsigned char length; + + length = itoa( data, str); + putstr( str); + return length; +} +/* + putint( 1000); putchar('\n'); // ok + putint( 10000); putchar('\n'); // ok + putint( 100000); putchar('\n'); // ok + putint( 1000000); putchar('\n'); // ok + putint( 10000000); putchar('\n'); // ok + putint( 100000000); putchar('\n'); // ok + putint( 200000000); putchar('\n'); // ok + putint( 400000000); putchar('\n'); // ok + putint( 800000000); putchar('\n'); // ok + putint( 1000000000); putchar('\n'); // ok + putint( 2000000000); putchar('\n'); // ok + putint( 4000000000); putchar('\n'); // -294967296 warning: this decimal constant is unsigned only in ISO C90 + putint( 8000000000); putchar('\n'); // -589934592 warning: integer constant is too large for "long" type +*/ + +unsigned char putfloat( float data) +{ + char str[20]; + unsigned char length; + + length = dtostrf( data, 2, 1, str); + putstr( str); + return length; +} + + +// p means pseudo float +// (an integer with 3 significant digits after the point) +void putpfloat( unsigned long data) +{ + putint( data/1000); + putchar( '.'); + putint( data%1000 ); +} + + +unsigned char putbool( int data) +{ + if (data) + { + putstr( "yes"); + } + else + { + putstr( "no"); + } + return 0; +} + diff --git a/mig_test/software/libhal/hw.c b/mig_test/software/libhal/hw.c new file mode 100644 index 0000000..8401010 --- /dev/null +++ b/mig_test/software/libhal/hw.c @@ -0,0 +1,28 @@ +#include "peripherie.h" + +volatile uint32_t *debug_con0 = (uint32_t *) 0x80000000; +volatile uint32_t *reset_reg = (uint32_t *) 0x80000004; +apbuart_t *uart0 = (apbuart_t *) 0x80000100; +gptimer_t *timer0 = (gptimer_t *) 0x80000200; +irqmp_t *irqmp0 = (irqmp_t *) 0x80000300; +grgpio_t *gpio0 = (grgpio_t *) 0x80000400; +apbvga_t *vga0 = (apbvga_t *) 0x80000600; +i2cmst_t *i2c_dvi = (i2cmst_t *) 0x80000700; +i2cmst_t *i2c_fmc = (i2cmst_t *) 0x80000a00; + +mctrl_t *mctrl0 = (mctrl_t *) 0x80000f00; +/* +greth_t *ether0 = (greth_t *) 0x80000c00; +dcm_ctrl_t *dcm_ctrl0 = (dcm_ctrl_t *) 0x80000e00; +ddrspa_t *ddr0 = (ddrspa_t *) 0xfff00000; +*/ + +char debug_putchar( char c) +{ + *debug_con0 = (uint32_t) c; + return 0; +} + +char (* stdout) (char) = debug_putchar; + + diff --git a/mig_test/software/libhal/include.mak b/mig_test/software/libhal/include.mak new file mode 100644 index 0000000..226ca66 --- /dev/null +++ b/mig_test/software/libhal/include.mak @@ -0,0 +1,16 @@ +AS=zpu-elf-as +CC=zpu-elf-gcc +LD=zpu-elf-ld +OBJCOPY=zpu-elf-objcopy +OBJDUMP=zpu-elf-objdump +AR=zpu-elf-ar +RANLIB=zpu-elf-ranlib +SIZE=zpu-elf-size + +ROMGEN=$(DIR)/support/zpuromgen + +INLCUDES=-I$(DIR)/include +ASFLAGS=-adhls -g $(INLCUDES) +CFLAGS=-O3 -phi -Wall -ffunction-sections -fdata-sections $(INLCUDES) +LDFLAGS=--relax --gc-sections +OBJCOPYFLAGS=--strip-debug --discard-locals diff --git a/mig_test/software/libhal/timer.c b/mig_test/software/libhal/timer.c new file mode 100644 index 0000000..789c565 --- /dev/null +++ b/mig_test/software/libhal/timer.c @@ -0,0 +1,132 @@ +#include "peripherie.h" + +#include "timer.h" + +//////////////////////////////////////// +// timer functions +// timer 0.0 is used for usleep +// timer 0.0 is used for msleep +// timer 0.0 is used for sleep (via msleep) +// +// timer 0.0 ticks with milliseconds +// timer 0.1 ticks with seconds + + +// wait for a given time in micro seconds +void usleep(uint32_t usec) +{ + uint32_t tcr; + + // 1 usec = 6 + timer0->e[0].reload = (F_CPU/TIMER_PRESCALER/1000000)*usec; + timer0->e[0].ctrl = TIMER_ENABLE | TIMER_LOAD; + + do + { + tcr = timer0->e[0].ctrl; + } while ( (tcr & TIMER_ENABLE)); +} + + +// wait for given time in milli seconds +void msleep(uint32_t msec) +{ + uint32_t tcr; + + // some values for 50MHz @ Spartan 3e + // 1 msec = 6250 + // 167 msec = 2**20 (20 bit counter) 391 slices + // 2684 msec = 2**24 (24 bit counter) 450 slices + // = 2**32 (32 bit counter) 572 slices + // some values for 52MHz @ Spartan 6 + // 1 msec = 6500 + // 161 msec = 2**20 (20 bit counter) + // 2581 msec = 2**24 (24 bit counter) 450 slices + // 660 sec = 2**32 (32 bit counter) 572 slices + timer0->e[0].reload = (F_CPU/TIMER_PRESCALER/1000)*msec; + timer0->e[0].ctrl = TIMER_ENABLE | TIMER_LOAD; + + do + { + tcr = timer0->e[0].ctrl; + } while ( (tcr & TIMER_ENABLE)); +} + + +// wait for given time in seconds +void sleep(uint32_t sec) +{ + uint32_t timer; + + for (timer=0; timere[0].value); +} + + +// deliver the seconds from timer 0.1 +uint32_t seconds( void) +{ + return( timer0->e[1].value); +} + + +// deliver the time (in seconds and fraction) from timer +uint32_t get_time( void) +{ + uint32_t value; + + TIMER_STOP; + + // combine values (seconds.milliseconds) + value = timer0->e[1].value * 1000 + timer0->e[0].value; + + TIMER_RUN; + + return( value); +} + + +// just a loop +void wait( uint32_t value) +{ + uint32_t i; + + for (i=0; iscaler_reload = TIMER_PRESCALER-1; // set prescaler + + // set timer 0.1 in chain mode to timer 0.0 + // so it counts in seconds + timer0->e[1].reload = 0xffffffff; + timer0->e[1].ctrl = TIMER_ENABLE | TIMER_RESTART | TIMER_LOAD | TIMER_CHAIN; + + // set timer 0.0 to free running in msec + timer0->e[0].reload = (F_CPU/TIMER_PRESCALER/CLOCKS_PER_SECOND); + timer0->e[0].ctrl = TIMER_ENABLE | TIMER_RESTART | TIMER_LOAD; +} + + diff --git a/mig_test/software/libhal/uart.c b/mig_test/software/libhal/uart.c new file mode 100644 index 0000000..d1290b5 --- /dev/null +++ b/mig_test/software/libhal/uart.c @@ -0,0 +1,56 @@ +//#include + +#include "peripherie.h" + +//////////////////////////////////////// +// common defines + +#define bit_is_set(mem, bv) (mem & bv) +#define bit_is_clear(mem, bv) (!(mem & bv)) +#define loop_until_bit_is_set(mem, bv) do {} while( bit_is_clear(mem, bv)) +#define loop_until_bit_is_clear(mem, bv) do {} while( bit_is_set(mem, bv)) + + +//////////////////////////////////////// +// uart functions + + +void uart_init( void) +{ + uart0->scaler = UART_SCALER; + uart0->ctrl = UART_CONTROL_TX_ENABLE | UART_CONTROL_RX_ENABLE; +} + + +unsigned int uart_check_receiver() +{ + return ( bit_is_set( uart0->status, UART_STATUS_DATA_READY) != 0); +} + + +char uart_getchar() +{ + loop_until_bit_is_set(uart0->status, UART_STATUS_DATA_READY); + return uart0->data; +} + + +void uart_putchar_raw( char c) +{ + #if UART_FIFOSIZE==1 || !defined(UART_FIFOSIZE) + loop_until_bit_is_set( uart0->status, UART_STATUS_TX_REG_EMPTY); + #else + loop_until_bit_is_clear( uart0->status, UART_STATUS_TX_FIFO_FULL); + #endif + uart0->data = c; +} + + +char uart_putchar( char c) +{ + if (c == '\n') + uart_putchar_raw( '\r'); + uart_putchar_raw( c); + return 0; +} + diff --git a/mig_test/software/libhal/vga.c b/mig_test/software/libhal/vga.c new file mode 100644 index 0000000..8cc55b9 --- /dev/null +++ b/mig_test/software/libhal/vga.c @@ -0,0 +1,67 @@ +//#include + +#include "peripherie.h" + + +//////////////////////////////////////// +// common defines + +#define bit_is_set(mem, bv) (mem & bv) +#define bit_is_clear(mem, bv) (!(mem & bv)) +#define loop_until_bit_is_set(mem, bv) do {} while( bit_is_clear(mem, bv)) +#define loop_until_bit_is_clear(mem, bv) do {} while( bit_is_set(mem, bv)) + + + + +uint8_t vga_line; +uint8_t vga_column; + +void vga_init( void) +{ + vga0->background_color = 0x00000000; + vga0->foreground_color = 0x0000ff00; + vga_line = 0; + vga_column = 0; +} + + + +void vga_clear( void) +{ + uint32_t count; + uint32_t count_max = 37*80; + + for(count = 0; count< count_max; count++) + vga0->data = count<<8; + + vga_line = 0; + vga_column = 0; +} + + +void vga_putchar( char c) +{ + + vga0->data = (( vga_line * 80 + vga_column)<<8) | c; + if ( (c == '\n') || (vga_column == 79) ) // line feed (+ carrige return) + { + if (vga_line<36) + vga_line++; + else + vga_line = 0; + + vga_column = 0; + } + else if (c == '\f') // form feed + { + vga_clear(); + } + else + { + vga_column++; + } + +} + + -- cgit v1.1