⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmac.c

📁 基于ARM核的HMS7202
💻 C
字号:
#include <mon.h>
#include <irqs.h>
#include <reg.h>
#include <tty.h>
#include <syscall.h>
#include <dmac.h>

/* Private data */
#if defined(HEI_ARM7) &&  HEI_ARM7 == 1
static volatile HW_DMAC_t *hw_dmac = (volatile HW_DMAC_t *)(DMAC_BASE + 0x2c);
#elif defined(HEI_ARM7) &&  HEI_ARM7 == 2
static volatile HW_DMAC_t *hw_dmac = (volatile HW_DMAC_t *)(DMAC_BASE + 0x44);
#endif


//static handler_t *dmaHandler[NUM_DMA];
static dma_registry_t *dma_table[NUM_DMA];
static dma_error_t error;
static dma_type_t intrID;
static int nintr;
static int dma_users[NUM_DMA];
static char *error_msg[] = {
	"no error",
	"invalid dma interrupt",
	"sound dma handler is not registered",
	"irda dma handler is not registered",
	"usb dma handler is not registered",
};

/* Private functions */
static void dma_interrupt(int);

int dma_init()
{
	int i;
	int ret;

	ret = MON_OK;
	ser_printf("Initialise DMA module\n");
	for(i=0; i<NUM_DMA; i++) {
		dma_table[i] = NULL;
		dma_users[i] = 0;
	}
	nintr = 0;

	ret = register_irqHandler(DMA_LEVEL, dma_interrupt);
	if(ret == MON_FAIL) {
		ser_printf("Cannot register DMA interrupt handler--> %d\n", DMA_LEVEL);
		return ret;
	}

	dma_power(true);

	return ret;
}

int dma_interrupt_count()
{
	return nintr;
}

dma_error_t dma_errtype()
{
	return error;
}

char *dma_error(dma_error_t errtype)
{
	return error_msg[errtype];
}

dma_type_t dma_intr_source()
{
	return intrID;
}

int dma_request(dma_type_t type)
{
	int ret = MON_OK;

	if(type == DMA_SOUND0_ID || type == DMA_SOUND1_ID) {
		if(dma_users[type] >= 1){
			ret = MON_FAIL;
		}
		else {
			dma_users[DMA_SOUND0_ID] ++;
			dma_users[DMA_SOUND1_ID] ++;
			unmaskInterrupt(DMA_LEVEL);
		}
	}
	else if(type == DMA_IRDA_ID) {
		if(dma_users[type] >= 1){
			ret = MON_FAIL;
		}
		else {
			dma_users[DMA_IRDA_ID] ++;
			unmaskInterrupt(DMA_LEVEL);
		}
	}
	else if(type == DMA_USB_ID) {
		if(dma_users[type] >= 1){
			ret = MON_FAIL;
		}
		else {
			dma_users[DMA_USB_ID] ++;
			unmaskInterrupt(DMA_LEVEL);
		}
	}

	return ret;
}

int dma_request_end(dma_type_t type)
{
	int i;
	int ret = MON_OK;
	int count = 0;

	if(type == DMA_SOUND0_ID || type == DMA_SOUND1_ID) {
		if(dma_users[type] <= 0){
			ret = MON_FAIL;
		}
		else {
			dma_users[DMA_SOUND0_ID] --;
			dma_users[DMA_SOUND1_ID] --;
		}
	}
	else if(type == DMA_IRDA_ID) {
		if(dma_users[type] <= 0){
			ret = MON_FAIL;
		}
		else
			dma_users[DMA_IRDA_ID] --;
	}
	else if(type == DMA_USB_ID) {
		if(dma_users[type] <= 0){
			ret = MON_FAIL;
		}
		else
			dma_users[DMA_USB_ID] --;
	}

	if(ret == MON_OK) {
		for(i=0; i< NUM_DMA; i++)
			count += dma_users[i];
		if(count <= 0)
			maskInterrupt(DMA_LEVEL);
	}

	return ret;
}

int register_dmaRegistry(dma_type_t type, dma_registry_t * dma)
{
	if(type < 0 && type >= NUM_DMA)
		return MON_FAIL;

	dma_table[type] = dma;

	return MON_OK;
}

int unregister_dmaRegistry(dma_type_t type)
{
	if(type < 0 && type >= NUM_DMA)
		return MON_FAIL;

	dma_table[type] = NULL;

	return MON_OK;
}


int dma_device_init(dma_type_t type)
{
	init_func_t *devInit;
	int ret;
	if(type < 0 && type >= NUM_DMA)
		return MON_FAIL;

	devInit = (init_func_t *)dma_table[type]->dev_init;
	ret = devInit();

	return ret;
}

int dma_device_reset(dma_type_t type)
{
	reset_func_t *devReset;
	if(type < 0 && type >= NUM_DMA)
		return MON_FAIL;

	devReset = (reset_func_t *)dma_table[type]->dev_reset;
	devReset();

	return MON_OK;
}

void dma_ack_interrupt(dma_type_t id)
{
	if(id == DMA_SOUND0_ID) {
		hw_dmac->intr.val = 1;
	}
	else if(id == DMA_SOUND1_ID) {
		hw_dmac->intr.val = 2;
	}
	else if(id == DMA_IRDA_ID) {
		hw_dmac->intr.val = 4;
	}
	else if(id == DMA_USB_ID) {
		hw_dmac->intr.val = 8;
	}
}

void dma_ack_all_interrupts()
{
	hw_dmac->intr.val = 0xf;
}

void dma_power(int on)
{
	if(on == true) {
		ser_printf("DMAC ON!\n");
		hw_dmac->u.ctrl.power = 1;
	}
	else {
		ser_printf("DMAC OFF!\n");
		hw_dmac->u.ctrl.power = 0;
	}
}
static void dma_interrupt(int level)
{
	int ok = false;

	error = NO_ERROR;
	nintr ++;

	if(hw_dmac->intr.flag.sound0 == 1) {
		intrID = DMA_SOUND0_ID;
		if(dma_table[0] == NULL || dma_table[0]->handler == NULL) {
			error = UNREGISTERED_SOUND;
			dma_power(false);
		}
		else {
//			handler = dma_table[0]->handler;
//			handler();
			(dma_table[0]->handler)();
			ok = true;
		}
	}
	if(hw_dmac->intr.flag.sound1 == 1) {
		intrID = DMA_SOUND1_ID;
		if(dma_table[1] == NULL || dma_table[1]->handler == NULL) {
			error = UNREGISTERED_IRDA;
			dma_power(false);
		}
		else {
//			handler = dma_table[1]->handler;
//			handler();
			(dma_table[1]->handler)();
			ok = true;
		}
	}
	if(hw_dmac->intr.flag.irda == 1) {
		intrID = DMA_IRDA_ID;
		if(dma_table[2] == NULL || dma_table[2]->handler == NULL) {
			error = UNREGISTERED_IRDA;
			dma_power(false);
		}
		else {
//			handler = dma_table[2]->handler;
//			handler();
			(dma_table[2]->handler)();
			ok = true;
		}
	}
	if(hw_dmac->intr.flag.usb == 1) {
		intrID = DMA_USB_ID;
		if(dma_table[3] == NULL || dma_table[3]->handler == NULL) {
			error = UNREGISTERED_USB;
			dma_power(false);
		}
		else {
//			handler = dma_table[3]->handler;
//			handler();
			(dma_table[3]->handler)();
			ok = true;
		}
	}

	if(ok != true) {
		error = INVALID_INTR;
		dma_power(false);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -