wrc_main.c 4.63 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 * This work is part of the White Rabbit project
 *
 * Copyright (C) 2011,2012 CERN (www.cern.ch)
 * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
 * Author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
 *
 * Released according to the GNU GPL, version 2 or any later version.
 */
10 11 12
#include <stdio.h>
#include <inttypes.h>

13 14
#include <stdarg.h>

15
#include <wrc.h>
16
#include <w1.h>
17
#include "syscon.h"
18 19 20 21
#include "uart.h"
#include "endpoint.h"
#include "minic.h"
#include "pps_gen.h"
22
#include "ptpd_netif.h"
Grzegorz Daniluk's avatar
Grzegorz Daniluk committed
23
#include "i2c.h"
24
#include "storage.h"
25
#include "softpll_ng.h"
26
#include "onewire.h"
27
#include "pps_gen.h"
28
#include "shell.h"
Wesley W. Terpstra's avatar
Wesley W. Terpstra committed
29
#include "lib/ipv4.h"
30
#include "rxts_calibrator.h"
31
#include "flash.h"
Grzegorz Daniluk's avatar
Grzegorz Daniluk committed
32

33
#include "wrc_ptp.h"
34
#include "system_checks.h"
35

36
int wrc_ui_mode = UI_SHELL_MODE;
37
int wrc_ui_refperiod = TICS_PER_SECOND; /* 1 sec */
38
int wrc_phase_tracking = 1;
39

40 41
///////////////////////////////////
//Calibration data (from EEPROM if available)
42
int32_t sfp_alpha = 73622176;	//default values if could not read EEPROM
43 44
int32_t sfp_deltaTx = 0;
int32_t sfp_deltaRx = 0;
45
uint32_t cal_phase_transition = 2389;
46

47
static void wrc_initialize(void)
48
{
49
	uint8_t mac_addr[6];
50

51
	sdb_find_devices();
52 53
	uart_init_sw();
	uart_init_hw();
54

55
	pp_printf("WR Core: starting up...\n");
56

57
	timer_init(1);
58
	wrpc_w1_init();
59 60
	wrpc_w1_bus.detail = ONEWIRE_PORT;
	w1_scan_bus(&wrpc_w1_bus);
61

62 63
	/*initialize flash*/
	flash_init();
64 65
	/*initialize I2C bus*/
	mi2c_init(WRPC_FMC_I2C);
66 67
	/*init storage (Flash / W1 EEPROM / I2C EEPROM*/
	storage_init(WRPC_FMC_I2C, FMC_EEPROM_ADR);
68

69
	if (get_persistent_mac(ONEWIRE_PORT, mac_addr) == -1) {
70
		pp_printf("Unable to determine MAC address\n");
71 72 73 74 75 76
		mac_addr[0] = 0x22;	//
		mac_addr[1] = 0x33;	//
		mac_addr[2] = 0x44;	// fallback MAC if get_persistent_mac fails
		mac_addr[3] = 0x55;	//
		mac_addr[4] = 0x66;	//
		mac_addr[5] = 0x77;	//
77
	}
78

79 80 81
	pp_printf("Local MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
		mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
		mac_addr[4], mac_addr[5]);
82

83 84
	ep_init(mac_addr);
	ep_enable(1, 1);
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
85

86
	minic_init();
87
	shw_pps_gen_init();
88
	wrc_ptp_init();
89 90
	//try reading t24 phase transition from EEPROM
	calib_t24p(WRC_MODE_MASTER, &cal_phase_transition);
91
	spll_very_init();
92

93
#ifdef CONFIG_ETHERBONE
94 95
	ipv4_init();
	arp_init();
96
#endif
97
}
98

99 100 101 102
#define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2
#define LINK_UP 3
#define LINK_DOWN 4
103

104
static int wrc_check_link(void)
105 106
{
	static int prev_link_state = -1;
107
	int link_state = ep_link_up(NULL);
108 109
	int rv = 0;

110 111 112 113 114 115 116 117 118 119 120 121 122
	if (!prev_link_state && link_state) {
		TRACE_DEV("Link up.\n");
		gpio_out(GPIO_LED_LINK, 1);
		rv = LINK_WENT_UP;
	} else if (prev_link_state && !link_state) {
		TRACE_DEV("Link down.\n");
		gpio_out(GPIO_LED_LINK, 0);
		rv = LINK_WENT_DOWN;
	} else
		rv = (link_state ? LINK_UP : LINK_DOWN);
	prev_link_state = link_state;

	return rv;
123
}
124

125 126 127
void wrc_debug_printf(int subsys, const char *fmt, ...)
{
	va_list ap;
128

129 130
	if (wrc_ui_mode)
		return;
131

132
	va_start(ap, fmt);
133

134
	if (subsys & (1 << 5) /* was: TRACE_SERVO -- see commit message */)
135
		vprintf(fmt, ap);
136

137 138 139 140 141
	va_end(ap);
}

int wrc_man_phase = 0;

142
static void ui_update(void)
143 144
{

145 146
	if (wrc_ui_mode == UI_GUI_MODE) {
		wrc_mon_gui();
147
		if (uart_read_byte() == 27 || wrc_ui_refperiod == 0) {
148 149
			shell_init();
			wrc_ui_mode = UI_SHELL_MODE;
150
		}
151
	} else {
152
		shell_interactive();
153 154 155 156
	}
	/* Stats is asynchronous now. It's not a different mode, but a flag */
	if (wrc_stat_running)
		wrc_log_stats();
157
}
158

159 160
/* initialize functions to be called after reset in check_reset function */
void init_hw_after_reset(void)
161
{
162 163
	/* Ok, now init the devices so we can printf and delay */
	sdb_find_devices();
164 165
	uart_init_sw();
	uart_init_hw();
166 167 168
	timer_init(1);
}

169 170
int main(void)
{
171 172 173
	extern uint32_t uptime_sec;
	uint32_t j, lastj, fraction = 0;

174
	check_reset();
175
	wrc_ui_mode = UI_SHELL_MODE;
176
	_endram = ENDRAM_MAGIC;
177

178
	wrc_initialize();
179
	usleep_init();
180
	shell_init();
181

182 183
	wrc_ptp_set_mode(WRC_MODE_SLAVE);
	wrc_ptp_start();
184

185 186
	//try to read and execute init script from EEPROM
	shell_boot_script();
187
	lastj = timer_get_tics();
188

189 190
	for (;;) {
		int l_status = wrc_check_link();
191

192 193 194 195 196 197 198 199 200
		/* count uptime, in seconds, for remote polling */
		j = timer_get_tics();
		fraction += j -lastj;
		lastj = j;
		while (fraction > TICS_PER_SECOND) {
			fraction -= TICS_PER_SECOND;
			uptime_sec++;
		}

201
		switch (l_status) {
202
#ifdef CONFIG_ETHERBONE
203 204 205
		case LINK_WENT_UP:
			needIP = 1;
			break;
206
#endif
207

208 209
		case LINK_UP:
			update_rx_queues();
210
#ifdef CONFIG_ETHERBONE
211 212
			ipv4_poll();
			arp_poll();
213
#endif
214 215 216
			break;

		case LINK_WENT_DOWN:
217
			if (wrc_ptp_get_mode() == WRC_MODE_SLAVE) {
218
				spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
219 220
				shw_pps_gen_enable_output(0);
			}
221 222 223 224 225
			break;
		}

		ui_update();
		wrc_ptp_update();
226
		spll_update();
227
		check_stack();
228
	}
229
}