方形波のフーリエ級数による合成プログラム。 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

Committer:
kawaberi12891
Date:
Tue Feb 02 00:50:24 2016 +0000
Revision:
1:da55c6735fa0
Parent:
0:529a855826ec
main.cpp ??????????????????????????

Who changed what in which revision?

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