[En-Nut-Discussion] node_cs definition in NUTSPINODE

0 views
Skip to first unread message

Uwe Bonnes

unread,
Feb 21, 2012, 10:18:09 AM2/21/12
to en-nut-d...@egnite.de
Hello,

if I understand right, node_cs in the NUTSPINODE structure is a symbolic
number that later in xxxSpiChipSelect() gets decoded from a fixed list of
possibilities into port/pin and an access to that port/pin combination.

Why don't we use both a node_port and node_pin entry in the NUTSPINODE
structure and xxxSpiChipSelect() does the access direct on the resulting
port/pin combination, at the cost of a NUTSPINODE structure 4 to 7 bytes
larger. 4 Bytes larger if the compiler aligns the NUTSPINODE structure at 4
byte, 7 bytes with no alignment in the NUTSPINODE structure.

If structure size is an issue, we could also encode port and pin via
((symbolic port number)& 0x0f) << 4 | (pin & 0x0f), in a microsoft like
attitude : Nobody will ever use more then 16 ports with 16 pins each :-) or
as uint16_t with ((symbolic port number) & 0xff) << 8 | (pin & 0xff)

That way, users can have SPI CS on arbitrary pins without the need to change
NUTOS.

On cm3 node_cs could also be the 32 bit bit-band adress to the GPIOx_BSRR of
that port/bit. To set CS high, we would write 1 to that address, to set CS
low we would write 1 to the address 64 bytes above. In that light I propose
to make node_cs a 32 bits entitie.

Bye
--
Uwe Bonnes b...@elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Harald Kipp

unread,
Feb 21, 2012, 1:57:21 PM2/21/12
to Ethernut User Chat (English)
Hello Uwe,

On 21.02.2012 16:18, Uwe Bonnes wrote:
> if I understand right, node_cs in the NUTSPINODE structure is a symbolic
> number that later in xxxSpiChipSelect() gets decoded from a fixed list of
> possibilities into port/pin and an access to that port/pin combination.

That's right. The "fixed" list is configurable, of course.


> That way, users can have SPI CS on arbitrary pins without the need to change
> NUTOS.

After finishing the code, I discovered that passing the chip select
number from application code via

int NutRegisterSpiDevice(NUTDEVICE * dev, NUTSPIBUS * bus, int cs);

was not a good idea. In practice you will configure Nut/OS for a
specific board once and never change it.

Furthermore, Nut/OS doesn't currently allow to re-use a device. If you
got 4 DataFlash chips, you'll need devSpiAt45d0 to devSpiAt45d3. Each
SPI bus device has a fixed hardware chip select.


> In that light I propose
> to make node_cs a 32 bits entitie.

My proposal would be to remove the cs parameter and configure the chip
select in the device driver.

I'm open to arguments, of course.

Regards,

Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Ulrich Prinz

unread,
Feb 22, 2012, 11:26:08 AM2/22/12
to Ethernut User Chat (English)
Hi!

>
> was not a good idea. In practice you will configure Nut/OS for a
> specific board once and never change it.

I fully agree :)


>
> Furthermore, Nut/OS doesn't currently allow to re-use a device. If you
> got 4 DataFlash chips, you'll need devSpiAt45d0 to devSpiAt45d3. Each
> SPI bus device has a fixed hardware chip select.
>

Right, there must be one ICB per used ChipSelect even the SPI bus
itself is reused.


>
>> In that light I propose
>> to make node_cs a 32 bits entitie.
>
> My proposal would be to remove the cs parameter and configure the chip
> select in the device driver.
>

I fully agree, as it is more convenient to do hardware-configuration
by qnutconf instead doing some here, some there, some...

> I'm open to arguments, of course.

Here you got mine :)

Ulrich
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Jose

unread,
Feb 23, 2012, 1:44:52 AM2/23/12
to Ethernut User Chat (English)
Hello.

Now that you mention CS lines of SPI drivers, one comment.

A while ago, before the new SPI drivers (in the 4.6 version), we could
not fully use NutOS SPI drivers in our boards because, to our best
knowledge, there was not support for decoders in CS lines. That is, we
wanted 16 chip select lines from up to 4 pins from the microcontroller.
Thus we had to make our own.

Let me abuse your knowledge here, so I don't have to check the source
code myself(I' a bit rusty ;)): do the new SPI drivers support decoders
for the CS lines? If not, it would be a nice feature to have, IMHO.

BR
Jose

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Uwe Bonnes

unread,
Feb 23, 2012, 5:27:48 AM2/23/12
to Ethernut User Chat (English)
>>>>> "Ulrich" == Ulrich Prinz <ulrich...@googlemail.com> writes:

Ulrich> Hi!


>> was not a good idea. In practice you will configure Nut/OS for a
>> specific board once and never change it.

Ulrich> I fully agree :)

I disagree:

With adrino-like board or the STM32 discovery boards, you have ample pin
headers and on a jumper board people would like to connect external SPI
devices with their CS_N connected to some arbitray GPIO. But probably in
that situation they don't like to do an extra branch of their NUTOS library.

And with Jose's question for decoded chip selects even more requirements
arise. What if the User could provide his own Stm32SpiChipSelect() function,
perhaps by making the Stm32SpiChipSelect() definition in the library
__weak__? And with an 32 bit argument to encode the GPIO Pin!

>> Furthermore, Nut/OS doesn't currently allow to re-use a device. If
>> you got 4 DataFlash chips, you'll need devSpiAt45d0 to
>> devSpiAt45d3. Each SPI bus device has a fixed hardware chip select.
>>

Ulrich> Right, there must be one ICB per used ChipSelect even the SPI
Ulrich> bus itself is reused.

Think also about the zillion of SPI devices where we don't have a NUTOS
driver. Users should be able to use these devices too, even on the same SPI
bus as e.g. devSpiAt45d0 with only a diffent CS.

Ulrich Prinz

unread,
Feb 24, 2012, 5:09:48 AM2/24/12
to Ethernut User Chat (English)
Hi Uwe,

one could see it like this or like that...

The problem is that we have to find a compromize between the different
options a CPU provides.
On some we have GPIO-CS only, on others we have fixed hardware CS and
on the third we have not only optional hardware-CS but diffferent
modes of it too.

I think we have to keep the basic setup features inside qnutconf as
these decide the parts of the low level driver that are to be compiled
into the library.
Then we could make the registration function more Nut/OS standard
alike so we provide port and pin as an option instead of a 32bit value
that no one knows of how to provide.
But then we must add some traps, at least for the debug version of the
libraries:
If you use an AT91SAM and enable hardware-CS, we must trap a
registration to illegal port/pin combinations as only a few pins are
provided for CS by this chips.

I hope this is a good compromize.

Ulrich

Am 23. Februar 2012 11:27 schrieb Uwe Bonnes
<b...@elektron.ikp.physik.tu-darmstadt.de>:

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Uwe Bonnes

unread,
Feb 26, 2012, 4:42:28 AM2/26/12
to Ethernut User Chat (English)
>>>>> "Ulrich" == Ulrich Prinz <ulrich...@googlemail.com> writes:

Ulrich> Hi Uwe, one could see it like this or like that...

Ulrich> The problem is that we have to find a compromize between the
Ulrich> different options a CPU provides. On some we have GPIO-CS only,
Ulrich> on others we have fixed hardware CS and on the third we have not
Ulrich> only optional hardware-CS but diffferent modes of it too.

Wouldn't a __weak__ linking definition of the NUTOS Stm32SpiChipSelect()
function be a good compromise?

Ulrich Prinz

unread,
Feb 27, 2012, 6:06:46 AM2/27/12
to Ethernut User Chat (English)
I am not sure if that really solves the problems.

Ok, in emac we started to implement a cross weak linking. So the emac
code provides read and write to phy and the phy provides init and
status requests.
This is simple as regardless of emac or phy these functions are standarized.

With SPI building a standard is difficult as the IPs on the silicons
are sometimes totally different.
On AVR jou have no CS but have to use manual GPIO.
On ARM/Cortex every chip is different.
So on SAM7 you can use GPIO, you can use the shadow SPI so you have 4
dedicated and hardware supported CS lines or you can use 1 out of 16
without shadow if you set a decoder behind the 4 CS lines.
On STM32 you again have to use GPIO

Oh, now I see what you think of!

we provide some standarized functions in the main spi driver routine
and provide separate CS drivers. Dependant on the nutconf setting the
one or the others are linked.
I am not sure if that will work as the core spi handling might differ
and connect much closer to the CS handling than we expect.

Nevertheless we need to provide a cs setup that correspands to our termes.
What we have to keep in mind too ist that the SPI bus configuration is
highly device dependent. I mean the chip connected on the other end.
So setting up the bus is fairly only activating the SPI system,
provide clocks to it and select the right alternate pin setups.
The real setup is device dependent. So speed, mode, delays whatever is
a separate thing.

So Stm32SpiChipSelect()... May be we should provide something like this:

NutSpiRegister( SPI_BUS);
NutSpiAssignDevice( SOME_DEVICE, cs_port, cs_pin, spi_mode, spi_speed);

And SOME_DEVICE can be a device that we already provide, but it may be
an empty framework that provides a simple read and write functionality
too.
So one could either use this simple device to work with any SPI slave
that he likes in the application code or he might copy that framework
and add a new driver that provides more functionality.

All that looks more easy to me than
uint32_t spi_port = (NUTGPIO_PORTA << 8) | NUT_GPIO_PIN7;
int mode = SPI_MODE3;

NutSpiRegister( SPI_BUS, &spi_port);
_ioctl(SPI_BUS, SPI_SET_MODE, &mode);
mode = 100000;
_ioctl(SPI_BUS, SPI_SET_SPEED, &mode);
and now youre lost as you need to provide a device driver.

Ulrich

Am 26. Februar 2012 10:42 schrieb Uwe Bonnes
<b...@elektron.ikp.physik.tu-darmstadt.de>:

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Reply all
Reply to author
Forward
0 new messages