OSDN Git Service

Updated the rotary encoder module.
[bluetank/bluetank.git] / firm / bare_metal / uzume.c
1 /**
2  * @file uzume.c
3  * @author Copyright(C) 2012 Shinichiro Nakamura
4  * @brief BlueTank ACB-BF592 Application Sample Codes.
5  */
6
7 /*
8  * ===============================================================
9  *  BlueTank
10  * ===============================================================
11  * Copyright (c) 2012 Shinichiro Nakamura
12  *
13  * Permission is hereby granted, free of charge, to any person
14  * obtaining a copy of this software and associated documentation
15  * files (the "Software"), to deal in the Software without
16  * restriction, including without limitation the rights to use,
17  * copy, modify, merge, publish, distribute, sublicense, and/or
18  * sell copies of the Software, and to permit persons to whom the
19  * Software is furnished to do so, subject to the following
20  * conditions:
21  *
22  * The above copyright notice and this permission notice shall be
23  * included in all copies or substantial portions of the Software.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
27  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
29  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
30  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32  * OTHER DEALINGS IN THE SOFTWARE.
33  * ===============================================================
34  */
35
36 #include <stdint.h>
37 #include <string.h>
38 #include <cdefBF592-A.h>
39 #include <builtins.h>
40 #include <sys/exception.h>
41 #include "lcd.h"
42 #include "led.h"
43 #include "pff.h"
44 #include "ssm2603.h"
45 #include "at24c.h"
46 #include "uzume.h"
47 #include "mmc.h"
48 #include "uart.h"
49
50 #define SCLOCK_HZ           (100000000) /**< システムクロック(100MHz) */
51 #define DMA_SAMPLE_SIZE     (256)       /**< 1回のサンプルサイズ */
52
53 typedef __attribute__((interrupt_handler)) void (*ex_handler_fn_gcc)(void);
54
55 static void setup_pll(uint8_t mul_val, uint8_t div_val);
56 static void __attribute__((interrupt_handler)) sport_rx_isr();
57
58 /**
59  * SPORT受信バッファ(ダブルバッファ)
60  */
61 static int32_t sport_buffer_rx[2][DMA_SAMPLE_SIZE];
62 /**
63  * SPORT受信バッファ(ダブルバッファ)
64  */
65 static int32_t sport_buffer_tx[2][DMA_SAMPLE_SIZE];
66 /**
67  * DMAがどのバッファ使用をしているか
68  */
69 static volatile int32_t bufidx_dma_target;
70 /**
71  * データ転送完了フラグ
72  */
73 static volatile int32_t data_ready;
74
75 static void setup_pll(uint8_t mul_val, uint8_t div_val)
76 {
77     *pSIC_IWR = IWR_ENABLE(0);  /* PLLのみIWRを許す */
78     *pPLL_DIV = div_val;
79     *pPLL_CTL = (mul_val) << 9;
80     asm("cli r0; csync; idle; sti r0;": : :"R0");
81     *pSIC_IWR = IWR_ENABLE_ALL;
82 }
83
84 static void __attribute__((interrupt_handler)) sport_rx_isr()
85 {
86     *pDMA1_IRQ_STATUS = DMA_DONE;
87     ssync();
88     /* オーディオコーデックからデータ到着 */
89     data_ready = 1;
90     /* DMAが使用するバッファを変更 */
91     bufidx_dma_target = (bufidx_dma_target ^ 1) & 1;
92 }
93
94 static void vdsp_register_handler(interrupt_kind kind, ex_handler_fn_gcc fn)
95 {
96     uint32_t mask;
97
98     if ((ik_emulation > kind) || (kind > ik_ivg15)) {
99         return;
100     }
101
102     *((ex_handler_fn_gcc*)&(((uint32_t*)EVT0)[(int32_t)kind])) = fn;
103     mask  = cli();
104     mask |= 1u << (int32_t)kind;
105     sti(mask);
106 }
107
108 void uzume_init(UZUME *p, void *user_data)
109 {
110     FATFS fatfs;
111 #if 0
112     DIR dir;
113     FILINFO finfo;
114 #endif
115
116     p->effect = NULL;
117     p->system = NULL;
118     p->user_data = user_data;
119
120     /*
121      * PLLを設定する。
122      */
123     setup_pll(16, 4);
124
125     uart_init();
126
127     /*
128      * LEDを初期化する。
129      */
130     led_init();
131
132     /*
133      * LCDを初期化する。
134      */
135     lcd_init();
136     lcd_clear();
137     lcd_goto(0, 0);
138     lcd_puts("BlueTank");
139     lcd_goto(0, 1);
140     lcd_puts(" UZUME! ");
141
142     /*
143      * オーディオコーデックを初期化する。
144      * 初期化された時点ではミュートされている。
145      */
146     ssm2603_init();
147
148     /*
149      * I2C ROMモジュールを初期化する。
150      */
151     at24c_init();
152
153     /*
154      * SDカードをマウントする。
155      */
156     pf_mount(&fatfs);
157
158     /*
159      * バッファをクリアする。
160      */
161     memset(sport_buffer_rx, 0 , sizeof(sport_buffer_rx));
162     memset(sport_buffer_tx, 0 , sizeof(sport_buffer_tx));
163     bufidx_dma_target = 0;
164     data_ready = 0;
165
166     /*
167      * 割り込みハンドラの登録。
168      * IVG9が登録先。
169      */
170     vdsp_register_handler(ik_ivg9, sport_rx_isr);
171     *pSIC_IMASK |= IRQ_DMA1;
172
173     /*
174      * SPORT RXの設定
175      * 外部クロック、外部SYNC、MSB First
176      * 24ビットデータ、 ステレオ
177      */
178     *pSPORT0_RCR1 = RFSR | RCKFE;
179     *pSPORT0_RCR2 = SLEN(31) | RSFSE;
180
181     /*
182      * SPORT TXの設定
183      * 外部クロック、外部SYNC、MSB First
184      * 24ビットデータ、 ステレオ
185      */
186     *pSPORT0_TCR1 = TFSR | TCKFE;
187     *pSPORT0_TCR2 = SLEN(31) | TSFSE;
188
189     /*
190      * DMA1(SPORT0 RX)の設定
191      */
192     *pDMA1_PERIPHERAL_MAP = 0x1000;
193     *pDMA1_CONFIG = FLOW_AUTO | DI_EN | DI_SEL | DMA2D | WDSIZE_32 | WNR;
194     *pDMA1_START_ADDR = sport_buffer_rx;
195     *pDMA1_X_COUNT = DMA_SAMPLE_SIZE;
196     *pDMA1_X_MODIFY = sizeof(int32_t);
197     *pDMA1_Y_COUNT = 2;
198     *pDMA1_Y_MODIFY = sizeof(int32_t);
199
200     /*
201      * DMA2(SPORT0 TX)の設定
202      */
203     *pDMA2_PERIPHERAL_MAP = 0x2000;
204     *pDMA2_CONFIG = FLOW_AUTO | DMA2D | WDSIZE_32;
205     *pDMA2_START_ADDR = sport_buffer_tx;
206     *pDMA2_X_COUNT = DMA_SAMPLE_SIZE;
207     *pDMA2_X_MODIFY = sizeof(int32_t);
208     *pDMA2_Y_COUNT = 2;
209     *pDMA2_Y_MODIFY = sizeof(int32_t);
210     ssync();
211
212     /*
213      * DMAを有効
214      */
215     *pDMA1_IRQ_STATUS = DMA_DONE;
216     *pDMA1_CONFIG |= DMAEN;
217     *pDMA2_CONFIG |= DMAEN;
218     ssync();
219
220     /*
221      * SPORT0を有効
222      */
223     *pSPORT0_TCR1 |= TSPEN;
224     *pSPORT0_RCR1 |= RSPEN;
225     ssync();
226
227     /*
228      * ミュートを解除する。
229      */
230     ssm2603_mute(false);
231
232     /*
233      * AT24C initialize.
234      */
235     at24c_init();
236 }
237
238 void uzume_set_effect(UZUME *p, UZUME_EFFECT_FUNC effect)
239 {
240     p->effect = effect;
241 }
242
243 void uzume_set_system(UZUME *p, UZUME_SYSTEM_FUNC system)
244 {
245     p->system = system;
246 }
247
248 void uzume_execute(UZUME *p)
249 {
250     int i, j;
251     char lcdbuf[16];
252     int32_t bufidx_dma_done;
253
254     FontSet fontset;
255
256     /*
257      * Initialize fontset
258      */
259     lcd_font_init(&fontset);
260     for (i = 0; i < (int)LCD_FONT_CHARS; i++) {
261         for (j = 0; j < i + 1; j++) {
262             lcd_font_draw_line(&fontset, (UserFont)i, 0, (7 - j), 4, (7 - j), 1);
263         }
264     }
265     lcd_font_setup_all(&fontset);
266
267     /*
268      * Draw the text string.
269      */
270     for (i = 0; i < 8; i++) {
271         lcdbuf[i] = 0x08 + i;
272     }
273     lcdbuf[8] = 0x00;
274     lcd_goto(0, 0);
275     lcd_puts(lcdbuf);
276
277     lcd_puts("[MENU 1]");
278     lcd_puts("[MENU 2]");
279     lcd_puts("[MENU 3]");
280     lcd_puts("[MENU 4]");
281
282     while (1) {
283         asm("idle;");
284         if (0 != data_ready) {
285             /*
286              * フラグをクリアする。
287              */
288             data_ready = 0;
289
290             /*
291              * DMAが完了したバッファを使用してオーディオ処理を行なう。
292              */
293             bufidx_dma_done = bufidx_dma_target ^ 1;
294             if (p->effect != NULL) {
295                 p->effect(
296                         p,
297                         sport_buffer_rx[bufidx_dma_done],
298                         sport_buffer_tx[bufidx_dma_done],
299                         DMA_SAMPLE_SIZE);
300             }
301         }
302         if (p->system != NULL) {
303             p->system(p);
304         }
305     }
306 }
307