add morse code
This commit is contained in:
parent
bcf1030226
commit
9f6d05a9e4
5 changed files with 158 additions and 66 deletions
13
Makefile
13
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 *~
|
||||
|
|
|
@ -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.
|
||||
|
|
44
io.cpp
44
io.cpp
|
@ -8,57 +8,57 @@ struct GpioAssocPort {
|
|||
uint32_t clkMask;
|
||||
};
|
||||
|
||||
/**
|
||||
namespace io {
|
||||
/**
|
||||
* @brief GPIO Configuration Mode enumeration
|
||||
*/
|
||||
typedef enum {
|
||||
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 */
|
||||
}GPIOMode_TypeDef;
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief GPIO Output type enumeration
|
||||
*/
|
||||
typedef enum {
|
||||
enum GPIOOType_TypeDef {
|
||||
GPIO_OType_PP = 0x00,
|
||||
GPIO_OType_OD = 0x01
|
||||
}GPIOOType_TypeDef;
|
||||
/**
|
||||
};
|
||||
/**
|
||||
* @brief GPIO Output Maximum frequency enumeration
|
||||
*/
|
||||
typedef enum {
|
||||
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 */
|
||||
}GPIOSpeed_TypeDef;
|
||||
/**
|
||||
};
|
||||
/**
|
||||
* @brief GPIO Configuration PullUp PullDown enumeration
|
||||
*/
|
||||
typedef enum {
|
||||
enum GPIOPuPd_TypeDef {
|
||||
GPIO_PuPd_NOPULL = 0x00,
|
||||
GPIO_PuPd_UP = 0x01,
|
||||
GPIO_PuPd_DOWN = 0x02
|
||||
}GPIOPuPd_TypeDef;
|
||||
};
|
||||
|
||||
/** Vstupní parametry metod */
|
||||
typedef enum {
|
||||
/** Vstupní parametry metod */
|
||||
enum GPIODir_TypeDef {
|
||||
GPIO_Dir_Mode_IN = 0x00, /*!< GPIO Input Mode */
|
||||
GPIO_Dir_Mode_OUT = 0x01, /*!< GPIO Output Mode */
|
||||
} GPIODir_TypeDef;
|
||||
};
|
||||
|
||||
/// Enum pro PortNumber
|
||||
typedef enum {
|
||||
GpioPortA,
|
||||
/// Enum pro PortNumber
|
||||
enum GpioPortNum {
|
||||
GpioPortA = 0,
|
||||
GpioPortB,
|
||||
GpioPortC,
|
||||
GpioPortD,
|
||||
GpioPortE,
|
||||
GpioPortH,
|
||||
} GpioPortNum;
|
||||
namespace io {
|
||||
};
|
||||
/** @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
|
||||
|
|
10
main.cpp
10
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;
|
||||
}
|
||||
|
|
87
morse.cpp
Normal file
87
morse.cpp
Normal file
|
@ -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<len; n++) {
|
||||
const char c = text [n];
|
||||
const char * mp = nullptr;
|
||||
if (c < '\x20') {
|
||||
mp = morse_code [0];
|
||||
} else if (c < '`') {
|
||||
const int i = c - '\x20';
|
||||
mp = morse_code [i];
|
||||
} else if (c == '`') {
|
||||
mp = morse_code [0];
|
||||
} else if (c <= 'z') {
|
||||
const int i = c - '\x40';
|
||||
mp = morse_code [i];
|
||||
} else {
|
||||
mp = morse_code [0];
|
||||
}
|
||||
if (!mp) return;
|
||||
out (mp);
|
||||
}
|
||||
sys::delay (10 * unit);
|
||||
}
|
||||
/* . => 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<len; n++) {
|
||||
led << false;
|
||||
sys::delay (unit);
|
||||
const char c = text [n];
|
||||
if (c == '.') {
|
||||
led << true;
|
||||
sys::delay (1 * unit);
|
||||
} else if (c == '-') {
|
||||
led << true;
|
||||
sys::delay (3 * unit);
|
||||
} else {
|
||||
sys::delay (4 * unit);
|
||||
}
|
||||
led << false;
|
||||
}
|
||||
sys::delay (3 * unit);
|
||||
}
|
||||
|
Loading…
Reference in a new issue