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

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/orpsocv2
    from Rev 373 to Rev 374
    Reverse comparison

Rev 373 → Rev 374

/sw/include/simple-spi.h
0,0 → 1,63
/*
* Defines and prototypes for Simple SPI module driver
*
* Julius Baxter, julius.baxter@orsoc.se
*
*/
 
#ifndef _SIMPLE_SPI_H_
#define _SIMPLE_SPI_H_
 
#define SIMPLESPI_SPCR 0x00 // Control register
#define SIMPLESPI_SPSR 0x01 // Status register
#define SIMPLESPI_SPDR 0x02 // Data register
#define SIMPLESPI_SPER 0x03 // Extensions Register
#define SIMPLESPI_SSPU 0x04 // Slave select pickups
 
//
// Bit masks for each register //
//
 
// Control Register
#define SIMPLESPI_SPCR_SPR 0x03 // Clock rate select
#define SIMPLESPI_SPCR_CPHA 0x04 // Clock phase
#define SIMPLESPI_SPCR_CPOL 0x08 // Clock polarity
#define SIMPLESPI_SPCR_MSTR 0x10 // Master mode select
#define SIMPLESPI_SPCR_SPE 0x40 // Serial peripheral enable (core enable)
#define SIMPLESPI_SPCR_SPIE 0x80 // Interrupt enable
 
// Status Register
#define SIMPLESPI_SPSR_RFEMPTY 0x01 // Read FIFO buffer empty
#define SIMPLESPI_SPSR_RFFULL 0x02 // Read FIFO buffer full
#define SIMPLESPI_SPSR_WFEMPTY 0x04 // Write FIFO buffer empty
#define SIMPLESPI_SPSR_WFFULL 0x08 // Write FIFO buffer full
#define SIMPLESPI_SPSR_WCOL 0x40 // Write collision
#define SIMPLESPI_SPSR_SPIF 0x80 // Interrupt flag
 
// Extensions register
#define SIMPLESPI_SPER_ESPR 0x03 // Extended clock rate select
#define SIMPLESPI_SPER_ICNT 0xc0 // Interrupt count (IRQ set after no. xfer)
 
// Pass these to the spi_core_set_int_count() function
#define SIMPLESPI_SPER_ICNT_EVERY 0x00
#define SIMPLESPI_SPER_ICNT_TWO 0x40
#define SIMPLESPI_SPER_ICNT_THREE 0x80
#define SIMPLESPI_SPER_ICNT_FOUR 0xC0
 
 
void spi_core_enable(int core);
void spi_core_disable(int core);
void spi_core_interrupt_enable(int core);
void spi_core_interrupt_disable(int core);
void spi_core_interrupt_flag_clear(int core);
void spi_core_clock_setup(int core, char polarity, char phase, char rate,char ext_rate);
void spi_core_set_int_count(int core, char cnt);
void spi_core_slave_select(int core, char slave_sel_dec);
void spi_core_write_data(int core, char data);
int spi_core_data_avail(int core);
int spi_core_write_avail(int core);
char spi_core_read_data(int core);
 
 
 
#endif
/sw/or1200/or1200-div.c
0,0 → 1,187
/*
Test integer division
Use a software division algorithm to perform division and compare against
the hardware calculated results
 
TODO: Check the signed division software calculation stuff is 100% correct!
 
Julius Baxter, julius@opencores.org
 
*/
 
#include "or32-utils.h"
#include "uart.h"
#include "printf.h"
 
static int sdiv_errors, udiv_errors;
 
#define VERBOSE_TESTS 0
 
// Make this bigger for running on target. For us it's enough.
#define NUM_TESTS 200
 
int
or1k_div(int dividend, int divisor)
{
int result;
asm ("l.div\t%0,%1,%2" : "=r" (result) : "r" (dividend), "r" (divisor));
return result;
}
 
unsigned int
or1k_divu(unsigned int dividend, unsigned int divisor)
{
int result;
asm ("l.divu\t%0,%1,%2" : "=r" (result) : "r" (dividend), "r" (divisor));
return result;
}
 
 
void
check_div(int dividend, int divisor, int expected_result)
{
#if VERBOSE_TESTS
printf("l.div 0x%.8x / 0x%.8x = 0x%.8x : ", dividend, divisor,
expected_result);
#endif
int result = or1k_div(dividend, divisor);
if ( result != expected_result)
{
printf("l.div 0x%.8x / 0x%.8x = 0x%.8x : ", dividend, divisor,
expected_result);
printf("FAIL - 0x%.8x\n",result);
sdiv_errors++;
}
#if VERBOSE_TESTS
else
printf("OK\n");
#endif
}
 
void
check_divu(unsigned int dividend, unsigned int divisor,
unsigned int expected_result)
{
#if VERBOSE_TESTS
printf("l.divu 0x%.8x / 0x%.8x = 0x%.8x : ", dividend, divisor,
expected_result);
#endif
 
unsigned int result = or1k_div(dividend, divisor);
if ( result != expected_result)
{
printf("l.divu 0x%.8x / 0x%.8x = 0x%.8x : ", dividend, divisor,
expected_result);
printf("FAIL - 0x%.8x\n",result);
udiv_errors++;
}
#if VERBOSE_TESTS
else
printf("OK\n");
#endif
}
 
 
// Software implementation of division
unsigned int
div_soft(unsigned int n, unsigned int d)
{
 
// unsigned 32-bit restoring divide algo:
unsigned long long p, dd;
long long p_signed;
unsigned int q = 0;
 
p = (unsigned long long) n;
dd = (unsigned long long) d << 32;
 
int i;
for(i=31; i>-1; i--){
p_signed = (2*p) - dd;
if (p_signed>=0)
{
p = (2*p) - dd;
q |= 1 << i;
}
else
{
p = p_signed + dd;
}
}
return q;
 
}
 
int
main(void)
{
#ifdef _UART_H_
uart_init(DEFAULT_UART);
#endif
udiv_errors = 0;
sdiv_errors = 0;
 
int i;
 
unsigned long n, d;
unsigned long expected_result;
i=0;
while(i < NUM_TESTS)
{
n = rand();
d = rand();
 
while ( d >= n )
d >>= (rand() & 0xff);
 
if (n&0x80000000) // numerator is negative
{
// Calculate a value that's really smaller than the numerator
while ( d >= ~(n-1) )
d >>= (rand() & 0xff);
// Processor thinks it's in 2's complement already, so we'll convert
// from the interpreted 2's complement to unsigned for our calculation
expected_result = div_soft(~(n-1), d);
// Answer will be an unsigned +ve value, but of course it has to be
// negative so convert back to 2's complment negative
expected_result = ~expected_result + 1; // 2's complement
}
else
expected_result = div_soft(n, d);
 
check_div(n, d, expected_result);
n >>= 1;
 
while ( d >= n )
d >>= (rand() & 0xff);
 
expected_result = div_soft(n, d);
check_divu(n, d, expected_result);
i++;
//printf("%d\n",i);
 
}
 
 
printf("Division check complete\n");
printf("Unsigned:\t%d tests\t %d errors\n",
NUM_TESTS, udiv_errors);
printf("Signed:\t\t%d tests\t %d errors\n",
NUM_TESTS, sdiv_errors);
 
if ((udiv_errors > 0) || (sdiv_errors > 0))
report(0xbaaaaaad);
else
report(0x8000000d);
 
return 0;
}
/sw/support/simple-spi.c
0,0 → 1,100
/*
* Simple SPI module driver
*
* Julius Baxter, julius.baxter@orsoc.se
*
*/
 
#include "board.h"
#include "simple-spi.h"
#include "or32-utils.h"
 
const int spi_base_adr[1] = {SPI0_BASE};
 
void spi_core_enable(int core)
{
REG8((spi_base_adr[core] + SIMPLESPI_SPCR)) |= SIMPLESPI_SPCR_SPE;
}
 
void spi_core_disable(int core)
{
REG8((spi_base_adr[core] + SIMPLESPI_SPCR)) &= ~SIMPLESPI_SPCR_SPE;
}
 
void spi_core_interrupt_enable(int core)
{
REG8((spi_base_adr[core] + SIMPLESPI_SPCR)) |= SIMPLESPI_SPCR_SPIE;
}
 
void spi_core_interrupt_disable(int core)
{
REG8((spi_base_adr[core] + SIMPLESPI_SPCR)) &= ~SIMPLESPI_SPCR_SPIE;
}
 
void spi_core_interrupt_flag_clear(int core)
{
REG8((spi_base_adr[core] + SIMPLESPI_SPSR)) = SIMPLESPI_SPSR_SPIF;
}
 
void spi_core_clock_setup(int core, char polarity, char phase, char rate,
char ext_rate)
{
char spcr = REG8((spi_base_adr[core] + SIMPLESPI_SPCR));
 
if (polarity)
spcr |= SIMPLESPI_SPCR_CPOL;
else
spcr &= ~SIMPLESPI_SPCR_CPOL;
 
if (phase)
spcr |= SIMPLESPI_SPCR_CPHA;
else
spcr &= ~SIMPLESPI_SPCR_CPHA;
 
spcr = (spcr & ~SIMPLESPI_SPCR_SPR) | (rate & SIMPLESPI_SPCR_SPR);
 
REG8((spi_base_adr[core] + SIMPLESPI_SPCR)) = spcr;
 
char sper = REG8((spi_base_adr[core] + SIMPLESPI_SPER));
sper = (sper & ~SIMPLESPI_SPER_ESPR) | (ext_rate & SIMPLESPI_SPER_ESPR);
 
REG8((spi_base_adr[core] + SIMPLESPI_SPER)) = sper;
 
}
 
void spi_core_set_int_count(int core, char cnt)
{
char sper = REG8((spi_base_adr[core] + SIMPLESPI_SPER));
sper = (sper & ~SIMPLESPI_SPER_ICNT) | cnt;
REG8((spi_base_adr[core] + SIMPLESPI_SPER)) = sper;
}
// slave_sel_dec is decoded (so asserted bit in right place)
void spi_core_slave_select(int core, char slave_sel_dec)
{
REG8((spi_base_adr[core] + SIMPLESPI_SSPU)) = slave_sel_dec;
}
 
int spi_core_data_avail(int core)
{
return !!!(REG8((spi_base_adr[core]+SIMPLESPI_SPSR))&SIMPLESPI_SPSR_RFEMPTY);
}
 
int spi_core_write_avail(int core)
{
return !!!(REG8((spi_base_adr[core]+SIMPLESPI_SPSR))&SIMPLESPI_SPSR_WFFULL);
}
 
// Should call spi_core_write_avail() before calling this, we don't check
void spi_core_write_data(int core, char data)
{
REG8((spi_base_adr[core] + SIMPLESPI_SPDR)) = data;
}
 
char spi_core_read_data(int core)
{
return REG8((spi_base_adr[core] + SIMPLESPI_SPDR));
}

powered by: WebSVN 2.1.0

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