geezmolycos / uni-STC

SDCC support + HAL + drivers for STC 8051 MCU

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

uni-STC is an attempt to address the numerous naming inconsistencies 
between STC MCUs, and even across SFR and bit masks, that make porting 
a piece of code to a different STC MCU a rather unpleasant activity.

I've developed this for myself and I quickly felt the need to create 
a HAL on top of it. It makes the migration of a project from, for 
instance, STC15W408AS to STC8G1K08A ridiculously easy, changes only 
affecting the Makefile and a project-wide header called project-defs.h.

While I was at it, I also integrated drivers in the project structure 
in the same way as the HAL so they can be centralised and reused as 
easily as HAL modules.

I make this work available under a permissive license in the hope they 
would be useful to someone else. Their documentation is perfectible, 
when existent at all, but I would create or improve it little by little 
if asked, and time permitting. I also welcome help requests, comments 
and suggestions.

I can be reached at vincent dot defert at posteo dot net.

Each subdirectory contains a README file describing its content and how 
to use it.

Finally, below are a few notes you might find useful or interesting.


TERMINOLOGY

I use the term Hardware Abstraction Layer (HAL) to name pieces of code
allowing to manipulate an MCU's internal peripherals in a way that is
independent of the specific part used.

I use the term Driver to name pieces of code providing a high-level 
programming interface to use devices external to the MCU.


DESIGN CHOICES

The necessity of this work arose from the desire to use SDCC to work 
with STC MCU. This has 2 consequences:

- I'm not interested in supporting Keil's compiler, STC already does it.

- STC16 and STC32 MCS-251 MCU cannot be supported as long as SDCC only 
supports MCS-51. I'd be interested to work on this, but lack time for 
the moment.

Also, I do NOT want to support MCU older than STC12C5AxxS2. For clarity,
the STC12C520x, STC12C54xx, and STC12C56xx series are NOT and will NOT 
be supported. In fact, I added support for the STC12C5AxxS2 only to 
assess the relevance of my design. It also gave me a better understanding 
of the evolution of STC's MCU.

This is why every time I had to make a choice, I made it with the most 
capable MCU and/or most recent in mind.

In the HAL, my strategy was to offer high-level APIs, and encapsulate 
all the dirty details (such as the GPIO default configuration changing 
in the STC8G series and up).

Above all, I love to KISS POLA, so I did my best to make things as 
simple and natural as possible.

	https://en.wikipedia.org/wiki/KISS_principle
	https://en.wikipedia.org/wiki/Principle_of_least_astonishment

The drawbacks of my approach are that my naming differs from STC's
documentation and it can complicate the reuse of STC's examples. The 
latter isn't really an issue since software is clearly not a strength 
of STC. All in all, I deemed this a decent price to pay for clarity, 
consistency, and predictability.


INCONSISTENCIES ADDRESSED AND IMPLEMENTATION CHOICES

Numbering inconsistencies

	IE, IE2, IE3 => IE1, IE2, IE3

Naming inconsistencies

	IP2, IP2H => IP2L, IP2H     (H calls for L)
	TL0, TL1  => T0L, T1L       (like T3L and T4L)
	TF0, TF1  => T0IF, T1IF     (like T2IF)
	IF0, IF1  => INT0IF, INT1IF (like INT2IF)

Generational inconsistencies

	The STC12 has AUXR1 and the STC15/STC8 have P_SW1 at the same 
	address for the same purpose (pin switching)
	=> used P_SW1 for STC12 too

Confusing naming

	It's impossible to determine at first sight if a symbol is the 
	name of an SFR, a bit accessor, or a constant defining a bit mask
	or position. I consistently used the following convention:
	
	M_ prefix: bit mask, e.g.     CSSETUP => M_CSSETUP
	P_ prefix: bit position, e.g. CSSETUP => P_CSSETUP
	No prefix: SFR or bit accessor, e.g. P_SW1 or EA
	
	Whenever I defined an M_ constant, I also defined the corresponding 
	P_ constant, so bit manipulations are a no-brainer (OR with M_*, 
	AND with ~M_*, shift with P_*).
	
Unhelpful complication or redundancy, cryptic naming

	PLVD and PLVDH have the same value => M_PLVD only
	
	Idem with S2SM0, S3SM0, S4SM0      => M_SM0

	UR1TPTY, UR1RPTY, UR1TPTY, UR1RPTY, SPIPTY, LCMPTY
	(all with the same value)          => M_DMA_BUS_PRIORITY

Bit ranges instead of individual bit constants

	OC1M2,OC1M1,OC1M0 (0x40, 0x20, 0x10) => M_OC1M (0x70)
	                        and, of course, P_OC1M (4)

OTHER NOTES

I have implemented a HAL for the Multiply/Divide Unit and compared it
against SDCC's software multiplication, division and modulo.

For the comparison to be fair, I implemented using the MDU the 
_muluchar, _mulint, _mullong, _divuint, _divulong, _moduint, and 
_modulong functions from SDCC's standard C library implementation
and compared the execution times of both implementations on the
same set of values.

It appears that SDCC provides very efficient implementations of these
operations, with a constant execution time.

Using the MDU is an order of magnitude LESS EFFICIENT, and execution 
time is variable.

This is why you won't see an MDU HAL in uni-STC.

About

SDCC support + HAL + drivers for STC 8051 MCU

License:BSD 2-Clause "Simplified" License


Languages

Language:C 96.2%Language:Makefile 3.3%Language:Assembly 0.5%