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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.communication/] [n2h2/] [1.0/] [drv/] [tut_n2h_regs.c] - Rev 145

Compare with Previous | Blame | View Log

#include "tut_n2h_regs.h"
#include "N2H_registers_and_macros.h"
 
 
#if defined(API)
struct Channel_reservation {
 
    int mem_addr;
    int amount;
 
};
 
static struct Channel_reservation 
    channel_reservations[N2H_NUMBER_OF_CHANNELS] = {};
 
 
// Common interrupt service routine. Clear IRQ and call N2H_RX_DONE.
void isr() {
 
    int chan = N2H_GET_IRQ_CHAN(N2H_REGISTERS_BASE_ADDRESS);
    N2H_RX_DONE( chan, channel_reservations[chan].mem_addr, channel_reservations[chan].amount );
    channel_reservations[chan].mem_addr = 0;
    channel_reservations[chan].amount = 0;
    N2H_RX_CLEAR_IRQ(chan,N2H_REGISTERS_BASE_ADDRESS);
}
 
 
 
// eCos specific interrupt handling
#if defined(ECOS)
#include <cyg/kernel/kapi.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/hal_cache.h>
 
static cyg_interrupt l_rxIrq;
static cyg_handle_t l_rxIrqHandle;
extern void cyg_interrupt_post_dsr(CYG_ADDRWORD intr_handle);
 
cyg_uint32 RxIrqIsr(cyg_vector_t vector, cyg_addrword_t data) { 
    cyg_interrupt_mask(vector);
    cyg_interrupt_post_dsr(l_rxIrqHandle);
    return (CYG_ISR_HANDLED);
}
 
void RxIrqDsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) {
    isr();
    cyg_interrupt_unmask(vector);
 
}
 
 
// NIOSII specific interrupt handling
#else
void n2h_isr( void* context, int id ) {
    isr();
}
#endif
 
void N2H_INIT_ISR() {
 
// eCos specific interrupt init    
#if defined(ECOS)
    cyg_interrupt_create(
			 N2H_RX_IRQ,
			 N2H_RX_IRQ_PRI,
			 0,
			 &RxIrqIsr,
			 &RxIrqDsr,
			 &l_rxIrqHandle,
			 &l_rxIrq);
    cyg_interrupt_attach(l_rxIrqHandle);
    cyg_interrupt_unmask(N2H_RX_IRQ);
    N2H_RX_IRQ_ENA( N2H_REGISTERS_BASE_ADDRESS );
 
// NIOSII specific interrupt init
#else
    alt_irq_register( N2H_RX_IRQ, 0, n2h_isr );
    N2H_RX_IRQ_ENA( N2H_REGISTERS_BASE_ADDRESS );
#endif
}
 
void N2H_GET_RX_BUFFER( int* dst, int src, int amount ) {
 
    // TODO: check that src is inside RX buffer
    // TODO: if src and dst are same, do nothing    
    int i;
    for( i = 0; i < amount; ++i ) {
 
	*(dst + i) = *((int*)src + i);
    }
}
 
void N2H_PUT_TX_BUFFER( int dst, int* src, int amount ) {
 
    // TODO: check that dst is inside TX buffer
    // TODO: if src and dst are same, do nothing   
 
    int i;
    for( i = 0; i < amount; ++i ) {
 
	*((int*)dst + i) = *(src + i);
    }
 
}
#endif // API
 
/*
* DMA engine configuration functions (Updated on 27/04/2005)
*/
 
// Prepare channel for receiving data.
void N2H_CHAN_CONF(int channel, int dst_mem_addr, int rx_haddr, int amount, 
		   int* base)
{
#ifdef API
  channel_reservations[channel].mem_addr = dst_mem_addr;
  channel_reservations[channel].amount = amount; 
#endif
  N2H_CHAN_MEM_ADDR(channel, dst_mem_addr, base);
  N2H_CHAN_HIBI_ADDR(channel, rx_haddr, base);
  N2H_CHAN_AMOUNT(channel, amount, base);
  N2H_CHAN_INIT(channel, base);
}
 
void N2H_SEND(int src_mem_addr, int amount, int dst_haddr, int* base) {
  while( !N2H_TX_DONE(base) );
  N2H_TX_MEM_ADDR(src_mem_addr, base);
  N2H_TX_AMOUNT(amount, base);
  N2H_TX_HIBI_ADDR(dst_haddr, base);
  N2H_TX_COMM_WRITE(base);
  N2H_TX_START(base);
}
 
// Parameter types were uint32. Int works in other places, so why not here?
void N2H_SEND_READ(int mem_addr, int amount, int haddr, int* base) {
  while( !N2H_TX_DONE(base) );
  N2H_TX_MEM_ADDR(mem_addr, base);
  N2H_TX_AMOUNT(amount, base);
  N2H_TX_HIBI_ADDR(haddr, base);
  N2H_TX_COMM_READ(base);
  N2H_TX_START(base);
}
 
void N2H_SEND_MSG(int src_mem_addr, int amount, int dst_haddr, int* base) {
  while( !N2H_TX_DONE(base) );
  N2H_TX_MEM_ADDR(src_mem_addr, base);
  N2H_TX_AMOUNT(amount, base);
  N2H_TX_HIBI_ADDR(dst_haddr, base);
  N2H_TX_COMM_WRITE_MSG(base);
  N2H_TX_START(base);
}
 
// Return 0 if transmission is not done yet, 1 otherwise.
int N2H_TX_DONE(int* base) {
  int y = 0;
  N2H_GET_TX_DONE(y, base);
  return y;  
}
 
void N2H_CLEAR_IRQ(int chan, int* base) {
  N2H_RX_CLEAR_IRQ(chan, base);
}
 
// Returns first channel number which has IRQ flag up.
// If no interrupts have been received -1 is returned.
int N2H_GET_IRQ_CHAN(int* base)
{
  volatile int * apu = base + 7;
  int irq_reg = *apu;
  int mask = 1;
  int shift = 0;
  for (shift = 0; shift < 32; shift++) {
    if ((irq_reg & (mask << shift)) != 0) {
      return shift;
    }
  }
  return -1;
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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