Пример #1
0
void gptimer1_handler(int id) {
	uint32_t irq = reg32r(GPTIMER1_BASE, GPT_TISR);

	{
		static int blink = 0;

		if (blink & (1<<2)) {
			LEDS_OFF(LED0);
			LEDS_ON(LED1);
		} else {
			LEDS_ON(LED0);
			LEDS_OFF(LED1);
		}
		blink++;
	}

	// check for overflow int
	if (irq & OVF_IT_FLAG) {
		Remove(&thistask->Node);
		AddTail(&tasks, &thistask->Node);

		thistask = (struct task *)tasks.Head;
		irq_new_task(tcb_to_sp(&thistask->tcb));
	}

	// clear ints
	reg32w(GPTIMER1_BASE, GPT_TISR, ~0);
}
Пример #2
0
static RETURN_CODE writeSerial(Driver_t *self, void *message) {
	char *tmp = message;

	while (*tmp){
	while ((reg32r(UART3_BASE,LSR_REG) & 0x20) == 0);
 	 	 reg32w(UART3_BASE,0,(*tmp++));
 	}
	return SUCCESS;
}
Пример #3
0
void int_handler_function(void)
{
    int irq = reg32r(GPTIMER1_BASE, GPT_TISR);
    if (irq & OVF_IT_FLAG) 
    {
        // console_put_char('#'); 
        tick_handler_function(); 
        // console_put_char('@'); 
    }
    reg32w(GPTIMER1_BASE, GPT_TISR, ~0);
}
Пример #4
0
// DSS IRQ handler (irq 25)
// Is also invoked for DSI interrupts
void dispc_handler(int id) {
	uint32_t dssirq = reg32r(DSS_BASE, DSS_IRQSTATUS);

	{
		static int blink = 0;

		if (blink & (1<<6)) {
			LEDS_OFF(LED0);
			LEDS_ON(LED1);
		} else {
			LEDS_ON(LED0);
			LEDS_OFF(LED1);
		}
		blink++;
	}

	// see if we have any dispc interrupts
	if (dssirq & DSS_DISPC_IRQ) {
		uint32_t irqstatus = reg32r(DISPC_BASE, DISPC_IRQSTATUS);

		if (1 && (irqstatus & DISPC_VSYNC)) {
			// we do nothing special, just round-robin all tasks at every jiffy
			Remove(&thistask->Node);
			AddTail(&tasks, &thistask->Node);

			thistask = (struct task *)tasks.Head;
			irq_new_task(tcb_to_sp(&thistask->tcb));
		}

		// we handle no other interrrupts, so clear all interrupt status bits if any set
		reg32w(DISPC_BASE, DISPC_IRQSTATUS, irqstatus);
	}
	// check for dsi ints (to clear them)
	if (dssirq & DSS_DSI_IRQ) {
		// not expecting this, just clear everything
		reg32w(DSI_BASE, DSI_IRQSTATUS, ~0);
	}
}
Пример #5
0
static RETURN_CODE ioctlSerial(Driver_t *self, enum IOCTL_CMD cmd, void *data) {
	int baud_rate;

	switch(cmd) {
	case SERIAL_SET_BAUD_RATE:
		baud_rate = *((int *)data);


        reg32w(UART3_BASE, MDR1_REG, 0x07);
        reg32w(UART3_BASE, LCR_REG, 0x80|0x03);
        reg32w(UART3_BASE, DLL_REG, (baud_rate & 0xff));
        reg32w(UART3_BASE, DLH_REF, (baud_rate >> 8) & 0xff);
        reg32w(UART3_BASE, LCR_REG, 0x03);
        reg32w(UART3_BASE, MCR_REG, 0x01 | 0x02 );
        reg32w(UART3_BASE, FCR_REG, 0x01 | 0x02 | 0x04);

        reg32w(UART3_BASE, MDR1_REG, 0x0);

		return SUCCESS;
	default:
		return FAILURE;
	}
}
Пример #6
0
static RETURN_CODE openSerial(Driver_t *self) {
	reg32w(UART3_BASE, MDR1_REG, 0x0);

	return SUCCESS;
}
Пример #7
0
int main(int argc, char **argv) {

	local_exceptions_init();

	// example is too fast/boring with caches on, so don't
	//mmu_simple_init();

	video_init(1280, 1024);
	rp = graphics_init(FBADDR, WIDTH, HEIGHT, BM_RGB16);
	omap_attach_framebuffer(0, rp->drawable.bitmap);

	// also set it to the tv out (top-left corner of same data)
	omap_attach_framebuffer(VID_VID2 | VID_TVOUT, rp->drawable.bitmap);

	moveTo(rp, 0, 0);
	setColour(rp, 0x3e31a2);
	drawRect(rp, WIDTH, HEIGHT);

	// setup tasks to run
	int i;

	NewList(&tasks);
	dprintf("tasks   %08x,  Head=%08x Tail=%08x TailPred=%08x\n",
		&tasks, tasks.Head, tasks.Tail, tasks.TailPred);

	for (i=0;taskinit[i];i++ ){
		struct task *t = taskinit[i];

		// set initial pc and proc state
		t->tcb.pc = taskpc[i];

		// runs in user mode
		t->tcb.spsr = 0x10;
		// initial argument 0 in reg 0
		t->tcb.regs[0] = i;
		t->id = i;
		int j;
		for (j=1;j<10;j++)
			t->tcb.regs[j] = j;
		// initial stack - 4K each, before 32K of master stack
		t->tcb.regs[13] = 0x88000000 - 32768 - i*4096;
		AddTail((struct List *)&tasks, &t->Node);

		dprintf("adding task %d = %08x pc=%08x sp=%08x\n", i, t, t->tcb.pc, t->tcb.regs[13]);

	}
	dprintf("tasks   %08x,  Head=%08x Tail=%08x TailPred=%08x\n",
		&tasks, tasks.Head, tasks.Tail, tasks.TailPred);

	// set task 0 to `execute first' (it's actually us)
	thistask = &t1;
	fptask = 0;
	irq_new_task(tcb_to_sp(&thistask->tcb));

	// add an irq handler for the vsync interrupt (lcd display?)
	irq_set_handler(INTC_DSS_IRQ, dispc_handler);
	irq_set_mask(INTC_DSS_IRQ, 1);

	// disable all but vsync
	reg32w(DISPC_BASE, DISPC_IRQENABLE, DISPC_VSYNC);
	reg32w(DISPC_BASE, DISPC_IRQSTATUS, ~0);
	// dss intterrupt can also receive DSI, so disable those too
	reg32w(DSI_BASE, DSI_IRQENABLE, 0);
	reg32w(DSI_BASE, DSI_IRQSTATUS, ~0);

	dprintf("enabling interrupts\n");

	// data barrier for previous register writes
	asm volatile("dsb");

	// turn on irq's, which enables task switching
	irq_enable();

	// jump to user mode - we are now 'task 0'
	asm volatile("cps #0x10");
	asm volatile("ldr sp,=0x88000000 - 32768");

	task1(0);

	return 0;
}
Пример #8
0
int main(int argc, char **argv) {

	local_exceptions_init();

	// example is too fast/boring with caches on, so don't
	//mmu_simple_init();

	video_init(1280, 1024);
	rp = graphics_init(FBADDR, WIDTH, HEIGHT, BM_RGB16);
	omap_attach_framebuffer(0, rp->drawable.bitmap);

	// also set it to the tv out (top-left corner of same data)
	omap_attach_framebuffer(VID_VID2 | VID_TVOUT, rp->drawable.bitmap);

	moveTo(rp, 0, 0);
	setColour(rp, 0x3e31a2);
	drawRect(rp, WIDTH, HEIGHT);

	// setup tasks to run
	int i;

	NewList(&tasks);
	dprintf("tasks   %08x,  Head=%08x Tail=%08x TailPred=%08x\n",
		&tasks, tasks.Head, tasks.Tail, tasks.TailPred);

	for (i=0;taskinit[i];i++ ){
		struct task *t = taskinit[i];

		// set initial pc and proc state
		t->tcb.pc = (uint32_t)task;
		// runs in user mode
		t->tcb.spsr = 0x10;
		// initial argument 0 in reg 0
		t->tcb.regs[0] = i;
		t->id = i;
		int j;
		for (j=1;j<10;j++)
			t->tcb.regs[j] = j;
		// initial stack - 4K each, before 32K of master stack
		t->tcb.regs[13] = 0x88000000 - 32768 - i*4096;
		AddTail((struct List *)&tasks, &t->Node);

		dprintf("adding task %d = %08x pc=%08x sp=%08x\n", i, t, t->tcb.pc, t->tcb.regs[13]);

	}
	dprintf("tasks   %08x,  Head=%08x Tail=%08x TailPred=%08x\n",
		&tasks, tasks.Head, tasks.Tail, tasks.TailPred);

	// set task 0 to `execute first' (it's actually us)
	thistask = &t1;
	irq_new_task(tcb_to_sp(&thistask->tcb));

	//
	// Setup timer interrupt via GPTIMER1
	//

	// timer off
	reg32s(GPTIMER1_BASE, GPT_TCLR, 1, 0);

	// Sets true 1Khz rate w/ 32768Hz clock:  S 16.2.4.3 TRM D
	reg32w(GPTIMER1_BASE, GPT_TPIR, 232000);
	reg32w(GPTIMER1_BASE, GPT_TNIR, -768000);
	reg32w(GPTIMER1_BASE, GPT_TLDR, 0xffffffe0);
	reg32w(GPTIMER1_BASE, GPT_TCRR, 0xffffffe0);

	// clear int status bits
	reg32w(GPTIMER1_BASE, GPT_TISR, ~0);
	// enable overflow int
	reg32w(GPTIMER1_BASE, GPT_TIER, OVF_IT_FLAG);

	// dividisor = 100 -> 10Hz so it's visible
	reg32w(GPTIMER1_BASE, GPT_TOCR, 0);
	reg32w(GPTIMER1_BASE, GPT_TOWR, 100);

	irq_set_handler(INTC_GPT1_IRQ, gptimer1_handler);
	irq_set_mask(INTC_GPT1_IRQ, 1);

	// force 32K clock
	reg32s(0x48004c00, 0x40, 1, 0);

	// turn timer back on
	reg32s(GPTIMER1_BASE, GPT_TCLR, 1|2|(2<<10), ~0);

	dprintf("enabling interrupts\n");

	// data barrier for previous register writes
	asm volatile("dsb");

	// turn on irq's, which enables task switching
	irq_enable();

	// jump to user mode - we are now 'task 0'
	asm volatile("cps #0x10");
	asm volatile("ldr sp,=0x88000000 - 32768");

	task(0);

	return 0;
}