Rev 3463 Rev 3470
Line -... Line 1...
-   1 // Atomic counter with I2C and RS232 output
-   2  
-   3 // Usage conditions:
-   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.
-   6 // 3. An I2C readout can be performed at 15-th, 35-th and 55-th second of UTC.
-   7 //
-   8 // Counter gives 32 bit value:
-   9 // I2C register address 0 = LSB
-   10 // I2C register address 3 = MSB
-   11  
1 #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 $"
2 #include "main.h" 13 #include "main.h"
3 #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)
4   15  
5 //#include <string.h> 16 #include <string.h>
6   -  
7 #define LED PIN_E1 -  
8 #define CE PIN_E2 -  
9   17  
10 #define SEL0 PIN_E0 // external counter division ratio 18 #define SEL0 PIN_E0 // external counter division ratio
11 #define SEL1 PIN_E1 // external counter division ratio 19 #define SEL1 PIN_E1 // external counter division ratio
12 #define MR PIN_E2 // external counter master reset 20 #define MR PIN_E2 // external counter master reset
13 #define CLKI PIN_C0 // internal counter input 21 #define CLKI PIN_C0 // internal counter input
14 #define BEEP PIN_C3 // buzzer -  
15   22  
16 unsigned int32 count; 23 unsigned int32 count; // count per second
17   24  
18 const int8 buf_len=8; 25 #define BUF_LEN 4
19 int8 buffer[buf_len]; // I2C buffer 26 int8 buffer[BUF_LEN]; // I2C buffer
20 int8 address=0; 27 int8 address=0;
21   28  
22 unsigned int16 of=0; // count of overflow 29 unsigned int16 of=0; // count of overflow
23   30  
24 const char cmd[40]={0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x80, 0x84, 0x1E, 0x00, 0xE0, 0xC8, 0x10, 0x00, 0x40, 0x42, 0x0F, 0x00, 0xA0, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x00, 0x00, 0x12, 0x03}; 31 // 1x 100 us per 10 s UTC synchronised
25   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};
26   -  
-   33
27 #INT_SSP 34 #INT_SSP
28 void ssp_interupt () 35 void ssp_interupt ()
29 { 36 {
30 BYTE incoming, state; 37 int8 incoming, state;
31   38  
32 state = i2c_isr_state(); 39 state = i2c_isr_state();
-   40  
33 if(state < 0x80) //Master is sending data 41 if(state < 0x80) //Master is sending data
34 { 42 {
35 incoming = i2c_read(); 43 incoming = i2c_read(); // Read byte
-   44  
36 if(state == 1) //First received byte is address 45 if(state == 1) //Second received byte is address of register
37 { 46 {
38 address = incoming; 47 address = incoming;
39 if (incoming == 2) -  
40 { -  
41 /* buffer[0]=make8(anemo,0); -  
42 buffer[1]=make8(anemo,1); -  
43 buffer[2]=make8(rain,0); -  
44 buffer[3]=make8(rain,1); -  
45 */ } -  
46 } 48 }
47 if(state == 2) //Second received byte is data -  
48 buffer[address] = incoming; -  
49 } 49 }
50 if(state == 0x80) //Master is requesting data 50 if(state == 0x80) //Master is requesting data
51 { 51 {
-   52 //i2c_read(); // Dummy read of I2C device address
-   53
-   54 if(address == 0) // Change buffer atomically at reading of the first byte
-   55 {
-   56 buffer[0]=make8(count,0);
-   57 buffer[1]=make8(count,1);
-   58 buffer[2]=make8(count,2);
-   59 buffer[3]=make8(count,3);
-   60 }
52 if(address <= buf_len) i2c_write(buffer[address]); 61 if(address <= BUF_LEN) i2c_write(buffer[address]); // Prepare one byte to SSP buffer
-   62 else
-   63 {
53 else i2c_write(ID[address - buf_len]); 64 i2c_write(0x00); // There is nothing to prepare, so zero
-   65 }
-   66 }
-   67  
-   68 if(state == 0x81) //Master is requesting data
-   69 {
-   70 i2c_write(buffer[1]); // Prepare next byte to SSP buffer
-   71 }
-   72 if(state == 0x82) //Master is requesting data
-   73 {
-   74 i2c_write(buffer[2]); // Prepare next byte to SSP buffer
-   75 }
-   76 if(state == 0x83) //Master is requesting data
-   77 {
-   78 i2c_write(buffer[3]); // Prepare next byte to SSP buffer
-   79 }
-   80  
-   81 if(state > 0x83) //Master is requesting data
-   82 {
-   83 i2c_write(0x00); // There is nothing to prepare, so zero
54 } 84 }
55 } 85 }
56   86  
57   87  
58   88  
59 /*#int_EXT // Interrupt from 1PPS 89 #int_EXT // Interrupt from 1PPS (RB0)
60 void EXT_isr(void) 90 void EXT_isr(void)
61 { 91 {
62 unsigned int16 countH; 92 unsigned int16 countH;
63 unsigned int8 countL; 93 unsigned int8 countL;
64 char countS[10], a[4], b[4], c[4]; // strings for printing results 94 int16 of2;
65 95
66 countL=0; 96 of2=of; // read overflow counter
67 countH=get_timer1(); // read internal counter 97 countH=get_timer1(); // read internal counter
-   98 countL=0;
68 output_low(SEL0); 99 output_low(SEL0);
69 output_low(SEL1); 100 output_low(SEL1);
70 countL=input(CLKI); // read bit 0 of external counter 101 countL=input(CLKI); // read bit 0 of external counter
71 output_high(SEL0); 102 output_high(SEL0);
72 output_low(SEL1); 103 // output_low(SEL1);
73 countL|=input(CLKI)<<1; // read bit 1 of external counter 104 countL|=input(CLKI)<<1; // read bit 1 of external counter
74 output_low(SEL0); 105 output_low(SEL0);
75 output_high(SEL1); 106 output_high(SEL1);
76 countL|=input(CLKI)<<2; // read bit 2 of external counter 107 countL|=input(CLKI)<<2; // read bit 2 of external counter
77 output_high(SEL0); 108 output_high(SEL0);
78 output_high(SEL1); 109 // output_high(SEL1);
79 countL|=input(CLKI)<<3; // read bit 3 of external counter 110 countL|=input(CLKI)<<3; // read bit 3 of external counter
80   111  
81 output_low(MR); // External counter Master Reset 112 output_low(MR); // External counter Master Reset
82 output_high(MR); 113 output_high(MR);
83 -  
84 set_timer1(0); // Internal counter reset 114 set_timer1(0); // Internal counter reset
-   115 of=0; // Overflow counter reset
85 116
86 count=((unsigned int32)of<<20)+((unsigned int32)countH<<4)+(unsigned int32)countL; // concatenate 117 count=((unsigned int32)of2<<20)+((unsigned int32)countH<<4)+(unsigned int32)countL; // concatenate
87   -  
88 sprintf(countS,"%09Lu", count); // engeneering values conversion -  
89 strncpy(a, countS, 3); a[3]='\0'; -  
90 strncpy(b, &countS[3], 3); b[3]='\0'; -  
91 strncpy(c, &countS[6], 3); c[3]='\0'; -  
92 -  
93 printf("%s\r\n", countS); // output to RS232 -  
94   -  
95 output_toggle(BEEP); // cvak... -  
96   118  
97 of=0; // reset overflow counter 119 printf("%010Lu\r\n", count);
98 } 120 }
99   121  
100 #int_TIMER1 // Interrupf from overflow 122 #int_TIMER1 // Interrupf from overflow
101 void TIMER1_isr(void) 123 void TIMER1_isr(void)
102 { 124 {
103 of++; 125 of++;
104 } 126 }
105   127  
106   128  
107 /*#int_TIMER2 // every 10 ms -  
108 void TIMER2_isr(void) -  
109 { -  
110 output_low(CE); -  
111 count=get_timer1(); -  
112 set_timer1(0); -  
113 output_high(CE); -  
114 }*/ -  
115   -  
116 -  
117 void main() 129 void main()
118 { 130 {
119 /* setup_adc_ports(NO_ANALOGS|VSS_VDD); 131 setup_adc_ports(NO_ANALOGS|VSS_VDD);
120 setup_adc(ADC_OFF); 132 setup_adc(ADC_OFF);
121 // setup_spi(SPI_SS_DISABLED); 133 // setup_spi(SPI_SS_DISABLED); //must not be set if I2C are in use!
122 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); 134 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
123 // setup_wdt(WDT_144MS); 135 setup_wdt(WDT_2304MS);
124 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); 136 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
125 setup_timer_2(T2_DIV_BY_16,196,16); 137 setup_timer_2(T2_DISABLED,0,1);
126 setup_ccp1(CCP_OFF); -  
127 setup_comparator(NC_NC_NC_NC); 138 setup_comparator(NC_NC_NC_NC);
128 setup_vref(FALSE); 139 setup_vref(FALSE);
129   140  
130 */ -  
131   -  
132 setup_adc_ports(NO_ANALOGS|VSS_VDD); 141 restart_wdt();
133 // setup_adc(ADC_CLOCK_DIV_2); 142 delay_ms(1000);
134 setup_adc(ADC_OFF); 143 restart_wdt();
135 // setup_spi(SPI_SS_DISABLED); //must not be set if I2C are in use! -  
136 setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1); -  
137 // setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_144MS); -  
138 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT); -  
-   144
139 // setup_timer_2(T2_DISABLED,0,1); 145 // setup GPS
140 setup_comparator(NC_NC_NC_NC); 146 {
141 setup_vref(FALSE); 147 int n;
142 // setup_oscillator(OSC_8MHZ|OSC_INTRC); 148 for (n=0;n<40;n++) putc(cmd[n]);
-   149 }
143   150  
144 // ext_int_edge( L_TO_H ); // set 1PPS active edge 151 ext_int_edge( L_TO_H ); // set 1PPS active edge
145 // enable_interrupts(INT_TIMER1); 152 enable_interrupts(INT_TIMER1);
146 // enable_interrupts(INT_EXT); 153 enable_interrupts(INT_EXT);
147 enable_interrupts(INT_SSP); 154 enable_interrupts(INT_SSP);
148 // enable_interrupts(INT_TIMER2); -  
149 enable_interrupts(GLOBAL); 155 enable_interrupts(GLOBAL);
150   -  
151   -  
152 /* delay_ms(1000); -  
153 int n; -  
154 for (n=0;n<40;n++) putc(cmd[n]); // setup GPS -  
155   -  
156 */ -  
157   -  
158 printf("cvak...\r\n"); -  
159 156
-   157 buffer[0]=0x0; // Clear I2C output buffer
-   158 buffer[1]=0x0;
-   159 buffer[2]=0x0;
-   160 buffer[3]=0x0;
160   161  
161 buffer[2]=0; -  
162 buffer[3]=0; -  
163 buffer[4]=0; -  
164 buffer[5]=0; 162 printf("\r\ncvak...\r\n");
165   163  
166 while(true) 164 while(true)
167 { 165 {
168 // output_high(LED); 166 restart_wdt();
169 delay_ms(1000); 167 delay_ms(1000);
170 // output_low(LED); -  
171 // delay_ms(999); -  
172 printf("%X %X %X %X\r\n", buffer[0],buffer[1],buffer[2],buffer[3]); 168 // printf("%X %X %X %X\r\n", buffer[0],buffer[1],buffer[2],buffer[3]);
173   -  
174 } 169 }
175 } 170 }