Rev 3735 Rev 3741
1 // Atomic counter with I2C and RS232 output 1 // Atomic counter with I2C and RS232 output
2   2  
3 // Usage conditions: 3 // Usage conditions:
4 // 1. The first I2C or RS232 readout can be performed minimally 20 s after power up. 4 // 1. The first I2C or RS232 readout can be performed minimally 20 s after power up.
5 // 2. The I2C internal address 0 has to be read first. 5 // 2. The I2C internal address 0 has to be read first.
6 // 3. An I2C readout can be performed at 15-th, 35-th and 55-th second of UTC. 6 // 3. An I2C readout can be performed at 15-th, 35-th and 55-th second of UTC.
7 // 7 //
8 // Counter gives 32 bit value: 8 // Counter gives 32 bit value:
9 // I2C register address 0 = LSB 9 // I2C register address 0 = LSB
10 // I2C register address 3 = MSB 10 // I2C register address 3 = MSB
11   11  
12 #define ID "$Id: main.c 2916 2013-04-14 17:42:03Z kaklik $" 12 #define ID "$Id: main.c 3741 2014-10-25 22:30:12Z kakl $"
13 #include "main.h" 13 #include "main.h"
14 #use i2c(SLAVE, Fast, sda=PIN_C4, scl=PIN_C3, force_hw, address=0xA2) 14 #use i2c(SLAVE, Fast, sda=PIN_C4, scl=PIN_C3, force_hw, address=0xA2)
15   15  
16 #include <string.h> 16 #include <string.h>
17   17  
-   18 #define LED PIN_B3 // heartbeat indicator
18 #define SEL0 PIN_E0 // external counter division ratio 19 #define SEL0 PIN_E0 // external counter division ratio
19 #define SEL1 PIN_E1 // external counter division ratio 20 #define SEL1 PIN_E1 // external counter division ratio
20 #define MR PIN_E2 // external counter master reset 21 #define MR PIN_E2 // external counter master reset
21 #define CLKI PIN_C0 // internal counter input 22 #define CLKI PIN_C0 // internal counter input
22   23  
23 unsigned int32 count; // count per second 24 unsigned int32 count; // count per second
24   25  
25 int1 fire_setup; // flag for sending setup to GPS 26 int1 fire_setup; // flag for sending setup to GPS
26   27  
27 #define BUF_LEN 4 28 #define BUF_LEN 4
28 int8 buffer[BUF_LEN]; // I2C buffer 29 int8 buffer[BUF_LEN]; // I2C buffer
29 int8 address=0; 30 int8 address=0;
30   31  
31 unsigned int16 of=0; // count of overflow 32 unsigned int16 of=0; // count of overflow
32   33  
33 // 1x 100 us per 10 s UTC synchronised; 40 configuration bytes 34 // 1x 100 us per 10 s UTC synchronised; 40 configuration bytes
34 char cmd[50]={40, 0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x80, 0x96, 0x98, 0x00, 0xE0, 0xC8, 0x10, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xC6, 0x51}; 35 char cmd[50]={40, 0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x80, 0x96, 0x98, 0x00, 0xE0, 0xC8, 0x10, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xC6, 0x51};
35   36  
36 // configure GPS 37 // configure GPS
37 void setup_GPS() 38 void setup_GPS()
38 { 39 {
39 int n; 40 int n;
40 int len; 41 int len;
41 len=cmd[0]; 42 len=cmd[0];
42 for (n=1;n<=len;n++) putc(cmd[n]); 43 for (n=1;n<=len;n++) putc(cmd[n]);
43 } 44 }
44   45  
45 #INT_SSP 46 #INT_SSP
46 void ssp_interupt () 47 void ssp_interupt ()
47 { 48 {
48 int8 incoming, state; 49 int8 incoming, state;
49   50  
50 state = i2c_isr_state(); 51 state = i2c_isr_state();
51   52  
52 if(state < 0x80) //Master is sending data 53 if(state < 0x80) //Master is sending data
53 { 54 {
54 incoming = i2c_read(); // Read byte 55 incoming = i2c_read(); // Read byte
55   56  
56 if(state == 1) //Second received byte is address of register 57 if(state == 1) //Second received byte is address of register
57 { 58 {
58 address = incoming; 59 address = incoming;
59 } 60 }
60   61  
61 if(state == 2) //Thid received byte are configuration data 62 if(state == 2) //Thid received byte are configuration data
62 { 63 {
63 if ((address==0)&&(incoming==0)) 64 if ((address==0)&&(incoming==0))
64 { 65 {
65 fire_setup = 1; // Write configuration to the GPS if configuration data length is 0 66 fire_setup = 1; // Write configuration to the GPS if configuration data length is 0
66 } 67 }
67 else 68 else
68 { 69 {
69 cmd[address] = incoming; // Store byte to configuration sentence 70 cmd[address] = incoming; // Store byte to configuration sentence
70 } 71 }
71 } 72 }
72 } 73 }
73 if(state == 0x80) //Master is requesting data 74 if(state == 0x80) //Master is requesting data
74 { 75 {
75 //i2c_read(); // Dummy read of I2C device address 76 //i2c_read(); // Dummy read of I2C device address
76 77
77 if(address == 0) // Change buffer atomically at reading of the first byte 78 if(address == 0) // Change buffer atomically at reading of the first byte
78 { 79 {
79 buffer[0]=make8(count,0); 80 buffer[0]=make8(count,0);
80 buffer[1]=make8(count,1); 81 buffer[1]=make8(count,1);
81 buffer[2]=make8(count,2); 82 buffer[2]=make8(count,2);
82 buffer[3]=make8(count,3); 83 buffer[3]=make8(count,3);
83 } 84 }
84 if(address <= BUF_LEN) 85 if(address <= BUF_LEN)
85 { 86 {
86 i2c_write(buffer[address]); // Prepare one byte to SSP buffer 87 i2c_write(buffer[address]); // Prepare one byte to SSP buffer
87 } 88 }
88 else 89 else
89 { 90 {
90 i2c_write(0x00); // There is nothing to prepare, so zero 91 i2c_write(0x00); // There is nothing to prepare, so zero
91 } 92 }
92 } 93 }
93   94  
94 if(state == 0x81) //Master is requesting data 95 if(state == 0x81) //Master is requesting data
95 { 96 {
96 i2c_write(buffer[1]); // Prepare next byte to SSP buffer 97 i2c_write(buffer[1]); // Prepare next byte to SSP buffer
97 } 98 }
98 if(state == 0x82) //Master is requesting data 99 if(state == 0x82) //Master is requesting data
99 { 100 {
100 i2c_write(buffer[2]); // Prepare next byte to SSP buffer 101 i2c_write(buffer[2]); // Prepare next byte to SSP buffer
101 } 102 }
102 if(state == 0x83) //Master is requesting data 103 if(state == 0x83) //Master is requesting data
103 { 104 {
104 i2c_write(buffer[3]); // Prepare next byte to SSP buffer 105 i2c_write(buffer[3]); // Prepare next byte to SSP buffer
105 } 106 }
106   107  
107 if(state > 0x83) //Master is requesting data 108 if(state > 0x83) //Master is requesting data
108 { 109 {
109 i2c_write(0x00); // There is nothing to prepare, so zero 110 i2c_write(0x00); // There is nothing to prepare, so zero
110 } 111 }
111 } 112 }
112   113  
113   114  
114   115  
115 #int_EXT // Interrupt from 1PPS (RB0) 116 #int_EXT // Interrupt from 1PPS (RB0)
116 void EXT_isr(void) 117 void EXT_isr(void)
117 { 118 {
118 unsigned int16 countH; 119 unsigned int16 countH;
119 unsigned int8 countL; 120 unsigned int8 countL;
120 int16 of2; 121 int16 of2;
121 122
122 of2=of; // read overflow counter 123 of2=of; // read overflow counter
123 countH=get_timer1(); // read internal counter 124 countH=get_timer1(); // read internal counter
124 countL=0; 125 countL=0;
125 output_low(SEL0); 126 output_low(SEL0);
126 output_low(SEL1); 127 output_low(SEL1);
127 countL=input(CLKI); // read bit 0 of external counter 128 countL=input(CLKI); // read bit 0 of external counter
128 output_high(SEL0); 129 output_high(SEL0);
129 // output_low(SEL1); 130 // output_low(SEL1);
130 countL|=input(CLKI)<<1; // read bit 1 of external counter 131 countL|=input(CLKI)<<1; // read bit 1 of external counter
131 output_low(SEL0); 132 output_low(SEL0);
132 output_high(SEL1); 133 output_high(SEL1);
133 countL|=input(CLKI)<<2; // read bit 2 of external counter 134 countL|=input(CLKI)<<2; // read bit 2 of external counter
134 output_high(SEL0); 135 output_high(SEL0);
135 // output_high(SEL1); 136 // output_high(SEL1);
136 countL|=input(CLKI)<<3; // read bit 3 of external counter 137 countL|=input(CLKI)<<3; // read bit 3 of external counter
137   138  
-   139 output_toggle(LED); // heartbeat
138 output_low(MR); // External counter Master Reset 140 output_low(MR); // External counter Master Reset
139 output_high(MR); 141 output_high(MR);
140 set_timer1(0); // Internal counter reset 142 set_timer1(0); // Internal counter reset
141 of=0; // Overflow counter reset 143 of=0; // Overflow counter reset
142 144
143 count=((unsigned int32)of2<<20)+((unsigned int32)countH<<4)+(unsigned int32)countL; // concatenate 145 count=((unsigned int32)of2<<20)+((unsigned int32)countH<<4)+(unsigned int32)countL; // concatenate
144   146  
145 // printf("%010Lu\r\n", count); 147 // printf("%010Lu\r\n", count);
146 } 148 }
147   149  
148 #int_TIMER1 // Interrupf from overflow 150 #int_TIMER1 // Interrupf from overflow
149 void TIMER1_isr(void) 151 void TIMER1_isr(void)
150 { 152 {
151 of++; 153 of++;
152 } 154 }
153   155  
154 void main() 156 void main()
155 { 157 {
156 setup_adc_ports(NO_ANALOGS|VSS_VDD); 158 setup_adc_ports(NO_ANALOGS|VSS_VDD);
157 setup_adc(ADC_OFF); 159 setup_adc(ADC_OFF);
158 // setup_spi(SPI_SS_DISABLED); //must not be set if I2C are in use! 160 // setup_spi(SPI_SS_DISABLED); //must not be set if I2C are in use!
159 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); 161 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
160 setup_wdt(WDT_2304MS); 162 setup_wdt(WDT_2304MS);
161 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); 163 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
162 setup_timer_2(T2_DISABLED,0,1); 164 setup_timer_2(T2_DISABLED,0,1);
163 setup_comparator(NC_NC_NC_NC); 165 setup_comparator(NC_NC_NC_NC);
164 setup_vref(FALSE); 166 setup_vref(FALSE);
165   167  
166 restart_wdt(); 168 restart_wdt();
167 delay_ms(1000); 169 delay_ms(1000);
168 restart_wdt(); 170 restart_wdt();
169 171
170 // setup GPS 172 // setup GPS
171 setup_GPS(); 173 setup_GPS();
172   174  
173 ext_int_edge( L_TO_H ); // set 1PPS active edge 175 ext_int_edge( L_TO_H ); // set 1PPS active edge
174 enable_interrupts(INT_TIMER1); 176 enable_interrupts(INT_TIMER1);
175 enable_interrupts(INT_EXT); 177 enable_interrupts(INT_EXT);
176 enable_interrupts(INT_SSP); 178 enable_interrupts(INT_SSP);
177 enable_interrupts(GLOBAL); 179 enable_interrupts(GLOBAL);
178 180
179 buffer[0]=0x0; // Clear I2C output buffer 181 buffer[0]=0x0; // Clear I2C output buffer
180 buffer[1]=0x0; 182 buffer[1]=0x0;
181 buffer[2]=0x0; 183 buffer[2]=0x0;
182 buffer[3]=0x0; 184 buffer[3]=0x0;
183   185  
184 //printf("\r\ncvak...\r\n"); 186 //printf("\r\ncvak...\r\n");
185 187
186 fire_setup = 0; 188 fire_setup = 0;
187   189  
188 while(true) 190 while(true)
189 { 191 {
190 restart_wdt(); 192 restart_wdt();
191 delay_ms(1000); 193 delay_ms(1000);
192 if (fire_setup) 194 if (fire_setup)
193 { 195 {
194 setup_GPS(); // Write configuration to the GPS 196 setup_GPS(); // Write configuration to the GPS
195 fire_setup = 0; 197 fire_setup = 0;
196 } 198 }
-   199 output_toggle(LED); // heartbeat
197 //printf("%X %X %X %X\r\n", buffer[0],buffer[1],buffer[2],buffer[3]); 200 //printf("%X %X %X %X\r\n", buffer[0],buffer[1],buffer[2],buffer[3]);
198 //printf("%010Lu\r\n", count); 201 //printf("%010Lu\r\n", count);
199 } 202 }
200 } 203 }