Si5351 library uses the Si configuration tool output to program frequencies via I2C

Dependencies:   mbed

Committer:
wd5gnr
Date:
Tue Oct 13 02:03:48 2015 +0000
Revision:
0:e9b74a8ed1d1
Initial commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wd5gnr 0:e9b74a8ed1d1 1 #include "mbed.h"
wd5gnr 0:e9b74a8ed1d1 2
wd5gnr 0:e9b74a8ed1d1 3 // Simple driver for Si5351 -- Williams
wd5gnr 0:e9b74a8ed1d1 4 // Expects you to use the desktop configuration tool at
wd5gnr 0:e9b74a8ed1d1 5 // https://www.silabs.com/products/clocksoscillators/pages/timing-software-development-tools.aspx
wd5gnr 0:e9b74a8ed1d1 6
wd5gnr 0:e9b74a8ed1d1 7 I2C i2c(dp5, dp27); // change to suit your i2c -- I used an LPC1114
wd5gnr 0:e9b74a8ed1d1 8
wd5gnr 0:e9b74a8ed1d1 9 DigitalOut myled(LED1);
wd5gnr 0:e9b74a8ed1d1 10 const int addr = 0xC0; // note: address is x2 so really 0x60 shifted over
wd5gnr 0:e9b74a8ed1d1 11
wd5gnr 0:e9b74a8ed1d1 12 // The SI tool for generating a clock plan will dump a large
wd5gnr 0:e9b74a8ed1d1 13 // text file (select export plan for others)
wd5gnr 0:e9b74a8ed1d1 14 // In there will be 232 lines of register "map"
wd5gnr 0:e9b74a8ed1d1 15 // You need entries 15-92 and 149-170
wd5gnr 0:e9b74a8ed1d1 16 // The entries will look like:
wd5gnr 0:e9b74a8ed1d1 17 // 15,00h
wd5gnr 0:e9b74a8ed1d1 18 // I used regular expressions in my editor (emacs)
wd5gnr 0:e9b74a8ed1d1 19 // to convert ,\(..\)h -> ,0x\1
wd5gnr 0:e9b74a8ed1d1 20 // Then I copy paste the lines I want to another buffer
wd5gnr 0:e9b74a8ed1d1 21 // and then replace
wd5gnr 0:e9b74a8ed1d1 22 // [0-9]+, -> ,
wd5gnr 0:e9b74a8ed1d1 23 // That is relace the nubers ahead of the commas with nothing
wd5gnr 0:e9b74a8ed1d1 24 // Then you can paste it below in map0 (15-92) and map1 (149-170)
wd5gnr 0:e9b74a8ed1d1 25 // You actually don't even need all of these for the little 3 channel
wd5gnr 0:e9b74a8ed1d1 26 // breakout board, but it is fast and simple to just blow it all out
wd5gnr 0:e9b74a8ed1d1 27 // NOTE: Do not replace the first byte of each array (15 and 149) as
wd5gnr 0:e9b74a8ed1d1 28 // these are the register addresses.
wd5gnr 0:e9b74a8ed1d1 29
wd5gnr 0:e9b74a8ed1d1 30 char map0[] = { 15, // registers 15-92
wd5gnr 0:e9b74a8ed1d1 31 0x00
wd5gnr 0:e9b74a8ed1d1 32 ,0x4F
wd5gnr 0:e9b74a8ed1d1 33 ,0x6F
wd5gnr 0:e9b74a8ed1d1 34 ,0x4F
wd5gnr 0:e9b74a8ed1d1 35 ,0x80
wd5gnr 0:e9b74a8ed1d1 36 ,0x80
wd5gnr 0:e9b74a8ed1d1 37 ,0x80
wd5gnr 0:e9b74a8ed1d1 38 ,0xC0
wd5gnr 0:e9b74a8ed1d1 39 ,0xC0
wd5gnr 0:e9b74a8ed1d1 40 ,0x00
wd5gnr 0:e9b74a8ed1d1 41 ,0x00
wd5gnr 0:e9b74a8ed1d1 42 ,0x00
wd5gnr 0:e9b74a8ed1d1 43 ,0x01
wd5gnr 0:e9b74a8ed1d1 44 ,0x00
wd5gnr 0:e9b74a8ed1d1 45 ,0x10
wd5gnr 0:e9b74a8ed1d1 46 ,0x00
wd5gnr 0:e9b74a8ed1d1 47 ,0x00
wd5gnr 0:e9b74a8ed1d1 48 ,0x00
wd5gnr 0:e9b74a8ed1d1 49 ,0x00
wd5gnr 0:e9b74a8ed1d1 50 ,0x00
wd5gnr 0:e9b74a8ed1d1 51 ,0x01
wd5gnr 0:e9b74a8ed1d1 52 ,0x00
wd5gnr 0:e9b74a8ed1d1 53 ,0x0E
wd5gnr 0:e9b74a8ed1d1 54 ,0x00
wd5gnr 0:e9b74a8ed1d1 55 ,0x00
wd5gnr 0:e9b74a8ed1d1 56 ,0x00
wd5gnr 0:e9b74a8ed1d1 57 ,0x00
wd5gnr 0:e9b74a8ed1d1 58 ,0x00
wd5gnr 0:e9b74a8ed1d1 59 ,0x01
wd5gnr 0:e9b74a8ed1d1 60 ,0x01
wd5gnr 0:e9b74a8ed1d1 61 ,0xC0
wd5gnr 0:e9b74a8ed1d1 62 ,0x00
wd5gnr 0:e9b74a8ed1d1 63 ,0x00
wd5gnr 0:e9b74a8ed1d1 64 ,0x00
wd5gnr 0:e9b74a8ed1d1 65 ,0x00
wd5gnr 0:e9b74a8ed1d1 66 ,0x00
wd5gnr 0:e9b74a8ed1d1 67 ,0x01
wd5gnr 0:e9b74a8ed1d1 68 ,0x43
wd5gnr 0:e9b74a8ed1d1 69 ,0xE6
wd5gnr 0:e9b74a8ed1d1 70 ,0x00
wd5gnr 0:e9b74a8ed1d1 71 ,0x00
wd5gnr 0:e9b74a8ed1d1 72 ,0x00
wd5gnr 0:e9b74a8ed1d1 73 ,0x00
wd5gnr 0:e9b74a8ed1d1 74 ,0x00
wd5gnr 0:e9b74a8ed1d1 75 ,0x01
wd5gnr 0:e9b74a8ed1d1 76 ,0x03
wd5gnr 0:e9b74a8ed1d1 77 ,0x82
wd5gnr 0:e9b74a8ed1d1 78 ,0x00
wd5gnr 0:e9b74a8ed1d1 79 ,0x00
wd5gnr 0:e9b74a8ed1d1 80 ,0x00
wd5gnr 0:e9b74a8ed1d1 81 ,0x00
wd5gnr 0:e9b74a8ed1d1 82 ,0x00
wd5gnr 0:e9b74a8ed1d1 83 ,0x00
wd5gnr 0:e9b74a8ed1d1 84 ,0x00
wd5gnr 0:e9b74a8ed1d1 85 ,0x00
wd5gnr 0:e9b74a8ed1d1 86 ,0x00
wd5gnr 0:e9b74a8ed1d1 87 ,0x00
wd5gnr 0:e9b74a8ed1d1 88 ,0x00
wd5gnr 0:e9b74a8ed1d1 89 ,0x00
wd5gnr 0:e9b74a8ed1d1 90 ,0x00
wd5gnr 0:e9b74a8ed1d1 91 ,0x00
wd5gnr 0:e9b74a8ed1d1 92 ,0x00
wd5gnr 0:e9b74a8ed1d1 93 ,0x00
wd5gnr 0:e9b74a8ed1d1 94 ,0x00
wd5gnr 0:e9b74a8ed1d1 95 ,0x00
wd5gnr 0:e9b74a8ed1d1 96 ,0x00
wd5gnr 0:e9b74a8ed1d1 97 ,0x00
wd5gnr 0:e9b74a8ed1d1 98 ,0x00
wd5gnr 0:e9b74a8ed1d1 99 ,0x00
wd5gnr 0:e9b74a8ed1d1 100 ,0x00
wd5gnr 0:e9b74a8ed1d1 101 ,0x00
wd5gnr 0:e9b74a8ed1d1 102 ,0x00
wd5gnr 0:e9b74a8ed1d1 103 ,0x00
wd5gnr 0:e9b74a8ed1d1 104 ,0x00
wd5gnr 0:e9b74a8ed1d1 105 ,0x00
wd5gnr 0:e9b74a8ed1d1 106 ,0x00
wd5gnr 0:e9b74a8ed1d1 107 ,0x00
wd5gnr 0:e9b74a8ed1d1 108 ,0x00
wd5gnr 0:e9b74a8ed1d1 109 };
wd5gnr 0:e9b74a8ed1d1 110
wd5gnr 0:e9b74a8ed1d1 111 char map1[] = {
wd5gnr 0:e9b74a8ed1d1 112 149, // registers 149-170
wd5gnr 0:e9b74a8ed1d1 113 0x00,
wd5gnr 0:e9b74a8ed1d1 114 0x00,
wd5gnr 0:e9b74a8ed1d1 115 0x00,
wd5gnr 0:e9b74a8ed1d1 116 0x00,
wd5gnr 0:e9b74a8ed1d1 117 0x00,
wd5gnr 0:e9b74a8ed1d1 118 0x00,
wd5gnr 0:e9b74a8ed1d1 119 0x00,
wd5gnr 0:e9b74a8ed1d1 120 0x00,
wd5gnr 0:e9b74a8ed1d1 121 0x00,
wd5gnr 0:e9b74a8ed1d1 122 0x00,
wd5gnr 0:e9b74a8ed1d1 123 0x00,
wd5gnr 0:e9b74a8ed1d1 124 0x00,
wd5gnr 0:e9b74a8ed1d1 125 0x00,
wd5gnr 0:e9b74a8ed1d1 126 0x00,
wd5gnr 0:e9b74a8ed1d1 127 0x00,
wd5gnr 0:e9b74a8ed1d1 128 0x00,
wd5gnr 0:e9b74a8ed1d1 129 0x00,
wd5gnr 0:e9b74a8ed1d1 130 0x00,
wd5gnr 0:e9b74a8ed1d1 131 0x00,
wd5gnr 0:e9b74a8ed1d1 132 0x00,
wd5gnr 0:e9b74a8ed1d1 133 0x00,
wd5gnr 0:e9b74a8ed1d1 134 0x00
wd5gnr 0:e9b74a8ed1d1 135 };
wd5gnr 0:e9b74a8ed1d1 136
wd5gnr 0:e9b74a8ed1d1 137
wd5gnr 0:e9b74a8ed1d1 138 // Easily send a byte to a register
wd5gnr 0:e9b74a8ed1d1 139 void send(int r,int x)
wd5gnr 0:e9b74a8ed1d1 140 {
wd5gnr 0:e9b74a8ed1d1 141 char cmd[2];
wd5gnr 0:e9b74a8ed1d1 142 cmd[0]=r;
wd5gnr 0:e9b74a8ed1d1 143 cmd[1]=x;
wd5gnr 0:e9b74a8ed1d1 144 i2c.write(addr,cmd,2);
wd5gnr 0:e9b74a8ed1d1 145 }
wd5gnr 0:e9b74a8ed1d1 146
wd5gnr 0:e9b74a8ed1d1 147 // Once the map arrays are set up, call this to load the chip with those values
wd5gnr 0:e9b74a8ed1d1 148 int updatemap(void)
wd5gnr 0:e9b74a8ed1d1 149 {
wd5gnr 0:e9b74a8ed1d1 150 char cmd[5];
wd5gnr 0:e9b74a8ed1d1 151 send(3,0xFF); // disable everything
wd5gnr 0:e9b74a8ed1d1 152 cmd[0]=16;
wd5gnr 0:e9b74a8ed1d1 153 cmd[1]=cmd[2]=cmd[3]=0x80;
wd5gnr 0:e9b74a8ed1d1 154 i2c.write(addr,cmd,4);
wd5gnr 0:e9b74a8ed1d1 155 i2c.write(addr,map0,sizeof(map0)); // blow register map to chip
wd5gnr 0:e9b74a8ed1d1 156 i2c.write(addr,map1,sizeof(map1));
wd5gnr 0:e9b74a8ed1d1 157 send(3,0); // turn everything back on
wd5gnr 0:e9b74a8ed1d1 158 send(177,0xAC); // reset PLLs
wd5gnr 0:e9b74a8ed1d1 159
wd5gnr 0:e9b74a8ed1d1 160 // To do: ought to make accessors to the map arrays to set different parameters
wd5gnr 0:e9b74a8ed1d1 161 return 0; // To do: error checking
wd5gnr 0:e9b74a8ed1d1 162 }
wd5gnr 0:e9b74a8ed1d1 163
wd5gnr 0:e9b74a8ed1d1 164 int main()
wd5gnr 0:e9b74a8ed1d1 165 {
wd5gnr 0:e9b74a8ed1d1 166
wd5gnr 0:e9b74a8ed1d1 167
wd5gnr 0:e9b74a8ed1d1 168 // Blink a light so as to not be boring
wd5gnr 0:e9b74a8ed1d1 169 updatemap();
wd5gnr 0:e9b74a8ed1d1 170 while(1) {
wd5gnr 0:e9b74a8ed1d1 171
wd5gnr 0:e9b74a8ed1d1 172 myled = 1;
wd5gnr 0:e9b74a8ed1d1 173 wait(0.2);
wd5gnr 0:e9b74a8ed1d1 174 myled = 0;
wd5gnr 0:e9b74a8ed1d1 175 wait(0.2);
wd5gnr 0:e9b74a8ed1d1 176 }
wd5gnr 0:e9b74a8ed1d1 177 }