Rev 3599 Rev 3734
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 2916 2013-04-14 17:42:03Z kaklik $"
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 SEL0 PIN_E0 // external counter division ratio 18 #define SEL0 PIN_E0 // external counter division ratio
19 #define SEL1 PIN_E1 // external counter division ratio 19 #define SEL1 PIN_E1 // external counter division ratio
20 #define MR PIN_E2 // external counter master reset 20 #define MR PIN_E2 // external counter master reset
21 #define CLKI PIN_C0 // internal counter input 21 #define CLKI PIN_C0 // internal counter input
22   22  
23 unsigned int32 count; // count per second 23 unsigned int32 count; // count per second
24   24  
25 #define BUF_LEN 4 25 #define BUF_LEN 4
26 int8 buffer[BUF_LEN]; // I2C buffer 26 int8 buffer[BUF_LEN]; // I2C buffer
27 int8 address=0; 27 int8 address=0;
28   28  
29 unsigned int16 of=0; // count of overflow 29 unsigned int16 of=0; // count of overflow
30   -  
31 // 1x 100 us per 10 s UTC synchronised -  
32 const char cmd[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}; -  
33 30
-   31 // configure GPS
-   32 void setup_GPS()
-   33 {
-   34 // 1x 100 us per 10 s UTC synchronised
-   35 const char cmd[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};
-   36 int n;
-   37 for (n=0;n<40;n++) putc(cmd[n]);
-   38 }
-   39  
34 #INT_SSP 40 #INT_SSP
35 void ssp_interupt () 41 void ssp_interupt ()
36 { 42 {
37 int8 incoming, state; 43 int8 incoming, state;
38   44  
39 state = i2c_isr_state(); 45 state = i2c_isr_state();
40   46  
41 if(state < 0x80) //Master is sending data 47 if(state < 0x80) //Master is sending data
42 { 48 {
43 incoming = i2c_read(); // Read byte 49 incoming = i2c_read(); // Read byte
44   50  
45 if(state == 1) //Second received byte is address of register 51 if(state == 1) //Second received byte is address of register
46 { 52 {
47 address = incoming; 53 address = incoming;
48 } 54 }
49 } 55 }
50 if(state == 0x80) //Master is requesting data 56 if(state == 0x80) //Master is requesting data
51 { 57 {
52 //i2c_read(); // Dummy read of I2C device address 58 //i2c_read(); // Dummy read of I2C device address
53 59
54 if(address == 0) // Change buffer atomically at reading of the first byte 60 if(address == 0) // Change buffer atomically at reading of the first byte
55 { 61 {
56 buffer[0]=make8(count,0); 62 buffer[0]=make8(count,0);
57 buffer[1]=make8(count,1); 63 buffer[1]=make8(count,1);
58 buffer[2]=make8(count,2); 64 buffer[2]=make8(count,2);
59 buffer[3]=make8(count,3); 65 buffer[3]=make8(count,3);
60 } 66 }
61 if(address <= BUF_LEN) i2c_write(buffer[address]); // Prepare one byte to SSP buffer 67 if(address <= BUF_LEN) i2c_write(buffer[address]); // Prepare one byte to SSP buffer
62 else 68 else
63 { 69 {
64 i2c_write(0x00); // There is nothing to prepare, so zero 70 i2c_write(0x00); // There is nothing to prepare, so zero
65 } 71 }
66 } 72 }
67   73  
68 if(state == 0x81) //Master is requesting data 74 if(state == 0x81) //Master is requesting data
69 { 75 {
70 i2c_write(buffer[1]); // Prepare next byte to SSP buffer 76 i2c_write(buffer[1]); // Prepare next byte to SSP buffer
71 } 77 }
72 if(state == 0x82) //Master is requesting data 78 if(state == 0x82) //Master is requesting data
73 { 79 {
74 i2c_write(buffer[2]); // Prepare next byte to SSP buffer 80 i2c_write(buffer[2]); // Prepare next byte to SSP buffer
75 } 81 }
76 if(state == 0x83) //Master is requesting data 82 if(state == 0x83) //Master is requesting data
77 { 83 {
78 i2c_write(buffer[3]); // Prepare next byte to SSP buffer 84 i2c_write(buffer[3]); // Prepare next byte to SSP buffer
-   85
-   86 setup_GPS();
79 } 87 }
80   88  
81 if(state > 0x83) //Master is requesting data 89 if(state > 0x83) //Master is requesting data
82 { 90 {
83 i2c_write(0x00); // There is nothing to prepare, so zero 91 i2c_write(0x00); // There is nothing to prepare, so zero
84 } 92 }
85 } 93 }
86   94  
87   95  
88   96  
89 #int_EXT // Interrupt from 1PPS (RB0) 97 #int_EXT // Interrupt from 1PPS (RB0)
90 void EXT_isr(void) 98 void EXT_isr(void)
91 { 99 {
92 unsigned int16 countH; 100 unsigned int16 countH;
93 unsigned int8 countL; 101 unsigned int8 countL;
94 int16 of2; 102 int16 of2;
95 103
96 of2=of; // read overflow counter 104 of2=of; // read overflow counter
97 countH=get_timer1(); // read internal counter 105 countH=get_timer1(); // read internal counter
98 countL=0; 106 countL=0;
99 output_low(SEL0); 107 output_low(SEL0);
100 output_low(SEL1); 108 output_low(SEL1);
101 countL=input(CLKI); // read bit 0 of external counter 109 countL=input(CLKI); // read bit 0 of external counter
102 output_high(SEL0); 110 output_high(SEL0);
103 // output_low(SEL1); 111 // output_low(SEL1);
104 countL|=input(CLKI)<<1; // read bit 1 of external counter 112 countL|=input(CLKI)<<1; // read bit 1 of external counter
105 output_low(SEL0); 113 output_low(SEL0);
106 output_high(SEL1); 114 output_high(SEL1);
107 countL|=input(CLKI)<<2; // read bit 2 of external counter 115 countL|=input(CLKI)<<2; // read bit 2 of external counter
108 output_high(SEL0); 116 output_high(SEL0);
109 // output_high(SEL1); 117 // output_high(SEL1);
110 countL|=input(CLKI)<<3; // read bit 3 of external counter 118 countL|=input(CLKI)<<3; // read bit 3 of external counter
111   119  
112 output_low(MR); // External counter Master Reset 120 output_low(MR); // External counter Master Reset
113 output_high(MR); 121 output_high(MR);
114 set_timer1(0); // Internal counter reset 122 set_timer1(0); // Internal counter reset
115 of=0; // Overflow counter reset 123 of=0; // Overflow counter reset
116 124
117 count=((unsigned int32)of2<<20)+((unsigned int32)countH<<4)+(unsigned int32)countL; // concatenate 125 count=((unsigned int32)of2<<20)+((unsigned int32)countH<<4)+(unsigned int32)countL; // concatenate
118   126  
119 // printf("%010Lu\r\n", count); 127 // printf("%010Lu\r\n", count);
120 } 128 }
121   129  
122 #int_TIMER1 // Interrupf from overflow 130 #int_TIMER1 // Interrupf from overflow
123 void TIMER1_isr(void) 131 void TIMER1_isr(void)
124 { 132 {
125 of++; 133 of++;
126 } 134 }
127   135  
128   -  
129 void main() 136 void main()
130 { 137 {
131 setup_adc_ports(NO_ANALOGS|VSS_VDD); 138 setup_adc_ports(NO_ANALOGS|VSS_VDD);
132 setup_adc(ADC_OFF); 139 setup_adc(ADC_OFF);
133 // setup_spi(SPI_SS_DISABLED); //must not be set if I2C are in use! 140 // setup_spi(SPI_SS_DISABLED); //must not be set if I2C are in use!
134 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); 141 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
135 setup_wdt(WDT_2304MS); 142 setup_wdt(WDT_2304MS);
136 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); 143 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
137 setup_timer_2(T2_DISABLED,0,1); 144 setup_timer_2(T2_DISABLED,0,1);
138 setup_comparator(NC_NC_NC_NC); 145 setup_comparator(NC_NC_NC_NC);
139 setup_vref(FALSE); 146 setup_vref(FALSE);
140   147  
141 restart_wdt(); 148 restart_wdt();
142 delay_ms(1000); 149 delay_ms(1000);
143 restart_wdt(); 150 restart_wdt();
144 151
145 // setup GPS 152 // setup GPS
146 { -  
147 int n; 153 setup_GPS();
148 for (n=0;n<40;n++) putc(cmd[n]); -  
149 } -  
150   154  
151 ext_int_edge( L_TO_H ); // set 1PPS active edge 155 ext_int_edge( L_TO_H ); // set 1PPS active edge
152 enable_interrupts(INT_TIMER1); 156 enable_interrupts(INT_TIMER1);
153 enable_interrupts(INT_EXT); 157 enable_interrupts(INT_EXT);
154 enable_interrupts(INT_SSP); 158 enable_interrupts(INT_SSP);
155 enable_interrupts(GLOBAL); 159 enable_interrupts(GLOBAL);
156 160
157 buffer[0]=0x0; // Clear I2C output buffer 161 buffer[0]=0x0; // Clear I2C output buffer
158 buffer[1]=0x0; 162 buffer[1]=0x0;
159 buffer[2]=0x0; 163 buffer[2]=0x0;
160 buffer[3]=0x0; 164 buffer[3]=0x0;
161   165  
162 printf("\r\ncvak...\r\n"); 166 printf("\r\ncvak...\r\n");
163   167  
164 while(true) 168 while(true)
165 { 169 {
166 restart_wdt(); 170 restart_wdt();
167 delay_ms(1500); 171 delay_ms(1500);
168 // printf("%X %X %X %X\r\n", buffer[0],buffer[1],buffer[2],buffer[3]); 172 // printf("%X %X %X %X\r\n", buffer[0],buffer[1],buffer[2],buffer[3]);
169 printf("%010Lu\r\n", count); 173 printf("%010Lu\r\n", count);
170 } 174 }
171 } 175 }