Al Williams
/
freqgen1114
Si5351 library uses the Si configuration tool output to program frequencies via I2C
main.cpp@0:e9b74a8ed1d1, 2015-10-13 (annotated)
- Committer:
- wd5gnr
- Date:
- Tue Oct 13 02:03:48 2015 +0000
- Revision:
- 0:e9b74a8ed1d1
Initial commit;
Who changed what in which revision?
User | Revision | Line number | New 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 | } |