/*
|
* FIR_acc.c
|
*
|
* Created on: 2022Äê5ÔÂ13ÈÕ
|
* Author: graydon
|
*/
|
//#include <def21489.h>
|
//#include <cdef21489.h>
|
#include <services/int/adi_int.h>
|
#include <string.h>
|
#include "FIR_acc.h"
|
#include "memory.h"
|
|
enum acc_status{
|
acc_idle,
|
acc_processing,
|
acc_completely,
|
};
|
|
/* Declaring the external buffers needed for FIR Accelerator*/
|
struct FIR_tcb {
|
u16 id;
|
u8 cp_update;
|
ubool remove;
|
|
u32 mtap;
|
|
const ufloat* ip_buff; //ÊäÈëÊý¾ÝBUFFER. TAPS+WINDOW_SIZE-1
|
const ufloat* op_buff; //Êä³öÊý¾ÝBUFFER.WINDOW_SIZE
|
const ufloat* cf_buff; //ϵÊýBUFFER. TAPS,×î´ó1024.
|
const ufloat* cf_temp; //ϵÊýÁÙʱBUFFER. TAPS,×î´ó1024.
|
|
s32 tcb[13]; //DMA tcb.
|
struct FIR_tcb* next;
|
uvoid* content;
|
acc_completely_handler callback;
|
};
|
|
struct FIR_tcb_head {
|
u8 status;
|
ubool stop;
|
|
u16 num ;
|
u32 count;
|
struct FIR_tcb* next;
|
};
|
|
static volatile struct FIR_tcb_head firHead;
|
void fir_acc_isr(s32 sig, uvoidptr arg)
|
{
|
|
// if(*pFIRDMASTAT & FIR_DMAACDONE){ //All Channels Done
|
firHead.status = acc_completely;
|
firHead.count++;
|
|
if(!firHead.stop)
|
fir_acc_startup();
|
// }
|
|
}
|
|
uvoid fir_acc_init()
|
{
|
s32 temp;
|
u32 _sig = 0xD;
|
s32 index = _sig*5/30;
|
s32 offset = (_sig-index*6)*5 ;
|
|
//Mapping the FFT DMA interrupt
|
// temp=* (pPICR0+index);
|
// temp&=~(0x1f<<offset);
|
// temp|= (0x1b<<offset);
|
// *(pPICR0+index)=temp;
|
//
|
// //Selecting the FIR Accelerator
|
// temp = *pPMCTL1;
|
// temp &= ~(BIT_17|BIT_18);
|
// temp |= FIRACCSEL; //FIRÓëFFT ¶þѡһ.
|
// *pPMCTL1 = temp;
|
//
|
// //PMCTL1 effect latency
|
// asm("nop;nop;nop;nop;");
|
//
|
// //Now Enabling the FIR Acceleratord
|
// *pFIRCTL1= 0; //FIR_EN|FIR_DMAEN|FIR_CH8;
|
//
|
// adi_int_InstallHandler(ADI_CID_P13I, fir_acc_isr, 0, true);
|
|
memset((uvoid*)&firHead, 0 , sizeof(firHead));
|
}
|
|
uvoid fir_acc_delete()
|
{
|
struct FIR_tcb* fir = firHead.next;
|
|
firHead.stop = utrue;
|
while(firHead.status == acc_processing) ;
|
|
//delete tcb.
|
while(fir != NULL) {
|
struct FIR_tcb* q = fir;
|
fir = fir->next;
|
sram_free(SRAM_L2, q);
|
firHead.num --;
|
}
|
firHead.next = NULL;
|
firHead.stop = ufalse;
|
firHead.count =0;
|
firHead.status = 0;
|
}
|
|
uvoid fir_acc_startup()
|
{
|
if(firHead.status == acc_completely) {
|
struct FIR_tcb* fir = firHead.next;
|
while(fir != NULL) {
|
if(fir->callback) fir->callback(fir->content);
|
if(fir->cp_update) {
|
memcpy((uvoid*)fir->cf_buff, fir->cf_temp , fir->mtap*sizeof(ufloat));
|
fir->cp_update = ufalse;
|
}
|
fir = fir->next;
|
}
|
firHead.status = acc_idle;
|
}
|
|
if(firHead.status == acc_idle && firHead.num > 0) {
|
//Initializing the chain pointer register
|
// *pCPFIR=(s32)firHead.next->tcb+12-0x80000;
|
//
|
// *pFIRCTL1 = 0;
|
// //Now Enabling the FIR Acceleratord
|
// *pFIRCTL1=FIR_EN|FIR_DMAEN|((firHead.num-1)<<1); //|FIR_CAI|FIR_CCINTR;
|
|
firHead.status = acc_processing;
|
}
|
}
|
|
|
u16 fir_acc_add(u16 ID
|
, const ufloat* input_buffer
|
, const ufloat* output_buffer
|
,const ufloat* coeffs_buffer
|
, u16 win_size
|
,u16 tap
|
,uvoid* content
|
, acc_completely_handler cb)
|
{
|
struct FIR_tcb* fir = NULL;
|
|
if(firHead.num >= 8) {
|
return ufalse;
|
}
|
//check is exsit
|
fir = firHead.next;
|
while(fir != NULL) {
|
if(fir->id == ID) {
|
return ufalse;
|
}
|
fir = fir->next;
|
}
|
|
fir = (struct FIR_tcb*)sram_malloc(SRAM_L2, 0, sizeof(struct FIR_tcb));
|
if(fir == NULL) {
|
return ufalse;
|
}
|
if(firHead.num >=4 && tap > 512) {
|
tap = 512;
|
}
|
fir->id = ID;
|
fir->callback = cb;
|
fir->ip_buff = input_buffer;
|
fir->op_buff = output_buffer;
|
fir->cf_buff = coeffs_buffer;
|
fir->cf_temp = 0;
|
fir->content = content;
|
fir->cp_update = ufalse;
|
fir->mtap = tap;
|
|
fir->tcb[0] = 0; //CPFIR
|
fir->tcb[1] = tap; //CCFIR
|
fir->tcb[2] = 1; //CMFIR
|
fir->tcb[3] = (s32)coeffs_buffer;//+tap-1; //CIFIR
|
fir->tcb[4] = (s32)output_buffer; //OBFIR
|
fir->tcb[5] = win_size; //OCFIR
|
fir->tcb[6] = 1; //OMFIR
|
fir->tcb[7] = (s32)output_buffer; //OIFIR
|
fir->tcb[8] = (s32)input_buffer; //IBFIR
|
fir->tcb[9] = tap+win_size-1; //ICFIR
|
fir->tcb[10] = 1; //IMFIR
|
fir->tcb[11] = (s32)input_buffer; //IIFIR
|
fir->tcb[12] = tap-1|((win_size-1)<<14); //FIRCTL2
|
fir->next = NULL;
|
|
if(firHead.next == NULL) {
|
firHead.next = fir;
|
}
|
else {
|
struct FIR_tcb* tmp = firHead.next;
|
|
while(tmp->next != NULL) tmp = tmp->next;
|
tmp->next = fir;
|
tmp->tcb[0] = (s32)fir->tcb+12;
|
}
|
fir->tcb[0] = (s32)firHead.next->tcb+12;
|
firHead.num ++;
|
|
return tap;
|
}
|
|
|
uvoid fir_acc_update_coeffs(u16 ID, const ufloat* cp)
|
{
|
struct FIR_tcb* fir = firHead.next;
|
|
while(fir != NULL) {
|
if(fir->id == ID) {
|
fir->cf_temp = cp;
|
fir->cp_update = 1;
|
break;
|
}
|
fir = fir->next;
|
}
|
}
|
|
uvoid fir_acc_remove(u16 ID)
|
{
|
struct FIR_tcb* fir = firHead.next;
|
|
//delete tcb.
|
while(fir != NULL) {
|
if(fir->id == ID) {
|
fir->remove = utrue;
|
}
|
fir = fir->next;
|
}
|
}
|
//
|
//ubool fir_acc_remove(u16 ID)
|
//{
|
// struct FIR_tcb* fir = firHead.next;
|
//
|
// if(fir->id == ID) {
|
// firHead.next = fir->next;
|
// sram_free(SRAM_PM, fir);
|
// firHead.num --;
|
// return utrue;
|
// }
|
//
|
// while(fir->next != NULL) {
|
// if(fir->next->id == ID) {
|
// //remove fir next.
|
// struct FIR_tcb* p = fir->next;
|
// fir->next = fir->next->next;
|
// sram_free(SRAM_PM, fir->next);
|
// firHead.num --;
|
// }
|
// fir = fir->next;
|
// }
|
// return utrue;
|
//}
|