/*******************(abc916-18857.c)***************
* SDカードから画像データの読込・表示
****************************************************/
#include "mcc_generated_files/mcc.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "myProject.h"
#define SSP2_ON() SSP2CON1bits.SSPEN = 1
#define SSP2_OFF() SSP2CON1bits.SSPEN = 0
enum { NON = 0, TXT, CSV, BIN = 8, BMP };
//--- File Systme 変数
FRESULT result; // FatFs処理結果
FATFS drive; // FatFsオブジェクトへのポインタ
FIL file; // ドライブ番号、ex: "0:"
//--- アプリ変数
char FilNam[16] = "FLOWER.BMP";
uint8_t F_ext = BMP; // 1:TXT, 2:CSV, 8:BIN, 9:BMP
uint16_t Length[2]; // 送受信用文字数格納配列
char Buffer[192]; // データ受信用バッファー
char Msg[40]; // コメント等送信用文字列
uint8_t tFlag; // タイマーフラグ
uint16_t Counter; // タイマーカウンタ
//---- EUSART用変数
char RBuf[BFSIZE];
uint8_t SFlg;
/***************************************
* タイマ0 Callback関数 (1秒周期割り込み)
***************************************/
void TMR0_Process(void){
tFlag = 1; // フラグセット
}
/***************************************
* 文字列バッファ出力関数
***************************************/
void StrWrite(char * str){
while(*str != 0){ // '\0'(文字列終り)まで繰り返し
EUSART_Write(*str++); // 1文字バッファに出力(送信)
}
}
void EU_Write_CR(void){
EUSART_Write('\n');
}
//--- EUSARTへ文字列送信(改行付)
void EU_Puts(char * str){
StrWrite(str);
EU_Write_CR();
}
/*******************************************************
* 有機ELカラーグラフィック QT095B(SSD1331)
********************************************************/
//--- SSD1331 初期化
void SSD1331_Init(void){
RES_SetLow(); // Reset OLED (SSD1331))
__delay_ms(100); // 最終的にOLCDリセットは省略可
RES_SetHigh();
__delay_ms(500);
gCS_SetLow(); // Select gCS
gDC_SetLow(); // Select Command
SPI2_ExchangeByte(0xAE); // Set Display Off
SPI2_ExchangeByte(0xA0); // Remap & Color Depth setting
SPI2_ExchangeByte(0x20); // =20H [40],(0b00100000);
// A[7:6] = 00; 256 color
// A[5] = 1; Enable COM Sprit
// A[4] = 0; Scan from 0-COMn
// A[3] = 0; Disable Swaping
// A[2] = 0; Norma Order (RGB)
// A[1] = 0; RAM Colum Seg:95-0
// A[0] = 0; Horizontal Address Incriment
SPI2_ExchangeByte(0xA1); // Set Display Start Line
SPI2_ExchangeByte(0); // = 0 [00]
SPI2_ExchangeByte(0xA2); // Set Display Offset
SPI2_ExchangeByte(0); // = 0 [00]
SPI2_ExchangeByte(0xA4); // Set Display Mode (Normal)
SPI2_ExchangeByte(0xA8); // Set Multiplex Ratio
SPI2_ExchangeByte(63); // = 63 [63]
SPI2_ExchangeByte(0xAD); // Set Master Configration
SPI2_ExchangeByte(0x8E); // =8E [8F],a[0]=0 Select external Vcc supply
SPI2_ExchangeByte(0xB0); // Power Save Mode
SPI2_ExchangeByte(0x1A); // = 1AH [1A},Enable power save mode
SPI2_ExchangeByte(0xB1); // Phase 1 and 2 period adjustment
SPI2_ExchangeByte(0x74); // = 74H [74]
SPI2_ExchangeByte(0xB3); // Display Clock DIV
SPI2_ExchangeByte(0xF0); // = F0H [D0]
SPI2_ExchangeByte(0x8A); // Pre Charge A
SPI2_ExchangeByte(0x81); // = 81H [81]
SPI2_ExchangeByte(0x8B); // Pre Charge B
SPI2_ExchangeByte(0x82); // = 82H [82]
SPI2_ExchangeByte(0x8C); // Pre Charge C
SPI2_ExchangeByte(0x83); // = 83H [83]
SPI2_ExchangeByte(0xBB); // Set Pre-charge level
SPI2_ExchangeByte(0x3A); // = 3AH [3E]
SPI2_ExchangeByte(0xBE); // Set VcomH
SPI2_ExchangeByte(0x3E); // = 3EH [3E]
SPI2_ExchangeByte(0x87); // Set Master Current Control
SPI2_ExchangeByte(0x06); // = 06H [0F]
SPI2_ExchangeByte(0x15); // Set Column Address
SPI2_ExchangeByte(0); // = 00 [00]
SPI2_ExchangeByte(95); // = 95 [95]
SPI2_ExchangeByte(0x75); // Set Row Address
SPI2_ExchangeByte(0); // = 00 [00]
SPI2_ExchangeByte(63); // = 63 [63]
SPI2_ExchangeByte(0x81); // Set Contrast for Color A
SPI2_ExchangeByte(255); // = 255 [80]
SPI2_ExchangeByte(0x82); // Set Contrast for Color B
SPI2_ExchangeByte(255); // = 255 [80]
SPI2_ExchangeByte(0x83); // Set Contrast for Color C
SPI2_ExchangeByte(255); // = 255 [80]
SPI2_ExchangeByte(0xAF); // Set Display On
__delay_ms(110); // 0xAFコマンド後最低100ms必要
gCS_SetHigh(); // DeSelect gCS
}
void gOLED_Set256Md(void){
gCS_SetLow(); // Select gCS
gDC_SetLow(); // Select Command
SPI2_ExchangeByte(0xA0); // Remap & Color Depth setting
SPI2_ExchangeByte(0x20); // = 20H (0b00100000)
gCS_SetHigh(); // DeSelect gCS
__delay_ms(50);
}
void gOLED_Set64kMd(void){
gCS_SetLow(); // Select gCS
gDC_SetLow(); // Select Command
SPI2_ExchangeByte(0xA0); // Remap & Color Depth setting
SPI2_ExchangeByte(0x62); // = 62H (0b01100010)
gCS_SetHigh(); // DeSelect gCS
__delay_ms(50);
}
//----- 表示エリアの設定
void setArea(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1){
gCS_SetLow(); // Select gCs
gDC_SetLow(); // Select Comand
SPI2_ExchangeByte(0x15); // Set Colum Address
SPI2_ExchangeByte(x0);
SPI2_ExchangeByte(x1);
SPI2_ExchangeByte(0x75); // Set Row Address
SPI2_ExchangeByte(y0);
SPI2_ExchangeByte(y1);
gCS_SetHigh(); // DeSelect gCS
}
//----- 表示エリアのリセット
void rstArea(void){
setArea(0,0,95,63);
}
//--- 画面クリア
void gOLED_Clr(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1){
gCS_SetLow(); // Select gCS
gDC_SetLow(); // Select Comand
SPI2_ExchangeByte(0x25); // Line Command
SPI2_ExchangeByte(x0); // Start X
SPI2_ExchangeByte(y0); // Start Y
SPI2_ExchangeByte(x1); // End X
SPI2_ExchangeByte(y1); // End Y
gCS_SetHigh(); // DeSelect gCS
__delay_ms(1);
}
//---- Set 256Color ( R = 0-7, G = 0-7, B = 0-3 )
uint8_t gRGB256(uint8_t r,uint8_t g, uint8_t b){
return (uint8_t)((r << 5) | (g << 2) | b);
}
//--- 塗りつぶし指定
void gOLED_Fill(uint8_t md){
gCS_SetLow(); // Select gCs
gDC_SetLow(); // Select Comand
SPI2_ExchangeByte(0x26); // Fill Command
SPI2_ExchangeByte(md); // Start X
gCS_SetHigh(); // DeSelect gCs
}
//--- 線描画
void gOLED_Line(uint8_t x0,uint8_t y0, uint8_t x1,uint8_t y1, uint8_t r, uint8_t g ,uint8_t b){
gCS_SetLow(); // Select gCs
gDC_SetLow(); // Select Comand
SPI2_ExchangeByte(0x21); // Line Command
SPI2_ExchangeByte(x0); // Start X
SPI2_ExchangeByte(y0); // Start Y
SPI2_ExchangeByte(x1); // End X
SPI2_ExchangeByte(y1); // End Y
SPI2_ExchangeByte(r); // Line color Red
SPI2_ExchangeByte(g); // Line color Green
SPI2_ExchangeByte(b); // Line color Blue
gCS_SetHigh(); // DeSelect gCs
}
//--- 四角形描画
void gOLED_Rect(uint8_t x0,uint8_t y0, uint8_t x1,uint8_t y1, uint8_t r, uint8_t g ,uint8_t b){
gCS_SetLow(); // Select gCs
gDC_SetLow(); // Select Comand
SPI2_ExchangeByte(0x22); // Rect Command
SPI2_ExchangeByte(x0); // Start X
SPI2_ExchangeByte(y0); // Start Y
SPI2_ExchangeByte(x1); // End X
SPI2_ExchangeByte(y1); // End Y
SPI2_ExchangeByte(r); // Line color Red
SPI2_ExchangeByte(g); // Line color Green
SPI2_ExchangeByte(b); // Line color Blue
SPI2_ExchangeByte(r); // Fill color Red
SPI2_ExchangeByte(g); // Fill color Green
SPI2_ExchangeByte(b); // Fill color Blue
gCS_SetHigh(); // DeSelect gCS
}
//--- Test QT095 (1)
void test1(void){
uint8_t i, j;
uint8_t Dot1, Dot2, Dot3, Dot4;
Dot1 = gRGB256(0,7,0);
Dot2 = gRGB256(7,0,0);
Dot3 = gRGB256(0,0,3);
Dot4 = gRGB256(7,7,0);
SSP2_ON();
gOLED_Clr(0,0,95,63);
gCS_SetLow(); // Selct gCS
gDC_SetHigh(); // Selct data
for(j=0; j<64; j++){
for(i=0; i<96; i++){
if(j<32){
if(i<32) SPI2_ExchangeByte(Dot1);
else SPI2_ExchangeByte(Dot3);
}else{
if(i<48) SPI2_ExchangeByte(Dot2);
else SPI2_ExchangeByte(Dot4);
}
}
}
SSP2_OFF();
gCS_SetHigh();
}
//--- Test QT095 (2) (Color Map)
void test2(void){
uint8_t i,j,r,g,b,col;
SSP2_ON();
gOLED_Clr(0,0,95,63);
gCS_SetLow(); // Selct gCS
gDC_SetHigh(); // Selct data
for(g=0; g<8; g++){
for(i=0; i<8; i++){
for(b=0;b<4;b++){
for(r=0;r<8;r++){
col=(uint8_t)((r<<5)+(g<<2)+b);
SPI2_ExchangeByte(col);
SPI2_ExchangeByte(col);
SPI2_ExchangeByte(col);
}
}
}
}
SSP2_OFF();
gCS_SetHigh();
}
//--- Test QT095 (3) (Draw Command)
void test3(void){
SSP2_ON();
gOLED_Clr(0,0,95,63);
gOLED_Line( 0, 0,95,63,63,63,63);
gOLED_Line( 0,63,95, 0, 0, 0,63);
gOLED_Fill(0); // 塗りつぶし無し
gOLED_Rect(16,12,78,51,63, 0, 0);
gOLED_Fill(1); // 塗りつぶし有り
gOLED_Rect(32,24,63,40, 0,63, 0);
SSP2_OFF();
}
/***************************************
* SDカード用汎用関数
***************************************/
//--- SDカードのマウント
FRESULT SD_Mount(void){
uint8_t ct = 10;
FRESULT res;
do{
res = f_mount(&drive,"0:",1);
EUSART_Write('.');
}while((res != FR_OK) && ct--); // 10回まで試みる
if(res != FR_OK){ // マウント失敗なら
EU_Puts("** SD Not Mounted !!");
}else{
EU_Puts("SD Mount OK!");
LED_SetHigh();
}
return res;
}
//--- SDカードのクローズとアンマウント
void SD_All_Close(void){
f_close(&file); // ファイルクローズ
f_mount(0, "0:", 0); // アンマウント
EU_Puts("closed & Un_Mounted");
LED_SetLow();
}
/***************************************
* コマンド処理
***************************************/
//--- SDカードテストコマンド (兼テンプレート)
void SD_cmd_T(void){
EU_Puts("Start Command T");
// SDCard_CS_SetLow();
if(SD_Mount() == FR_OK){ // SDマウント
__delay_ms(2000);
f_mount(0, "0:", 0); // アンマウント
EU_Puts("Un_Mounted");
}
// SDCard_CS_SetHigh();
LED_SetLow();
}
//--- SDカードから読込コマンド
void SD_cmd_R(void){
FRESULT res;
if(F_ext != TXT){ // テキストファイルでないなら
sprintf(Msg,"%s is not Text File!",FilNam);
EU_Puts(Msg);
return;
}
EU_Puts("Start Command R");
if(SD_Mount() == FR_OK){ // SDマウント
res = f_open(&file, FilNam, FA_READ); // ファイルオープン
if(res == FR_OK){
sprintf(Msg,"Open %s",FilNam);
EU_Puts(Msg);
do{
f_read(&file, Buffer, 64, (UINT *)Length); // SDから読込む
Buffer[Length[0]] = 0;
EU_Puts(Buffer);
}while(Length[0]!=0);
}else{
sprintf(Msg,"** Can't open %s !!",FilNam);
EU_Puts(Msg);
}
SD_All_Close(); // ファイルクローズ&アンマウント
}
// LED_SetLow();
}
//--- SDカードへデータ書込コマンド
void SD_cmd_W(void){
FRESULT res;
EU_Puts("Start Command W");
if(SD_Mount() == FR_OK){ // SDマウント
res = f_open(&file, FilNam, FA_WRITE | FA_OPEN_APPEND); // ファイルオープン
if(res == FR_OK){
sprintf(Msg,"Open %s",FilNam);
EU_Puts(Msg);
sprintf(Msg, "%07d,", Counter);
f_write(&file, Msg, 8, (UINT *)Length); // SDへ書込
EU_Puts(Msg);
}else{
sprintf(Msg,"** Can't open %s !!",FilNam);
EU_Puts(Msg);
}
SD_All_Close(); // ファイルクローズ&アンマウント
}
// LED_SetLow();
}
//--- ファイル名セット
void SD_cmd_F(char *str){
size_t i,n;
char *p;
n = strlen(str);
if(n > 1){
if(n > 12) n = 12;
for(i = 0; i < n; i++)
FilNam[i] = toupper(str[i+1]);
FilNam[n]=0;
}
p = strchr(FilNam,'.');
if (strncmp(p+1,"TXT",3)==0) F_ext = TXT;
else if(strncmp(p+1,"CSV",3)==0) F_ext = CSV;
else if(strncmp(p+1,"BIN",3)==0) F_ext = BIN;
else if(strncmp(p+1,"BMP",3)==0) F_ext = BMP;
else F_ext = NON;
sprintf(Msg,"NewFileName = %s: %d\n",FilNam,F_ext);
EU_Puts(Msg);
}
//--- SDカードから読込コマンド
void SD_cmd_U(void){
FRESULT res;
uint8_t i, n;
EU_Puts("Start Command D");
if(SD_Mount() == FR_OK){ // SDマウント
res = f_open(&file, FilNam, FA_READ); // ファイルオープン
if(res == FR_OK){
sprintf(Msg,"Open %s",FilNam);
EU_Puts(Msg);
do{
f_read(&file, Buffer, 192, (UINT *)Length); // SDから読込む
n = (uint8_t)Length[0];
for(i = 0; i < n; i++){
sprintf(Msg,"%02X,",Buffer[i]);
StrWrite(Msg);
if((i % 16)==15) EU_Write_CR();
}
SSP2_ON();
gOLED_Line( 0, 48,95,48,63,63,63);
SSP2_OFF();
}while(Length[0]!=0);
EU_Write_CR();
}else{
sprintf(Msg,"** Can't open %s !!",FilNam);
EU_Puts(Msg);
}
SD_All_Close(); // ファイルクローズ&アンマウント
}
// LED_SetLow();
}
//--- SDカードからBMPファイル読込んで表示コマンド
void SD_cmd_V(void){
FRESULT res;
uint8_t i, n;
if(F_ext != BMP){ // ファイルがBMPで無い?
sprintf(Msg,"%s is not BMP File!",FilNam);
EU_Puts(Msg);
return;
}
EU_Puts("Start Command B");
SSP2_ON(); //グラフィック表示準備
gOLED_Set64kMd(); // 64k(16ビット)カラーに
rstArea(); // 全画面を対象に
SSP2_OFF();
if(SD_Mount() == FR_OK){ // SDマウント
res = f_open(&file, FilNam, FA_READ); // ファイルオープン
if(res == FR_OK){
sprintf(Msg,"Open %s",FilNam);
EU_Puts(Msg);
//--- SDからヘッダー部を読込む
f_read(&file, Buffer, 138, (UINT *)Length);
n = (uint8_t)Length[0];
sprintf(Msg,"W:%d - H:%d\n",Buffer[0x12],Buffer[0x16]);
EU_Puts(Msg);
for(i = 0; i < n; i++){
sprintf(Msg,"%02X,",Buffer[i]);
StrWrite(Msg);
if((i % 16)==15) EU_Write_CR();
}
EU_Write_CR();
//--- SDからデータを読み出し、表示
do{
f_read(&file, Buffer, 192, (UINT *)Length); // SDから読込む
n = (uint8_t)Length[0];
SSP2_ON(); // OLED選択
gCS_SetLow(); // Select gCS
gDC_SetHigh(); // Select Data
for(i = 0; i < n; i+=2){
SPI2_ExchangeByte(Buffer[i+1]); // 64k画素書込
SPI2_ExchangeByte(Buffer[i]);
sprintf(Msg,"%02X,%02X,",Buffer[i],Buffer[i+1]);
StrWrite(Msg);
if((i % 16)==14) EU_Write_CR();
}
gCS_SetHigh(); // DeSelect gCS
SSP2_OFF();
}while(Length[0]!=0);
EU_Write_CR();
}else{
sprintf(Msg,"** Can't open %s !!",FilNam);
EU_Puts(Msg);
}
SD_All_Close(); // ファイルクローズ&アンマウント
}
// LED_SetLow();
SSP2_ON(); //グラフィック表示準備
gOLED_Set256Md(); // 256(8ビット)カラーに
rstArea(); // 全画面を対象に
SSP2_OFF();
}
/***************************************
* メイン関数
***************************************/
void main(void){
uint8_t tMode = 0; // タイマカウンタ表示モードフラグ
char cmd; // 受信コマンド文字
SYSTEM_Initialize();
SSP2_ON();
SSD1331_Init();
SSP2_OFF();
// タイマ0 Callback関数定義
TMR0_SetInterruptHandler(TMR0_Process);
EU_Puts("\n==== SD Test ====");
// 割り込み許可
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
//======= メインループ =========
while(1){
// 1秒周期の処理
if(tFlag == 1){ // フラグオンの場合
LED_Toggle();
tFlag = 0; // フラグリセット
if(tMode == 0){
sprintf(Msg,"Counter = %05d",Counter++);
EU_Puts(Msg); // 送信
}
}
// コマンド処理
if(SFlg){ // 受信ありの場合
cmd = RBuf[0];
sprintf(Msg,"Input = %s CMD = %c\n",RBuf,cmd);
EU_Puts(Msg);
switch(cmd){
case 'T': SD_cmd_T(); break; // SDマウントテスト
case 'R': SD_cmd_R(); break; // SDからデータ読出し
case 'W': SD_cmd_W(); break; // SDにデータを書込む
case 'X': tMode = 1; break; // カウンタ表示OFF
case 'C': tMode = 0; break; // カウンタ表示ON
case 'F': SD_cmd_F(RBuf); break; // ファイル名セット
case 'U': SD_cmd_U(); break; // 16進数でダンプ
case 'V': SD_cmd_V(); break; // グラフィック描画
case 'A': test1(); break; // グラフィックテスト1
case 'B': test2(); break; // グラフィックテスト2
case 'G': test3(); break; // グラフィックテスト3
default: EU_Puts("???"); break; // 無効なコマンド
}
SFlg = 0;
}
}
}
/****** End of File ******/
|