test program for Silicon Laboratories Inc. Si5351A-B-GT I2C-PROGRAMMABLE ANY-FREQUENCY CMOS CLOCK GENERATOR
Diff: si5351a_check.cpp
- Revision:
- 0:d68f1e7f7f49
- Child:
- 1:2b29f68043f7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/si5351a_check.cpp Sun Jan 01 01:28:25 2017 +0000 @@ -0,0 +1,556 @@ +/* + * 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'); +}