CQエレクトロニクス・セミナ「実習・マイコンを動かしながら学ぶディジタル・フィルタ」で使うプログラム.雛形として使う. http://seminar.cqpub.co.jp/ccm/ES18-0020
Dependencies: F746_GUI F746_SAI_IO mbed
Revision 0:b6d17af0f47a, committed 2017-09-29
- Comitter:
- MikamiUitOpen
- Date:
- Fri Sep 29 12:50:44 2017 +0000
- Child:
- 1:d9fdd52ea43a
- Commit message:
- 1
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/Array_Matrix.lib Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/users/MikamiUitOpen/code/Array_Matrix/#a25dba17218c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/BSP_DISCO_F746NG.lib Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/ST/code/BSP_DISCO_F746NG/#df2ea349c37a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/BlinkLabel.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,46 @@ +//----------------------------------------------------------- +// BlinkLabel class -- derived class of Label class +// For displaying error message +// +// 2017/01/25, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_BLINK_LABEL_HPP +#define F746_BLINK_LABEL_HPP + +#include "Label.hpp" +#include "ResetButton.hpp" + +namespace Mikami +{ + class BlinkLabel : public Label + { + public: + // Constructor + BlinkLabel(uint16_t x, uint16_t y, const string str, + TextAlignMode mode = LEFT, + sFONT &fonts = Font20, + uint32_t textColor = LCD_COLOR_RED, + uint32_t backColor = GuiBase::ENUM_BACK, + uint32_t on = 500, uint32_t off = 200) + : Label(x, y, str, mode, fonts, textColor, backColor) + { + ResetButton reset; + while (true) // Blinking here + { + wait_ms(on); + Draw(backColor); + wait_ms(off); + Draw(textColor); + reset.DoIfTouched(); + } + } + + private: + // disallow copy constructor and assignment operator + BlinkLabel(const BlinkLabel&); + BlinkLabel& operator=(const BlinkLabel&); + }; +} +#endif // F746_BLINK_LABEL_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/Button.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,67 @@ +//----------------------------------------------------------- +// Button class handling multi-touch +// Multi-touch: Enabled (default) +// +// 2016/04/08, Copyright (c) 2016 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "Button.hpp" + +namespace Mikami +{ + // Draw button + void Button::Draw(uint32_t color, uint32_t textColor) + { + if (color == BACK_COLOR_) active_ = true; + if (!active_) return; + lcd_.SetTextColor(color); + lcd_.FillRect(X_, Y_, W_, H_); + + if (STR_.length() != 0) + { + lcd_.SetFont(FONTS_); + lcd_.SetBackColor(color); + lcd_.SetTextColor(textColor); + uint16_t x0 = X_ + (W_ - FONTS_->Width*(STR_.length()))/2; + uint16_t y0 = Y_ + (H_ - FONTS_->Height)/2 + 1; + DrawString(x0, y0, STR_); + lcd_.SetBackColor(BACK_COLOR_); // recover back color + } + } + + // Check touch detected + bool Button::Touched() + { + if (!active_) return false; + if (!PanelTouched()) return false; + if (!IsOnButton()) return false; + Draw(TOUCHED_COLOR_, TEXT_COLOR_); + return true; + } + + // If touched position is on the button, return true + bool Button::IsOnButton() + { + int nTouch = multiTouch_ ? state_.touchDetected : 1; + for (int n=0; n<nTouch; n++) + { + uint16_t x = state_.touchX[n]; + uint16_t y = state_.touchY[n]; + if ( (X_ <= x) && (x <= X_+W_) && + (Y_ <= y) && (y <= Y_+H_) ) return true; + } + return false; + } + + void Button::Activate() + { + active_ = true; + Draw(); + } + + void Button::Inactivate() + { + Draw(INACTIVE_COLOR_, INACTIVE_TEXT_COLOR_); + active_ = false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/Button.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,65 @@ +//----------------------------------------------------------- +// Button class handling multi-touch -- Header +// Multi-touch: Enabled (default) +// +// 2016/03/29, Copyright (c) 2016 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_BUTTON_HPP +#define F746_BUTTON_HPP + +#include "GuiBase.hpp" + +namespace Mikami +{ + class Button : public GuiBase + { + public: + // Constructor + Button(uint16_t x, uint16_t y, + uint16_t width, uint16_t height, + const string str = "", sFONT &fonts = Font12, + uint32_t textColor = GuiBase::ENUM_TEXT, + uint32_t backColor = GuiBase::ENUM_BACK, + uint32_t createdColor = GuiBase::ENUM_CREATED, + uint32_t touchedColor = GuiBase::ENUM_TOUCHED, + uint32_t inactiveColor = GuiBase::ENUM_INACTIVE, + uint32_t inactiveTextColor = GuiBase::ENUM_INACTIVE_TEXT) + : GuiBase(x, y, fonts, + textColor, backColor, createdColor, + touchedColor, inactiveColor, + inactiveTextColor), + W_(width), H_(height), STR_(str), active_(true) + { Draw(); } + + // Draw button + void Draw(uint32_t color, uint32_t textColor); + void Draw(uint32_t color) { Draw(color, TEXT_COLOR_); } + void Draw() { Draw(CREATED_COLOR_, TEXT_COLOR_); } + + // Erase button + void Erase() { Draw(BACK_COLOR_, BACK_COLOR_); } + + // Check touch detected and redraw button + bool Touched(); + + bool IsOnButton(); + + void Activate(); + void Inactivate(); + bool IsActive() { return active_; } + + // Set or reset multi-touch + static void SetMultiTouch(bool tf) { multiTouch_ = tf; } + + private: + const uint16_t W_, H_; + const string STR_; + bool active_; + + // disallow copy constructor and assignment operator + Button(const Button&); + Button& operator=(const Button&); + }; +} +#endif // F746_BUTTON_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/ButtonGroup.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,134 @@ +//----------------------------------------------------------- +// ButtonGroup class +// +// 2017/01/25, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "ButtonGroup.hpp" + +namespace Mikami +{ + // Constructor + ButtonGroup::ButtonGroup( + uint16_t x0, uint16_t y0, + uint16_t width, uint16_t height, + uint16_t number, const string str[], + uint16_t spaceX, uint16_t spaceY, + uint16_t column, int touched, + sFONT &fonts, + uint32_t textColor, uint32_t backColor, + uint32_t createdColor, uint32_t touchedColor, + uint32_t inactiveColor, uint32_t inactiveTextColor) + : TEXT_COLOR_(textColor), CREATED_COLOR_(createdColor), + TOUCHED_COLOR_(touchedColor), + NUMBER_(number), prevNum_(touched) + { + buttons_.SetSize(number); + for (int n=0; n<number; n++) + { + div_t u1 = div(n, column); + uint16_t x = x0 + u1.rem*(width + spaceX); + uint16_t y = y0 + u1.quot*(height + spaceY); + buttons_[n] = + new Button(x, y, width, height, str[n], fonts, + textColor, backColor, + createdColor, touchedColor, + inactiveColor, inactiveTextColor); + } + // On created, set touched color as needed + if (touched >= 0) TouchedColor(touched); + } + + // Draw button + bool ButtonGroup::Draw(int num, uint32_t color, uint32_t textColor) + { + if (!Range(num)) return false; + buttons_[num]->Draw(color, textColor); + return true; + } + + // Change to touched color + bool ButtonGroup::TouchedColor(int num) + { + if (prevNum_ != num) prevNum_ = num; + return Draw(num, TOUCHED_COLOR_, TEXT_COLOR_); + } + + // Erase button + bool ButtonGroup::Erase(int num) + { + if (!Range(num)) return false; + buttons_[num]->Erase(); + return true; + } + + // Check touch detected for specified button + bool ButtonGroup::Touched(int num) + { + if (!Range(num)) return false; + if (!buttons_[num]->IsActive()) return false; + int touched; + if (!GetTouchedNumber(touched)) return false; + bool rtn = (touched == num) ? true : false; + return rtn; + } + + // Get touched number, return value: true or false + bool ButtonGroup::GetTouchedNumber(int &num) + { + bool rtn = false; + if (GuiBase::PanelTouched()) + { + for (int n=0; n<NUMBER_; n++) + if (buttons_[n]->IsOnButton() && + buttons_[n]->IsActive()) + { + num = n; + rtn = true; + } + + if (!rtn) return false; + } + else + return false; + + buttons_[num]->Draw(TOUCHED_COLOR_); + if ((prevNum_ >= 0) && (prevNum_ != num)) + buttons_[prevNum_]->Draw(); + if (prevNum_ != num) prevNum_ = num; + return true; + } + + // Get touched number, return value: touched number + int ButtonGroup::GetTouchedNumber() + { + int num; + if (GetTouchedNumber(num)) + return num; + else + return -1; + } + + // Wait until touched and get touched number + int ButtonGroup::WaitTouchedAndGet() + { + int num; + while (!GetTouchedNumber(num)) {} + return num; + } + + // Activate and inactivate button(s) + bool ButtonGroup::Activate(int num) + { + if (!Range(num)) return false; + buttons_[num]->Activate(); + return true; + } + bool ButtonGroup::Inactivate(int num) + { + if (!Range(num)) return false; + buttons_[num]->Inactivate(); + return true; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/ButtonGroup.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,95 @@ +//----------------------------------------------------------- +// ButtonGroup class -- Header +// +// 2017/01/25, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_BUTTON_GROUP_HPP +#define F746_BUTTON_GROUP_HPP + +#include "Button.hpp" +#include "Array.hpp" + +namespace Mikami +{ + class ButtonGroup + { + public: + // Constructor + ButtonGroup(uint16_t x0, uint16_t y0, + uint16_t width, uint16_t height, + uint16_t number, const string str[], + uint16_t spaceX = 0, uint16_t spaceY = 0, + uint16_t column = 1, + int touched = -1, // number for button initially touched-color + sFONT &fonts = Font12, + uint32_t textColor = GuiBase::ENUM_TEXT, + uint32_t backColor = GuiBase::ENUM_BACK, + uint32_t createdColor = GuiBase::ENUM_CREATED, + uint32_t touchedColor = GuiBase::ENUM_TOUCHED, + uint32_t inactiveColor = GuiBase::ENUM_INACTIVE, + uint32_t inactiveTextColor = GuiBase::ENUM_INACTIVE_TEXT); + + // Destructor + virtual ~ButtonGroup() + { for (int n=0; n<NUMBER_; n++) delete buttons_[n]; } + + // Draw button + bool Draw(int num, uint32_t color, uint32_t textColor); + bool Draw(int num) { return Draw(num, CREATED_COLOR_, TEXT_COLOR_); } + + // Change to touched color + bool TouchedColor(int num); + + // Draw all buttons + void DrawAll(uint32_t color, uint32_t textColor) + { for (int n=0; n<NUMBER_; n++) Draw(n, color, textColor); } + void DrawAll() { DrawAll(CREATED_COLOR_, TEXT_COLOR_); } + + // Erase button + bool Erase(int num); + void EraseAll() + { for (int n=0; n<NUMBER_; n++) Erase(n); } + + // Check touch detected for specified button + bool Touched(int num); + + // Get touched number, return value: true or false + bool GetTouchedNumber(int &num); + // Get touched number, return value: touched number + int GetTouchedNumber(); + + // Wait until touched + void WaitTouched(int num) + { while (!Touched(num)) {} } + // Wait until touched and get touched number + int WaitTouchedAndGet(); + + // Activate and inactivate button(s) + bool Activate(int num); + void ActivateAll() + { for (int n=0; n<NUMBER_; n++) Activate(n); } + bool Inactivate(int num); + void InactivateAll() + { for (int n=0; n<NUMBER_; n++) Inactivate(n); } + + private: + const uint32_t TEXT_COLOR_; + const uint32_t CREATED_COLOR_; + const uint32_t TOUCHED_COLOR_; + const int NUMBER_; + + Array<Button *> buttons_; + __IO int prevNum_; + + // Check range of argument + bool Range(int n) + { return ((n >= 0) && (n < NUMBER_)); } + + // disallow copy constructor and assignment operator + ButtonGroup(const ButtonGroup&); + ButtonGroup& operator=(const ButtonGroup&); + }; +} +#endif // F746_BUTTON_GROUP_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/F746_GUI.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,20 @@ +//-------------------------------------------------------------- +// F746-DISCO の GUI 用のインクルード文とそれらを使うための +// using 宣言をまとめたもの +// Include statements for F746-DISCO GUI and using directive +// +// 2016/08/15, Copyright (c) 2016 MIKAMI, Naoki +//-------------------------------------------------------------- + +#include "mbed.h" +#ifndef __STM32F746xx_H +#error Platform is not F746NG-DISCOVERY +#endif + +#include "BlinkLabel.hpp" +#include "ButtonGroup.hpp" +#include "NumericLabel.hpp" +#include "ResetButton.hpp" +#include "SeekbarGroup.hpp" + +using namespace Mikami;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/GuiBase.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,44 @@ +//----------------------------------------------------------- +// GuiBase class (abstract base class) +// +// 2016/03/29, Copyright (c) 2016 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "GuiBase.hpp" + +namespace Mikami +{ + GuiBase::GuiBase( + uint16_t x, uint16_t y, sFONT &fonts, + uint32_t textColor, uint32_t backColor, + uint32_t createdColor, uint32_t touchedColor, + uint32_t inactiveColor, uint32_t inactiveTextColor) + : X_(x), Y_(y), FONTS_(&fonts), + TEXT_COLOR_(textColor), BACK_COLOR_(backColor), + CREATED_COLOR_(createdColor), + TOUCHED_COLOR_(touchedColor), + INACTIVE_COLOR_(inactiveColor), + INACTIVE_TEXT_COLOR_(inactiveTextColor) + { + if (first_) + { + lcd_.Clear(backColor); + first_ = false; + } + } + + // If panel touched, return true + bool GuiBase::PanelTouched() + { + ts_.GetState(&state_); + return (bool)(state_.touchDetected); + } + + LCD_DISCO_F746NG GuiBase::lcd_; + TS_DISCO_F746NG GuiBase::ts_; + + TS_StateTypeDef GuiBase::state_; + + bool GuiBase::multiTouch_ = false; + bool GuiBase::first_ = true; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/GuiBase.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,70 @@ +//----------------------------------------------------------- +// GuiBase class (abstract base class) ---- Header +// +// 2017/03/17, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_GUI_BASE_HPP +#define F746_GUI_BASE_HPP + +#include "mbed.h" +#include <string> +#include "TS_DISCO_F746NG.h" +#include "LCD_DISCO_F746NG.h" + +namespace Mikami +{ + class GuiBase + { + public: + static LCD_DISCO_F746NG& GetLcd() { return lcd_; } + static TS_DISCO_F746NG& GetTs() { return ts_; } + + // If panel touched, return true + static bool PanelTouched(); + // Get touch panel state + static TS_StateTypeDef GetTsState() { return state_; } + + enum { ENUM_TEXT = 0xFFFFFFFF, ENUM_BACK = 0xFF003538, + ENUM_CREATED = 0xFF0068B7, ENUM_TOUCHED = 0xFF7F7FFF, + ENUM_INACTIVE = 0xD0003538, ENUM_INACTIVE_TEXT = 0xFF808080}; + + protected: + static LCD_DISCO_F746NG lcd_; // for LCD display + static TS_DISCO_F746NG ts_; // for touch pannel + + static TS_StateTypeDef state_; + static bool multiTouch_; + + const uint16_t X_, Y_; + sFONT *const FONTS_; + + const uint32_t TEXT_COLOR_; + const uint32_t BACK_COLOR_; + const uint32_t CREATED_COLOR_; + const uint32_t TOUCHED_COLOR_; + const uint32_t INACTIVE_COLOR_; + const uint32_t INACTIVE_TEXT_COLOR_; + + // Constructor + GuiBase(uint16_t x =0, uint16_t y =0, + sFONT &fonts = Font12, + uint32_t textColor = ENUM_TEXT, + uint32_t backColor = ENUM_BACK, + uint32_t createdColor = ENUM_CREATED, + uint32_t touchedColor = ENUM_TOUCHED, + uint32_t inactiveColor = ENUM_INACTIVE, + uint32_t inactiveTextColor = ENUM_INACTIVE_TEXT); + + void DrawString(uint16_t x, uint16_t y, const string str) + { lcd_.DisplayStringAt(x, y, (uint8_t *)str.c_str(), LEFT_MODE); } + + private: + static bool first_; + + // disallow copy constructor and assignment operator + GuiBase(const GuiBase&); + GuiBase& operator=(const GuiBase&); + }; +} +#endif // F746_GUI_BASE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/LCD_DISCO_F746NG.lib Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/ST/code/LCD_DISCO_F746NG/#d44525b1de98
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/Label.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,50 @@ +//----------------------------------------------------------- +// Label class +// +// 2016/04/24, Copyright (c) 2016 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "Label.hpp" + +namespace Mikami +{ + // Constructor + Label::Label(uint16_t x, uint16_t y, + const string str, TextAlignMode mode, sFONT &fonts, + uint32_t textColor, uint32_t backColor) + : GuiBase(x, y, fonts, textColor, backColor), + MODE_(mode), STR_(str) + { + length_ = str.length(); + lcd_.SetBackColor(backColor); + lcd_.SetTextColor(textColor); + lcd_.SetFont(&fonts); + DrawString(PosX(x), y, str); + } + + void Label::Draw(const string str, uint32_t textColor) + { + // Erase previously-drawn string + lcd_.SetTextColor(BACK_COLOR_); + length_ = (length_ > str.length()) ? length_ : str.length(); + lcd_.FillRect(PosX(X_), Y_, FONTS_->Width*length_+1, FONTS_->Height); + + // Draw new string + length_ = str.length(); + lcd_.SetFont(FONTS_); + lcd_.SetTextColor(textColor); + DrawString(PosX(X_), Y_, str); + } + + uint16_t Label::PosX(uint16_t x) + { + if (MODE_ == LEFT) return x; + else + { + if (MODE_ == CENTER) + return x - length_*FONTS_->Width/2; + else + return x - length_*FONTS_->Width; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/Label.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,58 @@ +//----------------------------------------------------------- +// Label class -- Header +// +// 2016/10/02, Copyright (c) 2016 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_LABEL_HPP +#define F746_LABEL_HPP + +#include "GuiBase.hpp" + +namespace Mikami +{ + class Label : public GuiBase + { + public: + enum TextAlignMode { LEFT, CENTER, RIGHT }; + // Constructor + Label(uint16_t x, uint16_t y, const string str, + TextAlignMode mode = LEFT, + sFONT &fonts = Font12, + uint32_t textColor = GuiBase::ENUM_TEXT, + uint32_t backColor = GuiBase::ENUM_BACK); + + // Constructor without string + Label(uint16_t x, uint16_t y, + TextAlignMode mode = LEFT, + sFONT &fonts = Font12, + uint32_t textColor = GuiBase::ENUM_TEXT, + uint32_t backColor = GuiBase::ENUM_BACK) + : GuiBase(x, y, fonts, textColor, backColor), + MODE_(mode), STR_(""), length_(0) {} + + void Draw() + { Draw(STR_, TEXT_COLOR_); } + + void Draw(const string str) + { Draw(str, TEXT_COLOR_); } + + void Draw(uint32_t textColor) + { Draw(STR_, textColor); } + + void Draw(const string str, + uint32_t textColor); + + private: + const TextAlignMode MODE_; + const string STR_; + + uint8_t length_; + uint16_t PosX(uint16_t x); + + // disallow copy constructor and assignment operator + Label(const Label&); + Label& operator=(const Label&); + }; +} +#endif // F746_LABEL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/NumericLabel.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,64 @@ +//----------------------------------------------------------- +// NumericLabel class -- derived class of Label class +// +// 2016/11/07, Copyright (c) 2016 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_NUMERIC_LABEL_HPP +#define F746_NUMERIC_LABEL_HPP + +#include "Label.hpp" + +namespace Mikami +{ + template <typename T> class NumericLabel : public Label + { + public: + // Constructor without drawing value + NumericLabel(uint16_t x, uint16_t y, + const char fmt[], + TextAlignMode mode = LEFT, + sFONT &fonts = Font12, + uint32_t textColor = GuiBase::ENUM_TEXT, + uint32_t backColor = GuiBase::ENUM_BACK) + : Label(x, y, "", mode, fonts, textColor, backColor), FMT_(fmt) {} + + // Constructor with drawing value + NumericLabel(uint16_t x, uint16_t y, + const char fmt[], T val, + TextAlignMode mode = LEFT, + sFONT &fonts = Font12, + uint32_t textColor = GuiBase::ENUM_TEXT, + uint32_t backColor = GuiBase::ENUM_BACK) + : Label(x, y, "", mode, fonts, textColor, backColor), FMT_(fmt) + { Draw(val); } + + // Draw value using format specified in constructor + void Draw(T val) + { + sprintf(str_, FMT_, val); + Label::Draw(str_); + } + + // Draw value + void Draw(const char fmt[], T val) + { + sprintf(str_, fmt, val); + Label::Draw(str_); + } + + // Draw previous value with specified color + void Redraw(uint32_t color) + { Label::Draw(str_, color); } + + private: + const char *const FMT_; + char str_[81]; + + // disallow copy constructor and assignment operator + NumericLabel(const NumericLabel&); + NumericLabel& operator=(const NumericLabel&); + }; +} +#endif // F746_NUMERIC_LABEL_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/ResetButton.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,46 @@ +//----------------------------------------------------------- +// ResetButton class -- derived class of Button class +// +// 2017/01/16, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_RESET_BUTTON_HPP +#define F746_RESET_BUTTON_HPP + +#include "Button.hpp" + +namespace Mikami +{ + class ResetButton : public Button + { + public: + ResetButton(uint16_t x = 0, uint16_t y = 240, + uint16_t w = 32, uint16_t h = 32) + : Button(x, y, w, h) + { + pt_[0] = (Point){x+0.2f*w, y+h/2}; + pt_[1] = (Point){x+0.75f*w, y+0.175f*h}; + pt_[2] = (Point){x+0.75f*w, y+0.825f*h}; + Draw(); + } + + void DoIfTouched() + { + if (!Touched()) return; + + wait(0.2f); + NVIC_SystemReset(); + } + + void Draw() + { + Activate(); + lcd_.SetTextColor(LCD_COLOR_WHITE); + lcd_.FillPolygon(pt_, 3); + } + + private: + Point pt_[3]; + }; +} +#endif // F746_RESET_BUTTON_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/SeekBar.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,182 @@ +//----------------------------------------------------------- +// SeekBar class +// +// 2017/01/25, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "SeekBar.hpp" + +namespace Mikami +{ + // Constructor with scale value (only horizontal) + SeekBar::SeekBar(uint16_t x, uint16_t y, uint16_t length, + float min, float max, float initialValue, + string left, string center, string right, + uint32_t thumbColor, + uint16_t thumbSize, uint16_t width, + uint32_t colorL, uint32_t colorH, + uint32_t backColor) + : GuiBase(x, y, Font12, GuiBase::ENUM_TEXT, backColor, thumbColor), + L_(length), W_(width), + SIZE_(thumbSize), COLOR_L_(colorL), COLOR_H_(colorH), + MIN_(min), MAX_(max), ORIENT_(Holizontal), v_(initialValue), + labelOn_(true), slided_(false), active_(true) + { + Draw(initialValue); + uint16_t y0 = y - thumbSize/2 - 13; + labelLCR_[0] = new Label(x, y0, left, Label::CENTER); + labelLCR_[1] = new Label(x+length/2, y0, center, Label::CENTER); + labelLCR_[2] = new Label(x+length, y0, right, Label::CENTER); + } + + // Slide thumb + // If the thumb is not touched, return false + bool SeekBar::Slide() + { + if (!active_) return false; + + if (!PanelTouched()) + { + if (slided_) Draw(v_); + slided_ = false; + return false; + } + + uint16_t x, y; + bool rtn = IsOnThumb(x, y); + if (rtn || slided_) + { + if (rtn) v_ = ToValue(Point(x, y)); + Draw(v_, rtn); + slided_ = rtn; + } + return rtn; + } + + void SeekBar::Activate() + { + active_ = true; + Draw(v_); + if (labelOn_) + for (int n=0; n<3; n++) labelLCR_[n]->Draw(TEXT_COLOR_); + } + + void SeekBar::Inactivate() + { + active_ = false; + Draw(v_); + if (labelOn_) + for (int n=0; n<3; n++) labelLCR_[n]->Draw(INACTIVE_TEXT_COLOR_); + } + + // If touched position is on the thumb, return true + bool SeekBar::IsOnThumb(uint16_t &x, uint16_t &y) + { + x = state_.touchX[0]; + y = state_.touchY[0]; + + uint16_t th = SIZE_/2; + Point pt = ToPoint(v_); + if (ORIENT_ == Holizontal) + { + if ( (pt.x-th <= x) && (x <= pt.x+th) && + (pt.y-th <= y) && (y <= pt.y+th) ) return true; + } + else + { + if ( (pt.x-th <= x) && (x <= pt.x+th) && + (pt.y-th <= y) && (y <= pt.y+th) ) return true; + } + + return false; + } + + // Draw seekbar + void SeekBar::Draw(float value, bool fill) + { + uint16_t sizeS = (uint16_t)(SIZE_*0.6f); + // Erase previous seekbar + lcd_.SetTextColor(BACK_COLOR_); + if (ORIENT_ == Holizontal) + lcd_.FillRect(X_-sizeS/2, Y_-SIZE_/2, L_+sizeS+1, SIZE_+1); + else + lcd_.FillRect(X_-SIZE_/2, Y_-sizeS/2, SIZE_+1, L_+sizeS+1); + + v_ = Saturate(value); // current value + Point pt = ToPoint(v_); // Position of thumb + + // Draw upper line + if (active_) lcd_.SetTextColor(COLOR_H_); + else lcd_.SetTextColor(INACTIVE_TEXT_COLOR_-0x404040); + if ((ORIENT_ == Holizontal) && ((X_+L_-pt.x) > 0)) + lcd_.FillRect(pt.x, Y_-W_/4, X_+L_-pt.x, W_/2); + if ((ORIENT_ == Vertical) && ((pt.y-Y_) > 0)) + lcd_.FillRect(X_-W_/4, Y_, W_/2, pt.y-Y_); + + // Draw lower line + if (active_) lcd_.SetTextColor(COLOR_L_); + else lcd_.SetTextColor(INACTIVE_TEXT_COLOR_-0x202020); + if ((ORIENT_ == Holizontal) && ((pt.x-X_) > 0)) + lcd_.FillRect(X_, Y_-W_/2, pt.x-X_, W_); + if ((ORIENT_ == Vertical) && ((Y_+L_-pt.y) > 0)) + lcd_.FillRect(X_-W_/2, pt.y, W_, Y_+L_-pt.y); + + // Draw thumb + if (active_) lcd_.SetTextColor(CREATED_COLOR_); + else lcd_.SetTextColor(INACTIVE_TEXT_COLOR_); + uint16_t width = SIZE_; + uint16_t height = SIZE_; + if (ORIENT_ == Holizontal) width = sizeS; + else height = sizeS; + uint16_t xPos = pt.x - width/2; + uint16_t yPos = pt.y - height/2; + + if (fill) + lcd_.FillRect(xPos, yPos, width+1, height+1); + else + { + lcd_.DrawRect(xPos, yPos, width, height); + lcd_.DrawHLine(pt.x+width/2, pt.y+height/2, 1); + lcd_.DrawRect(xPos+1, yPos+1, width-2, height-2); + lcd_.DrawHLine(pt.x+width/2-1, pt.y+height/2-1, 1); + if (ORIENT_ == Holizontal) + lcd_.DrawVLine(pt.x, yPos+4, SIZE_-7); + else + lcd_.DrawHLine(xPos+4, pt.y, SIZE_-7); + } + } + + void SeekBar::Redraw(bool fill) + { + Draw(GetValue(), fill); + if (labelOn_) + for (int n=0; n<3; n++) labelLCR_[n]->Draw(TEXT_COLOR_); + } + + SeekBar::Point SeekBar::ToPoint(float value) + { + if (ORIENT_ == Holizontal) + return Point(X_ + Round(L_*(value - MIN_)/(MAX_ - MIN_)), Y_); + else + return Point(X_, Y_ + L_ - Round(L_*(value - MIN_)/(MAX_ - MIN_))); + } + + float SeekBar::ToValue(Point pt) + { + float value; + if (ORIENT_ == Holizontal) + value = (pt.x - X_)*(MAX_ - MIN_)/(float)L_ + MIN_; + else + value = -(pt.y - Y_ - L_)*(MAX_ - MIN_)/(float)L_ + MIN_; + return Saturate(value); + } + + float SeekBar::Saturate(float value) + { + if (value < MIN_) value = MIN_; + if (value > MAX_) value = MAX_; + return value; + } +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/SeekBar.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,95 @@ +//----------------------------------------------------------- +// SeekBar class -- Header +// +// 2017/01/25, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_SEEKBAR_HPP +#define F746_SEEKBAR_HPP + +#include "GuiBase.hpp" +#include "Label.hpp" + +namespace Mikami +{ + class SeekBar : public GuiBase + { + public: + enum Orientation { Holizontal, Vertical }; + + struct Point + { + uint16_t x, y; + Point(uint16_t x0 = 0, uint16_t y0 = 0) : x(x0), y(y0) {} + }; + + // Constructor + SeekBar(uint16_t x, uint16_t y, uint16_t length, + float min, float max, float initialValue, + Orientation hv = Holizontal, + uint32_t thumbColor = 0xFFB0B0FF, + uint16_t thumbSize = 30, uint16_t width = 4, + uint32_t colorL = LCD_COLOR_LIGHTGRAY, + uint32_t colorH = 0xFFB0B0B0, + uint32_t backColor = GuiBase::ENUM_BACK) + : GuiBase(x, y, Font12, 0, backColor, thumbColor), + L_(length), W_(width), + SIZE_(thumbSize), COLOR_L_(colorL), COLOR_H_(colorH), + MIN_(min), MAX_(max), ORIENT_(hv), v_(initialValue), + labelOn_(false), slided_(false), active_(true) + { Draw(initialValue); } + + // Constructor with scale value (only horizontal) + SeekBar(uint16_t x, uint16_t y, uint16_t length, + float min, float max, float initialValue, + string left, string center, string right, + uint32_t thumbColor = 0xFFB0B0FF, + uint16_t thumbSize = 30, uint16_t width = 4, + uint32_t colorL = LCD_COLOR_LIGHTGRAY, + uint32_t colorH = 0xFFB0B0B0, + uint32_t backColor = GuiBase::ENUM_BACK); + + virtual ~SeekBar() + { for (int n=0; n<3; n++) delete labelLCR_[n]; } + + bool Slide(); + float GetValue() { return v_; } + int GetIntValue() { return Round(v_); } + + void Activate(); + void Inactivate(); + bool IsActive() { return active_; } + + bool IsOnThumb(uint16_t &x, uint16_t &y); + void Draw(float value, bool fill = false); + void Redraw(bool fill = false); + float ToValue(Point pt); + + void SetValue(float v) { v_ = v; } + void SetSlided(bool tf) { slided_ = tf; } + bool GetSlided() { return slided_; } + + private: + const uint16_t L_, W_; + const uint16_t SIZE_; // Size of thumb + const uint32_t COLOR_L_, COLOR_H_; + const float MIN_, MAX_; + const Orientation ORIENT_; + + Label *labelLCR_[3]; + float v_; // value of seekbar + bool labelOn_; + bool slided_; + bool active_; + + int Round(float x) { return x + 0.5f - (x < 0); } + Point ToPoint(float value); + float Saturate(float value); + + // disallow copy constructor and assignment operator + SeekBar(const SeekBar&); + SeekBar& operator=(const SeekBar&); + }; +} +#endif // F746_SEEKBAR_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/SeekbarGroup.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,72 @@ +//----------------------------------------------------------- +// SeekbarGroup class +// +// 2017/01/25, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "SeekbarGroup.hpp" + +namespace Mikami +{ + SeekbarGroup::SeekbarGroup( + uint16_t x0, uint16_t y0, uint16_t length, + uint16_t number, uint16_t space, + float min, float max, float initialValue, + SeekBar::Orientation hv, + uint32_t thumbColor, uint16_t thumbSize, uint16_t width, + uint32_t colorL, uint32_t colorH, uint32_t backColor) + : NUMBER_(number) + { + seekBars_.SetSize(number); + for (int n=0; n<number; n++) + { + uint16_t x = x0; + uint16_t y = y0; + if (hv == SeekBar::Holizontal) y += space*n; + else x += space*n; + seekBars_[n] = + new SeekBar(x, y, length, min, max, initialValue, hv, + thumbColor, thumbSize, width, + colorL, colorH, backColor); + } + } + + // Get slided number + bool SeekbarGroup::GetSlidedNumber(int &num) + { + bool active = false; + for (int n=0; n<NUMBER_; n++) + if (seekBars_[n]->IsActive()) active = true; + if (!active) return false; + + if (!GuiBase::PanelTouched()) + { + for (int n=0; n<NUMBER_; n++) + { + if (seekBars_[n]->GetSlided()) + seekBars_[n]->Draw(seekBars_[n]->GetValue()); + seekBars_[n]->SetSlided(false); + } + return false; + } + + bool rtn = false; + uint16_t x, y; + for (int n=0; n<NUMBER_; n++) + { + if (seekBars_[n]->IsOnThumb(x, y)) + { + if ((num != n) && Range(num)) + seekBars_[num]->Draw(seekBars_[num]->GetValue()); + num = n; + seekBars_[n]->SetValue(seekBars_[n]->ToValue(SeekBar::Point(x, y))); + seekBars_[n]->Draw(seekBars_[n]->GetValue(), true); + seekBars_[n]->SetSlided(true); + rtn = true; + } + if (rtn) break; + } + return rtn; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/SeekbarGroup.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,79 @@ +//----------------------------------------------------------- +// SeekbarGroup class -- Header +// +// 2017/01/25, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_SEEKBAR_GROUP_HPP +#define F746_SEEKBAR_GROUP_HPP + +#include "SeekBar.hpp" +#include "Array.hpp" + +namespace Mikami +{ + class SeekbarGroup + { + public: + SeekbarGroup(uint16_t x0, uint16_t y0, uint16_t length, + uint16_t number, uint16_t space, + float min, float max, float initialValue, + SeekBar::Orientation hv = SeekBar::Holizontal, + uint32_t thumbColor = 0xFFB0B0FF, + uint16_t thumbSize = 30, uint16_t width = 4, + uint32_t colorL = LCD_COLOR_LIGHTGRAY, + uint32_t colorH = 0xFFB0B0B0, + uint32_t backColor = GuiBase::ENUM_BACK); + + virtual ~SeekbarGroup() + { for (int n=0; n<NUMBER_; n++) delete seekBars_[n]; } + + bool Slide(int num) { return seekBars_[num]->Slide(); } + float GetValue(int num) { return seekBars_[num]->GetValue(); } + int GetIntValue(int num) { return seekBars_[num]->GetIntValue(); } + + // Get slided number + bool GetSlidedNumber(int &num); + + void Draw(int num, float value, bool fill = false) + { seekBars_[num]->Draw(value, fill); } + + // Draw all thumbs with same value + void DrawAll(float value, bool fill = false) + { for (int n=0; n<NUMBER_; n++) Draw(n, value, fill); } + + void Redraw(int num, bool fill = false) + { seekBars_[num]->Draw(seekBars_[num]->GetValue(), fill); } + + void RedrawAll(bool fill = false) + { for (int n=0; n<NUMBER_; n++) Redraw(n, fill); } + + // Activate and inactivate + void Activate(int num) { seekBars_[num]->Activate(); } + void Inactivate(int num) { seekBars_[num]->Inactivate(); } + void ActivateAll() + { + for (int n=0; n<NUMBER_; n++) + seekBars_[n]->Activate(); + } + void InactivateAll() + { + for (int n=0; n<NUMBER_; n++) + seekBars_[n]->Inactivate(); + } + + private: + const int NUMBER_; + Array<SeekBar *> seekBars_; + + // Check range of argument + bool Range(int n) + { return ((n >= 0) && (n < NUMBER_)); } + + // disallow copy constructor and assignment operator + SeekbarGroup(const SeekbarGroup&); + SeekbarGroup& operator=(const SeekbarGroup&); + }; +} +#endif // F746_SEEKBAR_GROUP_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_Gui_New/TS_DISCO_F746NG.lib Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/ST/code/TS_DISCO_F746NG/#fe0cf5e2960f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_SAI_IO_New/Array_Matrix.lib Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/Array_Matrix/#a25dba17218c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_SAI_IO_New/BSP_AudioIn_Overwrite.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,102 @@ +//------------------------------------------------------------------------------ +// Overwrite functuions and define calback function +// for functions in stm32746g_discovery_audio.cpp +// +// Original version: BSP_overwrite.cpp by Nanase +// https://developer.mbed.org/users/nanase/code/DISCO-F746NG_Oscilloscope/ +//------------------------------------------------------------------------------ + +#include "BSP_AudioIn_Overwrite.hpp" + +// These three callback functions are modyfied by Mikami +void BSP_AUDIO_IN_HalfTransfer_CallBack() +{ + Mikami::SaiIO::Captured1st(); +} + +void BSP_AUDIO_IN_TransferComplete_CallBack() +{ + Mikami::SaiIO::Captured2nd(); +} + +void BSP_AUDIO_IN_Error_CallBack() +{ + Mikami::SaiIO::ErrorTrap(); +} + +//-------------------------------------------------------------- +// Followings are original by Nanase +//-------------------------------------------------------------- + +DMA_HandleTypeDef hdma_sai_rx; + +void AUDIO_IN_SAIx_DMAx_IRQHandler() +{ + HAL_DMA_IRQHandler(&hdma_sai_rx); +} + +void BSP_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params) +{ + GPIO_InitTypeDef gpio_init_structure; + + /* Enable SAI clock */ + AUDIO_IN_SAIx_CLK_ENABLE(); + + /* Enable SD GPIO clock */ + AUDIO_IN_SAIx_SD_ENABLE(); + /* CODEC_SAI pin configuration: SD pin */ + gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FAST; + gpio_init_structure.Alternate = AUDIO_IN_SAIx_SD_AF; + HAL_GPIO_Init(AUDIO_IN_SAIx_SD_GPIO_PORT, &gpio_init_structure); + + /* Enable Audio INT GPIO clock */ + AUDIO_IN_INT_GPIO_ENABLE(); + /* Audio INT pin configuration: input */ + gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN; + gpio_init_structure.Mode = GPIO_MODE_INPUT; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FAST; + HAL_GPIO_Init(AUDIO_IN_INT_GPIO_PORT, &gpio_init_structure); + + /* Enable the DMA clock */ + AUDIO_IN_SAIx_DMAx_CLK_ENABLE(); + + if(hsai->Instance == AUDIO_IN_SAIx) + { + /* Configure the hdma_sai_rx handle parameters */ + hdma_sai_rx.Init.Channel = AUDIO_IN_SAIx_DMAx_CHANNEL; + hdma_sai_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_sai_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_sai_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE; + hdma_sai_rx.Init.MemDataAlignment = AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE; + hdma_sai_rx.Init.Mode = DMA_CIRCULAR; + hdma_sai_rx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_sai_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + hdma_sai_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_sai_rx.Init.MemBurst = DMA_MBURST_SINGLE; + hdma_sai_rx.Init.PeriphBurst = DMA_MBURST_SINGLE; + + hdma_sai_rx.Instance = AUDIO_IN_SAIx_DMAx_STREAM; + + /* Associate the DMA handle */ + __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx); + + /* Deinitialize the Stream for new transfer */ + HAL_DMA_DeInit(&hdma_sai_rx); + + /* Configure the DMA Stream */ + HAL_DMA_Init(&hdma_sai_rx); + } + + /* SAI DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_IN_SAIx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0); + HAL_NVIC_EnableIRQ(AUDIO_IN_SAIx_DMAx_IRQ); + + /* Audio INT IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_IN_INT_IRQ, AUDIO_IN_IRQ_PREPRIO, 0); + HAL_NVIC_EnableIRQ(AUDIO_IN_INT_IRQ); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_SAI_IO_New/BSP_AudioIn_Overwrite.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,15 @@ +//-------------------------------------------------------------- +// Overwrite functuions and define calback function (Header) +// for functions in stm32746g_discovery_audio.cpp +//-------------------------------------------------------------- + +#ifndef F746_AUDIO_IN_OVERWRITE_HPP +#define F746_AUDIO_IN_OVERWRITE_HPP + +#include "stm32746g_discovery_audio.h" +#include "SAI_InOut.hpp" + +void AUDIO_IN_SAIx_DMAx_IRQHandler(); + +#endif // F746_AUDIO_IN_OVERWRITE_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_SAI_IO_New/BSP_AudioOut_Overwrite.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,113 @@ +//------------------------------------------------------------------------------ +// Overwrite functuions and define calback functions +// for functions in stm32746g_discovery_audio.cpp +// +// Original version: BSP_overwrite.cpp by Nanase +// https://developer.mbed.org/users/nanase/code/DISCO-F746NG_Sweep/ +//------------------------------------------------------------------------------ +#include "BSP_AudioOut_Overwrite.hpp" + +// These three callback functions are modyfied by Mikami +void BSP_AUDIO_OUT_HalfTransfer_CallBack() +{ + Mikami::SaiIO::FillBuffer1st(); +} + +void BSP_AUDIO_OUT_TransferComplete_CallBack() +{ + Mikami::SaiIO::FillBuffer2nd(); +} + +void BSP_AUDIO_OUT_Error_CallBack() +{ + Mikami::SaiIO::ErrorTrap(); +} + +//-------------------------------------------------------------- +// Followings are original by Nanase +//-------------------------------------------------------------- + +DMA_HandleTypeDef hdma_sai_tx; + +void AUDIO_OUT_SAIx_DMAx_IRQHandler() +{ + HAL_DMA_IRQHandler(&hdma_sai_tx); +} + +void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params) +{ + //static DMA_HandleTypeDef hdma_sai_tx; + GPIO_InitTypeDef gpio_init_structure; + + /* Enable SAI clock */ + AUDIO_OUT_SAIx_CLK_ENABLE(); + + /* Enable GPIO clock */ + AUDIO_OUT_SAIx_MCLK_ENABLE(); + AUDIO_OUT_SAIx_SCK_SD_ENABLE(); + AUDIO_OUT_SAIx_FS_ENABLE(); + + /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/ + gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_HIGH; + gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF; + HAL_GPIO_Init(AUDIO_OUT_SAIx_FS_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = AUDIO_OUT_SAIx_SCK_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_HIGH; + gpio_init_structure.Alternate = AUDIO_OUT_SAIx_SCK_AF; + HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = AUDIO_OUT_SAIx_SD_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_HIGH; + gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF; + HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_HIGH; + gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF; + HAL_GPIO_Init(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, &gpio_init_structure); + + /* Enable the DMA clock */ + AUDIO_OUT_SAIx_DMAx_CLK_ENABLE(); + + if(hsai->Instance == AUDIO_OUT_SAIx) + { + /* Configure the hdma_saiTx handle parameters */ + hdma_sai_tx.Init.Channel = AUDIO_OUT_SAIx_DMAx_CHANNEL; + hdma_sai_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_sai_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_sai_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE; + hdma_sai_tx.Init.MemDataAlignment = AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE; + hdma_sai_tx.Init.Mode = DMA_CIRCULAR; + hdma_sai_tx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_sai_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; + hdma_sai_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_sai_tx.Init.MemBurst = DMA_MBURST_SINGLE; + hdma_sai_tx.Init.PeriphBurst = DMA_PBURST_SINGLE; + + hdma_sai_tx.Instance = AUDIO_OUT_SAIx_DMAx_STREAM; + + /* Associate the DMA handle */ + __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx); + + /* Deinitialize the Stream for new transfer */ + HAL_DMA_DeInit(&hdma_sai_tx); + + /* Configure the DMA Stream */ + HAL_DMA_Init(&hdma_sai_tx); + } + + /* SAI DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_OUT_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0); + HAL_NVIC_EnableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_SAI_IO_New/BSP_AudioOut_Overwrite.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,14 @@ +//-------------------------------------------------------------- +// Overwrite functuions and define calback function (Header) +// for functions in stm32746g_discovery_audio.cpp +//-------------------------------------------------------------- + +#ifndef F746_AUDIO_OUT_OVERWRITE_HPP +#define F746_AUDIO_OUT_OVERWRITE_HPP + +#include "stm32746g_discovery_audio.h" +#include "SAI_InOut.hpp" + +void AUDIO_OUT_SAIx_DMAx_IRQHandler(); + +#endif // F746_AUDIO_OUT_OVERWRITE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_SAI_IO_New/SAI_InOut.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,197 @@ +//----------------------------------------------------------- +// SaiIO class +// BSP_DISCO_F746NG Rev.9 に合わせて変更 +// InitInput() の内容を一部変更(変更前の部分はコメントアウト) +// +// 2017/09/17, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "SAI_InOut.hpp" + +namespace Mikami +{ + // Constructor + SaiIO::SaiIO(InOutBoth ioBoth, int size, int fs, + uint16_t inputDevice) + : FS_(fs), IOBOTH_(ioBoth) + { + nData_ = size; + bufferSize_ = (size*2)*2; + + if (ioBoth != OUTPUT) + { + inBuffer_.SetSize((size*2)*2); + inOffset_ = 0; + captured_ = false; + } + if (ioBoth != INPUT) + { + outBuffer_.SetSize((size*2)*2); + tmp_.SetSize(size*2); + tmpIndex_ = 0; + xferred_ = false; + ClearBuffer(); + } + InitCodec(inputDevice); + } + + // Input start + void SaiIO::RecordIn() + { + if (BSP_AUDIO_IN_Record(inBuffer_, bufferSize_) == AUDIO_ERROR) + ErrorTrap(); + } + + // Switching input device and run + void SaiIO::SwitchInputDevice(int sw) + { + uint16_t dev = (sw == 0) ? + INPUT_DEVICE_DIGITAL_MICROPHONE_2 + : INPUT_DEVICE_INPUT_LINE_1; + InitInput(dev); + ClearBuffer(); + RecordIn(); + if (IOBOTH_ == BOTH) PlayOut(); + } + + // If captured, return true + bool SaiIO::IsCaptured() + { + if (!captured_) return false; + + inIndex_ = inOffset_; + captured_ = false; + return true; + } + + void SaiIO::PlayOut() + { + ClearBuffer(); + BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); + if (BSP_AUDIO_OUT_Play(outBuffer_, bufferSize_*AUDIODATA_SIZE) + == AUDIO_ERROR) + ErrorTrap(); + } + + // Return true if transfer completion to output + bool SaiIO::IsXferred() + { + if (!xferred_) return false; + + tmpIndex_ = 0; + xferred_ = false; + return true; + } + + void SaiIO::Output(int16_t xL, int16_t xR) + { + tmp_[tmpIndex_++] = xL; // Left + tmp_[tmpIndex_++] = xR; // Right + } + + void SaiIO::ErrorTrap() + { + DigitalOut led1(LED1); + fprintf(stderr, "\r\n#### ERROR ####\r\n"); + while(true) + { + led1 = !led1; + wait_ms(250); + } + } + + // Initialize audio input and output + void SaiIO::InitCodec(uint16_t inputDevice) + { + if (inputDevice != 0) InitInput(inputDevice); + + if (IOBOTH_ == OUTPUT) + if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, + 100, FS_) == AUDIO_ERROR) + ErrorTrap(); + + if (IOBOTH_ != OUTPUT) SetInput(); + if (IOBOTH_ != INPUT) SetOutput(); + } + + void SaiIO::InitInput(uint16_t inputDevice) + { + int audioInVolume = (inputDevice == INPUT_DEVICE_INPUT_LINE_1) ? + 70 : 90; + InputFp = (inputDevice == INPUT_DEVICE_INPUT_LINE_1) ? + &SaiIO::InputNormal : &SaiIO::InputReversal; + if (IOBOTH_ == BOTH) +/* + if (BSP_AUDIO_IN_OUT_Init(inputDevice, OUTPUT_DEVICE_HEADPHONE, + audioInVolume, FS_) == AUDIO_ERROR) +*/ + if (BSP_AUDIO_IN_OUT_Init(inputDevice, OUTPUT_DEVICE_HEADPHONE, + FS_, DEFAULT_AUDIO_IN_BIT_RESOLUTION, + DEFAULT_AUDIO_IN_CHANNEL_NBR) == AUDIO_ERROR) + ErrorTrap(); + + if (IOBOTH_ == INPUT) + if (BSP_AUDIO_IN_Init(inputDevice, + audioInVolume, FS_) == AUDIO_ERROR) + ErrorTrap(); + } + + void SaiIO::SetInput() + { + NVIC_SetVector(AUDIO_IN_SAIx_DMAx_IRQ, + (uint32_t)AUDIO_IN_SAIx_DMAx_IRQHandler); + } + + void SaiIO::SetOutput() + { + NVIC_SetVector(AUDIO_OUT_SAIx_DMAx_IRQ, + (uint32_t)AUDIO_OUT_SAIx_DMAx_IRQHandler); + BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); + } + + void SaiIO::ClearBuffer() + { + if (IOBOTH_ != OUTPUT) + for (int n=0; n<bufferSize_; n++) inBuffer_[n] = 0; + for (int n=0; n<bufferSize_; n++) outBuffer_[n] = 0; + for (int n=0; n<nData_*2; n++) tmp_[n] = 0; + } + + // For line input + void SaiIO::InputNormal(int16_t &xL, int16_t &xR) + { + xL = inBuffer_[inIndex_++]; + xR = inBuffer_[inIndex_++]; + } + + // For MEMS microphone input + void SaiIO::InputReversal(int16_t &xL, int16_t &xR) + { + xR = inBuffer_[inIndex_++]; + xL = inBuffer_[inIndex_++]; + } + + void SaiIO::Captured(int32_t offset) + { + captured_ = true; + inOffset_ = offset; + } + + void SaiIO::FillBuffer(uint32_t offset) + { + int k = offset; + for (int n=0; n<nData_*2; n++) + outBuffer_[k++] = tmp_[n]; + xferred_ = true; + } + + int32_t SaiIO::nData_; + int32_t SaiIO::bufferSize_; + + __IO bool SaiIO::captured_; + __IO int32_t SaiIO::inOffset_; + + Array<uint16_t> SaiIO::outBuffer_; + Array<uint16_t> SaiIO::tmp_; + __IO bool SaiIO::xferred_; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F746_SAI_IO_New/SAI_InOut.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,110 @@ +//----------------------------------------------------------- +// SaiIO class (Header) +// 2017/03/17, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_SAI_IO_HPP +#define F746_SAI_IO_HPP + +#include "mbed.h" +#include "stm32746g_discovery_audio.h" +#include "BSP_AudioIn_Overwrite.hpp" +#include "BSP_AudioOut_Overwrite.hpp" +#include "Array.hpp" + +namespace Mikami +{ + class SaiIO + { + public: + enum InOutBoth { INPUT, // input only + OUTPUT, // output only + BOTH }; // input and output + // Constructor + // inputDevice: INPUT_DEVICE_DIGITAL_MICROPHONE_2 or + // INPUT_DEVICE_INPUT_LINE_1 + // inputDevice == 0 : not use input device + SaiIO(InOutBoth ioBoth, int size, int fs, + uint16_t inputDevice = 0); + virtual ~SaiIO() {} + + int32_t GetLength() { return nData_; } + + void RecordIn(); + // sw = 0: DIGITAL_MICROPHONE_2 + // 1: LINE_1 + void SwitchInputDevice(int sw); + + bool IsCaptured(); + // Input using SAI + void Input(int16_t &xL, int16_t &xR) + { (this->*InputFp)(xL, xR); } + + void StopIn() { BSP_AUDIO_IN_Stop(CODEC_PDWN_SW); } + void PauseIn() { BSP_AUDIO_IN_Pause(); } + void ResumeIn() { BSP_AUDIO_IN_Resume(); } + + void PlayOut(); + bool IsXferred(); + // Output using SAI + void Output(int16_t xL, int16_t xR); + + void StopOut() { BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW); } + void PauseOut() { BSP_AUDIO_OUT_Pause(); } + void ResumeOut() { BSP_AUDIO_OUT_Resume(); } + + // IF you use both input and output of SAI, + // you can use following function + bool IsCompleted() + { return IsCaptured() && IsXferred(); } + + // Following two member functions are called from + // callback functions in "BSP_AudioIn_Overwrite.cpp" + static void Captured1st() { Captured(0); } + static void Captured2nd() { Captured(bufferSize_/2); } + + // Following two member functions are called from + // callback functions in "BSP_AudioOut_Overwrite.cpp" + static void FillBuffer1st() { FillBuffer(0); } + static void FillBuffer2nd() { FillBuffer(bufferSize_/2); } + + // Called form the functions in "BSP_AudioIn_Overwrite.cpp" + // and "BSP_AudioOut_Overwrite.cpp" + static void ErrorTrap(); + + private: + const int FS_; + const InOutBoth IOBOTH_; + + Array<uint16_t> inBuffer_; + static Array<uint16_t> outBuffer_; + static Array<uint16_t> tmp_; + + __IO int32_t inIndex_; + __IO int32_t tmpIndex_; + + static int32_t nData_; + static int32_t bufferSize_; + static __IO bool captured_; + static __IO int32_t inOffset_; + static __IO bool xferred_; + + void InitCodec(uint16_t inputDevice); + void InitInput(uint16_t inputDevice); + void SetInput(); + void SetOutput(); + void ClearBuffer(); + + // This function pointer is assigned by + // InputNormal() or InputReversal() + void (SaiIO::*InputFp)(int16_t &, int16_t &); + // For line input + void InputNormal(int16_t &xL, int16_t &xR); + // For MEMS microphone input + void InputReversal(int16_t &xL, int16_t &xR); + + static void Captured(int32_t offset); + static void FillBuffer(uint32_t offset); + }; +} +#endif // F746_SAI_IO_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Filter/Multiplier.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,27 @@ +//--------------------------------------------------- +// 定数乗算器 +// +// 2017/09/27, Copyright (c) 2017 MIKAMI, Naoki +//--------------------------------------------------- + +#ifndef CONST_MULTIPLY_HPP +#define CONST_MULTIPLY_HPP + +#include "mbed.h" + +class Multiplier +{ +public: + // コンストラクタ + Multiplier(float factor) : C_(factor) {} + + // 定数を乗算する処理の実行,戻り値は int16_t 型とすること + int16_t Execute(int16_t xn) + { + int16_t yn = C_*xn; + return yn; + } +private: + const float C_; +}; +#endif // CONST_MULTIPLY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyFiles/DelayedEnabler.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,42 @@ +//----------------------------------------------------------- +// ある機能を一定の時間が経過するまでは無効にし,その後有効に +// するためのクラス +// +// 2017/08/21, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef DELAYED_ENABLER_HPP +#define DELAYED_ENABLER_HPP + +#include "mbed.h" + +namespace Mikami +{ + class DelayedEnabler + { + public: + DelayedEnabler(float delayTime = 0.3f) + : DELAY_TIME_(delayTime), enable_(true) {} + + // このメンバ関数の実行直後から指定された時間,IsEnabled() は false を + // 返し,その後 InEnabled() は true を返す + void Disable() + { + enable_ = false; + Enabler_.attach(callback(this, &DelayedEnabler::TimeoutIsr), + DELAY_TIME_); + } + + bool IsEnabled() { return enable_; } + + private: + const float DELAY_TIME_; // 無効になっている時間 + + __IO bool enable_; + Timeout Enabler_; + + // 有効にする(Timeout 割り込みに対応する ISR) + void TimeoutIsr() { enable_ = true; } + }; +} +#endif // DELAYED_ENABLER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyFiles/LcdPanelFrq.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,119 @@ +//----------------------------------------------------------- +// ディジタルフィルタ実験のためのプラットフォームの +// LCD パネル表示と入力信号の周波数設定で使う +// +// 2017/08/21, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef PANEL_MANIPULATOR_HPP +#define PANEL_MANIPULATOR_HPP + +#include "F746_GUI.hpp" +#include "NumericUpDown.hpp" +#include "Zoom.hpp" +#include "WaveformDisplay.hpp" +#include "Trigger.hpp" + +namespace Mikami +{ + class LcdPanel + { + public: + // ts : 標本化間隔(単位:μs) + LcdPanel(float ts) + : TS_(ts), lcd_(GuiBase::GetLcd()), + xnD_(N_DISP_BUF_), ynD_(N_DISP_BUF_), frq_(1000), + dPhi_(PI2_*frq_*TS_), phi_(0), factor_(1) + { + Label title(240, 10, "Digital Filter LAB", Label::CENTER, Font16); + + const uint16_t Y0 = 170; + // 凡例 + lcd_.SetTextColor(LINE_COLOR1_); + lcd_.DrawHLine(360, Y0+6, 50); + Label label1(420, Y0, "Input"); + lcd_.SetTextColor(LINE_COLOR2_); + lcd_.DrawHLine(360, Y0+26, 50); + Label label2(420, Y0+20, "Output"); + + waveDisp_ = new WaveformDisplay(lcd_, 30, 90, xnD_, ynD_, 400, 8, + AXIS_COLOR_, + LINE_COLOR1_, LINE_COLOR2_, + BACK_COLOR_); + + // GUI 設定 + ud_ = new NumericUpDown(4, 0, 271, frq_, 9999, 100, "Hz"); + bar_ = new SeekBar(230, 250, 230, + log10f(MIN_FRQ_), log10f(MAX_FRQ_), log10f(1000), + "0.1", "1.0", "10.0"); + // 時間軸の拡大率は 8 倍まで + zmButton_ = new ZoomButton(240, Y0, 40, 30, 8); + } + + // 正弦波の発生で使う値の更新し,取得する + float GetPhi() + { + if ((phi_ += dPhi_) > PI2_) phi_ -= PI2_; + return phi_; + } + + // 周波数設定の更新とズームイン/アウト・ボタンの処理 + void Update() + { + if (bar_->Slide()) // SeekBar をスライドした場合の処理 + { + frq_ = (int)(powf(10, bar_->GetValue())+0.5f); + if (frq_ >= MAX_FRQ_) frq_ = MAX_FRQ_ - 1; + ud_->Set(frq_); // SeekBar の数値を NumericUpDown に表示する + dPhi_ = PI2_*frq_*TS_; + } + + if (ud_->Touched()) // NumericUpDown をタッチした場合の処理 + { + frq_ = ud_->Get(); + bar_->Draw(log10f(frq_)); // NumericUpDown の数値で SeekBar のツマミの位置を設定 + dPhi_ = PI2_*frq_*TS_; + } + + zmButton_->Touched(factor_); // ズームインとズームアウト + } + + // 入出力信号のデータを表示用バッファへ格納 + void Store(int16_t xn, int16_t yn, int n) + { + if (n >= N_DISP_BUF_) return; + + xnD_[n] = xn; + ynD_[n] = yn; + } + + // 入出力信号の波形の表示 + void Display() { waveDisp_->Execute(Trigger(xnD_, 1), factor_); } + + private: + static const float PI_ = 3.1415926536f; + static const float PI2_ = 2.0f*PI_; + static const int MIN_FRQ_ = 100; // 発生する周波数の最小値 + static const int MAX_FRQ_ = 10000; // 発生する周波数の最大値 + static const uint32_t BACK_COLOR_ = GuiBase::ENUM_BACK; + static const uint32_t AXIS_COLOR_ = 0xFFCCFFFF; + static const uint32_t LINE_COLOR1_ = LCD_COLOR_CYAN; + static const uint32_t LINE_COLOR2_ = LCD_COLOR_MAGENTA; + static const int N_DISP_BUF_ = 1000; // 波形表示用のバッファのサイズ + + const float TS_; // 標本化間隔 + + LCD_DISCO_F746NG &lcd_; + WaveformDisplay *waveDisp_; + NumericUpDown *ud_; // 入力信号の周波数設定用(1 Hz 単位での設定用) + SeekBar *bar_; // 入力信号の周波数設定用(概略の設定用) + ZoomButton *zmButton_; // 波形表示:ズームイン/アウト用 + + Array<int16_t> xnD_; // 波形表示で使うバッファ(入力信号用) + Array<int16_t> ynD_; // 波形表示で使うバッファ(出力信号用) + int frq_; // 現在の入力信号の周波数,初期値は 1 kHz + float dPhi_, phi_; // 入力信号の生成で使う変数 + int factor_; // 波形表示の際の標本化間隔に対応するピクセル数 + }; +} +#endif // PANEL_MANIPULATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyFiles/NumericUpDown.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,94 @@ +//----------------------------------------------------------- +// NumericUpDown class +// 指定された桁を up/down する GUI 部品 +// 6 桁まで可能 +// +// 2017/08/21, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "NumericUpDown.hpp" + +namespace Mikami +{ + // digit 表示する桁数 + // initVal 最初に表示する数値 + NumericUpDown::NumericUpDown(uint16_t digit, uint16_t x0, uint16_t y0, + uint32_t initVal, uint32_t max, uint32_t min, + string unit, float delay) + : DIGIT_(digit), X0_(x0), Y0_(y0), MAX_(max), MIN_(min), + POW10_(6, (uint32_t []){1, 10, 100, 1000, 10000, 10000}), + numUd_(-1), value_(initVal), + delay_(delay), labels_(digit), lcd_(GuiBase::GetLcd()) + { + MBED_ASSERT(DIGIT_ <= 6); // 6 桁まで + sprintf(fmt_, "%%""0%1dd", DIGIT_); + for (int n=0; n<DIGIT_; n++) + labels_[n] = new Label( + X0_+10+n*XW_, Y0_-46, "", Label::LEFT, Font16); + Set(initVal); // 初期値として表示 + Label lbUnit(X0_+0+DIGIT_*XW_, Y0_-46, unit, Label::LEFT, Font16); + Array<string> nonString(DIGIT_*2, ""); + ud_ = new ButtonGroup(X0_, Y0_-81, 30, 30, DIGIT_*2, nonString, + XW_-30, 22, DIGIT_); + for (int n=0; n<DIGIT_*2; n++) UpDownSymbol(X0_, Y0_, n); + } + + // Up, Down をタッチした場合は対応する数値を +1 または -1 する + bool NumericUpDown::Touched() + { + if (!delay_.IsEnabled()) return false; + int num; + if (!ud_->GetTouchedNumber(num)) return false; + + // タッチ後一定の時間が経過してから,再びタッチの検出を有効にするため + delay_.Disable(); + + // 三角を再描画 + UpDownSymbol(X0_, Y0_, num); + if (numUd_ != -1) UpDownSymbol(X0_, Y0_, numUd_); + numUd_ = num; + + int index = num % DIGIT_; + if (num < DIGIT_) value_ += POW10_[DIGIT_-index-1]; + else + if (index != 0) + value_ -= POW10_[DIGIT_-index-1]; + else + if (value_ >= POW10_[DIGIT_-1]) + value_ -= POW10_[DIGIT_-index-1]; + Set(value_); + return true; + } + + // 引数の数値を Label に表示する + void NumericUpDown::Set(uint32_t frq) + { + if (frq > MAX_) frq = MAX_; + if (frq < MIN_) frq = MIN_; + char frqCh[7]; + sprintf(frqCh, fmt_, frq); + + for (int n=0; n<DIGIT_; n++) + labels_[n]->Draw((string)""+frqCh[n]); + value_ = frq; + } + + // 数値の up, down に使う三角形の描画 + void NumericUpDown::UpDownSymbol(uint16_t x, uint16_t y, int k) + { + lcd_.SetTextColor(GuiBase::ENUM_TEXT); + Point *pt = k < DIGIT_ ? ptU_ : ptD_; + int16_t y0 = k < DIGIT_ ? y - 25 : y + 31; + + Point tri[3]; + for (int n=0; n<3; n++) + { + tri[n].X = pt[n].X + x + XW_*(k % DIGIT_) + 15; + tri[n].Y = pt[n].Y + y0 - 46; + } + lcd_.FillPolygon(tri, 3); + } + + Point NumericUpDown::ptU_[] = {{0, 0}, {-SIZE_, SIZE_}, {SIZE_, SIZE_}}; + Point NumericUpDown::ptD_[] = {{0, SIZE_}, {SIZE_, 0}, {-SIZE_, 0}}; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyFiles/NumericUpDown.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,59 @@ +//----------------------------------------------------------- +// NumericUpDown class +// 指定された桁を up/down する GUI 部品 +// 6 桁まで可能 +// +// 2017/08/21, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef NUMERIC_UPDOWN_HPP +#define NUMERIC_UPDOWN_HPP + +#include "F746_GUI.hpp" +#include "DelayedEnabler.hpp" + +namespace Mikami +{ + class NumericUpDown + { + public: + // digit 表示する桁数 + // initVal 最初に表示する数値 + NumericUpDown(uint16_t digit, uint16_t x0, uint16_t y0, + uint32_t initVal, uint32_t max, uint32_t min, + string unit = "", float delay = 0.2f); + + // Up, Down をタッチした場合は対応する数値を +1 または -1 する + bool Touched(); + + // 引数の数値を Label に表示する + void Set(uint32_t frq); + + // Label に表示されている値を数値データとして取り出す + uint32_t Get() { return value_; } + + private: + const int DIGIT_; // 桁数 + const int X0_, Y0_; + const uint32_t MAX_; // 最大値 + const uint32_t MIN_; // 最小値 + const Array<uint32_t> POW10_; + const static uint16_t XW_ = 45; + const static int16_t SIZE_ = 6; + + static Point ptU_[3], ptD_[3]; + + char fmt_[5]; + int numUd_; // 一つ前にタッチしたボタンの番号 + uint32_t value_; + + DelayedEnabler delay_; + Array<Label *> labels_; + ButtonGroup *ud_; + LCD_DISCO_F746NG &lcd_; + + // 数値の up, down に使う三角形の描画 + void UpDownSymbol(uint16_t x, uint16_t y, int k); + }; +} +#endif // NUMERIC_UPDOWN_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyFiles/Trigger.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,25 @@ +//--------------------------------------------------------------- +// トリガの条件を満足する点を探す +// +// 2017/07/24, Copyright (c) 2017 MIKAMI, Naoki +//--------------------------------------------------------------- + +#ifndef F746_TRIGGER_HPP +#define F746_TRIGGER_HPP + +#include "mbed.h" +#include "Array.hpp" + +namespace Mikami +{ + int Trigger(const Array<int16_t>& xn, // 対象とするデータ + int th) // トリガの基準値 + { + int n; + for (n=1; n<xn.Length()/2; n++) + if ((xn[n-1] < -th) && (xn[n] > th)) + return n; + return 0; + } +} +#endif // F746_TRIGGER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyFiles/WaveformDisplay.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,55 @@ +//----------------------------------------------------------- +// Class for waveform display +// +// 2017/07/24, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "WaveformDisplay.hpp" + +namespace Mikami +{ + void WaveformDisplay::Execute(int start, int factor) + { + Axis(); + dt_ = factor; + Draw(xn_, start, LINE_COLOR1_); + Draw(yn_, start, LINE_COLOR2_); + lcd_.SetTextColor(BACK_COLOR_); + } + + // Clipping + uint16_t WaveformDisplay::Clip(int16_t xn) + { + int16_t x = xn >> R_SHIFT_; + if (x > LIMIT_ ) x = LIMIT2_; + if (x < -LIMIT_ ) x = -LIMIT2_ ; + return Y0_ - x; + } + + void WaveformDisplay::Draw(const Array<int16_t>& xn, int start, uint32_t color) + { + lcd_.SetTextColor(color); + uint16_t x1 = X0_; + uint16_t y1 = Clip(xn[start]); +// for (int n=1; n<N_DATA_; n++) + for (int n=1; n<N_DATA_/dt_; n++) + { +// uint16_t x2 = X0_ + n; + uint16_t x2 = X0_ + n*dt_; + uint16_t y2 = Clip(xn[start+n]); + lcd_.DrawLine(x1, y1, x2, y2); + + x1 = x2; + y1 = y2; + } + } + + void WaveformDisplay::Axis() + { + lcd_.SetTextColor(BACK_COLOR_); + lcd_.FillRect(X0_, Y0_-LIMIT2_, N_DATA_, LIMIT2_*2+1); + + lcd_.SetTextColor(AXIS_COLOR_); + lcd_.DrawLine(X0_-5, Y0_, X0_+N_DATA_+5, Y0_); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyFiles/WaveformDisplay.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,65 @@ +//----------------------------------------------------------- +// Class for waveform display ---- Header +// +// 2017/07/24, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_WAVEFORM_DISPLAY_HPP +#define F746_WAVEFORM_DISPLAY_HPP + +#include "mbed.h" +#include "LCD_DISCO_F746NG.h" +#include "Array.hpp" + +namespace Mikami +{ + class WaveformDisplay + { + public: + WaveformDisplay(LCD_DISCO_F746NG &lcd, + uint16_t x0, uint16_t y0, + const Array<int16_t>& xn, + const Array<int16_t>& yn, + uint16_t nData, + uint16_t rShift, + uint32_t axisColor, + uint32_t lineColor1, + uint32_t lineColor2, + uint32_t backColor) + : X0_(x0), Y0_(y0), xn_(xn), yn_(yn), + N_DATA_(nData), + R_SHIFT_(rShift), + AXIS_COLOR_(axisColor), + LINE_COLOR1_(lineColor1), LINE_COLOR2_(lineColor2), + BACK_COLOR_(backColor), + lcd_(lcd), dt_(1) { Axis(); } + + void Execute(int start, int factor); + + private: + const uint16_t X0_, Y0_; + const Array<int16_t>& xn_; + const Array<int16_t>& yn_; + const int N_DATA_; + const uint16_t R_SHIFT_; + const uint32_t AXIS_COLOR_; + const uint32_t LINE_COLOR1_; + const uint32_t LINE_COLOR2_; + const uint32_t BACK_COLOR_; + static const int LIMIT_ = 64; + static const int LIMIT2_ = LIMIT_ + 1; + + LCD_DISCO_F746NG &lcd_; + + int dt_; + + uint16_t Clip(int16_t xn); // Clipping + void Draw(const Array<int16_t>& xn, int start, uint32_t color); + void Axis(); + + // disallow copy constructor and assignment operator + WaveformDisplay(const WaveformDisplay& ); + WaveformDisplay& operator=(const WaveformDisplay& ); + }; +} +#endif // F746_WAVEFORM_DISPLAY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyFiles/Zoom.hpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,62 @@ +//----------------------------------------------------------- +// 時間軸の Zoom ボタン +// +// 2017/08/09, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef ZOOM_BUTTON_HPP +#define ZOOM_BUTTON_HPP + +#include "F746_GUI.hpp" +#include "DelayedEnabler.hpp" + +namespace Mikami +{ + class ZoomButton + { + public: + // delay: ZoomButton がタッチされた後に再び有効になるまでの時間(単位:秒) + ZoomButton(uint16_t x0, uint16_t y0, uint16_t w0, uint16_t h0, + uint32_t max, uint32_t min = 1, float delay = 0.2f) + : X0_(x0), Y0_(y0), W0_(w0), H0_(h0), + MAX_(max), MIN_(min), delay_(delay), factor_(1) + { + zoom_ = new ButtonGroup(x0, y0, w0, h0, 2, (string[]){"-", "+"}, + 5, 0, 2); + zoom_->Inactivate(0); // ズームアウトボタンは無効にする + } + + // タッチした場合は factor を *2 または /2 する + bool Touched(int &factor) + { + if (!delay_.IsEnabled()) return false; + int num; + if (!zoom_->GetTouchedNumber(num)) return false; + + // タッチ後一定の時間が経過してから,再びタッチの検出を有効にするため + delay_.Disable(); + + factor_ = (num == 1) ? factor_*2 : factor_/2; + if (factor_ > MAX_) factor_ = MAX_; + if (factor_ < MIN_) factor_ = MIN_; + + zoom_->ActivateAll(); + if (factor_ == MAX_) zoom_->Inactivate(num); + if (factor_ == MIN_) zoom_->Inactivate(num); + + factor = factor_; + + return true; + } + + private: + const int X0_, Y0_, W0_, H0_; + const uint32_t MAX_; // 最大値 + const uint32_t MIN_; // 最小値 + + ButtonGroup *zoom_; + DelayedEnabler delay_; + int factor_; + }; +} +#endif // ZOOM_BUTTON_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,67 @@ +//----------------------------------------------------------------- +// ディジタルフィルタ実験のためのプラットフォーム(標本化周波数:48 kHz) +// ---- 入出力信号の波形表示付き ---- +// +// このプログラムでは,例として定数乗算器を実装している +// +// 使用しているライブラリのリビジョン: +// mbed Rev.151 +// BSP_DISCO_F746NG Rev.9 +// +// 2017/09/29, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------------- + +#include "SAI_InOut.hpp" +#include "LcdPanelFrq.hpp" + +//----------------------------------------------------------------- +// 実行するフィルタに応じて以下のインクルードファイルを変更する +#include "Multiplier.hpp" // 入力を定数倍して出力する処理 +//----------------------------------------------------------------- + +int main() +{ + const int FS = I2S_AUDIOFREQ_48K; // 標本化周波数:48 kHz + // オーディオ信号出力用 + SaiIO mySai(SaiIO::OUTPUT, 2048, FS); + + // LCD パネル表示用 + LcdPanel myPanel(1.0f/(float)FS); + + //----------------------------------------------------------------- + // ここでディジタルフィルタのオブジェクト生成や初期化などを行う + Multiplier df(-0.5f); // 定数乗算の処理 + //----------------------------------------------------------------- + + mySai.PlayOut(); // オーディオ信号出力開始 + + const float MAX_AMP = 10000.0f; + float phi = 0; + + while (true) // 無限ループ + { + // 出力バッファへの転送が完了したら以下の処理を行う + if (mySai.IsXferred()) + { + for (int n=0; n<mySai.GetLength(); n++) + { + // 入力信号の生成 + float sn = sinf(phi); // 入力信号となる正弦波を発生 + + int16_t xn = (int16_t)(MAX_AMP*sn); + //------------------------------------------------------ + // ディジタルフィルタなどの信号処理の実行 + int16_t yn = df.Execute(xn); + //------------------------------------------------------ + mySai.Output(xn, yn); // xn:入力(左チャンネル) + // yn:出力(右チャンネル) + + phi = myPanel.GetPhi(); // phi の更新 + myPanel.Store(xn, yn, n); // 表示用として格納 + } + + myPanel.Display(); // 入出力信号の波形表示 + } + myPanel.Update(); // パネルの状態を読み取り必要なパラメータなどを更新する + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Sep 29 12:50:44 2017 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/mbed_official/code/mbed/builds/675da3299148 \ No newline at end of file