The problem is obvious. You changed the architecture of the hardware, without changing how you write code. If you take 20 years advance there, you should advance here also. I mean ARM is not meant to be programmed with magic numbers to registers. It has CMSIS, and a help file, which is the first place to look at, if you need to configure something. Help file, not the datasheet.
I agree that setting up the develpoment tools is much harder with ARM, and the learning curve is much steeper, but I suspect that it will wash away every 8 bit development in the very near future.Sorry, can't agree with this at all.
From my experience with trying to develop a new application on an STM32 a couple of weeks ago, two things became painfully obvious:
- despite the fact that it's apparently frowned upon in some circles, poking hardware registers to drive the standard peripherals such as timers and UARTs was by far the clearest, fastest and most space efficient way to do it. Allowing for the fact the peripherals themselves are more complex and capable than their counterparts in 8-bit micros, accessing them directly is really no more difficult. If you don't want to use the extra features, set the bits that control those features to zero.
- by complete contrast, trying to work out what the ST library functions were actually doing (and not doing!), and which function calls are actually needed to configure and use a device in a particular way, was a pain. Adding a layer of poorly documented obfuscation is absolutely NOT a way to make code easier to write, read, or port across platforms.
I really dont understand why would anyone write registers directly, instead of using the library and call standard functions from the c library like printf to send data through the serial port.
poking hardware registers to drive the standard peripherals such as timers and UARTs was by far the clearest, fastest and most space efficient way to do it.
the problem is in choosing a vendor which uses obfustigated peripherals. So next time spend $30 on an NXP LPCExpresso board instead of $5 on some piece of crap from ST or TI.For starting hobbieist use I can agree with you esp. for some peripherals, most are ok though. For business use, the difference in BOM price (huge numbers) between ST and NXP is significant. I know NRE does also count but in the end few companies calculate those in the costprice
SPIdrv->Initialize(mySPI_callback);
/* Power up the SPI peripheral */
SPIdrv->PowerControl(ARM_POWER_FULL);
/* Configure the SPI to Master, 8-bit mode @10000 kBits/sec */
SPIdrv->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL1_CPHA1 | ARM_SPI_MSB_LSB | ARM_SPI_SS_MASTER_SW | ARM_SPI_DATA_BITS(8), 10000000);
LPC_SYSCON->SSPCLKDIV=1;
LPC_SSP0->CPSR=36; //divider=36 (1MHz clock)
LPC_SSP0->CR0=0x7; //8 bits
LPC_SSP0->CR1=(1<<1);
Besides that CMSIS seems to assume some kind of threaded operation using interrupts and callback. That is something I don't want in most cases due to other real-time interrupts.
Besides that CMSIS seems to assume some kind of threaded operation using interrupts and callback.
+there is no non-limited, free (or low cost) toolchains for NXP
I'm not using STM32 chips so no go this time. I evaluated the ARM chips from ST a long time ago and found out the peripherals where so bad and obfustigated that mediocre is a huge overstatement. I'm actually amazed people actually put up with them just to save a few pennies per chip. No wonder people find ARM controllers hard. But that is not the problem with ARM controller in general; the problem is in choosing a vendor which uses obfustigated peripherals. So next time spend $30 on an NXP LPCExpresso board instead of $5 on some piece of crap from ST or TI.
On the NXP ARM controllers I use setting an I/O pin is a simple matter of setting a bit in a memory address. No more complicated or different than on an 8 bit PIC or MSP430. Same goes for the other peripherals.
Let's look at CMSIS versus poking registers. This is how CMSIS works ( http://www.keil.com/pack/doc/CMSIS/Driver/html/group__spi__interface__gr.html ):Code: [Select]SPIdrv->Initialize(mySPI_callback);
/* Power up the SPI peripheral */
SPIdrv->PowerControl(ARM_POWER_FULL);
/* Configure the SPI to Master, 8-bit mode @10000 kBits/sec */
SPIdrv->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL1_CPHA1 | ARM_SPI_MSB_LSB | ARM_SPI_SS_MASTER_SW | ARM_SPI_DATA_BITS(8), 10000000);
Now the same for poking registers:Code: [Select]LPC_SYSCON->SSPCLKDIV=1;
Besides that CMSIS seems to assume some kind of threaded operation using interrupts and callback. That is something I don't want in most cases due to other real-time interrupts.
LPC_SSP0->CPSR=36; //divider=36 (1MHz clock)
LPC_SSP0->CR0=0x7; //8 bits
LPC_SSP0->CR1=(1<<1);
On the NXP ARM controllers I use setting an I/O pin is a simple matter of setting a bit in a memory address.
Remember, I am a newbie here so please help me.
On the NXP ARM controllers I use setting an I/O pin is a simple matter of setting a bit in a memory address. No more complicated or different than on an 8 bit PIC or MSP430. Same goes for the other peripherals.This is exactly how you set an I/O pin in an STM32 as well. Why would you think this wasn't the case?
Let's look at CMSIS versus poking registers. This is how CMSIS works ( http://www.keil.com/pack/doc/CMSIS/Driver/html/group__spi__interface__gr.html ):Code: [Select]SPIdrv->Initialize(mySPI_callback);
/* Power up the SPI peripheral */
SPIdrv->PowerControl(ARM_POWER_FULL);
/* Configure the SPI to Master, 8-bit mode @10000 kBits/sec */
SPIdrv->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL1_CPHA1 | ARM_SPI_MSB_LSB | ARM_SPI_SS_MASTER_SW | ARM_SPI_DATA_BITS(8), 10000000);
Now the same for poking registers:Code: [Select]LPC_SYSCON->SSPCLKDIV=1;
Besides that CMSIS seems to assume some kind of threaded operation using interrupts and callback. That is something I don't want in most cases due to other real-time interrupts.
LPC_SSP0->CPSR=36; //divider=36 (1MHz clock)
LPC_SSP0->CR0=0x7; //8 bits
LPC_SSP0->CR1=(1<<1);
That looks like a good argument for using CMSIS right there. The CMSIS code is reasonably self explanatory, anyone with reasonable experience could look at that code and get a good idea of exactly what it is supposed to do. With the LPC example you have a bunch of ambiguously named registers being loaded with magic numbers; a classic example of how it shouldn't be done.
That looks like a good argument for using CMSIS right there. The CMSIS code is reasonably self explanatory, anyone with reasonable experience could look at that code and get a good idea of exactly what it is supposed to do.
you aren't forced to use CMSIS and the STM32 libraries. They are provided to permit compatibility between different vendors, but you can simply program the registers directly with magic numbers if you really think that's the best way to do things.
well, right for a reader the CMSIS is easier to understand, for a developer those defined function are not well documented and the only available help i have found is some commented line in the library files, the usual procedure is to configure the peripheral with some constant name then call an init function, go figure what the stupid parameter is named, i jump from a library file to an other library file for that.
but the registers are well explained in the data-sheet and there functionality is well defined. i think that's why some of us find it easier to work with registers directly.
Then why people keep complaining about the GPIO on the STM32 takes 280 registers?
The registers are not named ambiguously; they match the documentation of the chip. Maybe I should have put //enable as a remark behind the last line for more clarity. I think there are some defines for each bit as well but I never bother to use those. There are only a few bits in each register to configure the SPI interface. Maybe 12 in total including setting the word length.
Because they are either misinformed or prone to ridiculous exaggeration at a guess.
A decent peer review would check the configuration settings against the datasheets/user manuals of both the SPI slave and the controller. Who is to say the programmer choose the right CPHA, CPOL, word length options?
It would be magic numbers if ...
Code: [Select]SPIdrv->Initialize(mySPI_callback);
/* Power up the SPI peripheral */
SPIdrv->PowerControl(ARM_POWER_FULL);
/* Configure the SPI to Master, 8-bit mode @10000 kBits/sec */
SPIdrv->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL1_CPHA1 | ARM_SPI_MSB_LSB | ARM_SPI_SS_MASTER_SW | ARM_SPI_DATA_BITS(8), 10000000);Code: [Select]LPC_SYSCON->SSPCLKDIV=1;
LPC_SSP0->CPSR=36; //divider=36 (1MHz clock)
LPC_SSP0->CR0=0x7; //8 bits
LPC_SSP0->CR1=(1<<1);
Code reviews take a lot of time which is a busy engineers most precious resource, so why wouldn't you want to make their job as painless as possible by making your code clear and easy to read?
the 32-bit version of the PIC mcu,
Everything was done using the STM's libraries and i didn't had a single problem.
I tried the NXP's LPC1769 with LPCXpresso, but the absence of proper libraries made the experience much more unpleasant
Calling a library function to, say, set up a timer is completely different. ST's libraries just don't have a simple function that means, say, "generate an interrupt every 10ms, and toggle this GPIO each time", even though the hardware can do it.
I have to instead say "Set up timer 3 in compare mode with a clock source X, period Y, output mode Z, interrupts enabled, priority P..." and so on.
GPIO on the STM32 takes 280 registers?
spi_send() sends out a byte