Initial import of OsmocomBB into git repository
[osmocom-bb.git] / src / target / firmware / apps / layer1 / main.c
1 /* main program of Free Software for Calypso Phone */
2
3 /* (C) 2010 by Harald Welte <laforge@gnumonks.org>
4  *
5  * All Rights Reserved
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22
23 #include <stdint.h>
24 #include <stdio.h>
25
26 #include <gsm.h>
27 #include <debug.h>
28 #include <memory.h>
29 #include <rffe.h>
30 #include <keypad.h>
31 #include <board.h>
32
33 #include <abb/twl3025.h>
34 #include <display/st7558.h>
35 #include <rf/trf6151.h>
36
37 #include <comm/sercomm.h>
38
39 #include <calypso/clock.h>
40 #include <calypso/tpu.h>
41 #include <calypso/tsp.h>
42 #include <calypso/irq.h>
43 #include <calypso/misc.h>
44
45 #include <layer1/sync.h>
46 #include <layer1/tpu_window.h>
47
48 /* FIXME: We need proper calibrated delay loops at some point! */
49 void delay_us(unsigned int us)
50 {
51         volatile unsigned int i;
52
53         for (i= 0; i < us*4; i++) { i; }
54 }
55
56 void delay_ms(unsigned int ms)
57 {
58         volatile unsigned int i;
59
60         for (i= 0; i < ms*1300; i++) { i; }
61 }
62
63 const char *hr = "======================================================================\n";
64
65 /* MAIN program **************************************************************/
66
67 /* completion call-back for the L1 Sync Pwer Measurement */
68 static void l1s_signal_cb(struct l1_signal *sig)
69 {
70         uint16_t i, next_arfcn;
71
72         switch (sig->signum) {
73         case L1_SIG_PM:
74                 break;
75         case L1_SIG_NB:
76                 break;
77         }
78 }
79
80 static void key_handler(enum key_codes code, enum key_states state);
81 static void la1_l23_rx_cb(uint8_t dlci, struct msgb *msg);
82
83 int main(void)
84 {
85         board_init();
86         puts("\n\nHello World from " __FILE__ " program code\n");
87
88         puts(hr);
89         /* Dump device identification */
90         dump_dev_id();
91         puts(hr);
92
93         keypad_set_handler(&key_handler);
94
95         /* Dump clock config aftee PLL set */
96         calypso_clk_dump();
97         puts(hr);
98
99         st7558_set_attr(DISP_ATTR_INVERT);
100         st7558_puts("layer1.bin");
101
102         sercomm_register_rx_cb(SC_DLCI_L1A_L23, la1_l23_rx_cb);
103
104         layer1_init();
105         l1s_set_handler(&l1s_signal_cb);
106
107         tpu_frame_irq_en(1, 1);
108
109         while (1) {}
110
111         /* NOT REACHED */
112
113         twl3025_power_off();
114 }
115
116 static int8_t vga_gain = 40;
117 static int high_gain = 0;
118 static int afcout = 0;
119
120 static void update_vga_gain(void)
121 {
122         printf("VGA Gain: %u %s\n", vga_gain, high_gain ? "HIGH" : "LOW");
123         trf6151_set_gain(vga_gain, high_gain);
124         tpu_enq_sleep();
125         tpu_enable(1);
126         tpu_wait_idle();
127 }
128
129 static void tspact_toggle(uint8_t num)
130 {
131         printf("TSPACT%u toggle\n", num);
132         tsp_act_toggle((1 << num));
133         tpu_enq_sleep();
134         tpu_enable(1);
135         tpu_wait_idle();
136 }
137
138 static void key_handler(enum key_codes code, enum key_states state)
139 {
140         if (state != PRESSED)
141                 return;
142
143         switch (code) {
144         case KEY_1:     /* VGA gain decrement */
145                 vga_gain -= 2;
146                 if (vga_gain < 14)
147                         vga_gain = 14;
148                 update_vga_gain();
149                 break;
150         case KEY_2:     /* High/Low Rx gain */
151                 high_gain ^= 1;
152                 update_vga_gain();
153                 break;
154         case KEY_3:     /* VGA gain increment */
155                 vga_gain += 2;
156                 if (vga_gain > 40)
157                         vga_gain = 40;
158                 update_vga_gain();
159                 break;
160         case KEY_4:
161                 tspact_toggle(6);       /* TRENA (RFFE) */
162                 break;
163         case KEY_5:
164                 tspact_toggle(8);       /* GSM_TXEN (RFFE) */
165                 break;
166         case KEY_6:
167                 tspact_toggle(1);       /* PAENA (RFFE) */
168                 break;
169         case KEY_7:                     /* decrement AFC OUT */
170                 afcout -= 100;
171                 if (afcout < -4096)
172                         afcout = -4096;
173                 twl3025_afc_set(afcout);
174                 printf("AFC OUT: %u\n", twl3025_afcout_get());
175                 break;
176         case KEY_9:                     /* increase AFC OUT */
177                 afcout += 100;
178                 if (afcout > 4095)
179                         afcout = 4095;
180                 twl3025_afc_set(afcout);
181                 printf("AFC OUT: %u\n", twl3025_afcout_get());
182                 break;
183         default:
184                 break;
185         }
186 }
187
188 static void la1_l23_rx_cb(uint8_t dlci, struct msgb *msg)
189 {
190         struct l1_info_ul *ul = msg->data;
191         struct l1_sync_new_ccch_req *sync_req;
192
193         if (sizeof(*ul) > msg->len) {
194                 printf("la1_l23_cb: Short message. %u\n", msg->len);
195                 goto exit;
196         }
197
198         switch (ul->msg_type) {
199         case SYNC_NEW_CCCH_REQ:
200                 if (sizeof(*ul) + sizeof(*sync_req) > msg->len) {
201                         printf("Short sync msg. %u\n", msg->len);
202                         break;
203                 }
204
205                 sync_req = (struct l1_sync_new_ccch_req *) (&msg->data[0] + sizeof(*ul));
206                 printf("Asked to tune to frequency: %u\n", sync_req->band_arfcn);
207                 break;
208         case DEDIC_MODE_EST_REQ:
209                 break;
210         }
211
212 exit:
213         msgb_free(msg);
214 }