![stm8 cosmic stm8 cosmic](https://circuitdigest.com/sites/default/files/projectimage_mic/ADC-on-STM8S-using-Cosmic-C-Compiler.jpg)
However, to use it you will need to register and acquire a license key via email.
#Stm8 cosmic software
We will need STVP to upload codes to target STM8 micros.Ĭosmic used to be a paid tool just like your PC’s antivirus software but at the time of writing this article, the Cosmic team has made it absolutely free for STM8 family. STVD also packs with a programmer software tool called ST Visual Programmer (STVP). Both are free but a rather difficult to use at first. The best stuffs you can get your hands on at zero costs are ST Visual Develop (STVD) IDE and Cosmic C compiler. We will need an Integrated Development Environment (IDE) and a C-language toolchain. All that we will ever need is the clear concept of each hardware block, their working principles, their capabilities and limitations. We will never need to access registers for any reason as everything is done under the hood of SPL. With SPL, it becomes totally unnecessary to program each peripheral register with meaningless numbers and maintain coding sequence. Apart from these reasons, I chose C language for the fact that STMicroelectronics has provided a Standard Peripheral Library (SPL) that is very easy to use. I don’t want to spend time coding complex stuffs in assembly or other languages.
#Stm8 cosmic code
The rest of the code is pretty much self-explanatory: we jump to loop_end if the third argument (len) is 0, otherwise we continue with the main loop which copies source byte into destination address, increments the pointers and decrements len.Just like any other software developer, my choice of language for software development is C language. So the offset for the second argument would be 0x03 + 2 = 0x05. Since the first two arguments are pointers, each of them will occupy 2 bytes on the stack. Stack pointer decreases when you push something on the stack, so if we offset it by 1, we get the address of the last byte that was pushed on the stack (which is PCH), if we offset it by 2 we get PCL and if we offset it by 3 - bingo! We get the first argument that was passed to the function. At the end of our function we issure a ret instruction which restores PC.
#Stm8 cosmic manual
The programming manual describes what the instruction does: it saves the high and low bytes of Program Counter (PC) register on the stack and loads PC with the destination address of the function being called. Just like with pointers in C you can think of ldw (x), y as *((uint16_t *) &x) = y.īut what’s the deal with those values - 0x03 and 0x05? When we call a function, we (unsurprisingly) issue a call instruction.
![stm8 cosmic stm8 cosmic](http://www.emcu.it/STM8/STM8S-Portfolio/f1.png)
This value is then treated as a memory address, and the processor loads the value from that address into register X. Here’s how you read it: we get a value from the stack located at. Now for the function itself - the first instruction is ldw x, (0x03, sp). globl - that means we make a symbol accessible from the outside world, and. But I would still prefer doing it the ‘right way’, since this would allow inlining the function without any consequences:Īll right, let’s figure out what’s going on here.
![stm8 cosmic stm8 cosmic](http://www.emcu.it/STM8/STM8-Discovery/Touch1/fig1.png)
The second one means that any register modified by the function must be restored by the function itself when the it returns.Īccording to the documentation, SDCC uses caller saves convention by default, which means that we can implement our functions without saving the context. The first one means that functions are allowed to modify registers as they please and function caller is responsible for saving and restoring context. There are two calling conventions for assembly functions: caller saves and callee saves. That being said, in our case saving registers is not really necessary. The proper way is to save the contents of the registers before altering them and restore them afterwards. The compiler does not know about this - it just places assembly instructions where we told it to. There’s a slight issue with this function, though: we’re modifying a commonly used register X, which means that if some value was loaded before calling the function, it will be lost.