AUTOSAR MCAL之SPI(Specification of SPI Handler/Driver)

This article will introduce the knowledge points and precautions of the AUTOSAR MCAL SPI module in detail, and the configuration of this module will be shared in other articles. Most of the content of this article comes from the standard, and refers to the MCAL SPI code of the NXP S32K1 series.
After patiently reading this article, you will have a very in-depth understanding of AUTOSAR MCAL SPI.

Table of contents

1. Introduction to the module

2. Module restrictions

3. Main concepts: Sequence/Job/Channel

4. Sequence/Job/Channel sending timing

5. MCAL SPI mode classification

6. SPI Buffer

7. Other important mechanisms of SPI

8. Precautions



1. Introduction to the module


The SPI driver provides read and write services to devices connected through the SPI bus. Common devices, such as EEPROM, external Watchdog, or some other application-specific integrated circuits (ASICs) . Of course, the SPI driver also provides configuration and use of the on-chip SPI peripherals.

The driver divides functions and configurations into multiple levels to achieve high scalability and flexibility. For example, in terms of function, it is divided into 3 levels. It can be configured as synchronous or asynchronous according to different levels.

Of course, many other concepts are abstracted, such as Sequence, Job, Channel , etc. Please see the figure below for important concepts/key points:

insert image description here


2. Module restrictions

  • Only Master mode is supported.
  • Only full-duplex mode is supported.
  • LEVEL 2 is designated for those chips that need to provide at least two SPI buses separately. Otherwise, there is no point in using this level of functionality.
  • Peripheral clock initialization and frequency division are in charge of the MCU module
  • If there are registers that need to be shared with other peripherals, the MCU is responsible for such registers.

3. Main concepts: Sequence/Job/Channel

 

insert image description here

 


First of all, it needs to be explained that the Channel here is at the software level , and has nothing to do with the physical channel/Channel of the hardware , and there is no binding. The Channel at the software level is just to configure the BUFF.

Job is bound to peripherals . So a Channel can belong to multiple jobs at the same time, such as CH2 and CH5 above. The difference between CH2 and CH5 is that the former is used for different peripherals, while the latter uses the same peripheral. Personally, I don't recommend using it like this, because if the management is not good, it is easy to cause confusion in the data in the buff. A Job can also belong to multiple Sequences at the same time, such as Job0 above.

There can be multiple Channels under a Job, such as Job1, Job2, and Job3 above; and there should be at least one Channel, otherwise it is meaningless, and Job5 above is not allowed. In this case, the Job/Seq is usually used by multiple users, and each user is assigned its own independent Channel.

Similarly, there can be multiple jobs under a Sequence, such as Seq3 above; there should be at least one Job, otherwise it is meaningless, and Seq2 above is not allowed.

Multiple jobs under the same sequence have the same priority.

A peripheral can have multiple Job bindings.

As can be seen from the figure above, a Sequence can have Jobs with different peripherals (buses).

The transmission is based on Sequence, and only Sequence can be operated. Reception is specific to a Channel. Get status or callback, both Job and Sequence are available (Level1, Level2).

4. Sequence/Job/Channel sending timing

insert image description here

 


As shown in the figure above, the sending task needs to wait for all Jobs and all Channels under the Sequence to be sent before the bus is free (released).

If multiple jobs share a channel (sequence is the same), then the user needs to ensure that the read/write related functions are not called during the transmission process , otherwise the data consistency cannot be guaranteed (data confusion).

During the transmission process, the read/write function itself cannot guarantee the integrity of the data.

It is allowed to initiate multiple Sequence transfer requests at the same time. For example, when a Seq is being transmitted, it is allowed to initiate another Seq transmission request, but the same Seq cannot be initiated multiple times at the same time. The driver will choose to accept or decline based on the current situation. For example, the new Seq has a shared Job with the original Seq. In this case, the request will not be accepted to prevent conflicts.

The Sequence transfer request can be canceled (Spi_Cancel), and the cancellation of this operation is processed in the atomic unit of Job. After canceling, the callback function will still be called to notify the user (if enabled). It should be noted that whether the cancel operation will cause damage to the peripheral or other undefined behaviors needs to be controlled by the user, and the driver is not responsible.

The Sequence can contain multiple jobs, and each job will be rescheduled according to the priority policy (see later) after the transmission is completed. Scheduling in Polling mode is implemented by calling the Spi_MainFunction function periodically by the user.

5. MCAL SPI mode classification


√: support/available x: not support/unavailable IB/EB: see below

LEVEL 0: Provides a simplified set of services that only handle simple isochronous transfers. This happens frequently for ECUs that contain simple SPI networks, even for ECUs that use high-speed external devices.

Synchronous transmission means that once the transmission service function is called, the program will be blocked until the transmission request is completed (a good code implementation usually also has a timeout monitoring mechanism, and the CPU will be released after timeout).

LEVEL 1: Provides a simplified set of services that only handle asynchronous transfers. For functions that use SPI and define different priorities, asynchronous transfers are often used. There are also some low-speed peripherals that are also suitable for this asynchronous mode.

Asynchronous transfers mean that users calling the transfer service will not be blocked while the transfer is in progress. The driver can notify the user when the transfer is complete (configurable by the user). The asynchronous transfer mode can be divided into realization by polling or interrupt.

LEVEL 2: A combination of the previous two. All features are included. It can meet complex demand scenarios such as different rates and different priorities. It is specified for those chips that need to provide at least two SPI buses separately. Otherwise, there is no point in using this level of functionality.

If it is configured as (asynchronous) polling mode (only valid when the API level is Level 2), it needs to be called periodically: Spi_MainFunction.

 


As can be seen from the above table, DMA is only valid in asynchronous mode (Async Mode).

6. SPI Buffer



IB: Internal Buffers EB: External Buffers

The advantages and disadvantages in the above table come from the translation of standard documents, some sentences are not smooth, please see the text description below. Does not affect your understanding.

IB: Statically allocated. EB: It can be static allocation or dynamic allocation, depending on the user's use environment.

Some hardware levels provide a relatively large Buffer. In this case, the IB type can give full play to the hardware characteristics and improve its performance (this is the original design intention of the IB Buffer) (note that if multiple channels are connected to a device at the same time, the feature usage is limited). If the hardware does not have a Buffer, software is required to simulate the implementation.

The size of the IB type Buffer is fixed. EB type Buffer can be set through API.

The SPI driver is not responsible for ensuring the continuity of the data in the IB Buffer. If a Channel is used by multiple Jobs/Seqs, the SPI driver is not responsible for maintaining the scenario where the Buffer is overwritten by multiple Jobs/Seqs.

But the sending and receiving Buffers are separate and independent. That is, the sending Buffer will not be overwritten by the received data.

The original design intention of EB Buffer is to reuse the external (here refers to the user) Buffer as much as possible, because in many cases, the user already has a Buffer, so to use the EB type Buffer, only need to provide the pointer of the user Buffer to the SPI driver to achieve shared Purpose. Therefore, the SPI driver cannot manage the Buffer, and the user needs to ensure its consistency. Another scenario is that sometimes our Buffer size changes (for example, the needs of multiple users may be different, or the data length of a user changes), this situation also needs to be solved by using EB type Buffer (because IB type Buffer is a fixed size). Of course, the EB type Buffer can also be a fixed size. But the maximum value of the Buffer size needs to be configured statically. In general, EB type Buffer is more flexible to use.

Channel transmission has its own parameter (Spi_SetupEB), but the parameter (source/target) can also be NULL. If the Source is NULL when sending, it will use the default parameter transmission. If the Target is NULL when receiving, it will ignore the received The data. For each Channel, the Spi_SetupEB function can only be called once before initiating a transfer request, unless there is information that needs to be changed, such as length information.


If the Data Width is also uint8, uint16, uint32 three types, since it is consistent with the Data Buffer Type, it can be forwarded directly. But if the Data Width is 8~32 and the types are inconsistent, you need to be careful. For example, if Data Width is set to 12Bits. Data Buffer Type can only choose uint16. In this case, only the lower 12Bits can be sent when sending, and the upper 4 bits are ignored. When receiving, only the lower 12 bits are received, and the upper 4 bits are filled with 0.

 

7. Other important mechanisms of SPI

  • Priority: The smaller the number, the lower the priority
  • Jobs linked by Sequence should have the same or decreasing priority
  • Sequence can be interrupted
  • concurrent synchronous transfer

The driver may be used simultaneously by multiple software modules, which may be independent of each other or belong to different layers. In order to prevent conflicts during simultaneous access, a priority mechanism is added, and each Job will be assigned a priority. This scenario usually occurs in real-time systems based on asynchronous mechanisms.

Multiple Jobs under a Sequence, or these Jobs all have the same priority. If the priorities are different, the first Job has the highest priority, and the lowest priority is placed last (this is required during configuration). Although there is a priority-based scheduler inside the driver, the scheduler is more used to handle the scheduling of a new higher-priority Sequence task that is allowed to be initiated during the execution of the interrupted Sequence.

Level 1 and Level 2 can configure whether a Sequence can be preempted. If the preempted function is enabled, after the Sequence starts transmission, if a job with a higher priority initiates a transmission request during the process, the current Sequence will be suspended (Suspend) to execute the job with a higher priority, and the interrupt is The job is carried out in atomic units, that is, it must wait for a job to be executed, and then switch when the next scheduling point is executed. Please refer to the previous sequence diagram.

If the preemption function is not enabled, once the Sequence starts to transmit, the transmission request of other Sequences cannot be executed until the transmission is completed.

If a Sequence is preempted, the user needs to know whether there are multiple Sequences sharing the same Channel. If so, the user needs to manage the data of the Channel to prevent the job in the original Channel from being replaced by a higher priority job during the preemption process. The data is overwritten (this configuration is usually not recommended).

Synchronous transmission can also initiate multiple different Sequence transmission requests at the same time, but the user must enable this function (SPI_SUPPORT_CONCURRENT_SYNC_TRANSMIT: Level 0, Level 2 is valid);

8. Precautions

  1. Before using the services in this module, the Spi _Init() function must be called to initialize.
  2. If the DMA function is used, the Spi _Init() function must be called after the Port_Init() function and the Mcl_Init() function.
  3. If it is configured as (asynchronous) polling mode (only valid when the API level is Level 2), it needs to be called periodically: Spi_MainFunction.
  4. If the fixed priority strategy is used, the SpiPhyRxDmaChannel priority must be greater than the SpiPhyTxDmaChannel priority.
  5. If configured in (asynchronous) interrupt mode with DMA enabled:
  • The corresponding channel interrupt of DMA must be enabled.
  • The receive/transmit interrupt function of the SPI module must be registered in the DMA completion callback function, see DMA module configuration for configuration.

SPI module interrupt function: Spi_LPspi_IsrRxDma_LPSPI_X/Spi_LPspi_IsrTxDma_LPSPI_X, where X is the channel number.

Taking channel 0 as an example, the interrupt function is: Spi_LPspi_IsrRxDma_LPSPI_0/Spi_LPspi_IsrTxDma_LPSPI_0.

        6. If configured as (asynchronous) interrupt mode, but using FIFO, you need to register the interrupt function (Spi_LPspi_IsrTDF_LPSPI_X) in the interrupt vector table, where X is the channel number.

Since MCAL itself does not provide the interrupt vector table registration function, you can refer to the interrupt registration function in the SDK or MCAL sample project: sys_registerIsrHandler().

        7. If the DMA transfer mode is enabled and D-CACHE is enabled, the internal buf (IB) cannot be used to send or receive, and the buf of the source address and destination address must be placed in the NON-CACHE area to avoid data consistency Sexual issues (if it is placed in the CACHE area, data chaos may occur). You can use the partition command in the link file (*.ld) to isolate the variables that need to be sent or received.

        8. Only the following functions can be called in the callback function of the SPI module, and other functions are not allowed to be called in it (protocol standard):

  1. Spi_ReadIB
  2. Spi_WriteIB
  3. Spi_SetupEB
  4. Spi_GetJobResult
  5. Spi_GetSequenceResult
  6. Spi_GetHWUnitStatus
  7. Spi_Cancel

Guess you like

Origin blog.csdn.net/qq_42700289/article/details/131251367
SPI