OpenCores
URL https://opencores.org/ocsvn/minsoc/minsoc/trunk

Subversion Repositories minsoc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /minsoc/trunk/sw
    from Rev 53 to Rev 51
    Reverse comparison

Rev 53 → Rev 51

/support/tick.c File deleted
/support/tick.h File deleted
/support/uart.c
0,0 → 1,77
#include "support.h"
#include "board.h"
#include "uart.h"
 
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
 
#define WAIT_FOR_XMITR \
do { \
lsr = REG8(UART_BASE + UART_LSR); \
} while ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
 
#define WAIT_FOR_THRE \
do { \
lsr = REG8(UART_BASE + UART_LSR); \
} while ((lsr & UART_LSR_THRE) != UART_LSR_THRE)
 
#define CHECK_FOR_CHAR (REG8(UART_BASE + UART_LSR) & UART_LSR_DR)
 
#define WAIT_FOR_CHAR \
do { \
lsr = REG8(UART_BASE + UART_LSR); \
} while ((lsr & UART_LSR_DR) != UART_LSR_DR)
 
#define UART_TX_BUFF_LEN 32
#define UART_TX_BUFF_MASK (UART_TX_BUFF_LEN -1)
 
char tx_buff[UART_TX_BUFF_LEN];
volatile int tx_level, rx_level;
 
void uart_init(void)
{
int divisor;
/* Reset receiver and transmiter */
/* Set RX interrupt for each byte */
REG8(UART_BASE + UART_FCR) = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_1;
/* Enable RX interrupt */
REG8(UART_BASE + UART_IER) = UART_IER_RDI | UART_IER_THRI;
/* Set 8 bit char, 1 stop bit, no parity */
REG8(UART_BASE + UART_LCR) = UART_LCR_WLEN8 & ~(UART_LCR_STOP | UART_LCR_PARITY);
/* Set baud rate */
divisor = IN_CLK/(16 * UART_BAUD_RATE);
REG8(UART_BASE + UART_LCR) |= UART_LCR_DLAB;
REG8(UART_BASE + UART_DLM) = (divisor >> 8) & 0x000000ff;
REG8(UART_BASE + UART_DLL) = divisor & 0x000000ff;
REG8(UART_BASE + UART_LCR) &= ~(UART_LCR_DLAB);
return;
}
 
void uart_putc(char c)
{
unsigned char lsr;
WAIT_FOR_THRE;
REG8(UART_BASE + UART_TX) = c;
if(c == '\n') {
WAIT_FOR_THRE;
REG8(UART_BASE + UART_TX) = '\r';
}
WAIT_FOR_XMITR;
}
 
 
 
char uart_getc()
{
unsigned char lsr;
char c;
 
// WAIT_FOR_CHAR;
c = REG8(UART_BASE + UART_RX);
return c;
}
support/uart.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: support/reset.S =================================================================== --- support/reset.S (revision 53) +++ support/reset.S (revision 51) @@ -1,5 +1,5 @@ /* Support file for c based tests */ -#include "or1200.h" +#include "spr_defs.h" #include "board.h" .section .stack
/support/except.S
1,152 → 1,152
#include "or1200.h"
#include "spr_defs.h"
 
// Linked from 0x200, so subtract 0x200 from each .org
.section .vectors, "ax"
 
/*
.org 0x100
.org 0x100
_reset:
l.nop
l.j _reset_except
l.nop
*/
 
_reset:
l.nop
l.j _reset_except
l.nop
*/
 
/* This cannot be a regular function because it would waste the return register r9 of the interrupted procedure. */
/* Furthermore, if this would be a function and l.j handler would be outside of this, the return register set here would be use upon return of this function. */
/* However, the desired behavior is to finish the handler and let the return of the service routine simply restore the registers and return to the interrupted procedure. */
#define intr_handler(handler) \
l.nop ;\
l.addi r1,r1,-244 /*free 29 words (29 x 4 = 112) + 4 because stack points to contained data (stack is r1)*/;\
/*plus 128 bytes not to mess with the previous frame pointer (32 register x 4 bytes = 128 bytes ) (required by C++ multiple threading) */;\
l.sw 0x18(r1),r9 /*save register r9(return addr) to stack*/;\
l.jal store_regs /*save registers r3-r31 (except r9) to stack (r9 is changed here)*/;\
l.nop ;\
;\
l.movhi r9,hi(end_except) /*set return addr to end_except instruction*/;\
l.ori r9,r9,lo(end_except)/*set return addr to end_except instruction*/;\
l.j handler ;\
l.nop
l.nop ;\
l.addi r1,r1,-244 /*free 29 words (29 x 4 = 112) + 4 because stack points to contained data (stack is r1)*/;\
/*plus 128 bytes not to mess with the previous frame pointer (32 register x 4 bytes = 128 bytes ) (required by C++ multiple threading) */;\
l.sw 0x18(r1),r9 /*save register r9(return addr) to stack*/;\
l.jal store_regs /*save registers r3-r31 (except r9) to stack (r9 is changed here)*/;\
l.nop ;\
;\
l.movhi r9,hi(end_except) /*set return addr to end_except instruction*/;\
l.ori r9,r9,lo(end_except)/*set return addr to end_except instruction*/;\
l.j handler ;\
l.nop
 
.org 0x000
_except_200:
intr_handler(buserr_except)
intr_handler(buserr_except)
 
.org 0x100
_except_300:
intr_handler(dpf_except)
.org 0x100
_except_300:
intr_handler(dpf_except)
 
.org 0x200
_except_400:
intr_handler(ipf_except)
.org 0x200
_except_400:
intr_handler(ipf_except)
 
.org 0x300
_except_500:
intr_handler(tick_except)
.org 0x300
_except_500:
intr_handler(tick_except)
 
.org 0x400
_except_600:
intr_handler(align_except)
.org 0x400
_except_600:
intr_handler(align_except)
 
.org 0x500
_except_700:
intr_handler(illegal_except)
.org 0x500
_except_700:
intr_handler(illegal_except)
 
.org 0x600
_except_800:
intr_handler(ext_except)
.org 0x600
_except_800:
intr_handler(ext_except)
 
.org 0x700
_except_900:
intr_handler(dtlbmiss_except)
.org 0x700
_except_900:
intr_handler(dtlbmiss_except)
 
.org 0x800
_except_a00:
intr_handler(itlbmiss_except)
.org 0x800
_except_a00:
intr_handler(itlbmiss_except)
 
.org 0x900
_except_b00:
intr_handler(range_except)
.org 0x900
_except_b00:
intr_handler(range_except)
 
.org 0xa00
_except_c00:
intr_handler(syscall_except)
.org 0xa00
_except_c00:
intr_handler(syscall_except)
 
.org 0xb00
_except_d00:
intr_handler(res1_except)
.org 0xb00
_except_d00:
intr_handler(res1_except)
 
.org 0xc00
_except_e00:
intr_handler(trap_except)
.org 0xc00
_except_e00:
intr_handler(trap_except)
 
.org 0xd00
_except_f00:
intr_handler(res2_except)
.org 0xd00
_except_f00:
intr_handler(res2_except)
 
store_regs: //save registers r3-r31 (except r9) to stack
l.sw 0x00(r1),r3
l.sw 0x04(r1),r4
l.sw 0x08(r1),r5
l.sw 0x0c(r1),r6
l.sw 0x10(r1),r7
l.sw 0x14(r1),r8
l.sw 0x1c(r1),r10
l.sw 0x20(r1),r11
l.sw 0x24(r1),r12
l.sw 0x28(r1),r13
l.sw 0x2c(r1),r14
l.sw 0x30(r1),r15
l.sw 0x34(r1),r16
l.sw 0x38(r1),r17
l.sw 0x3c(r1),r18
l.sw 0x40(r1),r19
l.sw 0x44(r1),r20
l.sw 0x48(r1),r21
l.sw 0x4c(r1),r22
l.sw 0x50(r1),r23
l.sw 0x54(r1),r24
l.sw 0x58(r1),r25
l.sw 0x5c(r1),r26
l.sw 0x60(r1),r27
l.sw 0x64(r1),r28
l.sw 0x68(r1),r29
l.sw 0x6c(r1),r30
l.sw 0x70(r1),r31
l.jr r9
l.nop
store_regs: //save registers r3-r31 (except r9) to stack
l.sw 0x00(r1),r3
l.sw 0x04(r1),r4
l.sw 0x08(r1),r5
l.sw 0x0c(r1),r6
l.sw 0x10(r1),r7
l.sw 0x14(r1),r8
l.sw 0x1c(r1),r10
l.sw 0x20(r1),r11
l.sw 0x24(r1),r12
l.sw 0x28(r1),r13
l.sw 0x2c(r1),r14
l.sw 0x30(r1),r15
l.sw 0x34(r1),r16
l.sw 0x38(r1),r17
l.sw 0x3c(r1),r18
l.sw 0x40(r1),r19
l.sw 0x44(r1),r20
l.sw 0x48(r1),r21
l.sw 0x4c(r1),r22
l.sw 0x50(r1),r23
l.sw 0x54(r1),r24
l.sw 0x58(r1),r25
l.sw 0x5c(r1),r26
l.sw 0x60(r1),r27
l.sw 0x64(r1),r28
l.sw 0x68(r1),r29
l.sw 0x6c(r1),r30
l.sw 0x70(r1),r31
l.jr r9
l.nop
 
end_except: //load back registers from stack r3-r31
l.lwz r3,0x00(r1)
l.lwz r4,0x04(r1)
l.lwz r5,0x08(r1)
l.lwz r6,0x0c(r1)
l.lwz r7,0x10(r1)
l.lwz r8,0x14(r1)
l.lwz r9,0x18(r1)
l.lwz r10,0x1c(r1)
l.lwz r11,0x20(r1)
l.lwz r12,0x24(r1)
l.lwz r13,0x28(r1)
l.lwz r14,0x2c(r1)
l.lwz r15,0x30(r1)
l.lwz r16,0x34(r1)
l.lwz r17,0x38(r1)
l.lwz r18,0x3c(r1)
l.lwz r19,0x40(r1)
l.lwz r20,0x44(r1)
l.lwz r21,0x48(r1)
l.lwz r22,0x4c(r1)
l.lwz r23,0x50(r1)
l.lwz r24,0x54(r1)
l.lwz r25,0x58(r1)
l.lwz r26,0x5c(r1)
l.lwz r27,0x60(r1)
l.lwz r28,0x64(r1)
l.lwz r29,0x68(r1)
l.lwz r30,0x6c(r1)
l.lwz r31,0x70(r1)
l.addi r1,r1,244 //free stack places
l.rfe //recover SR register and prior PC (jumps back to program)
l.nop
end_except: //load back registers from stack r3-r31
l.lwz r3,0x00(r1)
l.lwz r4,0x04(r1)
l.lwz r5,0x08(r1)
l.lwz r6,0x0c(r1)
l.lwz r7,0x10(r1)
l.lwz r8,0x14(r1)
l.lwz r9,0x18(r1)
l.lwz r10,0x1c(r1)
l.lwz r11,0x20(r1)
l.lwz r12,0x24(r1)
l.lwz r13,0x28(r1)
l.lwz r14,0x2c(r1)
l.lwz r15,0x30(r1)
l.lwz r16,0x34(r1)
l.lwz r17,0x38(r1)
l.lwz r18,0x3c(r1)
l.lwz r19,0x40(r1)
l.lwz r20,0x44(r1)
l.lwz r21,0x48(r1)
l.lwz r22,0x4c(r1)
l.lwz r23,0x50(r1)
l.lwz r24,0x54(r1)
l.lwz r25,0x58(r1)
l.lwz r26,0x5c(r1)
l.lwz r27,0x60(r1)
l.lwz r28,0x64(r1)
l.lwz r29,0x68(r1)
l.lwz r30,0x6c(r1)
l.lwz r31,0x70(r1)
l.addi r1,r1,244 //free stack places
l.rfe //recover SR register and prior PC (jumps back to program)
l.nop
 
/support/support.c
4,12 → 4,14
#include <sys/time.h>
#endif
 
#include "or1200.h"
#include "spr_defs.h"
#include "support.h"
#include "int.h"
 
#ifdef UART_PRINTF
#include "../drivers/uart.h"
//#include "snprintf.h"
#include "vfnprintf.h"
#include "uart.h"
#endif
 
#if OR32
23,16 → 25,16
/* Start function, called by reset exception handler. */
void reset ()
{
int i = main();
or32_exit (i);
int i = main();
or32_exit (i);
}
 
/* return value by making a syscall */
void or32_exit (int i)
{
asm("l.add r3,r0,%0": : "r" (i));
asm("l.nop %0": :"K" (NOP_EXIT));
while (1);
asm("l.add r3,r0,%0": : "r" (i));
asm("l.nop %0": :"K" (NOP_EXIT));
while (1);
}
 
#ifdef UART_PRINTF
44,27 → 46,27
 
void minsoc_printf(const char *fmt, ...)
{
// init uart if not done already
if (!uart_init_done)
{
uart_init();
uart_init_done = 1;
}
// init uart if not done already
if (!uart_init_done)
{
uart_init();
uart_init_done = 1;
}
 
va_list args;
va_start(args, fmt);
 
//int str_l = vsnprintf(PRINTFBUFFER, PRINTFBUFFER_SIZE, fmt, args);
int str_l = vfnprintf(PRINTFBUFFER, PRINTFBUFFER_SIZE, fmt, args);
 
if (!str_l) return; // no length string - just return
 
int c=0;
// now print each char via the UART
while (c < str_l)
uart_putc(PRINTFBUFFER[c++]);
 
va_end(args);
va_list args;
va_start(args, fmt);
//int str_l = vsnprintf(PRINTFBUFFER, PRINTFBUFFER_SIZE, fmt, args);
int str_l = vfnprintf(PRINTFBUFFER, PRINTFBUFFER_SIZE, fmt, args);
if (!str_l) return; // no length string - just return
int c=0;
// now print each char via the UART
while (c < str_l)
uart_putc(PRINTFBUFFER[c++]);
va_end(args);
}
 
#else
71,13 → 73,25
/* activate printf support in simulator */
void minsoc_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
__asm__ __volatile__ (" l.addi\tr3,%1,0\n \
l.addi\tr4,%2,0\n \
l.nop %0": :"K" (NOP_PRINTF), "r" (fmt), "r" (args));
va_list args;
va_start(args, fmt);
__asm__ __volatile__ (" l.addi\tr3,%1,0\n \
l.addi\tr4,%2,0\n \
l.nop %0": :"K" (NOP_PRINTF), "r" (fmt), "r" (args));
}
 
/*
void *memcpy (void *__restrict dstvoid,
__const void *__restrict srcvoid, size_t length)
{
char *dst = dstvoid;
const char *src = (const char *) srcvoid;
 
while (length--)
*dst++ = *src++;
return dst;
}
*/
#endif
 
 
87,8 → 101,8
/* print long */
void report(unsigned long value)
{
asm("l.addi\tr3,%0,0": :"r" (value));
asm("l.nop %0": :"K" (NOP_REPORT));
asm("l.addi\tr3,%0,0": :"r" (value));
asm("l.nop %0": :"K" (NOP_REPORT));
}
 
/* just to satisfy linker */
101,24 → 115,53
{
}
 
/* read_TIMER */
/* Returns a value since started in uS */
unsigned int read_timer(int x)
{
unsigned long count = 0;
 
/* Read the Time Stamp Counter */
/* asm("simrdtsc %0" :"=r" (count)); */
/*asm("l.sys 201"); */
return count;
}
 
/* For writing into SPR. */
void mtspr(unsigned long spr, unsigned long value)
{
asm("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value));
asm("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value));
}
 
/* For reading SPR. */
unsigned long mfspr(unsigned long spr)
{
unsigned long value;
asm("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
return value;
unsigned long value;
asm("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
return value;
}
 
#else
void report(unsigned long value)
{
printf("report(0x%x);\n", (unsigned) value);
printf("report(0x%x);\n", (unsigned) value);
}
 
/* start_TIMER */
void start_timer(int tmrnum)
{
}
 
/* read_TIMER */
/* Returns a value since started in uS */
unsigned int read_timer(int tmrnum)
{
struct timeval tv;
struct timezone tz;
 
gettimeofday(&tv, &tz);
return(tv.tv_sec*1000000+tv.tv_usec);
}
 
#endif
/support/vfnprintf.c
0,0 → 1,686
// Ripped out of latest ecos build from http://sources-redhat.mirrors.airband.net/ecos/releases/ecos-3.0b1/ecos-3.0beta1.i386linux.tar.bz2
// File: ecos-3.0b1/packages/language/c/libc/stdio/v3_0b1/src/output/vfnprintf.cxx
 
// Hacked to pieces so it would work with OpenRISC compiler, not using libc
//===========================================================================
//
// vfnprintf.c
//
// I/O routines for vfnprintf() for use with ANSI C library
//
//===========================================================================
// ####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later
// version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with eCos; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// As a special exception, if other files instantiate templates or use
// macros or inline functions from this file, or you compile this file
// and link it with other works to produce a work based on this file,
// this file does not by itself cause the resulting work to be covered by
// the GNU General Public License. However the source code for this file
// must still be made available in accordance with section (3) of the GNU
// General Public License v2.
//
// This exception does not invalidate any other reasons why a work based
// on this file might be covered by the GNU General Public License.
// -------------------------------------------
// ####ECOSGPLCOPYRIGHTEND####
//===========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jlarmour
// Contributors:
// Date: 2000-04-20
// Purpose:
// Description:
// Usage:
//
//####DESCRIPTIONEND####
//
//===========================================================================
//
// This code is based on original code with the following copyright:
//
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
 
 
// CONFIGURATION
 
//#include <pkgconf/libc_stdio.h> // Configuration header
//#include <pkgconf/libc_i18n.h> // Configuration header for mb support
 
// INCLUDES
 
//#include <stdlib.h> // For mbtowc()
#include <stddef.h>
 
 
//#include <cyg/infra/cyg_type.h> // Common type definitions and support
#define CYG_MACRO_START do {
#define CYG_MACRO_END } while (0)
 
#define CYG_EMPTY_STATEMENT CYG_MACRO_START CYG_MACRO_END
 
#define CYG_UNUSED_PARAM( _type_, _name_ ) CYG_MACRO_START \
_type_ __tmp1 = (_name_); \
_type_ __tmp2 = __tmp1; \
__tmp1 = __tmp2; \
CYG_MACRO_END
 
#include <stdarg.h> // Variable argument definitions
 
#include "vfnprintf.h"
 
 
# define BUF 40
 
/*
* Actual printf innards.
*
* This code is large and complicated...
*/
 
 
/*
* Macros for converting digits to letters and vice versa
*/
#define to_digit(c) ((c) - '0')
#define is_digit(c) ((unsigned)to_digit(c) <= 9)
#define to_char(n) ((n) + '0')
 
/*
* Flags used during conversion.
*/
#define ALT 0x001 /* alternate form */
#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
#define LADJUST 0x004 /* left adjustment */
#define LONGDBL 0x008 /* long double; unimplemented */
#define LONGINT 0x010 /* long integer */
#define QUADINT 0x020 /* quad integer */
#define SHORTINT 0x040 /* short integer */
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
#define FPT 0x100 /* Floating point number */
#define SIZET 0x200 /* size_t */
 
int
strlen(const char *s)
{
const char *p;
 
for (p = s; *p != '\0'; p++)
;
return (s - p);
}
 
void *
memcpy(void *dst, const void *src, size_t len)
{
const char *csrc;
char *cdst;
int i;
 
cdst = dst;
csrc = src;
for (i = len; i >= 0; i--) {
cdst[i] = csrc[i];
}
return dst;
}
 
// Function which prints back to the buffer, ptr, len bytes
// returns 1 if it should finish up, otherwise 0 to continue
int print_back_to_string(char * ptr, int len, size_t * n, int * ret, char ** stream)
{
#define MIN(a, b) ((a) < (b) ? (a) : (b))
do {
int length = MIN( (int) len, *n - *ret - 1);
memcpy(*stream + *ret, ptr, length);
if (length < (int)len) {
*ret += length;
return 1; // finish up
}
 
} while(0);
return 0;
}
 
//externC int
int
//vfnprintf ( FILE *stream, size_t n, const char *format, va_list arg) __THROW
vfnprintf ( char *stream, size_t n, const char *format, va_list arg)
{
char *fmt; /* format string */
int ch; /* character from fmt */
int x, y; /* handy integers (short term usage) */
char *cp; /* handy char pointer (short term usage) */
int flags; /* flags as above */
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format (%.3d), or -1 */
char sign; /* sign prefix (' ', '+', '-', or \0) */
wchar_t wc;
#define quad_t long long
#define u_quad_t unsigned long long
u_quad_t _uquad; /* integer arguments %[diouxX] */
enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
int dprec; /* a copy of prec if [diouxX], 0 otherwise */
int fieldsz; /* field size expanded by sign, etc */
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
char *xdigs; /* digits for [xX] conversion */
#define NIOV 8
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
char ox[2]; /* space for 0x hex-prefix */
/*
* Choose PADSIZE to trade efficiency vs. size. If larger printf
* fields occur frequently, increase PADSIZE and make the initialisers
* below longer.
*/
#define PADSIZE 16 /* pad chunk size */
static char blanks[PADSIZE] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
static char zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
// We'll copy len bytes from (char*) ptr, into the output stream
// making sure we don't go over the end, so calculate length to be
// either the whole length we've been passed, or the whole length
// that is possible to write
// We finish if it was not possible to write the entire variable
// into the buffer, ie we had to write all we could, not all we
// wanted to.
/*
#define PRINT(ptr, len) \
CYG_MACRO_START \
int length = MIN( (int) len, n - ret - 1); \
char* begin_stream_write = stream; \
stream = memcpy(stream, ptr, length); \
length = (unsigned long) stream - (unsigned long) begin_stream_write; \
if (length < (int)len) { \
ret += length; \
goto done; \
} \
CYG_MACRO_END
*/
//PRINT(with, PADSIZE); \
//PRINT(with, x); \
#define PAD(howmany, with) \
CYG_MACRO_START \
if ((x = (howmany)) > 0) { \
while (x > PADSIZE) { \
if (print_back_to_string(with, PADSIZE, &n, &ret, &stream)) goto done; \
x -= PADSIZE; \
} \
if (print_back_to_string(with, x, &n, &ret, &stream))goto done; \
} \
CYG_MACRO_END
/*
* To extend shorts properly, we need both signed and unsigned
* argument extraction methods.
*/
#define SARG() \
(flags&QUADINT ? va_arg(arg, long long) : \
flags&LONGINT ? va_arg(arg, long) : \
flags&SHORTINT ? (long)(short)va_arg(arg, int) : \
flags&SIZET ? (long)va_arg(arg, size_t) : \
(long)va_arg(arg, int))
#define UARG() \
(flags&QUADINT ? va_arg(arg, unsigned long long) : \
flags&LONGINT ? va_arg(arg, unsigned long) : \
flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(arg, int) : \
flags&SIZET ? va_arg(arg, size_t) : \
(unsigned long)va_arg(arg, unsigned int))
 
xdigs = NULL; // stop compiler whinging
fmt = (char *)format;
ret = 0;
/*
* Scan the format for conversions (`%' character).
*/
for (;;) {
cp = (char *)fmt; // char pointer - set to where we begin looking from
while ((x = ((wc = *fmt) != 0))) { // While, wc=next char and x is one while there's still chars left
fmt += x; // increment the pointer to the char
if (wc == '%') { // check if it's the beginning of
fmt--; // Decrement the char pointer, actually
break;
}
}
if ((y = fmt - cp) != 0) { // y is length of string to copy out just now
//PRINT(cp, y); // Copy macro
if(print_back_to_string(cp, y, &n, &ret, &stream)) goto done; // Copy macro
ret += y; // increment return chars
}
if ((x <= 0) || (ret >= (int)n)) // @@@ this check with n isn't good enough
goto done;
fmt++; /* skip over '%' */
flags = 0;
dprec = 0;
width = 0;
prec = -1;
sign = '\0';
rflag: ch = *fmt++;
reswitch: switch (ch) {
case ' ':
/*
* ``If the space and + flags both appear, the space
* flag will be ignored.''
* -- ANSI X3J11
*/
if (!sign)
sign = ' ';
goto rflag;
case '#':
flags |= ALT;
goto rflag;
case '*':
/*
* ``A negative field width argument is taken as a
* - flag followed by a positive field width.''
* -- ANSI X3J11
* They don't exclude field widths read from args.
*/
if ((width = va_arg(arg, int)) >= 0)
goto rflag;
width = -width;
/* FALLTHROUGH */
case '-':
flags |= LADJUST;
goto rflag;
case '+':
sign = '+';
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
x = va_arg(arg, int);
prec = x < 0 ? -1 : x;
goto rflag;
}
x = 0;
while (is_digit(ch)) {
x = 10 * x + to_digit(ch);
ch = *fmt++;
}
prec = x < 0 ? -1 : x;
goto reswitch;
case '0':
/*
* ``Note that 0 is taken as a flag, not as the
* beginning of a field width.''
* -- ANSI X3J11
*/
flags |= ZEROPAD;
goto rflag;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
x = 0;
do {
x = 10 * x + to_digit(ch);
ch = *fmt++;
} while (is_digit(ch));
width = x;
goto reswitch;
case 'h':
flags |= SHORTINT;
goto rflag;
case 'l':
if (*fmt == 'l') {
fmt++;
flags |= QUADINT;
} else {
flags |= LONGINT;
}
goto rflag;
case 'q':
flags |= QUADINT;
goto rflag;
case 'c':
*(cp = buf) = va_arg(arg, int);
size = 1;
sign = '\0';
break;
case 'D':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'd':
case 'i':
_uquad = SARG();
#ifndef _NO_LONGLONG
if ((quad_t)_uquad < 0)
#else
if ((long) _uquad < 0)
#endif
{
_uquad = -_uquad;
sign = '-';
}
base = DEC;
goto number;
case 'e':
case 'E':
case 'f':
case 'g':
case 'G':
// Output nothing at all
(void) va_arg(arg, double); // take off arg anyway
cp = "";
size = 0;
sign = '\0';
break;
case 'n':
#ifndef _NO_LONGLONG
if (flags & QUADINT)
*va_arg(arg, quad_t *) = ret;
else
#endif
if (flags & LONGINT)
*va_arg(arg, long *) = ret;
else if (flags & SHORTINT)
*va_arg(arg, short *) = ret;
else if (flags & SIZET)
*va_arg(arg, size_t *) = ret;
else
*va_arg(arg, int *) = ret;
continue; /* no output */
case 'O':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
_uquad = UARG();
base = OCT;
goto nosign;
case 'p':
/*
* ``The argument shall be a pointer to void. The
* value of the pointer is converted to a sequence
* of printable characters, in an implementation-
* defined manner.''
* -- ANSI X3J11
*/
/* NOSTRICT */
_uquad = (unsigned long)va_arg(arg, void *);
base = HEX;
xdigs = (char *)"0123456789abcdef";
flags |= HEXPREFIX;
ch = 'x';
goto nosign;
case 's':
if ((cp = va_arg(arg, char *)) == NULL)
cp = (char *)"(null)";
if (prec >= 0) {
/*
* can't use strlen; can only look for the
* NUL in the first `prec' characters, and
* strlen() will go further.
*/
char *p = (char *)memchr(cp, 0, prec);
if (p != NULL) {
size = p - cp;
if (size > prec)
size = prec;
} else
size = prec;
} else
size = strlen(cp);
sign = '\0';
break;
case 'U':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
_uquad = UARG();
base = DEC;
goto nosign;
case 'X':
xdigs = (char *)"0123456789ABCDEF";
goto hex;
case 'x':
xdigs = (char *)"0123456789abcdef";
hex: _uquad = UARG();
base = HEX;
/* leading 0x/X only if non-zero */
if (flags & ALT && _uquad != 0)
flags |= HEXPREFIX;
/* unsigned conversions */
nosign: sign = '\0';
/*
* ``... diouXx conversions ... if a precision is
* specified, the 0 flag will be ignored.''
* -- ANSI X3J11
*/
number: if ((dprec = prec) >= 0)
flags &= ~ZEROPAD;
/*
* ``The result of converting a zero value with an
* explicit precision of zero is no characters.''
* -- ANSI X3J11
*/
cp = buf + BUF;
if (_uquad != 0 || prec != 0) {
/*
* Unsigned mod is hard, and unsigned mod
* by a constant is easier than that by
* a variable; hence this switch.
*/
switch (base) {
case OCT:
do {
*--cp = to_char(_uquad & 7);
_uquad >>= 3;
} while (_uquad);
/* handle octal leading 0 */
if (flags & ALT && *cp != '0')
*--cp = '0';
break;
case DEC:
if (!(flags & QUADINT)) {
/* many numbers are 1 digit */
unsigned long v = (unsigned long)_uquad;
while (v >= 10) {
/* The following is usually faster than using a modulo */
unsigned long next = v / 10;
*--cp = to_char(v - (next * 10));
v = next;
}
*--cp = to_char(v);
}
else {
while (_uquad >= 10) {
/* The following is usually faster than using a modulo */
u_quad_t next = _uquad / 10;
*--cp = to_char(_uquad - (next * 10));
_uquad = next;
}
*--cp = to_char(_uquad);
}
break;
case HEX:
do {
*--cp = xdigs[_uquad & 15];
_uquad >>= 4;
} while (_uquad);
break;
default:
cp = (char *)"bug in vfprintf: bad base";
size = strlen(cp);
goto skipsize;
}
}
size = buf + BUF - cp;
skipsize:
break;
case 'z':
flags |= SIZET;
goto rflag;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
/* pretend it was %c with argument ch */
cp = buf;
*cp = ch;
size = 1;
sign = '\0';
break;
}
/*
* All reasonable formats wind up here. At this point, `cp'
* points to a string which (if not flags&LADJUST) should be
* padded out to `width' places. If flags&ZEROPAD, it should
* first be prefixed by any sign or other prefix; otherwise,
* it should be blank padded before the prefix is emitted.
* After any left-hand padding and prefixing, emit zeroes
* required by a decimal [diouxX] precision, then print the
* string proper, then emit zeroes required by any leftover
* floating precision; finally, if LADJUST, pad with blanks.
*
* Compute actual size, so we know how much to pad.
* fieldsz excludes decimal prec; realsz includes it.
*/
#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
fieldsz = size + fpprec;
#else
fieldsz = size;
#endif
if (sign)
fieldsz++;
else if (flags & HEXPREFIX)
fieldsz+= 2;
realsz = dprec > fieldsz ? dprec : fieldsz;
/* right-adjusting blank padding */
if ((flags & (LADJUST|ZEROPAD)) == 0) {
if (width - realsz > 0) {
PAD(width - realsz, blanks);
ret += width - realsz;
}
}
/* prefix */
if (sign) {
//PRINT(&sign, 1);
if(print_back_to_string(&sign, 1, &n, &ret, &stream))goto done;
ret++;
} else if (flags & HEXPREFIX) {
ox[0] = '0';
ox[1] = ch;
//PRINT(ox, 2);
if(print_back_to_string(ox, 2, &n, &ret, &stream))goto done;
ret += 2;
}
/* right-adjusting zero padding */
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
if (width - realsz > 0) {
PAD(width - realsz, zeroes);
ret += width - realsz;
}
}
if (dprec - fieldsz > 0) {
/* leading zeroes from decimal precision */
PAD(dprec - fieldsz, zeroes);
ret += dprec - fieldsz;
}
/* the string or number proper */
//PRINT(cp, size);
if(print_back_to_string(cp,size, &n, &ret, &stream))goto done;
ret += size;
#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
/* trailing f.p. zeroes */
PAD(fpprec, zeroes);
ret += fpprec;
#endif
/* left-adjusting padding (always blank) */
if (flags & LADJUST) {
if (width - realsz > 0) {
PAD(width - realsz, blanks);
ret += width - realsz;
}
}
}
done:
error:
return ret;// remove this error stuff (((Cyg_OutputStream *) stream)->get_error() ? EOF : ret);
/* NOTREACHED */
}
 
 
 
// EOF vfnprintf.c
support/vfnprintf.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: support/support.h =================================================================== --- support/support.h (revision 53) +++ support/support.h (revision 51) @@ -8,6 +8,8 @@ #include #include #include +#define OR1K 1 //ME added +#if OR1K /* Register access macros */ #define REG8(add) *((volatile unsigned char *)(add)) @@ -14,6 +16,8 @@ #define REG16(add) *((volatile unsigned short *)(add)) #define REG32(add) *((volatile unsigned long *)(add)) +void or32_printf(const char *fmt, ...); + /* For writing into SPR. */ void mtspr(unsigned long spr, unsigned long value); @@ -20,6 +24,14 @@ /* For reading SPR. */ unsigned long mfspr(unsigned long spr); +#else /* OR1K */ + +#include + +#endif /* OR1K */ + +#define printf or32_printf + /* Function to be called at entry point - not defined here. */ int main (); @@ -35,6 +47,10 @@ __const void *__restrict __src, size_t __n); */ +/* Timer functions */ +extern void start_timer(int); +extern unsigned int read_timer(int); + extern unsigned long excpt_buserr; extern unsigned long excpt_dpfault; extern unsigned long excpt_ipfault; @@ -49,4 +65,5 @@ extern unsigned long excpt_break; extern unsigned long excpt_trap; + #endif /* SUPPORT_H */
/support/board.h
1,22 → 1,23
#ifndef _BOARD_H_
#define _BOARD_H_
 
#define MC_ENABLED 0
#define MC_ENABLED 0
 
#define IC_ENABLE 0
#define IC_ENABLE 0
#define IC_SIZE 8192
#define DC_ENABLE 0
#define DC_ENABLE 0
#define DC_SIZE 8192
 
 
#define IN_CLK 25000000
#define IN_CLK 25000000
 
#define TICKS_PER_SEC 100
 
#define STACK_SIZE 0x01000
#define STACK_SIZE 0x01000
 
#define UART_BAUD_RATE 115200
 
#define UART_BASE 0x90000000
#define UART_BASE 0x90000000
#define UART_IRQ 2
#define ETH_BASE 0x92000000
#define ETH_IRQ 4
28,13 → 29,24
#define MC_BASE_ADDR 0x60000000
#define SPI_BASE 0xa0000000
 
#define ETH_DATA_BASE 0xa8000000 /* Address for ETH_DATA */
#define ETH_DATA_BASE 0xa8000000 /* Address for ETH_DATA */
 
#define ETH_MACADDR0 0x00
#define ETH_MACADDR1 0x12
#define BOARD_DEF_IP 0x0a010185
#define BOARD_DEF_MASK 0xff000000
#define BOARD_DEF_GW 0x0a010101
 
#define ETH_MACADDR0 0x00
#define ETH_MACADDR1 0x12
#define ETH_MACADDR2 0x34
#define ETH_MACADDR3 0x56
#define ETH_MACADDR3 0x56
#define ETH_MACADDR4 0x78
#define ETH_MACADDR5 0x9a
#define ETH_MACADDR5 0x9a
 
 
/* Whether online help is available -- saves space */
#define HELP_ENABLED 1
 
/* Whether self check is enabled */
#define SELF_CHECK 1
 
#endif
/support/Makefile
1,7 → 1,7
all: libsupport.a reset-nocache.o reset-ic.o reset-dc.o reset-icdc.o
 
libsupport.a: support.o int.o except.o tick.o
$(OR32_TOOL_PREFIX)-ar cru libsupport.a support.o except.o int.o tick.o
libsupport.a: support.o int.o except.o uart.o vfnprintf.o
$(OR32_TOOL_PREFIX)-ar cru libsupport.a support.o except.o int.o uart.o vfnprintf.o
$(OR32_TOOL_PREFIX)-ranlib libsupport.a
 
support.o: support.c
22,10 → 22,16
except.o: except.S
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -c -o $@ $?
 
uart.o: uart.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -c -o $@ $?
 
#snprintf.o: snprintf.c
# $(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -O2 -c -o $@ $?
 
vfnprintf.o: vfnprintf.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -c -o $@ $?
 
int.o: int.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) -c -o $@ $?
 
tick.o: tick.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $? -c -o $@
 
include Makefile.inc
/support/int.c
2,7 → 2,7
/* (C) 2001 Simon Srot, srot@opencores.org */
 
#include "support.h"
#include "or1200.h"
#include "spr_defs.h"
#include "int.h"
 
#ifdef OR1K
13,71 → 13,71
/* Initialize routine */
int int_init()
{
int i;
int i;
 
for(i = 0; i < MAX_INT_HANDLERS; i++) {
int_handlers[i].handler = 0;
int_handlers[i].arg = 0;
}
mtspr(SPR_PICMR, 0x00000000);
for(i = 0; i < MAX_INT_HANDLERS; i++) {
int_handlers[i].handler = 0;
int_handlers[i].arg = 0;
}
mtspr(SPR_PICMR, 0x00000000);
//set OR1200 to accept exceptions
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
 
//set OR1200 to accept exceptions
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
 
return 0;
return 0;
}
 
/* Add interrupt handler */
int int_add(unsigned long vect, void (* handler)(void *), void *arg)
{
if(vect >= MAX_INT_HANDLERS)
return -1;
if(vect >= MAX_INT_HANDLERS)
return -1;
 
int_handlers[vect].handler = handler;
int_handlers[vect].arg = arg;
int_handlers[vect].handler = handler;
int_handlers[vect].arg = arg;
 
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << vect));
 
return 0;
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << vect));
return 0;
}
 
/* Disable interrupt */
int int_disable(unsigned long vect)
{
if(vect >= MAX_INT_HANDLERS)
return -1;
if(vect >= MAX_INT_HANDLERS)
return -1;
 
mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(0x00000001L << vect));
 
return 0;
mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(0x00000001L << vect));
return 0;
}
 
/* Enable interrupt */
int int_enable(unsigned long vect)
{
if(vect >= MAX_INT_HANDLERS)
return -1;
if(vect >= MAX_INT_HANDLERS)
return -1;
 
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << vect));
 
return 0;
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << vect));
return 0;
}
 
/* Main interrupt handler */
void int_main()
{
unsigned long picsr = mfspr(SPR_PICSR); //process only the interrupts asserted at signal catch, ignore all during process
unsigned long i = 0;
unsigned long picsr = mfspr(SPR_PICSR); //process only the interrupts asserted at signal catch, ignore all during process
unsigned long i = 0;
 
while(i < 32) {
if((picsr & (0x01L << i)) && (int_handlers[i].handler != 0)) {
(*int_handlers[i].handler)(int_handlers[i].arg);
}
i++;
}
while(i < 32) {
if((picsr & (0x01L << i)) && (int_handlers[i].handler != 0)) {
(*int_handlers[i].handler)(int_handlers[i].arg);
}
i++;
}
 
mtspr(SPR_PICSR, 0); //clear interrupt status: all modules have level interrupts, which have to be cleared by software,
mtspr(SPR_PICSR, 0); //clear interrupt status: all modules have level interrupts, which have to be cleared by software,
} //thus this is safe, since non processed interrupts will get re-asserted soon enough
 
 
#endif
/support/int.h
1,3 → 1,4
 
/* Number of interrupt handlers */
#define MAX_INT_HANDLERS 32
 
/support/uart.h
0,0 → 1,122
 
void uart_init(void);
void uart_putc(char);
char uart_getc(void);
 
#define UART_RX 0 /* In: Receive buffer (DLAB=0) */
#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
#define UART_IER 1 /* Out: Interrupt Enable Register */
#define UART_IIR 2 /* In: Interrupt ID Register */
#define UART_FCR 2 /* Out: FIFO Control Register */
#define UART_EFR 2 /* I/O: Extended Features Register */
/* (DLAB=1, 16C660 only) */
#define UART_LCR 3 /* Out: Line Control Register */
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_LSR 5 /* In: Line Status Register */
#define UART_MSR 6 /* In: Modem Status Register */
#define UART_SCR 7 /* I/O: Scratch Register */
 
/*
* These are the definitions for the FIFO Control Register
* (16650 only)
*/
#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */
#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */
#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */
#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
/* 16650 redefinitions */
#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */
#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */
#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */
#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */
#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */
#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */
#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */
#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */
 
/*
* These are the definitions for the Line Control Register
*
* Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
* UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
*/
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_LCR_SBC 0x40 /* Set break control */
#define UART_LCR_SPAR 0x20 /* Stick parity (?) */
#define UART_LCR_EPAR 0x10 /* Even parity select */
#define UART_LCR_PARITY 0x08 /* Parity Enable */
#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 stop bit, 1= 2 stop bits */
#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */
#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */
#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
 
/*
* These are the definitions for the Line Status Register
*/
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
#define UART_LSR_FE 0x08 /* Frame error indicator */
#define UART_LSR_PE 0x04 /* Parity error indicator */
#define UART_LSR_OE 0x02 /* Overrun error indicator */
#define UART_LSR_DR 0x01 /* Receiver data ready */
 
/*
* These are the definitions for the Interrupt Identification Register
*/
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
 
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
#define UART_IIR_TOI 0x0c /* Receive time out interrupt */
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
 
/*
* These are the definitions for the Interrupt Enable Register
*/
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
 
/*
* These are the definitions for the Modem Control Register
*/
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
#define UART_MCR_OUT2 0x08 /* Out2 complement */
#define UART_MCR_OUT1 0x04 /* Out1 complement */
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR complement */
 
/*
* These are the definitions for the Modem Status Register
*/
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
#define UART_MSR_RI 0x40 /* Ring Indicator */
#define UART_MSR_DSR 0x20 /* Data Set Ready */
#define UART_MSR_CTS 0x10 /* Clear to Send */
#define UART_MSR_DDCD 0x08 /* Delta DCD */
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
#define UART_MSR_DDSR 0x02 /* Delta DSR */
#define UART_MSR_DCTS 0x01 /* Delta CTS */
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
 
/*
* These are the definitions for the Extended Features Register
* (StarTech 16C660 only, when DLAB=1)
*/
#define UART_EFR_CTS 0x80 /* CTS flow control */
#define UART_EFR_RTS 0x40 /* RTS flow control */
#define UART_EFR_SCD 0x20 /* Special character detect */
#define UART_EFR_ENI 0x10 /* Enhanced Interrupt */
 
support/uart.h Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: support/vfnprintf.h =================================================================== --- support/vfnprintf.h (nonexistent) +++ support/vfnprintf.h (revision 51) @@ -0,0 +1,2 @@ + +int vfnprintf ( char *stream, size_t n, const char *format, va_list arg);
support/vfnprintf.h Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: eth/eth.c =================================================================== --- eth/eth.c (revision 53) +++ eth/eth.c (revision 51) @@ -1,7 +1,7 @@ #include "../support/support.h" #include "../support/board.h" -#include "../support/or1200.h" +#include "../support/spr_defs.h" #include "../drivers/uart.h" #include "../drivers/eth.h" @@ -14,22 +14,22 @@ void eth_receive() { - int i; - uart_print_str("Length: \n"); - uart_print_long(eth_rx_len); - uart_print_str("\n"); - uart_print_str("Data: \n"); - for ( i = 0; i < eth_rx_len; i++ ) - { - uart_print_short(eth_rx_data[i]); - uart_print_str("\n"); - } - eth_recv_ack(); + int i; + uart_print_str("Length: \n"); + uart_print_long(eth_rx_len); + uart_print_str("\n"); + uart_print_str("Data: \n"); + for ( i = 0; i < eth_rx_len; i++ ) + { + uart_print_short(eth_rx_data[i]); + uart_print_str("\n"); + } + eth_recv_ack(); } int main() { - unsigned long lalala; + unsigned long lalala; uart_init(); int_init(); @@ -36,7 +36,7 @@ eth_init(); int_add(UART_IRQ, &uart_interrupt); int_add(ETH_IRQ, ð_interrupt); - + /* We can't use printf because in this simple example we don't link C library. */ uart_print_str("Hello World.\n\r"); @@ -48,14 +48,14 @@ eth_send(4); - while(1) - { - if (eth_rx_done) - { - eth_receive(); - } - } - + while(1) + { + if (eth_rx_done) + { + eth_receive(); + } + } + report(0xdeaddead); or32_exit(0); }
/uart/uart.c
1,7 → 1,8
#include "../support/support.h"
#include "../support/board.h"
#include "../support/or1200.h"
 
#include "../support/spr_defs.h"
 
#include "../drivers/uart.h"
 
int main()
/drivers/eth.c
12,10 → 12,10
 
void eth_recv_ack(void)
{
eth_rx_done = 0;
eth_rx_len = 0;
//accept further data (reset RXBD to empty)
REG32(ETH_BASE + ETH_RXBD0L) = RX_READY; //len = 0 | IRQ & WR = 1 | EMPTY = 1
eth_rx_done = 0;
eth_rx_len = 0;
//accept further data (reset RXBD to empty)
REG32(ETH_BASE + ETH_RXBD0L) = RX_READY; //len = 0 | IRQ & WR = 1 | EMPTY = 1
}
 
void eth_init()
31,7 → 31,7
//set MAC ADDRESS
REG32(ETH_BASE + ETH_MAC_ADDR1) = (OWN_MAC_ADDRESS_5 << 8) | OWN_MAC_ADDRESS_4; //low word = mac address high word
REG32(ETH_BASE + ETH_MAC_ADDR0) = (OWN_MAC_ADDRESS_3 << 24) | (OWN_MAC_ADDRESS_2 << 16)
| (OWN_MAC_ADDRESS_1 << 8) | OWN_MAC_ADDRESS_0; //mac address rest
| (OWN_MAC_ADDRESS_1 << 8) | OWN_MAC_ADDRESS_0; //mac address rest
 
//configure TXBD0
REG32(ETH_BASE + ETH_TXBD0H) = (unsigned long)eth_tx_packet; //address used for tx_data
59,43 → 59,44
//erase interrupts
REG32(ETH_BASE + ETH_INT_SOURCE) = ETH_RXC | ETH_TXC | ETH_BUSY | ETH_RXE | ETH_RXB | ETH_TXE | ETH_TXB;
 
eth_tx_done = 1;
eth_rx_done = 0;
eth_rx_len = 0;
eth_tx_data = &eth_tx_packet[HDR_LEN];
eth_rx_data = &eth_rx_packet[HDR_LEN];
eth_tx_done = 1;
eth_rx_done = 0;
eth_rx_len = 0;
eth_tx_data = &eth_tx_packet[HDR_LEN];
eth_rx_data = &eth_rx_packet[HDR_LEN];
}
 
int eth_send(int length)
{
if (!eth_tx_done) //if previous command not fully processed, bail out
return -1;
if (!eth_tx_done) //if previous command not fully processed, bail out
return -1;
 
int i;
int i;
 
eth_tx_done = 0;
eth_tx_done = 0;
eth_tx_packet[12] = length >> 8;
eth_tx_packet[13] = length;
 
REG32(ETH_BASE + ETH_TXBD0L) = (( 0x0000FFFF & ( length + HDR_LEN ) ) << 16) | BD_SND;
 
return length;
return length;
}
 
void eth_interrupt()
{
unsigned long source = REG32(ETH_BASE + ETH_INT_SOURCE);
if ( source & ETH_TXB )
{
eth_tx_done = 1;
//erase interrupt
REG32(ETH_BASE + ETH_INT_SOURCE) |= ETH_TXB;
}
if ( source & ETH_RXB )
{
eth_rx_done = 1;
eth_rx_len = (REG32(ETH_BASE + ETH_RXBD0L) >> 16) - HDR_LEN - CRC_LEN;
//erase interrupt
REG32(ETH_BASE + ETH_INT_SOURCE) |= ETH_RXB;
}
unsigned long source = REG32(ETH_BASE + ETH_INT_SOURCE);
if ( source & ETH_TXB )
{
eth_tx_done = 1;
//erase interrupt
REG32(ETH_BASE + ETH_INT_SOURCE) |= ETH_TXB;
}
if ( source & ETH_RXB )
{
eth_rx_done = 1;
eth_rx_len = (REG32(ETH_BASE + ETH_RXBD0L) >> 16) - HDR_LEN - CRC_LEN;
//erase interrupt
REG32(ETH_BASE + ETH_INT_SOURCE) |= ETH_RXB;
}
}
 
/drivers/tick.h
0,0 → 1,4
 
void tick_init(void);
 
void tick_ack(void);
/drivers/interrupts.c
1,3 → 1,4
 
// Dummy or32 except vectors
void buserr_except(){}
void dpf_except(){}
/drivers/uart.h
1,126 → 1,9
#define UART_RX 0 /* In: Receive buffer (DLAB=0) */
#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
#define UART_IER 1 /* Out: Interrupt Enable Register */
#define UART_IIR 2 /* In: Interrupt ID Register */
#define UART_FCR 2 /* Out: FIFO Control Register */
#define UART_EFR 2 /* I/O: Extended Features Register */
/* (DLAB=1, 16C660 only) */
#define UART_LCR 3 /* Out: Line Control Register */
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_LSR 5 /* In: Line Status Register */
#define UART_MSR 6 /* In: Modem Status Register */
#define UART_SCR 7 /* I/O: Scratch Register */
 
/*
* These are the definitions for the FIFO Control Register
* (16650 only)
*/
#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */
#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */
#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */
#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
#include "../support/uart.h"
 
/* 16650 redefinitions */
#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */
#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */
#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */
#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */
#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */
#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */
#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */
#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */
 
/*
* These are the definitions for the Line Control Register
*
* Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
* UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
*/
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_LCR_SBC 0x40 /* Set break control */
#define UART_LCR_SPAR 0x20 /* Stick parity (?) */
#define UART_LCR_EPAR 0x10 /* Even parity select */
#define UART_LCR_PARITY 0x08 /* Parity Enable */
#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 stop bit, 1= 2 stop bits */
#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */
#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */
#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
 
/*
* These are the definitions for the Line Status Register
*/
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
#define UART_LSR_FE 0x08 /* Frame error indicator */
#define UART_LSR_PE 0x04 /* Parity error indicator */
#define UART_LSR_OE 0x02 /* Overrun error indicator */
#define UART_LSR_DR 0x01 /* Receiver data ready */
 
/*
* These are the definitions for the Interrupt Identification Register
*/
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
 
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
#define UART_IIR_TOI 0x0c /* Receive time out interrupt */
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
 
/*
* These are the definitions for the Interrupt Enable Register
*/
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
 
/*
* These are the definitions for the Modem Control Register
*/
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
#define UART_MCR_OUT2 0x08 /* Out2 complement */
#define UART_MCR_OUT1 0x04 /* Out1 complement */
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR complement */
 
/*
* These are the definitions for the Modem Status Register
*/
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
#define UART_MSR_RI 0x40 /* Ring Indicator */
#define UART_MSR_DSR 0x20 /* Data Set Ready */
#define UART_MSR_CTS 0x10 /* Clear to Send */
#define UART_MSR_DDCD 0x08 /* Delta DCD */
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
#define UART_MSR_DDSR 0x02 /* Delta DSR */
#define UART_MSR_DCTS 0x01 /* Delta CTS */
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
 
/*
* These are the definitions for the Extended Features Register
* (StarTech 16C660 only, when DLAB=1)
*/
#define UART_EFR_CTS 0x80 /* CTS flow control */
#define UART_EFR_RTS 0x40 /* RTS flow control */
#define UART_EFR_SCD 0x20 /* Special character detect */
#define UART_EFR_ENI 0x10 /* Enhanced Interrupt */
 
 
void uart_init(void);
void uart_putc(char);
char uart_getc(void);
void uart_print_str(char *);
void uart_print_long(unsigned long);
 
void uart_interrupt();
void uart_print_short(unsigned long ul);
 
/drivers/can.c
3,6 → 3,7
#include "can.h"
 
int can_rx_done, can_tx_done;
 
int can_rx_rd_ptr;
int can_rx_wr_ptr;
int can_rx_buf_overflow;
11,139 → 12,139
 
can_type * can_get(void)
{
if ( !can_rx_done )
return NULL;
if ( !can_rx_done )
return NULL;
 
can_rx_done--;
can_rx_done--;
 
int tmp;
tmp = can_rx_rd_ptr;
int tmp;
tmp = can_rx_rd_ptr;
 
if (can_rx_rd_ptr < CAN_BUF_LEN-1)
can_rx_rd_ptr++;
else
can_rx_rd_ptr = 0;
if (can_rx_rd_ptr < CAN_BUF_LEN-1)
can_rx_rd_ptr++;
else
can_rx_rd_ptr = 0;
 
return &can_rx_data[tmp];
return &can_rx_data[tmp];
}
 
void can_init(void)
{
unsigned char sync_jmp, baudrate_presc, timing_seg1, timing_seg2, tripple_samp = 0;
unsigned char acpt_code, acpt_mask = 0;
unsigned char clk_div = 0 & CAN_BUS_CLKDIV_MASK;
unsigned char sync_jmp, baudrate_presc, timing_seg1, timing_seg2, tripple_samp = 0;
unsigned char acpt_code, acpt_mask = 0;
unsigned char clk_div = 0 & CAN_BUS_CLKDIV_MASK;
 
sync_jmp = 1;
baudrate_presc = 1;
timing_seg1 = 11;
timing_seg2 = 2;
tripple_samp = 1;
sync_jmp = 1;
baudrate_presc = 1;
timing_seg1 = 11;
timing_seg2 = 2;
tripple_samp = 1;
 
acpt_code = 0x81;
acpt_mask = 0xFF;
acpt_code = 0x81;
acpt_mask = 0xFF;
 
char timing0, timing1 = 0;
char timing0, timing1 = 0;
 
timing0 = (sync_jmp << CAN_BUS_TIMING_0_SYNC_JMP_SHIFT) & CAN_BUS_TIMING_0_SYNC_JMP;
timing0 |= baudrate_presc & CAN_BUS_TIMING_0_BAUD_PRESC;
timing0 = (sync_jmp << CAN_BUS_TIMING_0_SYNC_JMP_SHIFT) & CAN_BUS_TIMING_0_SYNC_JMP;
timing0 |= baudrate_presc & CAN_BUS_TIMING_0_BAUD_PRESC;
 
timing1 = (tripple_samp << CAN_BUS_TIMING_1_TRIPLE_SAMP_SHIFT) & CAN_BUS_TIMING_1_TRIPLE_SAMP;
timing1 |= (timing_seg2 << CAN_BUS_TIMING_1_TIME_SEG2_SHIFT) & CAN_BUS_TIMING_1_TIME_SEG2;
timing1 |= timing_seg1 & CAN_BUS_TIMING_1_TIME_SEG1;
timing1 = (tripple_samp << CAN_BUS_TIMING_1_TRIPLE_SAMP_SHIFT) & CAN_BUS_TIMING_1_TRIPLE_SAMP;
timing1 |= (timing_seg2 << CAN_BUS_TIMING_1_TIME_SEG2_SHIFT) & CAN_BUS_TIMING_1_TIME_SEG2;
timing1 |= timing_seg1 & CAN_BUS_TIMING_1_TIME_SEG1;
 
REG8(CAN_BASE+CAN_MODE) = CAN_MODE_RESET;
REG8(CAN_BASE+CAN_MODE) = CAN_MODE_RESET;
 
REG8(CAN_BASE+CAN_BUS_TIMING_0) = timing0;
REG8(CAN_BASE+CAN_BUS_TIMING_1) = timing1;
REG8(CAN_BASE+CAN_BUS_TIMING_0) = timing0;
REG8(CAN_BASE+CAN_BUS_TIMING_1) = timing1;
 
REG8(CAN_BASE+CAN_ACPT_CODE0) = acpt_code;
REG8(CAN_BASE+CAN_ACPT_MASK0) = acpt_mask;
REG8(CAN_BASE+CAN_ACPT_CODE0) = acpt_code;
REG8(CAN_BASE+CAN_ACPT_MASK0) = acpt_mask;
 
REG8(CAN_BASE+CAN_BUS_MODE) &= ~CAN_BUS_MODE_CLOCK_OFF & ~CAN_BUS_MODE_EXTENDED_MODE;
REG8(CAN_BASE+CAN_BUS_MODE) &= ~CAN_BUS_MODE_CLOCK_OFF & ~CAN_BUS_MODE_EXTENDED_MODE;
 
REG8(CAN_BASE+CAN_MODE) &= ~CAN_MODE_RESET;
REG8(CAN_BASE+CAN_BUS_CLKDIV) = clk_div;
REG8(CAN_BASE+CAN_MODE) &= ~CAN_MODE_RESET;
REG8(CAN_BASE+CAN_BUS_CLKDIV) = clk_div;
 
REG8(CAN_BASE+CAN_MODE) |= CAN_MODE_TX_IRQ_EN | CAN_MODE_RECV_IRQ_EN;
REG8(CAN_BASE+CAN_MODE) |= CAN_MODE_TX_IRQ_EN | CAN_MODE_RECV_IRQ_EN;
 
can_tx_done = 1;
can_rx_done = 0;
can_rx_rd_ptr = 0;
can_rx_wr_ptr = 0;
can_rx_buf_overflow = 0;
can_tx_done = 1;
can_rx_done = 0;
can_rx_rd_ptr = 0;
can_rx_wr_ptr = 0;
can_rx_buf_overflow = 0;
}
 
void can_recv_basic()
{
unsigned char byte0, byte1;
unsigned char byte0, byte1;
 
byte0 = REG8(CAN_BASE+CAN_RX_BUF);
byte1 = REG8(CAN_BASE+CAN_RX_BUF+1);
byte0 = REG8(CAN_BASE+CAN_RX_BUF);
byte1 = REG8(CAN_BASE+CAN_RX_BUF+1);
 
can_rx_data[can_rx_wr_ptr].data[0] = REG8(CAN_BASE+CAN_RX_BUF+2);
can_rx_data[can_rx_wr_ptr].data[1] = REG8(CAN_BASE+CAN_RX_BUF+3);
can_rx_data[can_rx_wr_ptr].data[2] = REG8(CAN_BASE+CAN_RX_BUF+4);
can_rx_data[can_rx_wr_ptr].data[3] = REG8(CAN_BASE+CAN_RX_BUF+5);
can_rx_data[can_rx_wr_ptr].data[4] = REG8(CAN_BASE+CAN_RX_BUF+6);
can_rx_data[can_rx_wr_ptr].data[5] = REG8(CAN_BASE+CAN_RX_BUF+7);
can_rx_data[can_rx_wr_ptr].data[6] = REG8(CAN_BASE+CAN_RX_BUF+8);
can_rx_data[can_rx_wr_ptr].data[7] = REG8(CAN_BASE+CAN_RX_BUF+9);
can_rx_data[can_rx_wr_ptr].data[0] = REG8(CAN_BASE+CAN_RX_BUF+2);
can_rx_data[can_rx_wr_ptr].data[1] = REG8(CAN_BASE+CAN_RX_BUF+3);
can_rx_data[can_rx_wr_ptr].data[2] = REG8(CAN_BASE+CAN_RX_BUF+4);
can_rx_data[can_rx_wr_ptr].data[3] = REG8(CAN_BASE+CAN_RX_BUF+5);
can_rx_data[can_rx_wr_ptr].data[4] = REG8(CAN_BASE+CAN_RX_BUF+6);
can_rx_data[can_rx_wr_ptr].data[5] = REG8(CAN_BASE+CAN_RX_BUF+7);
can_rx_data[can_rx_wr_ptr].data[6] = REG8(CAN_BASE+CAN_RX_BUF+8);
can_rx_data[can_rx_wr_ptr].data[7] = REG8(CAN_BASE+CAN_RX_BUF+9);
 
REG8(CAN_BASE+CAN_CMD) = CAN_CMD_RELEASE_BUFFER;
REG8(CAN_BASE+CAN_CMD) = CAN_CMD_RELEASE_BUFFER;
 
can_rx_data[can_rx_wr_ptr].identifier = (byte0 << 3) | (byte1 >> 5);
can_rx_data[can_rx_wr_ptr].rtr = byte1 & 0x10;
can_rx_data[can_rx_wr_ptr].len = byte1 & 0x0F;
can_rx_data[can_rx_wr_ptr].identifier = (byte0 << 3) | (byte1 >> 5);
can_rx_data[can_rx_wr_ptr].rtr = byte1 & 0x10;
can_rx_data[can_rx_wr_ptr].len = byte1 & 0x0F;
 
if (can_rx_wr_ptr < CAN_BUF_LEN-1)
can_rx_wr_ptr++;
else
can_rx_wr_ptr = 0;
if (can_rx_wr_ptr < CAN_BUF_LEN-1)
can_rx_wr_ptr++;
else
can_rx_wr_ptr = 0;
 
if (can_rx_wr_ptr == can_rx_rd_ptr+1) //buffer overflow
{
can_rx_done = 1;
can_rx_buf_overflow++;
}
else
can_rx_done++;
if (can_rx_wr_ptr == can_rx_rd_ptr+1) //buffer overflow
{
can_rx_done = 1;
can_rx_buf_overflow++;
}
else
can_rx_done++;
}
 
int can_send_basic()
{
if (!can_tx_done) //if previous command not fully processed, bail out
return -1;
if (!can_tx_done) //if previous command not fully processed, bail out
return -1;
 
can_tx_done = 0;
REG8(CAN_BASE+CAN_TX_BUF) = can_tx_data.identifier >> 3;
REG8(CAN_BASE+CAN_TX_BUF+1) = (can_tx_data.identifier << 5) | ((can_tx_data.rtr << 4) & 0x10) | (can_tx_data.len & 0x0F);
can_tx_done = 0;
REG8(CAN_BASE+CAN_TX_BUF) = can_tx_data.identifier >> 3;
REG8(CAN_BASE+CAN_TX_BUF+1) = (can_tx_data.identifier << 5) | ((can_tx_data.rtr << 4) & 0x10) | (can_tx_data.len & 0x0F);
 
REG8(CAN_BASE+CAN_TX_BUF+2) = can_tx_data.data[0];
REG8(CAN_BASE+CAN_TX_BUF+3) = can_tx_data.data[1];
REG8(CAN_BASE+CAN_TX_BUF+4) = can_tx_data.data[2];
REG8(CAN_BASE+CAN_TX_BUF+5) = can_tx_data.data[3];
REG8(CAN_BASE+CAN_TX_BUF+6) = can_tx_data.data[4];
REG8(CAN_BASE+CAN_TX_BUF+7) = can_tx_data.data[5];
REG8(CAN_BASE+CAN_TX_BUF+8) = can_tx_data.data[6];
REG8(CAN_BASE+CAN_TX_BUF+9) = can_tx_data.data[7];
REG8(CAN_BASE+CAN_TX_BUF+2) = can_tx_data.data[0];
REG8(CAN_BASE+CAN_TX_BUF+3) = can_tx_data.data[1];
REG8(CAN_BASE+CAN_TX_BUF+4) = can_tx_data.data[2];
REG8(CAN_BASE+CAN_TX_BUF+5) = can_tx_data.data[3];
REG8(CAN_BASE+CAN_TX_BUF+6) = can_tx_data.data[4];
REG8(CAN_BASE+CAN_TX_BUF+7) = can_tx_data.data[5];
REG8(CAN_BASE+CAN_TX_BUF+8) = can_tx_data.data[6];
REG8(CAN_BASE+CAN_TX_BUF+9) = can_tx_data.data[7];
 
REG8(CAN_BASE+CAN_CMD) = CAN_CMD_TX_REQ;
REG8(CAN_BASE+CAN_CMD) = CAN_CMD_TX_REQ;
 
return can_tx_data.len;
return can_tx_data.len;
}
 
void can_irq(void)
{
unsigned char irq_req, rx_done;
irq_req = REG8(CAN_BASE+IRQ_READ);
rx_done = irq_req & CAN_IRQ_READ_RX;
can_tx_done = irq_req & CAN_IRQ_READ_TX;
if (rx_done)
can_recv_basic();
unsigned char irq_req, rx_done;
irq_req = REG8(CAN_BASE+IRQ_READ);
rx_done = irq_req & CAN_IRQ_READ_RX;
can_tx_done = irq_req & CAN_IRQ_READ_TX;
if (rx_done)
can_recv_basic();
}
 
void can_abort(void)
{
REG8(CAN_BASE+CAN_CMD) = CAN_CMD_ABORT_TX;
REG8(CAN_BASE+CAN_CMD) = CAN_CMD_ABORT_TX;
}
 
/drivers/i2c.h
1,3 → 1,4
 
struct i2c_type
{
unsigned char address;
15,8 → 16,8
typedef struct i2c_type i2c_type;
typedef struct i2c_mode i2c_mode;
 
#define I2C_BUF_LEN 10
 
 
void i2c_init(void);
void i2c_irq(void);
 
25,36 → 26,37
void i2c_set_ack_lvl(int ack_lvl, int final_ack_lvl);
int i2c_trans(i2c_mode * mode, i2c_type * data); //return (-1) or length (still processing previous) or asserted
 
#define I2C_BUF_LEN 10
#define I2C_PRESC_LO 0x00
#define I2C_PRESC_HI 0x01
#define I2C_PRESC_LO 0x00
#define I2C_PRESC_HI 0x01
 
#define I2C_CTR 0x02
#define I2C_CTR 0x02
 
#define I2C_TXR 0x03
#define I2C_RXR 0x03
#define I2C_TXR 0x03
#define I2C_RXR 0x03
 
#define I2C_CR 0x04
#define I2C_SR 0x04
#define I2C_CR 0x04
#define I2C_SR 0x04
 
 
//BITS
#define I2C_CTR_EN 0x80
#define I2C_CTR_IRQ_EN 0x40
#define I2C_CTR_EN 0x80
#define I2C_CTR_IRQ_EN 0x40
 
#define I2C_TXR_ADR 0xFE
#define I2C_TXR_W 0x00
#define I2C_TXR_R 0x01
#define I2C_TXR_ADR 0xFE
#define I2C_TXR_W 0x00
#define I2C_TXR_R 0x01
 
#define I2C_CR_STA 0x80
#define I2C_CR_STO 0x40
#define I2C_CR_RD 0x20
#define I2C_CR_WR 0x10
#define I2C_CR_ACK 0x00
#define I2C_CR_NACK 0x08
#define I2C_CR_CLR_IRQ 0x01
#define I2C_CR_STA 0x80
#define I2C_CR_STO 0x40
#define I2C_CR_RD 0x20
#define I2C_CR_WR 0x10
#define I2C_CR_ACK 0x00
#define I2C_CR_NACK 0x08
#define I2C_CR_CLR_IRQ 0x01
 
#define I2C_SR_R_ACK 0x80
#define I2C_SR_BUSY 0x40
#define I2C_SR_ARB_LOST 0x20
#define I2C_SR_TX_BUSY 0x02
#define I2C_SR_IRQ_FLAG 0x01
#define I2C_SR_R_ACK 0x80
#define I2C_SR_BUSY 0x40
#define I2C_SR_ARB_LOST 0x20
#define I2C_SR_TX_BUSY 0x02
#define I2C_SR_IRQ_FLAG 0x01
 
/drivers/eth.h
1,3 → 1,4
 
void eth_init();
void eth_interrupt();
void eth_recv_ack(void);
4,26 → 5,26
 
int eth_send(int length); //return (-1) or length (still processing previous) or asserted
 
#define ETH_MODER 0x00
#define ETH_INT_SOURCE 0x04
#define ETH_INT_MASK 0x08
#define ETH_IPGT 0x0C
#define ETH_IPGR1 0x10
#define ETH_IPGR2 0x14
#define ETH_PACKETLEN 0x18
#define ETH_COLLCONF 0x1C
#define ETH_TX_BD_NUM 0x20
#define ETH_CTRLMODER 0x24
#define ETH_MIIMODER 0x28
#define ETH_MIICOMMAND 0x2C
#define ETH_MIIADDRESS 0x30
#define ETH_MIITX_DATA 0x34
#define ETH_MIIRX_DATA 0x38
#define ETH_MIISTATUS 0x3C
#define ETH_MAC_ADDR0 0x40
#define ETH_MAC_ADDR1 0x44
#define ETH_HASH0_ADR 0x48
#define ETH_HASH1_ADR 0x4C
#define ETH_MODER 0x00
#define ETH_INT_SOURCE 0x04
#define ETH_INT_MASK 0x08
#define ETH_IPGT 0x0C
#define ETH_IPGR1 0x10
#define ETH_IPGR2 0x14
#define ETH_PACKETLEN 0x18
#define ETH_COLLCONF 0x1C
#define ETH_TX_BD_NUM 0x20
#define ETH_CTRLMODER 0x24
#define ETH_MIIMODER 0x28
#define ETH_MIICOMMAND 0x2C
#define ETH_MIIADDRESS 0x30
#define ETH_MIITX_DATA 0x34
#define ETH_MIIRX_DATA 0x38
#define ETH_MIISTATUS 0x3C
#define ETH_MAC_ADDR0 0x40
#define ETH_MAC_ADDR1 0x44
#define ETH_HASH0_ADR 0x48
#define ETH_HASH1_ADR 0x4C
#define ETH_TXCTRL 0x50
 
#define ETH_TXBD0H 0x404
33,11 → 34,11
#define ETH_RXBD0L 0x600 //this depends on TX_BD_NUM but this is the standard value
 
//MODER BITS
#define ETH_RECSMAL 0x00010000
#define ETH_RECSMALL 0x00010000
#define ETH_PAD 0x00008000
#define ETH_HUGEN 0x00004000
#define ETH_CRCEN 0x00002000
#define ETH_DLYCRCEN 0x00001000
#define ETH_DLYCRCEN 0x00001000
#define ETH_FULLD 0x00000400
#define ETH_EXDFREN 0x00000200
#define ETH_NOBCKOF 0x00000100
60,24 → 61,24
#define ETH_TXB 0x00000001
 
//BUFFER DESCRIPTOR BITS
#define ETH_RXBD_EMPTY 0x00008000
#define ETH_RXBD_IRQ 0x00004000
#define ETH_RXBD_WRAP 0x00002000
#define ETH_RXBD_EMPTY 0x00008000
#define ETH_RXBD_IRQ 0x00004000
#define ETH_RXBD_WRAP 0x00002000
#define ETH_RXBD_CF 0x00000100
#define ETH_RXBD_MISS 0x00000080
#define ETH_RXBD_MISS 0x00000080
#define ETH_RXBD_OR 0x00000040
#define ETH_RXBD_IS 0x00000020
#define ETH_RXBD_DN 0x00000010
#define ETH_RXBD_TL 0x00000008
#define ETH_RXBD_SF 0x00000004
#define ETH_RXBD_CRC 0x00000002
#define ETH_RXBD_CRC 0x00000002
#define ETH_RXBD_LC 0x00000001
 
#define ETH_TXBD_READY 0x00008000
#define ETH_TXBD_IRQ 0x00004000
#define ETH_TXBD_WRAP 0x00002000
#define ETH_TXBD_PAD 0x00001000
#define ETH_TXBD_CRC 0x00000800
#define ETH_TXBD_READY 0x00008000
#define ETH_TXBD_IRQ 0x00004000
#define ETH_TXBD_WRAP 0x00002000
#define ETH_TXBD_PAD 0x00001000
#define ETH_TXBD_CRC 0x00000800
#define ETH_TXBD_UR 0x00000100
#define ETH_TXBD_RL 0x00000008
#define ETH_TXBD_LC 0x00000004
99,10 → 100,12
#define BROADCAST_ADDRESS_1 0xFF
#define BROADCAST_ADDRESS_0 0xFF
 
#define HDR_LEN 14
#define CRC_LEN 4
#define HDR_LEN 14
#define CRC_LEN 4
#define BD_SND ( ETH_TXBD_READY | ETH_TXBD_IRQ | ETH_TXBD_WRAP | ETH_TXBD_PAD | ETH_TXBD_CRC )
#define RX_READY ( ETH_RXBD_EMPTY | ETH_RXBD_IRQ | ETH_RXBD_WRAP )
#define TX_READY ( ETH_TXBD_IRQ | ETH_TXBD_WRAP | ETH_TXBD_PAD | ETH_TXBD_CRC )
 
//~user defines
 
 
/drivers/can.h
1,9 → 1,10
 
struct can_type
{
unsigned char rtr;
unsigned char len;
unsigned short identifier;
unsigned char data[8];
unsigned char rtr;
unsigned char len;
unsigned short identifier;
unsigned char data[8];
};
 
typedef struct can_type can_type;
146,11 → 147,12
#define CAN_IRQ_EN_EXT_RX 0x01
 
//EXTENDED ERROR CODES
#define CAN_ERROR_CAPTURE_CODE_TYPE_SHIFT 6
#define CAN_ERROR_CAPTURE_CODE_TYPE 0xC0
#define CAN_ERROR_CAPTURE_CODE_TYPE_BIT 0x0
#define CAN_ERROR_CAPTURE_CODE_TYPE_FORM 0x1
#define CAN_ERROR_CAPTURE_CODE_TYPE_STUFF 0x2
#define CAN_ERROR_CAPTURE_CODE_TYPE_OTHER 0x3
#define CAN_ERROR_CAPTURE_CODE_DIR 0x40 //1 = TX | 0 = RX
#define CAN_ERROR_CAPTURE_CODE_SEG 0x1F
#define CAN_ERROR_CAPTURE_CODE_TYPE_SHIFT 6
#define CAN_ERROR_CAPTURE_CODE_TYPE 0xC0
#define CAN_ERROR_CAPTURE_CODE_TYPE_BIT 0x0
#define CAN_ERROR_CAPTURE_CODE_TYPE_FORM 0x1
#define CAN_ERROR_CAPTURE_CODE_TYPE_STUFF 0x2
#define CAN_ERROR_CAPTURE_CODE_TYPE_OTHER 0x3
#define CAN_ERROR_CAPTURE_CODE_DIR 0x40 //1 = TX | 0 = RX
#define CAN_ERROR_CAPTURE_CODE_SEG 0x1F
 
/drivers/tick.c
0,0 → 1,31
#include "../support/spr_defs.h"
#include "../support/support.h"
#include "tick.h"
 
int tick_int;
 
void tick_ack(void)
{
tick_int--;
}
 
void tick_init(void)
{
mtspr(SPR_TTMR, 25000000 & SPR_TTMR_PERIOD); //1s
// mtspr(SPR_TTMR, 125000 & SPR_TTMR_PERIOD); //5ms
mtspr(SPR_TTMR, mfspr(SPR_TTMR) | SPR_TTMR_RT | SPR_TTMR_IE); //restart after match, enable interrupt
mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~(SPR_TTMR_IP)); //clears interrupt
//set OR1200 to accept exceptions
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
tick_int = 0;
}
 
void tick_except(void)
{
tick_int++;
mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~(SPR_TTMR_IP)); //clears interrupt
}
 
/drivers/uart.c
1,141 → 1,68
#include "../support/board.h"
#include "../support/support.h"
#include "../support/uart.h"
#include "uart.h"
 
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
 
#define WAIT_FOR_XMITR \
do { \
lsr = REG8(UART_BASE + UART_LSR); \
} while ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
 
#define WAIT_FOR_THRE \
do { \
lsr = REG8(UART_BASE + UART_LSR); \
} while ((lsr & UART_LSR_THRE) != UART_LSR_THRE)
 
#define CHECK_FOR_CHAR (REG8(UART_BASE + UART_LSR) & UART_LSR_DR)
 
#define WAIT_FOR_CHAR \
do { \
lsr = REG8(UART_BASE + UART_LSR); \
} while ((lsr & UART_LSR_DR) != UART_LSR_DR)
 
#define UART_TX_BUFF_LEN 32
#define UART_TX_BUFF_MASK (UART_TX_BUFF_LEN -1)
 
char tx_buff[UART_TX_BUFF_LEN];
volatile int tx_level, rx_level;
 
void uart_init(void)
{
int divisor;
 
/* Reset receiver and transmiter */
/* Set RX interrupt for each byte */
REG8(UART_BASE + UART_FCR) = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_1;
 
/* Enable RX interrupt */
REG8(UART_BASE + UART_IER) = UART_IER_RDI | UART_IER_THRI;
 
/* Set 8 bit char, 1 stop bit, no parity */
REG8(UART_BASE + UART_LCR) = UART_LCR_WLEN8 & ~(UART_LCR_STOP | UART_LCR_PARITY);
 
/* Set baud rate */
divisor = IN_CLK/(16 * UART_BAUD_RATE);
REG8(UART_BASE + UART_LCR) |= UART_LCR_DLAB;
REG8(UART_BASE + UART_DLM) = (divisor >> 8) & 0x000000ff;
REG8(UART_BASE + UART_DLL) = divisor & 0x000000ff;
REG8(UART_BASE + UART_LCR) &= ~(UART_LCR_DLAB);
 
return;
}
 
void uart_putc(char c)
{
unsigned char lsr;
 
WAIT_FOR_THRE;
REG8(UART_BASE + UART_TX) = c;
if(c == '\n') {
WAIT_FOR_THRE;
REG8(UART_BASE + UART_TX) = '\r';
}
WAIT_FOR_XMITR;
}
 
 
 
char uart_getc()
{
unsigned char lsr;
char c;
 
// WAIT_FOR_CHAR;
c = REG8(UART_BASE + UART_RX);
return c;
}
 
 
void uart_interrupt()
{
char lala;
unsigned char interrupt_id;
interrupt_id = REG8(UART_BASE + UART_IIR);
if ( interrupt_id & UART_IIR_RDI )
{
lala = uart_getc();
uart_putc(lala+1);
}
char lala;
unsigned char interrupt_id;
interrupt_id = REG8(UART_BASE + UART_IIR);
if ( interrupt_id & UART_IIR_RDI )
{
lala = uart_getc();
uart_putc(lala+1);
}
 
}
 
void uart_print_str(char *p)
{
while(*p != 0) {
uart_putc(*p);
p++;
}
while(*p != 0) {
uart_putc(*p);
p++;
}
}
 
void uart_print_long(unsigned long ul)
{
int i;
char c;
int i;
char c;
 
uart_print_str("0x");
for(i=0; i<8; i++) {
 
uart_print_str("0x");
for(i=0; i<8; i++) {
c = (char) (ul>>((7-i)*4)) & 0xf;
if(c >= 0x0 && c<=0x9)
c += '0';
else
c += 'a' - 10;
uart_putc(c);
}
 
c = (char) (ul>>((7-i)*4)) & 0xf;
if(c >= 0x0 && c<=0x9)
c += '0';
else
c += 'a' - 10;
uart_putc(c);
}
 
}
 
void uart_print_short(unsigned long ul)
{
int i;
char c;
char flag=0;
int i;
char c;
char flag=0;
 
uart_print_str("0x");
for(i=0; i<8; i++) {
 
uart_print_str("0x");
for(i=0; i<8; i++) {
c = (char) (ul>>((7-i)*4)) & 0xf;
if(c >= 0x0 && c<=0x9)
c += '0';
else
c += 'a' - 10;
if ((c != '0') || (i==7))
flag=1;
if(flag)
uart_putc(c);
}
 
c = (char) (ul>>((7-i)*4)) & 0xf;
if(c >= 0x0 && c<=0x9)
c += '0';
else
c += 'a' - 10;
if ((c != '0') || (i==7))
flag=1;
if(flag)
uart_putc(c);
}
}
 
}
/drivers/Makefile
1,7 → 1,7
all: libdrivers.a
 
libdrivers.a: eth.o uart.o interrupts.o can.o i2c.o
$(OR32_TOOL_PREFIX)-ar cru libdrivers.a eth.o uart.o interrupts.o can.o i2c.o
libdrivers.a: eth.o uart.o interrupts.o can.o i2c.o tick.o
$(OR32_TOOL_PREFIX)-ar cru libdrivers.a eth.o uart.o interrupts.o can.o i2c.o tick.o
$(OR32_TOOL_PREFIX)-ranlib libdrivers.a
 
eth.o: eth.c
19,4 → 19,7
i2c.o: i2c.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $? -c -o $@
 
tick.o: tick.c
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $? -c -o $@
 
include ../support/Makefile.inc
/drivers/i2c.c
19,147 → 19,148
 
i2c_type * i2c_get(void)
{
if ( !i2c_rd_done )
return NULL;
if ( !i2c_rd_done )
return NULL;
 
i2c_rd_done--;
i2c_rd_done--;
 
int tmp;
tmp = i2c_rd_ptr;
int tmp;
tmp = i2c_rd_ptr;
 
if (i2c_rd_ptr < I2C_BUF_LEN-1)
i2c_rd_ptr++;
else
i2c_rd_ptr = 0;
if (i2c_rd_ptr < I2C_BUF_LEN-1)
i2c_rd_ptr++;
else
i2c_rd_ptr = 0;
 
return &i2c_data[tmp];
return &i2c_data[tmp];
}
 
void i2c_init(void)
{
REG8(I2C_BASE+I2C_PRESC_HI) = 0x00;
REG8(I2C_BASE+I2C_PRESC_LO) = 49; //100kHz
REG8(I2C_BASE+I2C_CTR) = I2C_CTR_EN | I2C_CTR_IRQ_EN;
i2c_rd_done = 0;
i2c_wr_done = 0;
i2c_index = 0;
i2c_wr_ptr = 0;
i2c_rd_ptr = 0;
i2c_buf_overflow = 0;
REG8(I2C_BASE+I2C_PRESC_HI) = 0x00;
REG8(I2C_BASE+I2C_PRESC_LO) = 49; //100kHz
REG8(I2C_BASE+I2C_CTR) = I2C_CTR_EN | I2C_CTR_IRQ_EN;
i2c_rd_done = 0;
i2c_wr_done = 0;
i2c_index = 0;
i2c_wr_ptr = 0;
i2c_rd_ptr = 0;
i2c_buf_overflow = 0;
}
 
void i2c_set_ack_lvl(int ack_lvl, int final_ack_lvl)
{
int ack, final_ack;
int ack, final_ack;
 
ack = ( ack_lvl ) ? I2C_CR_NACK : I2C_CR_ACK;
final_ack = ( final_ack_lvl ) ? I2C_CR_NACK : I2C_CR_ACK;
ack = ( ack_lvl ) ? I2C_CR_NACK : I2C_CR_ACK;
final_ack = ( final_ack_lvl ) ? I2C_CR_NACK : I2C_CR_ACK;
 
start = I2C_CR_STA | I2C_CR_WR | ack;
pointer_write = I2C_CR_WR | ack;
write_hbyte = I2C_CR_WR | ack;
write_lbyte = I2C_CR_WR | I2C_CR_STO | final_ack;
read_hbyte = I2C_CR_RD | ack;
read_lbyte = I2C_CR_RD | I2C_CR_STO | final_ack;
start = I2C_CR_STA | I2C_CR_WR | ack;
pointer_write = I2C_CR_WR | ack;
write_hbyte = I2C_CR_WR | ack;
write_lbyte = I2C_CR_WR | I2C_CR_STO | final_ack;
read_hbyte = I2C_CR_RD | ack;
read_lbyte = I2C_CR_RD | I2C_CR_STO | final_ack;
}
 
void i2c_byte_transfer(void)
{
if ( i2c_index > 0 )
if ( cmd_list[i2c_index-1] == read_hbyte )
i2c_data[i2c_wr_ptr].data = (REG8(I2C_BASE+I2C_RXR) << 8) & 0xFF00;
if ( i2c_index > 0 )
if ( cmd_list[i2c_index-1] == read_hbyte )
i2c_data[i2c_wr_ptr].data = (REG8(I2C_BASE+I2C_RXR) << 8) & 0xFF00;
REG8(I2C_BASE+I2C_TXR) = dat_list[i2c_index];
REG8(I2C_BASE+I2C_CR) = cmd_list[i2c_index];
 
REG8(I2C_BASE+I2C_TXR) = dat_list[i2c_index];
REG8(I2C_BASE+I2C_CR) = cmd_list[i2c_index];
 
i2c_index++;
i2c_index++;
}
 
void i2c_irq(void)
{
REG8(I2C_BASE+I2C_CR) = I2C_CR_CLR_IRQ;
if (i2c_index <= i2c_end )
i2c_byte_transfer();
else
{
if ( cmd_list[i2c_index-1] == read_lbyte )
i2c_data[i2c_wr_ptr].data |= REG8(I2C_BASE+I2C_RXR);
REG8(I2C_BASE+I2C_CR) = I2C_CR_CLR_IRQ;
if (i2c_index <= i2c_end )
i2c_byte_transfer();
else
{
if ( cmd_list[i2c_index-1] == read_lbyte )
i2c_data[i2c_wr_ptr].data |= REG8(I2C_BASE+I2C_RXR);
 
i2c_index = 0;
i2c_index = 0;
 
if ( i2c_pending_write )
i2c_wr_done = 1;
else
{
if (i2c_wr_ptr < I2C_BUF_LEN-1)
i2c_wr_ptr++;
else
i2c_wr_ptr = 0;
if ( i2c_pending_write )
i2c_wr_done = 1;
else
{
if (i2c_wr_ptr < I2C_BUF_LEN-1)
i2c_wr_ptr++;
else
i2c_wr_ptr = 0;
 
if (i2c_wr_ptr == i2c_rd_ptr+1)
{
i2c_rd_done = 1;
i2c_buf_overflow++;
}
else
i2c_rd_done++;
}
}
if (i2c_wr_ptr == i2c_rd_ptr+1)
{
i2c_rd_done = 1;
i2c_buf_overflow++;
}
else
i2c_rd_done++;
}
}
}
 
int i2c_trans(i2c_mode * mode, i2c_type * data)
{
if ( i2c_index != 0 ) //if previous command not fully processed, bail out
return -1;
if ( i2c_index != 0 ) //if previous command not fully processed, bail out
return -1;
 
i2c_wr_done = 0;
i2c_wr_done = 0;
 
int i = 0;
int i = 0;
 
if ( mode->ptr_set || mode->read_write ) //start conditions with pointer set: (write always set ptr)
{
if ( mode->ptr_set || mode->read_write ) //start conditions with pointer set: (write always set ptr)
{
dat_list[i] = (data->address << 1) & I2C_TXR_ADR;
dat_list[i] |= I2C_TXR_W;
cmd_list[i++] = start;
 
dat_list[i] = data->pointer;
cmd_list[i++] = pointer_write;
dat_list[i] = data->pointer;
cmd_list[i++] = pointer_write;
if ( !mode->read_write ) //REstart for read, NO-REstart for write
{
dat_list[i] = (data->address << 1) & I2C_TXR_ADR;
dat_list[i] |= I2C_TXR_R;
cmd_list[i++] = start;
}
}
else //start conditions with NO pointer set (read only): ONE start
{
dat_list[i] = (data->address << 1) & I2C_TXR_ADR;
dat_list[i] |= I2C_TXR_R;
cmd_list[i++] = start;
}
 
if ( !mode->read_write ) //REstart for read, NO-REstart for write
{
dat_list[i] = (data->address << 1) & I2C_TXR_ADR;
dat_list[i] |= I2C_TXR_R;
cmd_list[i++] = start;
}
}
else //start conditions with NO pointer set (read only): ONE start
{
dat_list[i] = (data->address << 1) & I2C_TXR_ADR;
dat_list[i] |= I2C_TXR_R;
cmd_list[i++] = start;
}
if ( mode->byte_word ) //read/write high byte
{
dat_list[i] = data->data >> 8;
cmd_list[i++] = (mode->read_write) ? write_hbyte : read_hbyte;
}
dat_list[i] = data->data; //read/write low byte
cmd_list[i] = (mode->read_write) ? write_lbyte : read_lbyte;
 
if ( mode->byte_word ) //read/write high byte
{
dat_list[i] = data->data >> 8;
cmd_list[i++] = (mode->read_write) ? write_hbyte : read_hbyte;
}
i2c_end = i;
 
dat_list[i] = data->data; //read/write low byte
cmd_list[i] = (mode->read_write) ? write_lbyte : read_lbyte;
if ( !mode->read_write ) //set data to 0 for read, avoid or implications ((short)data |= byte)
{
i2c_data[i2c_wr_ptr] = *data;
i2c_data[i2c_wr_ptr].data = 0x0000;
}
 
i2c_end = i;
i2c_pending_write = mode->read_write;
 
if ( !mode->read_write ) //set data to 0 for read, avoid or implications ((short)data |= byte)
{
i2c_data[i2c_wr_ptr] = *data;
i2c_data[i2c_wr_ptr].data = 0x0000;
}
i2c_index = 0;
i2c_byte_transfer();
 
i2c_pending_write = mode->read_write;
return mode->read_write+1;
}
 
i2c_index = 0;
i2c_byte_transfer();
 
return mode->read_write+1;
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.