##// END OF EJS Templates
Message queue implemented for valid TC processing...
Message queue implemented for valid TC processing Default action coded

File last commit:

r0:452a68f7426f default
r9:515486994c1d default
Show More
LPP_spwAPI.c
176 lines | 5.2 KiB | text/x-c | CLexer
#include <..\header\LPP_spwAPI.h>
#include <stdlib.h>
#include <stdio.h>
volatile int *lreg = (int*) 0x80000200; // the IRQMP controller registers are at 0x80000200
inline int loadmemAPI(int addr)
{
int tmp;
asm volatile (" lda [%1]1, %0 " // LDA => Load Word from Alternate space
: "=r" (tmp)
: "r" (addr)
);
return tmp;
}
inline char loadb(int addr)
{
char tmp;
asm volatile (" lduba [%1]1, %0 "
: "=r" (tmp)
: "r" (addr)
);
return tmp;
}
char *almalloc(int sz)
{
char *tmp;
tmp = (char*) malloc(2*sz);
tmp = (char*) (((int)tmp+sz) & ~(sz-1));
return(tmp);
}
//////
// SPW
//////
void spw_reset(grspwregs_t *regs)
{
regs->ctrl = GRSPW_CTRL_RS; // make complete reset of the spacewire node, self clearing
}
void spw_init(int nodeaddr, int clkdiv, int destkey, int rxmaxlen, grspwregs_t *regs)
{
regs->ctrl = GRSPW_CTRL_LS | GRSPW_CTRL_RE; // link start (LS)
// RMAP enable (RE)
regs->ctrl = GRSPW_CTRL_LS | GRSPW_CTRL_RE;
regs->ctrl = GRSPW_CTRL_LS | GRSPW_CTRL_RE;
regs->ctrl = GRSPW_CTRL_LS | GRSPW_CTRL_RE;
regs->ctrl = GRSPW_CTRL_LS | GRSPW_CTRL_RE;
regs->ctrl = GRSPW_CTRL_LS | GRSPW_CTRL_RE;
regs->status = 0xffffffff;
regs->nodeaddr = nodeaddr;
regs->clkdiv = clkdiv;
regs->destkey = destkey;
regs->time = 0;
regs->dmactrl = GRSPW_DMACTRL_RA | GRSPW_DMACTRL_TA | GRSPW_DMACTRL_PR | GRSPW_DMACTRL_PS | GRSPW_DMACTRL_AI;
regs->rxmaxlen = rxmaxlen;
regs->txdesc = 0;
regs->rxdesc = 0;
}
void set_txd(char *dataAddress, unsigned int dataLength, char *headerAddress, unsigned int headerLength, volatile int *txd)
{
txd[4] = 0;
txd[3] = (int) dataAddress; // data address
txd[2] = dataLength; // data length
txd[1] = (int) headerAddress; // header address
txd[0] = (1 << 13) | (1 << 12) | headerLength; // bit 13 WR = 1 next descriptor read will be 1st one in the table (at the base address)
// bit 12 EN = 1 enable transmitter descriptor
// bit 0 to 7 stand for the header length
}
int spw_checkrx(int* size, volatile int *rxd, grspwregs_t *regs)
{
volatile int tmp = 0;
tmp = regs->dmactrl;
if ( ( (tmp >> 6) & 1 ) )
{ // bit 6 PR packet received
*size = loadmemAPI((int) &rxd[0]) & 0x00001fff;
regs->dmactrl = regs->dmactrl | 1 << 6; // clear bit 6 PR (packet received) by writing a one
return 1;
}
else return 0;
}
int spw_checktx(grspwregs_t *regs)
{
if ( ( (regs->dmactrl >> 5) & 1 )==1 )
{ // bit 5 PS (packet sent), cleared when written with a one
regs->dmactrl = regs->dmactrl | 1 << 5; // clear bit 5 PS (packet sent) by writing a one
return 1;
}
else return 0;
}
void enable_transmitter_descriptor(unsigned int headerLength, volatile int *txd)
{
txd[0] = GRSPW_TXBD_WR | GRSPW_TXBD_EN;
//WR = 1 next descriptor read will be 1st one in the table (at the base address)
//EN = 1 enable transmitter descriptor
}
void enable_transmitter(grspwregs_t *regs)
{
regs->dmactrl = regs->dmactrl | GRSPW_DMACTRL_TE;
}
void enable_receiver_descriptor(volatile char *rx, volatile int *rxd)
{
rxd[1] = (int) rx;
rxd[0] = GRSPW_RXBD_IE | GRSPW_RXBD_WR | GRSPW_RXBD_EN;
// IE = 1 Interrupt enable
// WR = 1 next descriptor will be the 1st one in the desc table (at the base address)
// EN = 1 activate the descriptor
}
void enable_receiver(grspwregs_t *regs)
{
regs->dmactrl = regs->dmactrl | 1 << 11 | 1 << 2;
}
int enable_timecode_reception(grspwregs_t *regs)
{
regs->ctrl = regs->ctrl | GRSPW_CTRL_TR;
return 1;
}
int check_time(grspwregs_t *grspw_regs)
{
int tmp = loadmemAPI((int)&(grspw_regs->status)) & 1;
if (tmp) {
grspw_regs->status = loadmemAPI((int)&(grspw_regs->status)) | 1;
}
return tmp;
}
//////////////
// GENERAL USE
//////////////
void send_fine_time(unsigned int fine_time){
spacewire_PARAMETERS.tx[0] = (char) fine_time; // send the fine time value to LPPMON
spacewire_PARAMETERS.tx[1] = (char) (fine_time>>8);
spacewire_PARAMETERS.tx[2] = (char) (fine_time>>16);
spacewire_PARAMETERS.tx[3] = (char) (fine_time>>24);
enable_transmitter_descriptor(HEADERLEN, spacewire_PARAMETERS.txd); // enable the descriptor for transmission
enable_transmitter(spacewire_PARAMETERS.regs); // enable the transmission
}
//////
// IRQ
//////
int irqhandler_receive_CCSDS(int irq, void * args, struct leonbare_pt_regs * leon_regs)
{
if (spw_checkrx(spacewire_PARAMETERS.size, spacewire_PARAMETERS.rxd, spacewire_PARAMETERS.regs)==1)
{
packet_type.time_packet = 1;
return 1;
}
return 0;
}
int enable_irq(int irq)
{
lreg[ICLEAR/4] = (1 << irq); // clear any pending irq
lreg[IMASK/4] = lreg[IMASK/4] | (1 << irq); // unmask irq
return 1;
}
int disable_irq(int irq) { lreg[IMASK/4] &= ~(1 << irq); return 1;}
int force_irq(int irq) { lreg[IFORCE/4] = lreg[IFORCE/4] | (1 << irq); return 1;}