test program for Silicon Laboratories Inc. Si5351A-B-GT I2C-PROGRAMMABLE ANY-FREQUENCY CMOS CLOCK GENERATOR

Dependencies:   Si5351A

si5351a_check.cpp

Committer:
kenjiArai
Date:
2017-01-01
Revision:
0:d68f1e7f7f49
Child:
1:2b29f68043f7

File content as of revision 0:d68f1e7f7f49:

/*
 * mbed Application program / Si5351A sample program
 *  tested on:
 *      ST Nucleo-F411RE & F401RE
 *		LPC1114FN28
 *
 *  Copyright (c) 2016,'17 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created:  December 28th, 2016
 *      Revised:  January   1st, 2017
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

//  Include --------------------------------------------------------------------
#include "mbed.h"
#include "si5351a.h"
#include "si5351a_check.h"

//  Definition -----------------------------------------------------------------

//  Object ---------------------------------------------------------------------
Serial		pc(USBTX, USBRX);
//I2C			i2c(dp5, dp27);	// communication with Si5351A
I2C			i2c(I2C_SDA, I2C_SCL);	// communication with Si5351A
SI5351A		clk(i2c, 25000000UL);	// base clock = 25.0MHz

//------------------------------------------------------------------------------
//  Control Program
//------------------------------------------------------------------------------
int main()
{
    while (true){ test_si5351();}
}

//  Help Massage
void msg_hlp (void)
{
    PRINTF(opening_msg);
    put_rn();
    PRINTF("0 - Check CLK0 output between 50KHz to 90MHz");
    put_rn();
    PRINTF("1 - Check CLK1 (same as #1)");
    put_rn();
    PRINTF("2 - Check CLK2 (same as #1)");
    put_rn();
    PRINTF("3 - Example CLK0:120.00MHz, CLK1:12.00MHz, CLK2:13.56MHz");
    put_rn();
    PRINTF("4 - Set desired freq. into CLK0");
    put_rn();
    PRINTF("5 - Set desired freq. into CLK0 & CLK1");
    put_rn();
    PRINTF("6 - Set desired freq. into CLK0, CLK1 & CLK2");
    put_rn();
    PRINTF("7 - CLK0: set desired center freq. then shift +/- range");
    put_rn();
    PRINTF("a - All clear registers");
    put_rn();
    PRINTF("c - Show current configration");
    put_rn();
    PRINTF("r - Show current resisters");
    put_rn();
    PRINTF("x - Go to special command");
    put_rn();
    PRINTF("Hit any key then return to prompt screen");
    put_rn();
    PRINTF("Reset mbed board -> please hit key <Alt>+<B>");
    put_rn();
}

#if defined(INCREMENT)
void test(uint8_t channel)
{
    uint32_t f_set = 4000;    // 4KHz
    double f = 0;
    uint32_t flg = 0;
    clk.all_reset();
    f = clk.set_frequency(channel, f_set);
    clk.debug_reg_print();
    PRINTF("CLK%u = %10.6f MHz\r\n", channel, f / 1000000.0f);
    while(true){
        f = clk.set_frequency(channel, f_set);
        PRINTF("CLK%u = %10.6f MHz\r\n", channel, f / 1000000.0f);
        if (flg){
            f_set = f * 0.95f;
            if (f_set < 5000){
                flg = 0;
            }
        } else {
            f_set = f * 1.05f;
            if (f_set > 190000000){
                flg = 1;
            }
        }
        if (READABLE()) {
            GETC();
            return;
        }
        wait(1.0);
    }
}
#endif

#if defined(TABLE_LOOK)
void test(uint8_t channel)
{
    uint32_t f_set = 0;
    uint32_t i,j;
    double f = 0;
    clk.all_reset();
    while(true){
        for (i = 0; ; i++){
        	f_set = freq_tbl[i];
        	if (f_set == 0){
        		break;
        	}
	        f = clk.set_frequency(channel, f_set);
	        PRINTF("CLK%u = %10.6f MHz\r\n", channel, f / 1000000.0f);
	        if (READABLE()) {
	            GETC();
	            return;
	        }
	        wait(1.0);
	    }
        for (j = i - 2; j > 0 ; j--){
        	f_set = freq_tbl[j];
	        f = clk.set_frequency(channel, f_set);
	        PRINTF("CLK%u = %10.6f MHz\r\n", channel, f / 1000000.0f);
	        if (READABLE()) {
	            GETC();
	            return;
	        }
	        wait(1.0);
	    }
    }
}
#endif

void special_command(void)
{
	PRINTF("Not impliment yet");
	put_rn();
}

// ---------- Program starts here! ---------------------------------------------
void test_si5351(void)
{
    char *ptr;
	int32_t f;

    BAUD(BAUD_RATE);
    put_rn();
    put_rn();
    PRINTF("%s [Help:'?' key]", opening_msg);
    put_rn();
    clk.all_reset();
    for (;;) {
        put_r();
        PUTC('>');
        ptr = linebuf;
        get_line(ptr, sizeof(linebuf));
        put_r();
        switch (*ptr++) {
                //--------------------------------------------------------------
                //  test0
                //--------------------------------------------------------------
            case '0' :
            	clk.all_reset();
            	test(0);
                //put_rn();
                break;
                //--------------------------------------------------------------
                //  test1
                //--------------------------------------------------------------
            case '1' :
            	clk.all_reset();
            	test(1);
                //put_rn();
                break;
                //--------------------------------------------------------------
                //  test2
                //--------------------------------------------------------------
            case '2' :
            	clk.all_reset();
            	test(2);
                //put_rn();
                break;
                //--------------------------------------------------------------
                //  test3
                //--------------------------------------------------------------
            case '3' :
			    clk.debug_example_clock();
			    //clk.debug_reg_print();
                //put_rn();
                break;
                //--------------------------------------------------------------
                //  test4
                //--------------------------------------------------------------
            case '4' :
            	clk.all_reset();
                PRINTF("CLK0 %s", msg0);
                put_rn();
                ptr = linebuf;
                get_line(ptr, buf_size);
                put_r();
                if (xatoi(&ptr,&f)){
                	if (f < 0){ break;}
                	PRINTF("CLK0:%u [Hz]", clk.set_frequency(0, f));
                } else {
                	PUTC('?');
                }
                put_rn();
                break;
                //--------------------------------------------------------------
                //  test5
                //--------------------------------------------------------------
            case '5' :
            	clk.all_reset();
                PRINTF("CLK0 %s", msg0);
                put_rn();
                ptr = linebuf;
                get_line(ptr, buf_size);
                put_r();
                if (xatoi(&ptr,&f)){
                	if (f < 0){ break;}
                	PRINTF("CLK0:%u [Hz]", clk.set_frequency(0, f));
                } else {
                	PUTC('?');
                }
                put_rn();
                PRINTF("CLK1 %s", msg0);
                put_rn();
                ptr = linebuf;
                get_line(ptr, buf_size);
                put_r();
                if (xatoi(&ptr,&f)){
                	if (f < 0){ break;}
                	PRINTF("CLK1:%u [Hz]", clk.set_frequency(1, f));
                } else {
                	PUTC('?');
                }
                put_rn();
                break;
                //--------------------------------------------------------------
                //  test6
                //--------------------------------------------------------------
            case '6' :
            	clk.all_reset();
                PRINTF("CLK0 %s", msg0);
                put_rn();
                ptr = linebuf;
                get_line(ptr, buf_size);
                put_r();
                if (xatoi(&ptr,&f)){
                	if (f < 0){ break;}
                	PRINTF("CLK0:%u [Hz]", clk.set_frequency(0, f));
                } else {
                	PUTC('?');
                }
                put_rn();
                PRINTF("CLK1 %s", msg0);
                put_rn();
                PRINTF(
                "If you set CLK1 over 100MHz, you cannt set CLK2 anymore");
                put_rn();
                ptr = linebuf;
                get_line(ptr, buf_size);
                put_r();
                if (xatoi(&ptr,&f)){
                	if (f < 0){ break;}
                	PRINTF("CLK1:%u [Hz]", clk.set_frequency(1, f));
                } else {
                	PUTC('?');
                }
                put_rn();
                PRINTF("CLK2 %s", msg0);
                put_rn();
                ptr = linebuf;
                get_line(ptr, buf_size);
                put_r();
                if (xatoi(&ptr,&f)){
                	if (f < 0){ break;}
                	PRINTF("CLK2:%u [Hz]", clk.set_frequency(2, f));
                } else {
                	PUTC('?');
                }
                put_rn();
                break;
                //--------------------------------------------------------------
                //  test7 CLK0: set desired center freq. then shift +/- range
                //--------------------------------------------------------------
            case '7' :
            	clk.all_reset();
                PRINTF("CLK0 %s", msg0);
                put_rn();
                ptr = linebuf;
                get_line(ptr, buf_size);
                put_r();
                if (xatoi(&ptr,&f)){
                	if (f < 0){ break;}
                	PRINTF("CLK0:%u [Hz]", clk.set_frequency(0, f));
                } else {
                	PUTC('?');
                }
                put_rn();
                PRINTF("Please enter sift command [Help: ?]");
                put_rn();
				while (true){
                    PRINTF("[S]>");
                    ptr = linebuf;
                    get_line(ptr, buf_size);
                    put_r();
                    switch(*ptr) {
                        case 'p' :
							PRINTF("Shift to %u [Hz]", clk.shift_freq(0, 10));
							put_rn();
                            break;
                        case 'm' :
							PRINTF("Shift to %u [Hz]", clk.shift_freq(0, -10));
							put_rn();
                            break;
                        case 's' :
                        	ptr++;
                        	xatoi(&ptr,&f);
                        	PRINTF("offset=%d\r\n", f);
                        	PRINTF("Shift to %u [Hz]", clk.shift_freq(0, f));
							put_rn();
                            break;
                        case '?' :
                            PRINTF("p -> +10Hz");
                            put_rn();
                            PRINTF("m -> -10Hz");
                            put_rn();
                            PRINTF("s -> Shift +/-x Hz (example -100)");
                            put_rn();                         
                            PRINTF("? -> You know this");
                            put_rn();
                            PRINTF("e -> Exit");
                            put_rn();
                            break;
                        case 'e' :
                            break;
                        default:
                            PUTC('?');
                            put_rn();
                    }
                    if (*ptr == 'e'){
                    	break;
                    }
                }
                break;
                //--------------------------------------------------------------
                //  All clear alll registers
                //--------------------------------------------------------------
            case 'a' :
            	clk.all_reset();
            	PRINTF("Cleared all of registers!\r\n");
            	break;
                //--------------------------------------------------------------
                //  Show configration
                //--------------------------------------------------------------
            case 'c' :
			    clk.debug_current_config();
                //put_rn();
                break;
                //--------------------------------------------------------------
                //  Show resisters
                //--------------------------------------------------------------
            case 'r' :
			    clk.debug_reg_print();
                //put_rn();
                break;         
                //--------------------------------------------------------------
                //  Go to special command
                //--------------------------------------------------------------
            case 'x' :
                special_command();
                break;
                //--------------------------------------------------------------
                //  help
                //--------------------------------------------------------------
            case '?' :
                msg_hlp();
                break;
                //--------------------------------------------------------------
                //    no support
                //--------------------------------------------------------------
            default:
                PUTC('?');
                put_rn();
                break;
        }
    }
}

//  Put \r\n
void put_rn ( void )
{
    PUTC('\r');
    PUTC('\n');
}

//  Put \r
void put_r ( void )
{
    PUTC('\r');
}

//  Change string -> integer
int xatoi (char **str, int32_t *res)
{
    uint32_t val;
    int8_t c, radix, s = 0;

    while ((c = **str) == ' ') (*str)++;
    if (c == '-') {
        s = 1;
        c = *(++(*str));
    }
    if (c == '+') {
    	c = *(++(*str));
	}
    if (c == '0') {
        c = *(++(*str));
        if (c <= ' ') {
            *res = 0;
            return 1;
        }
        if (c == 'x') {
            radix = 16;
            c = *(++(*str));
        } else {
            if (c == 'b') {
                radix = 2;
                c = *(++(*str));
            } else {
                if ((c >= '0')&&(c <= '9')) {
                    radix = 8;
                } else {
                    return 0;
                }
            }
        }
    } else {
        if ((c < '1')||(c > '9')) {
            return 0;
        }
        radix = 10;
    }
    val = 0;
    while (c > ' ') {
        if (c >= 'a') c -= 0x20;
        c -= '0';
        if (c >= 17) {
            c -= 7;
            if (c <= 9) return 0;
        }
        if (c >= radix) return 0;
        val = val * radix + c;
        c = *(++(*str));
    }
    if (s) val = -val;
    *res = val;
    return 1;
}

#if 0
int xatoi (			/* 0:Failed, 1:Successful */
	char **str,		/* Pointer to pointer to the string */
	long *res		/* Pointer to the valiable to store the value */
)
{
	unsigned long val;
	unsigned char c, r, s = 0;


	*res = 0;

	while ((c = **str) == ' ') (*str)++;	/* Skip leading spaces */

	if (c == '-') {		/* negative? */
		s = 1;
		c = *(++(*str));
	}

	if (c == '0') {
		c = *(++(*str));
		switch (c) {
		case 'x':		/* hexdecimal */
			r = 16; c = *(++(*str));
			break;
		case 'b':		/* binary */
			r = 2; c = *(++(*str));
			break;
		default:
			if (c <= ' ') return 1;	/* single zero */
			if (c < '0' || c > '9') return 0;	/* invalid char */
			r = 8;		/* octal */
		}
	} else {
		if (c < '0' || c > '9') return 0;	/* EOL or invalid char */
		r = 10;			/* decimal */
	}

	val = 0;
	while (c > ' ') {
		if (c >= 'a') c -= 0x20;
		c -= '0';
		if (c >= 17) {
			c -= 7;
			if (c <= 9) return 0;	/* invalid char */
		}
		if (c >= r) return 0;		/* invalid char for current radix */
		val = val * r + c;
		c = *(++(*str));
	}
	if (s) val = 0 - val;			/* apply sign if needed */

	*res = val;
	return 1;
}
#endif

//  Get key input data
void get_line (char *buff, int len)
{
    char c;
    int idx = 0;

    for (;;) {
        c = GETC();
        if (c == '\r') {
            buff[idx++] = c;
            break;
        }
        if ((c == '\b') && idx) {
            idx--;
            PUTC(c);
            PUTC(' ');
            PUTC(c);
        }
        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
            buff[idx++] = c;
            PUTC(c);
        }
    }
    buff[idx] = 0;
    PUTC('\n');
}