summaryrefslogtreecommitdiff
path: root/firmware/src/os/led.c
blob: 8c34c6caed3e7901e62a273e8609a28b00ff0998 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

#include <sys/types.h>
#include <errno.h>
#include <lib_AT91SAM7.h>
#include <openpcd.h>
#include "../openpcd.h"
#include <os/usb_handler.h>
#include <os/req_ctx.h>
#include <os/dbgu.h>

static int led2port(int led)
{
	if (led == 1)
		return OPENPCD_PIO_LED1;
	else if (led == 2)
		return OPENPCD_PIO_LED2;
	else
		return 0;
}

void led_switch(int led, int on)
{
	int port = led2port(led);

	if (port == -1)
		return;

	if (on)
		AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, port);
	else
		AT91F_PIO_SetOutput(AT91C_BASE_PIOA, port);
}

int led_get(int led)
{
	int port = led2port(led);

	if (port == -1)
		return -1;

	return !(AT91F_PIO_GetOutputDataStatus(AT91C_BASE_PIOA) & port);
}

int led_toggle(int led)
{
	int on = led_get(led);
	if (on == -1)
		return -1;

	if (on)
		led_switch(led, 0);
	else
		led_switch(led, 1);
	
	return !on;
}

static int led_usb_rx(struct req_ctx *rctx)
{
	struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->rx.data[0];
	int ret = 1;

	switch (poh->cmd) {
	case OPENPCD_CMD_SET_LED:
		DEBUGP("SET LED(%u,%u) ", poh->reg, poh->val);
		led_switch(poh->reg, poh->val);
		break;
	default:
		DEBUGP("UNKNOWN ");
		ret = -EINVAL;
		break;
	}
	req_ctx_put(rctx);
	return 1;
}

void led_init(void)
{
	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LED1);
	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LED2);
	led_switch(1, 0);
	led_switch(2, 0);

	usb_hdlr_register(&led_usb_rx, OPENPCD_CMD_CLS_LED);
}
personal git repositories of Harald Welte. Your mileage may vary