方形波のフーリエ級数による合成プログラム。 http://www.vector.co.jp/authors/VA000874/のリンク先http://homepage3.nifty.com/silo/FONTV/でダウンロードした VGON16.LZH のうち GONHN16X.TLF をQSPIフラッシュROMの0x90000000番地以降に、GONZN16X.TLF を0x90010000番地以降に配置してから実行して日本語表示をさせることが可能。
Dependencies: BSP_DISCO_F746NG_patch_fixed BUTTON_GROUP LCD_DISCO_F746NG QSPI_DISCO_F746NG TS_DISCO_F746NG mbed
main.cpp@0:529a855826ec, 2016-02-01 (annotated)
- Committer:
- kawaberi12891
- Date:
- Mon Feb 01 11:23:42 2016 +0000
- Revision:
- 0:529a855826ec
- Child:
- 1:da55c6735fa0
????????????????????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kawaberi12891 | 0:529a855826ec | 1 | //-------------------------------------------------------------- |
kawaberi12891 | 0:529a855826ec | 2 | // F746_Fourier_series_of_square_wave_01 |
kawaberi12891 | 0:529a855826ec | 3 | //-------------------------------------------------------------- |
kawaberi12891 | 0:529a855826ec | 4 | |
kawaberi12891 | 0:529a855826ec | 5 | #include "mbed.h" |
kawaberi12891 | 0:529a855826ec | 6 | #include <stdlib.h> |
kawaberi12891 | 0:529a855826ec | 7 | #include <string.h> |
kawaberi12891 | 0:529a855826ec | 8 | #include "LCD_DISCO_F746NG.h" |
kawaberi12891 | 0:529a855826ec | 9 | #include "TS_DISCO_F746NG.h" |
kawaberi12891 | 0:529a855826ec | 10 | #include "QSPI_DISCO_F746NG.h" |
kawaberi12891 | 0:529a855826ec | 11 | #include "button_group.hpp" |
kawaberi12891 | 0:529a855826ec | 12 | #include "sjis_utf_table.h" |
kawaberi12891 | 0:529a855826ec | 13 | |
kawaberi12891 | 0:529a855826ec | 14 | using namespace Mikami; |
kawaberi12891 | 0:529a855826ec | 15 | |
kawaberi12891 | 0:529a855826ec | 16 | LCD_DISCO_F746NG lcd; // Object for LCD display |
kawaberi12891 | 0:529a855826ec | 17 | TS_DISCO_F746NG ts; // Object for touch pannel |
kawaberi12891 | 0:529a855826ec | 18 | QSPI_DISCO_F746NG qspi; |
kawaberi12891 | 0:529a855826ec | 19 | DigitalIn user_button(USER_BUTTON); |
kawaberi12891 | 0:529a855826ec | 20 | DigitalOut led1(LED1); |
kawaberi12891 | 0:529a855826ec | 21 | DigitalOut led2(LED2); |
kawaberi12891 | 0:529a855826ec | 22 | |
kawaberi12891 | 0:529a855826ec | 23 | #define BUFFER_SIZE ((uint32_t)32) |
kawaberi12891 | 0:529a855826ec | 24 | #define NB 0x10011; // 全角フォントのコード・ブロック数 NBがあるオフセットアドレス 0x11 |
kawaberi12891 | 0:529a855826ec | 25 | #define countof(x) ( sizeof(x) / sizeof(x[0]) ) |
kawaberi12891 | 0:529a855826ec | 26 | #define LEN 60 |
kawaberi12891 | 0:529a855826ec | 27 | |
kawaberi12891 | 0:529a855826ec | 28 | const float PI = 3.141593f; |
kawaberi12891 | 0:529a855826ec | 29 | const int N_ = 480; |
kawaberi12891 | 0:529a855826ec | 30 | const double DT_ = ((2.2*PI)/(N_ - 1)); |
kawaberi12891 | 0:529a855826ec | 31 | const float DX_ = 0.3f; |
kawaberi12891 | 0:529a855826ec | 32 | |
kawaberi12891 | 0:529a855826ec | 33 | const uint32_t BACK_COLOR = 0xFF006A6C; // Teal green |
kawaberi12891 | 0:529a855826ec | 34 | const uint32_t INACTIVE_COLOR = BACK_COLOR & 0xD0FFFFFF; |
kawaberi12891 | 0:529a855826ec | 35 | const uint32_t TOUCHED_COLOR = 0xFF7F7FFF; |
kawaberi12891 | 0:529a855826ec | 36 | const uint32_t ORIGINAL_COLOR = 0xFF0068B7; |
kawaberi12891 | 0:529a855826ec | 37 | const uint32_t INACTIVE_TEXT_COLOR = LCD_COLOR_GRAY; |
kawaberi12891 | 0:529a855826ec | 38 | const uint32_t AXIS_COLOR = 0xFFCCFFFF; |
kawaberi12891 | 0:529a855826ec | 39 | const uint32_t LINE_COLOR = LCD_COLOR_CYAN; |
kawaberi12891 | 0:529a855826ec | 40 | |
kawaberi12891 | 0:529a855826ec | 41 | int order_ = 1; // フーリエ合成の次数 |
kawaberi12891 | 0:529a855826ec | 42 | |
kawaberi12891 | 0:529a855826ec | 43 | int x_size, y_size; //液晶画面の横・縦のドット数 |
kawaberi12891 | 0:529a855826ec | 44 | const float PI2 = PI*2; |
kawaberi12891 | 0:529a855826ec | 45 | const int FS_ = 48000; |
kawaberi12891 | 0:529a855826ec | 46 | const int MAX_ORDER_ = 199; // 使用する係数の最大の次数 |
kawaberi12891 | 0:529a855826ec | 47 | double bk1_[MAX_ORDER_]; // フーリエ係数 |
kawaberi12891 | 0:529a855826ec | 48 | |
kawaberi12891 | 0:529a855826ec | 49 | uint32_t hankaku_base_addr; // 半角フォントの先頭アドレス+0x90000000 |
kawaberi12891 | 0:529a855826ec | 50 | uint32_t zenkaku_base_addr; // 全角フォントの先頭アドレス+0x90010000 |
kawaberi12891 | 0:529a855826ec | 51 | uint32_t kanji_start_addr; |
kawaberi12891 | 0:529a855826ec | 52 | uint8_t WF; // 半角フォントのフォント幅 WF |
kawaberi12891 | 0:529a855826ec | 53 | char input_string[LEN]; // 表示文字列を入れる配列 |
kawaberi12891 | 0:529a855826ec | 54 | unsigned int output_utf8[LEN][3]; // 新check_utf8()の出力を受け取るための配列 |
kawaberi12891 | 0:529a855826ec | 55 | |
kawaberi12891 | 0:529a855826ec | 56 | struct point { |
kawaberi12891 | 0:529a855826ec | 57 | float x; |
kawaberi12891 | 0:529a855826ec | 58 | float y; |
kawaberi12891 | 0:529a855826ec | 59 | }; |
kawaberi12891 | 0:529a855826ec | 60 | |
kawaberi12891 | 0:529a855826ec | 61 | struct point ptn1_[N_]; |
kawaberi12891 | 0:529a855826ec | 62 | |
kawaberi12891 | 0:529a855826ec | 63 | void lcd_init(void); |
kawaberi12891 | 0:529a855826ec | 64 | void qspi_init(void); |
kawaberi12891 | 0:529a855826ec | 65 | void font_init(void); |
kawaberi12891 | 0:529a855826ec | 66 | void check_utf8(char *, unsigned int [256][3]); |
kawaberi12891 | 0:529a855826ec | 67 | void drawfont16(uint16_t, uint16_t, char, uint32_t); // draw 8x16 font |
kawaberi12891 | 0:529a855826ec | 68 | void draw_zenkaku(uint16_t, uint16_t, uint32_t, uint32_t); // draw 16x16 font |
kawaberi12891 | 0:529a855826ec | 69 | const char *findface(unsigned int); |
kawaberi12891 | 0:529a855826ec | 70 | void draw_string(uint16_t, uint16_t, char *, uint32_t); |
kawaberi12891 | 0:529a855826ec | 71 | char *itoa(int, char *, int); |
kawaberi12891 | 0:529a855826ec | 72 | |
kawaberi12891 | 0:529a855826ec | 73 | void Synthesize(void); // フーリエ合成関数 |
kawaberi12891 | 0:529a855826ec | 74 | void CreateCoefficients(void); // フーリエ係数生成関数 |
kawaberi12891 | 0:529a855826ec | 75 | |
kawaberi12891 | 0:529a855826ec | 76 | int main() |
kawaberi12891 | 0:529a855826ec | 77 | { |
kawaberi12891 | 0:529a855826ec | 78 | int i, j; |
kawaberi12891 | 0:529a855826ec | 79 | |
kawaberi12891 | 0:529a855826ec | 80 | printf("Hello Discovery F746NG!\r\n"); |
kawaberi12891 | 0:529a855826ec | 81 | printf("SystemCoreClock: %d MHz\r\n\n", SystemCoreClock/(1000*1000)); |
kawaberi12891 | 0:529a855826ec | 82 | CreateCoefficients(); // フーリエ係数の生成 |
kawaberi12891 | 0:529a855826ec | 83 | qspi_init(); |
kawaberi12891 | 0:529a855826ec | 84 | lcd_init(); |
kawaberi12891 | 0:529a855826ec | 85 | font_init(); |
kawaberi12891 | 0:529a855826ec | 86 | draw_string(0, 0, "方形波のフーリエ級数による合成", LCD_COLOR_WHITE); |
kawaberi12891 | 0:529a855826ec | 87 | draw_string(0, 250, "フーリエ級数の次数 N =", LCD_COLOR_WHITE); |
kawaberi12891 | 0:529a855826ec | 88 | // Setting of button group |
kawaberi12891 | 0:529a855826ec | 89 | const string DOWN_UP[2] = {"DOWN", "UP"}; // downUP は フーリエ級数の時数を増減させるためのボタングループ |
kawaberi12891 | 0:529a855826ec | 90 | ButtonGroup downUp(lcd, ts, 350, 230, 60, 40, ORIGINAL_COLOR, BACK_COLOR, 2, DOWN_UP, 5, 0, 2); |
kawaberi12891 | 0:529a855826ec | 91 | downUp.Draw(0, INACTIVE_COLOR, INACTIVE_TEXT_COLOR); |
kawaberi12891 | 0:529a855826ec | 92 | downUp.Draw(1, TOUCHED_COLOR, INACTIVE_TEXT_COLOR); |
kawaberi12891 | 0:529a855826ec | 93 | |
kawaberi12891 | 0:529a855826ec | 94 | while (1) { |
kawaberi12891 | 0:529a855826ec | 95 | Synthesize(); // フーリエ係数で波形を合成 |
kawaberi12891 | 0:529a855826ec | 96 | for (i = 0; i < x_size-20; i++) |
kawaberi12891 | 0:529a855826ec | 97 | { |
kawaberi12891 | 0:529a855826ec | 98 | lcd.DrawPixel(i, ptn1_[i].y + 100, LCD_COLOR_WHITE); |
kawaberi12891 | 0:529a855826ec | 99 | } |
kawaberi12891 | 0:529a855826ec | 100 | downUp.Draw(0, TOUCHED_COLOR, INACTIVE_TEXT_COLOR); |
kawaberi12891 | 0:529a855826ec | 101 | downUp.Draw(1, TOUCHED_COLOR, INACTIVE_TEXT_COLOR); |
kawaberi12891 | 0:529a855826ec | 102 | while (!downUp.Touched(0, TOUCHED_COLOR) && !downUp.Touched(1, TOUCHED_COLOR)) {} // ボタンが押されるのを待つ |
kawaberi12891 | 0:529a855826ec | 103 | if (downUp.Touched(1, TOUCHED_COLOR)) { |
kawaberi12891 | 0:529a855826ec | 104 | printf("UP Touched\n"); |
kawaberi12891 | 0:529a855826ec | 105 | if (order_ < 199) { |
kawaberi12891 | 0:529a855826ec | 106 | order_++; |
kawaberi12891 | 0:529a855826ec | 107 | } |
kawaberi12891 | 0:529a855826ec | 108 | lcd.Clear(BACK_COLOR); |
kawaberi12891 | 0:529a855826ec | 109 | }else if (downUp.Touched(0, TOUCHED_COLOR)) { |
kawaberi12891 | 0:529a855826ec | 110 | printf("DOWN Touched\n"); |
kawaberi12891 | 0:529a855826ec | 111 | if (order_ > 1) { |
kawaberi12891 | 0:529a855826ec | 112 | order_--; |
kawaberi12891 | 0:529a855826ec | 113 | } |
kawaberi12891 | 0:529a855826ec | 114 | lcd.Clear(BACK_COLOR); |
kawaberi12891 | 0:529a855826ec | 115 | } |
kawaberi12891 | 0:529a855826ec | 116 | itoa(order_, input_string, 10); |
kawaberi12891 | 0:529a855826ec | 117 | draw_string(182, 250, input_string, LCD_COLOR_WHITE); |
kawaberi12891 | 0:529a855826ec | 118 | draw_string(0, 0, "方形波のフーリエ級数による合成", LCD_COLOR_WHITE); |
kawaberi12891 | 0:529a855826ec | 119 | draw_string(0, 250, "フーリエ級数の次数 N =", LCD_COLOR_WHITE); |
kawaberi12891 | 0:529a855826ec | 120 | } |
kawaberi12891 | 0:529a855826ec | 121 | } |
kawaberi12891 | 0:529a855826ec | 122 | |
kawaberi12891 | 0:529a855826ec | 123 | |
kawaberi12891 | 0:529a855826ec | 124 | void lcd_init(void) |
kawaberi12891 | 0:529a855826ec | 125 | { |
kawaberi12891 | 0:529a855826ec | 126 | lcd.Clear(BACK_COLOR); |
kawaberi12891 | 0:529a855826ec | 127 | lcd.SetTextColor(LCD_COLOR_YELLOW); |
kawaberi12891 | 0:529a855826ec | 128 | lcd.SetFont(&Font20); |
kawaberi12891 | 0:529a855826ec | 129 | x_size = lcd.GetXSize(); |
kawaberi12891 | 0:529a855826ec | 130 | y_size = lcd.GetYSize(); |
kawaberi12891 | 0:529a855826ec | 131 | } |
kawaberi12891 | 0:529a855826ec | 132 | |
kawaberi12891 | 0:529a855826ec | 133 | void Synthesize(void) // bk1_[]を使用するハミング窓「なし」版 |
kawaberi12891 | 0:529a855826ec | 134 | { |
kawaberi12891 | 0:529a855826ec | 135 | const float A0 = -50; |
kawaberi12891 | 0:529a855826ec | 136 | const double SHIFT = -0.1 * PI; |
kawaberi12891 | 0:529a855826ec | 137 | float xn[N_]; |
kawaberi12891 | 0:529a855826ec | 138 | int n, k; |
kawaberi12891 | 0:529a855826ec | 139 | |
kawaberi12891 | 0:529a855826ec | 140 | // printf("DT_ = %f\n", DT_); |
kawaberi12891 | 0:529a855826ec | 141 | for (n = 0; n < N_; n++) { |
kawaberi12891 | 0:529a855826ec | 142 | xn[n] = 0; |
kawaberi12891 | 0:529a855826ec | 143 | for (k = 1; k <= order_; k++) { |
kawaberi12891 | 0:529a855826ec | 144 | xn[n] = xn[n] + (float)(bk1_[k-1]*sin(k*(DT_*n + SHIFT))); |
kawaberi12891 | 0:529a855826ec | 145 | } |
kawaberi12891 | 0:529a855826ec | 146 | // printf("%f\n", n, xn[n]); |
kawaberi12891 | 0:529a855826ec | 147 | } |
kawaberi12891 | 0:529a855826ec | 148 | for (n = 0; n < N_; n++) { |
kawaberi12891 | 0:529a855826ec | 149 | ptn1_[n].x = DX_ * n; |
kawaberi12891 | 0:529a855826ec | 150 | ptn1_[n].y = A0 * xn[n]; |
kawaberi12891 | 0:529a855826ec | 151 | // printf("ptn1_[%d].x=%f : ptn1_[%d].y=%f\n", n, ptn1_[n].x, n, ptn1_[n].y); |
kawaberi12891 | 0:529a855826ec | 152 | } |
kawaberi12891 | 0:529a855826ec | 153 | } |
kawaberi12891 | 0:529a855826ec | 154 | |
kawaberi12891 | 0:529a855826ec | 155 | // フーリエ係数の生成 |
kawaberi12891 | 0:529a855826ec | 156 | void CreateCoefficients(void) |
kawaberi12891 | 0:529a855826ec | 157 | { |
kawaberi12891 | 0:529a855826ec | 158 | int k; |
kawaberi12891 | 0:529a855826ec | 159 | const float FACTOR = 4.0/PI; // 4/π |
kawaberi12891 | 0:529a855826ec | 160 | |
kawaberi12891 | 0:529a855826ec | 161 | for (k=1; k<=MAX_ORDER_; k++) |
kawaberi12891 | 0:529a855826ec | 162 | { |
kawaberi12891 | 0:529a855826ec | 163 | if (k % 2 == 0) |
kawaberi12891 | 0:529a855826ec | 164 | { |
kawaberi12891 | 0:529a855826ec | 165 | bk1_[k-1] = 0; |
kawaberi12891 | 0:529a855826ec | 166 | }else{ |
kawaberi12891 | 0:529a855826ec | 167 | bk1_[k-1] = FACTOR/(double)k; |
kawaberi12891 | 0:529a855826ec | 168 | } |
kawaberi12891 | 0:529a855826ec | 169 | } |
kawaberi12891 | 0:529a855826ec | 170 | } |
kawaberi12891 | 0:529a855826ec | 171 | |
kawaberi12891 | 0:529a855826ec | 172 | // draw 8x16 font |
kawaberi12891 | 0:529a855826ec | 173 | void drawfont16(uint16_t Xpos, uint16_t Ypos, char c, uint32_t color) |
kawaberi12891 | 0:529a855826ec | 174 | { |
kawaberi12891 | 0:529a855826ec | 175 | int i, j; |
kawaberi12891 | 0:529a855826ec | 176 | const short data[] = { |
kawaberi12891 | 0:529a855826ec | 177 | 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01, |
kawaberi12891 | 0:529a855826ec | 178 | }; |
kawaberi12891 | 0:529a855826ec | 179 | uint8_t ReadBuffer[BUFFER_SIZE]; |
kawaberi12891 | 0:529a855826ec | 180 | uint32_t addr; |
kawaberi12891 | 0:529a855826ec | 181 | addr = c * 0x10 + hankaku_base_addr; |
kawaberi12891 | 0:529a855826ec | 182 | qspi.Read(ReadBuffer, (uint32_t)addr, BUFFER_SIZE); |
kawaberi12891 | 0:529a855826ec | 183 | i = j = 0; |
kawaberi12891 | 0:529a855826ec | 184 | for (j = 0; j < 16; j++) { // 半角1文字分16Byteを読み出す |
kawaberi12891 | 0:529a855826ec | 185 | for (i = 0; i < 8; i++) { // メモリ1Byte分の8 |
kawaberi12891 | 0:529a855826ec | 186 | if (ReadBuffer[j] & data[i]) { |
kawaberi12891 | 0:529a855826ec | 187 | lcd.DrawPixel((Xpos + i), (Ypos + j), color); |
kawaberi12891 | 0:529a855826ec | 188 | } |
kawaberi12891 | 0:529a855826ec | 189 | } |
kawaberi12891 | 0:529a855826ec | 190 | } |
kawaberi12891 | 0:529a855826ec | 191 | } |
kawaberi12891 | 0:529a855826ec | 192 | |
kawaberi12891 | 0:529a855826ec | 193 | |
kawaberi12891 | 0:529a855826ec | 194 | // 文字列表示関数 |
kawaberi12891 | 0:529a855826ec | 195 | void draw_string(uint16_t Xpos, uint16_t Ypos, char *str, uint32_t color) |
kawaberi12891 | 0:529a855826ec | 196 | { |
kawaberi12891 | 0:529a855826ec | 197 | int i = 0, j; |
kawaberi12891 | 0:529a855826ec | 198 | unsigned int utf8_code; |
kawaberi12891 | 0:529a855826ec | 199 | |
kawaberi12891 | 0:529a855826ec | 200 | check_utf8(str, output_utf8); |
kawaberi12891 | 0:529a855826ec | 201 | while (output_utf8[i][2] != 0) { |
kawaberi12891 | 0:529a855826ec | 202 | utf8_code = 0; |
kawaberi12891 | 0:529a855826ec | 203 | if (output_utf8[i][0] == 0) { // 1バイト文字の場合 |
kawaberi12891 | 0:529a855826ec | 204 | drawfont16(Xpos, Ypos, output_utf8[i][2], color); |
kawaberi12891 | 0:529a855826ec | 205 | Xpos += 8; |
kawaberi12891 | 0:529a855826ec | 206 | } else { // 2バイト文字(UTF-8)の場合 |
kawaberi12891 | 0:529a855826ec | 207 | utf8_code = output_utf8[i][0] << 16; |
kawaberi12891 | 0:529a855826ec | 208 | utf8_code += output_utf8[i][1] << 8; |
kawaberi12891 | 0:529a855826ec | 209 | utf8_code += output_utf8[i][2]; |
kawaberi12891 | 0:529a855826ec | 210 | draw_zenkaku(Xpos, Ypos, utf8_code, color); |
kawaberi12891 | 0:529a855826ec | 211 | Xpos += 16; |
kawaberi12891 | 0:529a855826ec | 212 | } |
kawaberi12891 | 0:529a855826ec | 213 | i++; |
kawaberi12891 | 0:529a855826ec | 214 | } |
kawaberi12891 | 0:529a855826ec | 215 | for (i = 0; i < LEN; i++) { |
kawaberi12891 | 0:529a855826ec | 216 | output_utf8[i][0] = 0; |
kawaberi12891 | 0:529a855826ec | 217 | } |
kawaberi12891 | 0:529a855826ec | 218 | } |
kawaberi12891 | 0:529a855826ec | 219 | |
kawaberi12891 | 0:529a855826ec | 220 | // findface() UTF-8コードを引数で受け取り、SJISに変換してフォントデータを検索し、先頭アドレスを返す |
kawaberi12891 | 0:529a855826ec | 221 | const char *findface(unsigned int utf8_code) |
kawaberi12891 | 0:529a855826ec | 222 | { |
kawaberi12891 | 0:529a855826ec | 223 | const char *p = NULL; |
kawaberi12891 | 0:529a855826ec | 224 | unsigned int sjis_code; |
kawaberi12891 | 0:529a855826ec | 225 | int i; |
kawaberi12891 | 0:529a855826ec | 226 | uint32_t addr; |
kawaberi12891 | 0:529a855826ec | 227 | |
kawaberi12891 | 0:529a855826ec | 228 | for (i = 0; i < countof(utf8_sjis_table); i++) { |
kawaberi12891 | 0:529a855826ec | 229 | if (utf8_code == utf8_sjis_table[i].utf8) { |
kawaberi12891 | 0:529a855826ec | 230 | sjis_code = utf8_sjis_table[i].sjis; |
kawaberi12891 | 0:529a855826ec | 231 | } |
kawaberi12891 | 0:529a855826ec | 232 | } |
kawaberi12891 | 0:529a855826ec | 233 | // Shift-JISコードをもとにフォントテーブルデータを参照しフォントインデックス番号を得る |
kawaberi12891 | 0:529a855826ec | 234 | if (sjis_code < 0x879f) { |
kawaberi12891 | 0:529a855826ec | 235 | i = 0; |
kawaberi12891 | 0:529a855826ec | 236 | while (sjis_code != utf8_sjis_table[i].sjis) { |
kawaberi12891 | 0:529a855826ec | 237 | i++; |
kawaberi12891 | 0:529a855826ec | 238 | } |
kawaberi12891 | 0:529a855826ec | 239 | addr = zenkaku_base_addr + (utf8_sjis_table[i].line -1) * 0x10; |
kawaberi12891 | 0:529a855826ec | 240 | }else{ // SJISコード 0x889F 亜 以降の文字コードを持つ文字 |
kawaberi12891 | 0:529a855826ec | 241 | i = 523; |
kawaberi12891 | 0:529a855826ec | 242 | while (sjis_code != utf8_sjis_table[i].sjis) { |
kawaberi12891 | 0:529a855826ec | 243 | i++; |
kawaberi12891 | 0:529a855826ec | 244 | } |
kawaberi12891 | 0:529a855826ec | 245 | addr = kanji_start_addr + ((utf8_sjis_table[i].line - 2445) << 4); |
kawaberi12891 | 0:529a855826ec | 246 | } |
kawaberi12891 | 0:529a855826ec | 247 | p = (const char *)addr; |
kawaberi12891 | 0:529a855826ec | 248 | return p; |
kawaberi12891 | 0:529a855826ec | 249 | } |
kawaberi12891 | 0:529a855826ec | 250 | |
kawaberi12891 | 0:529a855826ec | 251 | |
kawaberi12891 | 0:529a855826ec | 252 | // draw 16x16 font |
kawaberi12891 | 0:529a855826ec | 253 | void draw_zenkaku(uint16_t Xpos, uint16_t Ypos, unsigned int utf8_code, uint32_t color) |
kawaberi12891 | 0:529a855826ec | 254 | { |
kawaberi12891 | 0:529a855826ec | 255 | int i, j, k; |
kawaberi12891 | 0:529a855826ec | 256 | const short data[] = { |
kawaberi12891 | 0:529a855826ec | 257 | 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01, |
kawaberi12891 | 0:529a855826ec | 258 | }; |
kawaberi12891 | 0:529a855826ec | 259 | const char *p; |
kawaberi12891 | 0:529a855826ec | 260 | uint8_t ReadBuffer[BUFFER_SIZE]; |
kawaberi12891 | 0:529a855826ec | 261 | |
kawaberi12891 | 0:529a855826ec | 262 | p = findface(utf8_code); |
kawaberi12891 | 0:529a855826ec | 263 | if(p == NULL) return; |
kawaberi12891 | 0:529a855826ec | 264 | |
kawaberi12891 | 0:529a855826ec | 265 | if (qspi.Read(ReadBuffer, (uint32_t)p, BUFFER_SIZE)!= QSPI_OK) { |
kawaberi12891 | 0:529a855826ec | 266 | error("Read FAILED\n"); |
kawaberi12891 | 0:529a855826ec | 267 | } else { |
kawaberi12891 | 0:529a855826ec | 268 | ; |
kawaberi12891 | 0:529a855826ec | 269 | } |
kawaberi12891 | 0:529a855826ec | 270 | k = 0; |
kawaberi12891 | 0:529a855826ec | 271 | for (i = 0; i < 32; i++) { // 漢字1文字分32Byteを読み出す |
kawaberi12891 | 0:529a855826ec | 272 | if (k > 15) { // k=0,1,2,,,15 は漢字データの横1列16bit |
kawaberi12891 | 0:529a855826ec | 273 | k = 0; |
kawaberi12891 | 0:529a855826ec | 274 | } |
kawaberi12891 | 0:529a855826ec | 275 | for (j = 0; j < 8; j++) { // メモリ1Byte分の8 |
kawaberi12891 | 0:529a855826ec | 276 | if (ReadBuffer[i] & data[j]) { |
kawaberi12891 | 0:529a855826ec | 277 | lcd.DrawPixel((Xpos + k), (Ypos + i/2), color); |
kawaberi12891 | 0:529a855826ec | 278 | } |
kawaberi12891 | 0:529a855826ec | 279 | k++; |
kawaberi12891 | 0:529a855826ec | 280 | } |
kawaberi12891 | 0:529a855826ec | 281 | } |
kawaberi12891 | 0:529a855826ec | 282 | } |
kawaberi12891 | 0:529a855826ec | 283 | |
kawaberi12891 | 0:529a855826ec | 284 | |
kawaberi12891 | 0:529a855826ec | 285 | // 文字列を読み込み、1バイト半角英数文字と3バイトUTF-8文字の判別して |
kawaberi12891 | 0:529a855826ec | 286 | // 結果を2次元配列に返す関数 |
kawaberi12891 | 0:529a855826ec | 287 | // ※2バイトUTF-8文字は無視するので注意 |
kawaberi12891 | 0:529a855826ec | 288 | void check_utf8(char *sp, unsigned int utf8[256][3]) |
kawaberi12891 | 0:529a855826ec | 289 | { |
kawaberi12891 | 0:529a855826ec | 290 | int i, j; // 文字数を数えながら、配列の添え字をインクリメントするための変数 |
kawaberi12891 | 0:529a855826ec | 291 | char c1 = 0, c2 = 0; |
kawaberi12891 | 0:529a855826ec | 292 | unsigned int i1, i2, i3; |
kawaberi12891 | 0:529a855826ec | 293 | |
kawaberi12891 | 0:529a855826ec | 294 | i = 0; |
kawaberi12891 | 0:529a855826ec | 295 | while (*sp != '\0') { |
kawaberi12891 | 0:529a855826ec | 296 | j = 0; |
kawaberi12891 | 0:529a855826ec | 297 | if ((*sp & 0xf0) == 0xe0) { // 上位4ビットが1110なら、3バイト文字の1バイト目 |
kawaberi12891 | 0:529a855826ec | 298 | c1 = *sp; |
kawaberi12891 | 0:529a855826ec | 299 | i1 = c1; |
kawaberi12891 | 0:529a855826ec | 300 | i1 *= 0x10000; |
kawaberi12891 | 0:529a855826ec | 301 | } else if ((*sp & 0xc0) == 0x80) { // 上位2ビットが10なら、他バイト文字の2バイト目以降 |
kawaberi12891 | 0:529a855826ec | 302 | if (c2 == 0) { |
kawaberi12891 | 0:529a855826ec | 303 | c2 = *sp; |
kawaberi12891 | 0:529a855826ec | 304 | i2 = c2; |
kawaberi12891 | 0:529a855826ec | 305 | i2 *= 0x100; |
kawaberi12891 | 0:529a855826ec | 306 | } else { |
kawaberi12891 | 0:529a855826ec | 307 | utf8[i][j] = c1; |
kawaberi12891 | 0:529a855826ec | 308 | j++; |
kawaberi12891 | 0:529a855826ec | 309 | utf8[i][j] = c2; |
kawaberi12891 | 0:529a855826ec | 310 | j++; |
kawaberi12891 | 0:529a855826ec | 311 | utf8[i][j] = *sp; |
kawaberi12891 | 0:529a855826ec | 312 | i3 = *sp; |
kawaberi12891 | 0:529a855826ec | 313 | i3 = i1 + i2 + i3; |
kawaberi12891 | 0:529a855826ec | 314 | c1 = c2 = 0; |
kawaberi12891 | 0:529a855826ec | 315 | i++; // 次の文字へ進む |
kawaberi12891 | 0:529a855826ec | 316 | } |
kawaberi12891 | 0:529a855826ec | 317 | } else if ((*sp & 0x80) == 0) { // 1バイト文字の場合 |
kawaberi12891 | 0:529a855826ec | 318 | utf8[i][2] = *sp; |
kawaberi12891 | 0:529a855826ec | 319 | i++; // 次の文字へ進む |
kawaberi12891 | 0:529a855826ec | 320 | } |
kawaberi12891 | 0:529a855826ec | 321 | sp++; |
kawaberi12891 | 0:529a855826ec | 322 | } |
kawaberi12891 | 0:529a855826ec | 323 | for (j = 0; j < 3; j++) { |
kawaberi12891 | 0:529a855826ec | 324 | utf8[i][j] = 0; // データの終りが必ず0になるように書き込む |
kawaberi12891 | 0:529a855826ec | 325 | } |
kawaberi12891 | 0:529a855826ec | 326 | } |
kawaberi12891 | 0:529a855826ec | 327 | |
kawaberi12891 | 0:529a855826ec | 328 | char *itoa( int val, char *a, int radix ) |
kawaberi12891 | 0:529a855826ec | 329 | { |
kawaberi12891 | 0:529a855826ec | 330 | char *p = a; |
kawaberi12891 | 0:529a855826ec | 331 | unsigned int v = val;/* 作業用(変換対象の値) */ |
kawaberi12891 | 0:529a855826ec | 332 | int n = 1;/* 変換文字列の桁数記憶用 */ |
kawaberi12891 | 0:529a855826ec | 333 | while(v >= radix) { /* 桁数を求める */ |
kawaberi12891 | 0:529a855826ec | 334 | v /= radix; |
kawaberi12891 | 0:529a855826ec | 335 | n++; |
kawaberi12891 | 0:529a855826ec | 336 | } |
kawaberi12891 | 0:529a855826ec | 337 | p = a + n; /* 最下位の位置から設定する */ |
kawaberi12891 | 0:529a855826ec | 338 | v = val; |
kawaberi12891 | 0:529a855826ec | 339 | *p = '\0';/* 文字列終端の設定 */ |
kawaberi12891 | 0:529a855826ec | 340 | do { |
kawaberi12891 | 0:529a855826ec | 341 | --p; |
kawaberi12891 | 0:529a855826ec | 342 | *p = v % radix + '0';/* 1桁の数値を文字に変換 */ |
kawaberi12891 | 0:529a855826ec | 343 | if(*p > '9') {/* 変換した文字が10進で表現できない場合 */ |
kawaberi12891 | 0:529a855826ec | 344 | *p = v % radix - 10 + 'A'; /* アルファベットを使う */ |
kawaberi12891 | 0:529a855826ec | 345 | } |
kawaberi12891 | 0:529a855826ec | 346 | v /= radix; |
kawaberi12891 | 0:529a855826ec | 347 | } while ( p != a); |
kawaberi12891 | 0:529a855826ec | 348 | return a; |
kawaberi12891 | 0:529a855826ec | 349 | } |
kawaberi12891 | 0:529a855826ec | 350 | |
kawaberi12891 | 0:529a855826ec | 351 | |
kawaberi12891 | 0:529a855826ec | 352 | void qspi_init(void) |
kawaberi12891 | 0:529a855826ec | 353 | { |
kawaberi12891 | 0:529a855826ec | 354 | QSPI_Info pQSPI_Info; |
kawaberi12891 | 0:529a855826ec | 355 | // Check initialization |
kawaberi12891 | 0:529a855826ec | 356 | if (qspi.Init() != QSPI_OK) { |
kawaberi12891 | 0:529a855826ec | 357 | led2 = 1; |
kawaberi12891 | 0:529a855826ec | 358 | error("Initialization FAILED\n"); |
kawaberi12891 | 0:529a855826ec | 359 | } else { |
kawaberi12891 | 0:529a855826ec | 360 | led1 = 1; |
kawaberi12891 | 0:529a855826ec | 361 | } |
kawaberi12891 | 0:529a855826ec | 362 | // Check memory informations |
kawaberi12891 | 0:529a855826ec | 363 | qspi.GetInfo(&pQSPI_Info); |
kawaberi12891 | 0:529a855826ec | 364 | if ((pQSPI_Info.FlashSize != N25Q128A_FLASH_SIZE) || |
kawaberi12891 | 0:529a855826ec | 365 | (pQSPI_Info.EraseSectorSize != N25Q128A_SUBSECTOR_SIZE) || |
kawaberi12891 | 0:529a855826ec | 366 | (pQSPI_Info.ProgPageSize != N25Q128A_PAGE_SIZE) || |
kawaberi12891 | 0:529a855826ec | 367 | (pQSPI_Info.EraseSectorsNumber != N25Q128A_SUBSECTOR_SIZE) || |
kawaberi12891 | 0:529a855826ec | 368 | (pQSPI_Info.ProgPagesNumber != N25Q128A_SECTOR_SIZE)) { |
kawaberi12891 | 0:529a855826ec | 369 | led2 = 1; |
kawaberi12891 | 0:529a855826ec | 370 | error("Get informations FAILED\n"); |
kawaberi12891 | 0:529a855826ec | 371 | } else { |
kawaberi12891 | 0:529a855826ec | 372 | ; |
kawaberi12891 | 0:529a855826ec | 373 | } |
kawaberi12891 | 0:529a855826ec | 374 | |
kawaberi12891 | 0:529a855826ec | 375 | } |
kawaberi12891 | 0:529a855826ec | 376 | |
kawaberi12891 | 0:529a855826ec | 377 | |
kawaberi12891 | 0:529a855826ec | 378 | |
kawaberi12891 | 0:529a855826ec | 379 | void font_init(void) |
kawaberi12891 | 0:529a855826ec | 380 | { |
kawaberi12891 | 0:529a855826ec | 381 | uint8_t ReadBuffer[BUFFER_SIZE]; |
kawaberi12891 | 0:529a855826ec | 382 | uint32_t read_write_addr; |
kawaberi12891 | 0:529a855826ec | 383 | |
kawaberi12891 | 0:529a855826ec | 384 | // 半角フォント処理 |
kawaberi12891 | 0:529a855826ec | 385 | // フォントイメージ開始アドレスを求める |
kawaberi12891 | 0:529a855826ec | 386 | read_write_addr = 0x0d; // フォント幅(WF)を読み取る |
kawaberi12891 | 0:529a855826ec | 387 | if (qspi.Read(ReadBuffer, read_write_addr, 0x1) != QSPI_OK) { |
kawaberi12891 | 0:529a855826ec | 388 | led2 = 1; |
kawaberi12891 | 0:529a855826ec | 389 | error("Read FAILED\n"); |
kawaberi12891 | 0:529a855826ec | 390 | } else { |
kawaberi12891 | 0:529a855826ec | 391 | WF = ReadBuffer[0]; |
kawaberi12891 | 0:529a855826ec | 392 | hankaku_base_addr = 0x11; |
kawaberi12891 | 0:529a855826ec | 393 | } // 0x11はフォント先頭からフォントイメージまでのオフセット |
kawaberi12891 | 0:529a855826ec | 394 | |
kawaberi12891 | 0:529a855826ec | 395 | // 全角フォント処理 |
kawaberi12891 | 0:529a855826ec | 396 | // コード・ブロック数 NB を読み出し、フォントイメージ開始アドレスを求める |
kawaberi12891 | 0:529a855826ec | 397 | read_write_addr = NB; |
kawaberi12891 | 0:529a855826ec | 398 | if (qspi.Read(ReadBuffer, read_write_addr, 0x1) != QSPI_OK) { |
kawaberi12891 | 0:529a855826ec | 399 | led2 = 1; |
kawaberi12891 | 0:529a855826ec | 400 | error("Read FAILED\n"); |
kawaberi12891 | 0:529a855826ec | 401 | } else { |
kawaberi12891 | 0:529a855826ec | 402 | zenkaku_base_addr = 0x10000 + 0x12 + ReadBuffer[0] * 4; |
kawaberi12891 | 0:529a855826ec | 403 | } // 0x10000は全角フォントを0x90010000から配置してあるため 0x12はフォント先頭からNBまでのオフセット |
kawaberi12891 | 0:529a855826ec | 404 | kanji_start_addr = zenkaku_base_addr + 39104; // 39104はフォント先頭から漢字先頭"亜"までのオフセット |
kawaberi12891 | 0:529a855826ec | 405 | } |