2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-25 03:08:27 +08:00

runtime: allow selecting external clock at startup

This commit is contained in:
Sebastien Bourdeauducq 2015-07-28 00:19:07 +08:00
parent 09d837e4ba
commit 7feaca7c7c
5 changed files with 78 additions and 35 deletions

View File

@ -1,6 +1,6 @@
include $(MSCDIR)/software/common.mak
OBJECTS := isr.o flash_storage.o clock.o elf_loader.o services.o session.o log.o test_mode.o kloader.o bridge_ctl.o mailbox.o ksupport_data.o kserver.o moninj.o main.o
OBJECTS := isr.o flash_storage.o clock.o rtiocrg.o elf_loader.o services.o session.o log.o test_mode.o kloader.o bridge_ctl.o mailbox.o ksupport_data.o kserver.o moninj.o main.o
OBJECTS_KSUPPORT := ksupport.o exception_jmp.o exceptions.o mailbox.o bridge.o rtio.o ttl.o dds.o
CFLAGS += -Ilwip/src/include -Iliblwip

View File

@ -24,6 +24,7 @@
#include "kloader.h"
#include "flash_storage.h"
#include "clock.h"
#include "rtiocrg.h"
#include "test_mode.h"
#include "kserver.h"
#include "session.h"
@ -250,13 +251,10 @@ int main(void)
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
clock_init();
rtiocrg_init();
puts("Press 't' to enter test mode...");
blink_led();
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
rtio_crg_pll_reset_write(0);
#endif
if(check_test_mode()) {
puts("Entering test mode.");
test_main();

64
soc/runtime/rtiocrg.c Normal file
View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <generated/csr.h>
#include "clock.h"
#include "flash_storage.h"
#include "rtiocrg.h"
void rtiocrg_init(void)
{
char b;
int clk;
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
rtio_crg_pll_reset_write(0);
#endif
b = 'i';
clk = 0;
fs_read("startup_clock", &b, 1, NULL);
if(b == 'i')
printf("Startup RTIO clock: internal\n");
else if(b == 'e') {
printf("Startup RTIO clock: external\n");
clk = 1;
} else
printf("WARNING: unknown startup_clock entry in flash storage\n");
if(!rtiocrg_switch_clock(clk))
printf("WARNING: startup RTIO clock failed\n");
}
int rtiocrg_check(void)
{
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
return rtio_crg_pll_locked_read();
#else
return 1;
#endif
}
int rtiocrg_switch_clock(int clk)
{
int current_clk;
current_clk = rtio_crg_clock_sel_read();
if(clk == current_clk) {
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
busywait_us(150);
if(!rtio_crg_pll_locked_read())
return 0;
#endif
return 1;
}
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
rtio_crg_pll_reset_write(1);
#endif
rtio_crg_clock_sel_write(clk);
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
rtio_crg_pll_reset_write(0);
busywait_us(150);
if(!rtio_crg_pll_locked_read())
return 0;
#endif
return 1;
}

8
soc/runtime/rtiocrg.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __RTIOCRG_H
#define __RTIOCRG_H
void rtiocrg_init(void);
int rtiocrg_check(void);
int rtiocrg_switch_clock(int clk);
#endif /* __RTIOCRG_H */

View File

@ -12,6 +12,7 @@
#include "kloader.h"
#include "exceptions.h"
#include "flash_storage.h"
#include "rtiocrg.h"
#include "session.h"
#define BUFFER_IN_SIZE (1024*1024)
@ -128,32 +129,6 @@ static int check_flash_storage_key_len(char *key, unsigned int key_len)
return 1;
}
static int switch_clock(int clk)
{
int current_clk;
current_clk = rtio_crg_clock_sel_read();
if(clk == current_clk) {
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
busywait_us(150);
if(!rtio_crg_pll_locked_read())
return 0;
#endif
return 1;
}
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
rtio_crg_pll_reset_write(1);
#endif
rtio_crg_clock_sel_write(clk);
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
rtio_crg_pll_reset_write(0);
busywait_us(150);
if(!rtio_crg_pll_locked_read())
return 0;
#endif
return 1;
}
static int process_input(void)
{
switch(buffer_in[8]) {
@ -180,7 +155,7 @@ static int process_input(void)
submit_output(9);
break;
}
if(switch_clock(buffer_in[9]))
if(rtiocrg_switch_clock(buffer_in[9]))
buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_COMPLETED;
else
buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED;
@ -561,13 +536,11 @@ void session_poll(void **data, int *len)
*len = -1;
return;
}
#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR
if(!rtio_crg_pll_locked_read()) {
if(!rtiocrg_check()) {
log("RTIO clock failure");
*len = -1;
return;
}
#endif
}
l = get_out_packet_len();