test program for Silicon Laboratories Inc. Si5351A-B-GT I2C-PROGRAMMABLE ANY-FREQUENCY CMOS CLOCK GENERATOR
si5351a_check.cpp
- Committer:
- kenjiArai
- Date:
- 2017-08-23
- Revision:
- 5:e32ef4b85317
- Parent:
- 4:5981cf106502
File content as of revision 5:e32ef4b85317:
/* * 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 7th, 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 // RAM ------------------------------------------------------------------------ bool one_char = false; // ROM / Constant data -------------------------------------------------------- #if defined(RANGE_EXTENDED) static const uint32_t freq_tbl[] = { 1628, 1800, 1900, 2000, 2500, 2604, 2605, 2700, 3000, // 1.627KHz-3KHz // Above includes out of range freq. 4000, 5000, 8000, // 4KHz-8KHz 10000, 20000, 50000, 80000, // 10KHz-80KHz 100000, 200000, 500000, 800000, // 100KHz-800KHz 1000000, 2000000, 5000000, 8000000, // 1MHz-8MHz 10000000, 20000000, 50000000, 80000000, // 10MHz-80MHz 100000000, 150000000, 200000000, // 100MHz-200MHz // Belows are out of Si5351A specification !!!! 220000000, 250000000, 280000000, 300000000,// 200MHz-300MHz 0 // Terminate data!! }; #else static const uint32_t freq_tbl[] = { 2605, 4000, 5000, 8000, // 2.6KHz-8KHz 10000, 20000, 50000, 80000, // 10KHz-80KHz 100000, 200000, 500000, 800000, // 100KHz-800KHz 1000000, 2000000, 5000000, 8000000, // 1MHz-8MHz 10000000, 20000000, 50000000, 80000000, // 10MHz-80MHz 100000000, 150000000, 200000000, // 100MHz-200MHz 0 // Terminate data!! }; #endif //------------------------------------------------------------------------------ // Control Program //------------------------------------------------------------------------------ int main() { while (true){ test_si5351();} } // Help Massage void msg_hlp (void) { PRINTF(opening_msg); put_rn(); #if defined(RANGE_EXTENDED) PRINTF("0 - Check CLK0 output between 1.627KHz to 300MHz"); put_rn(); PRINTF("-> You are using RANGE_EXTENDED (defined in si5351a.h)"); put_rn(); PRINTF("-> In RANGE_EXTENDED mode, PLL sets 250MHz to 1.3GHz"); put_rn(); PRINTF("-> This causes high possibility to make a PARMANENT DAMAGE"); PRINTF(" for the chip!"); put_rn(); PRINTF("-> Don't use this mode!!!"); #else PRINTF("0 - Check CLK0 output between 2.605KHz to 200MHz"); #endif 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"); PRINTF("-> No wat to apply a frequency compensation"); 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("p - Compensation"); 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(); } // ---------- 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(); #if defined(RANGE_EXTENDED) PRINTF("-> You are using RANGE_EXTENDED (defined in si5351a.h)"); put_rn(); PRINTF("-> In RANGE_EXTENDED mode, PLL sets 375MHz to 1.3GHz"); put_rn(); PRINTF("-> This causes high possibility to make a PARMANENT DAMAGE"); PRINTF(" for the chip!"); put_rn(); #endif 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' : one_char = true; 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_r(); } 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, 100)); put_rn(); break; 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, -100)); 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, P -> +100Hz"); put_rn(); PRINTF("m -> -10Hz, M -> -100Hz"); 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; } } one_char = false; 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; //-------------------------------------------------------------- // Compensation //-------------------------------------------------------------- case 'p' : clk.set_frequency(0, 25000000); // Set CLK0=10MHz PRINTF( "Please measure Clock0 output frequency (aound 25MHz)\r\n"); PRINTF("Enter your mesured data = "); ptr = linebuf; get_line(ptr, buf_size); if (xatoi(&ptr,&f)){ if (f < 0){ PUTC('?'); break; } PRINTF("\r%u [Hz]\r\n", f); clk.f_compensation(25000000, f); clk.debug_current_config(); } else { PUTC('?'); } 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; } } } #if defined(INCREMENT) void test(uint8_t channel) { uint32_t f_set = 4000; // 4KHz double f = 0; uint32_t flg = 0; char *ptr; int32_t seconds = 1; 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); PRINTF("Please enter interval time[sec] -> "); ptr = linebuf; get_line(ptr, buf_size); put_r(); xatoi(&ptr,&seconds); if (seconds <= 0){ seconds = 1;} if (seconds > 1000){ seconds = 1000;} PRINTF("%u[sec]\r\n", seconds); 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; } delay(seconds); } } #endif #if defined(TABLE_LOOK) void test(uint8_t channel) { uint32_t f_set = 0; uint32_t i,j; double f = 0; char *ptr; int32_t seconds = 1; clk.all_reset(); PRINTF("Please enter interval time[sec] -> "); ptr = linebuf; get_line(ptr, buf_size); put_r(); xatoi(&ptr,&seconds); if (seconds <= 0){ seconds = 1;} if (seconds > 1000){ seconds = 1000;} PRINTF("%u[sec]\r\n", seconds); 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; } delay(seconds); } 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; } delay(seconds); } } } #endif void special_command(void) { PRINTF("Not impliment yet"); put_rn(); } void delay(int32_t time) { #if MBED_MAJOR_VERSION == 2 wait((float)time); #elif MBED_MAJOR_VERSION == 5 Thread::wait(time * 1000); #else #error "Running on Unknown OS" #endif } // 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; } // 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); // Special control if (one_char == true){ if ((c == 'p') || (c == 'm') || (c == 'P') || (c == 'M')){ break; } } } } buff[idx] = 0; PUTC('\n'); }