From 9f6d05a9e4c0b28880a4ea726b5995ce7feed0d7 Mon Sep 17 00:00:00 2001 From: Kizarm Date: Thu, 18 Jan 2024 11:42:56 +0100 Subject: [PATCH] add morse code --- Makefile | 13 ++++--- README.md | 8 ++++- io.cpp | 106 +++++++++++++++++++++++++++--------------------------- main.cpp | 10 ++---- morse.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 158 insertions(+), 66 deletions(-) create mode 100644 morse.cpp diff --git a/Makefile b/Makefile index ec201a4..b0f593c 100644 --- a/Makefile +++ b/Makefile @@ -16,12 +16,13 @@ CFLAGS = -Wall $(TGT) -Oz -gdwarf-3 -I./$(TARGET) -ffunction-sections -fdata-sec LFLAGS = -nostart-files --gc-sections -Map=example.map MFLAGS = $(CFLAGS) -fmodules -fprebuilt-module-path=. VFLAGS = -std=c++20 -fno-rtti +PFLAGS = c++-module $(TGT) -I./$(TARGET) -fprebuilt-module-path=. -fno-exceptions VPATH = . ./$(TARGET) # zdrojaky -> objekty OBJS = STM32L4x2_startup.o system.o -MOBJS = main.o io.o sys.o +MOBJS = morse.o io.o sys.o main.o BOBJS = $(addprefix $(BLD),$(OBJS)) @@ -30,7 +31,7 @@ all: $(BLD) $(PRJ).elf # -include $(BLD)*.d # linker $(PRJ).elf: $(BOBJS) $(MOBJS) - -@echo [LD $(TARGET)] $@ + -@echo [LLD $(TARGET)] $@ @$(LD) $(LFLAGS) -o $(PRJ).elf $(BOBJS) $(MOBJS) $(LDLIBS) -@echo "size:" @$(SIZE) $(PRJ).elf @@ -40,7 +41,7 @@ $(PRJ).elf: $(BOBJS) $(MOBJS) -@echo "OK." # preloz co je potreba $(BLD)%.o: %.c - -@echo [CC $(TARGET)] $@ + -@echo [CCC $(TARGET)] $@ @$(CC) -c $(CFLAGS) $< -o $@ $(BLD)%.o: %.cpp -@echo [CXX $(TARGET)] $@ @@ -48,13 +49,15 @@ $(BLD)%.o: %.cpp $(BLD): mkdir $(BLD) # MODULES # -main.o: main.cpp io.pcm sys.pcm +main.o: main.cpp morse.pcm +morse.o: morse.cpp io.pcm sys.pcm +morse.pcm: morse.cpp io.pcm sys.pcm %.o: %.cpp -@echo [CXM $(TARGET)] $@ @$(CXX) $(VFLAGS) -c $(MFLAGS) $< -o $@ %.pcm: %.cpp -@echo [PRE $(TARGET)] $@ - @$(CXX) $(VFLAGS) -x c++-module $(TGT) -I./$(TARGET) -fno-exceptions $< --precompile -o $@ + @$(CXX) $(VFLAGS) -x $(PFLAGS) $< --precompile -o $@ # vycisti clean: rm -f $(BLD)* *.o *.lst *.bin *.elf *.map *.pcm *~ diff --git a/README.md b/README.md index fc4746b..1cb7a32 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,11 @@ použít C++ moduly i v bare metal. Sice se to musí kompilovat clang ve verzi 18. (a asi i vyšší), postup je poměrně komplikovaný a nepochopitelný, ale funguje to. Zjevně je to hodně experimentální. +Moduly mohou mít hierarchickou strukturu a opravdu nejsou potřeba +něco jako hlavičky. Ovšem distribuovat takto knihovny jednoduše +nejde. Prostě musí k tomu být zdrojáky a ty je potřeba přeložit +specifickým (a dost komlikovaným) způsobem. Negeneruje to žádný +overhead, alespoň v tomto jednoduchém příkladu. + Připadá mi to složité a k ničemu, ale to je právě důvod, proč by -se to mohlo ujmout. +se to mohlo ujmout. Třeba v Arduinu. diff --git a/io.cpp b/io.cpp index 9502f2c..5003585 100644 --- a/io.cpp +++ b/io.cpp @@ -5,60 +5,60 @@ export module io; /// Asociace port Adress a RCC clock struct GpioAssocPort { GPIOA_Type * const portAdr; - uint32_t clkMask; + uint32_t clkMask; }; -/** - * @brief GPIO Configuration Mode enumeration - */ -typedef enum { - GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ - GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ - GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ - GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ -}GPIOMode_TypeDef; - -/** - * @brief GPIO Output type enumeration - */ -typedef enum { - GPIO_OType_PP = 0x00, - GPIO_OType_OD = 0x01 -}GPIOOType_TypeDef; -/** - * @brief GPIO Output Maximum frequency enumeration - */ -typedef enum { - GPIO_Speed_LS = 0x00, /*!< Low speed */ - GPIO_Speed_MS = 0x01, /*!< Medium speed */ - GPIO_Speed_FS = 0x02, /*!< Fast speed */ - GPIO_Speed_HS = 0x03 /*!< Very High speed */ -}GPIOSpeed_TypeDef; -/** - * @brief GPIO Configuration PullUp PullDown enumeration - */ -typedef enum { - GPIO_PuPd_NOPULL = 0x00, - GPIO_PuPd_UP = 0x01, - GPIO_PuPd_DOWN = 0x02 -}GPIOPuPd_TypeDef; - -/** Vstupní parametry metod */ -typedef enum { - GPIO_Dir_Mode_IN = 0x00, /*!< GPIO Input Mode */ - GPIO_Dir_Mode_OUT = 0x01, /*!< GPIO Output Mode */ -} GPIODir_TypeDef; - -/// Enum pro PortNumber -typedef enum { - GpioPortA, - GpioPortB, - GpioPortC, - GpioPortD, - GpioPortE, - GpioPortH, -} GpioPortNum; namespace io { + /** + * @brief GPIO Configuration Mode enumeration + */ + enum GPIOMode_TypeDef { + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ + GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ + GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ + }; + + /** + * @brief GPIO Output type enumeration + */ + enum GPIOOType_TypeDef { + GPIO_OType_PP = 0x00, + GPIO_OType_OD = 0x01 + }; + /** + * @brief GPIO Output Maximum frequency enumeration + */ + enum GPIOSpeed_TypeDef { + GPIO_Speed_LS = 0x00, /*!< Low speed */ + GPIO_Speed_MS = 0x01, /*!< Medium speed */ + GPIO_Speed_FS = 0x02, /*!< Fast speed */ + GPIO_Speed_HS = 0x03 /*!< Very High speed */ + }; + /** + * @brief GPIO Configuration PullUp PullDown enumeration + */ + enum GPIOPuPd_TypeDef { + GPIO_PuPd_NOPULL = 0x00, + GPIO_PuPd_UP = 0x01, + GPIO_PuPd_DOWN = 0x02 + }; + + /** Vstupní parametry metod */ + enum GPIODir_TypeDef { + GPIO_Dir_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Dir_Mode_OUT = 0x01, /*!< GPIO Output Mode */ + }; + + /// Enum pro PortNumber + enum GpioPortNum { + GpioPortA = 0, + GpioPortB, + GpioPortC, + GpioPortD, + GpioPortE, + GpioPortH, + }; /** @file * @brief Obecný GPIO pin. * @@ -76,8 +76,8 @@ namespace io { GpioClass (GpioPortNum const port, const uint32_t no, const GPIOMode_TypeDef type = GPIO_Mode_OUT); /// Nastav pin @param b na tuto hodnotu const GpioClass& operator<< (const bool b) const { - if (b) io->BSRR.R = (uint32_t) pos; - else io->BSRR.R = (uint32_t) pos << 16; + const uint32_t sh = b ? pos : pos << 16; + io->BSRR.R = sh; return *this; } /// Nastav pin na log. H diff --git a/main.cpp b/main.cpp index 6c7fe2c..fd36b75 100644 --- a/main.cpp +++ b/main.cpp @@ -1,14 +1,10 @@ /* SIMPLE EXAMPLE: LED blinking */ -import io; // use module !!! -import sys; +import morse; // use module !!! ////////////////////////////////////// -static io::GpioClass led (GpioPortA, 10); - int main () { - sys::init (); + Morse morse (330); for (;;) { - ~led; // change status - unary ~ - sys::delay (); + morse << "Hello world"; } return 0; } diff --git a/morse.cpp b/morse.cpp new file mode 100644 index 0000000..5a5b98d --- /dev/null +++ b/morse.cpp @@ -0,0 +1,87 @@ +module; +import sys; +import io; +export module morse; + +static const char * const morse_code [] = { /* nedefinované znaky nahrazeny mezrou */ + " ", /* */ " ", /*!*/ ".-..-.", /*"*/ " ", /*#*/ " ", /*$*/ + " ", /*%*/ " ", /*&*/ ".----.", /*'*/ "-.--.", /*(*/ "-.--.-", /*)*/ + " ", /***/ ".-.-.", /*+*/ "--..--", /*,*/ "-....-", /*-*/ ".-.-.-", /*.*/ "-..-." , /*/*/ + "-----", /*0*/ ".----", /*1*/ "..---", /*2*/ "...--", /*3*/ "....-", /*4*/ + ".....", /*5*/ "-....", /*6*/ "--...", /*7*/ "---..", /*8*/ "----.", /*9*/ + "---...", /*:*/ "-.-.-.", /*;*/ " ", /*<*/ "-...-" , /*=*/ " ", /*>*/ "..--..", /*?*/ + ".--.-.", /*@*/ + ".-", /*A*/ "-...", /*B*/ "-.-.", /*C*/ "-..", /*D*/ ".", /*E*/ "..-.", /*F*/ + "--.", /*G*/ "....", /*H*/ "..", /*I*/ ".---", /*J*/ "-.-", /*K*/ ".-..", /*L*/ + "--", /*M*/ "-.", /*N*/ "---", /*O*/ ".--.", /*P*/ "--.-", /*Q*/ ".-.", /*R*/ + "...", /*S*/ "-", /*T*/ "..-", /*U*/ "...-", /*V*/ ".--", /*W*/ "-..-", /*X*/ + "-.--", /*Y*/ "--..", /*Z*/ " ", " ", " ", " ", "..--.-", /*_*/ +}; + +static unsigned slen (const char * str) { + unsigned n = 0; + while (*str++) n++; + return n; +} + +export class Morse { + const unsigned unit; + const io::GpioClass led; + + public: + explicit Morse (const unsigned ms = 100) noexcept : unit (ms), led (io::GpioPortA, 10) { + sys::init (); + } + void operator<< (const char * text) const; + protected: + void out (const char * text) const; +}; +void Morse::operator<< (const char * text) const { + const unsigned len = slen (text); + for (unsigned n=0; n 1 x unit + * - => 3 x unit + * mezera mezi značkami => 1 x unit + * mezera mezi znaky => 3 x unit + * mezera mezi slovy => 7 x unit + * */ +void Morse::out (const char * text) const { + const unsigned len = slen(text); + for (unsigned n=0; n