NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
This writeup discusses the behavior of PSPs McASP driver (based on DSP/BIOSTM) when applications cannot meet real-time needs of audio. This writeup also discusses configuration of McASP driver in these circumstances to avoid un-desired side effects.
The notes below is applicable for (DSP/BIOSTM) PSP provide on following SoC
- 1 What is IDLE time and IDLE time transfers
- 2 Configuring loopJobBuffer and loopJobLength
- 2.1 Time Lines, Configurability and Need
- 2.2 Side Effects
- 2.3 Computing Length (loopJobLength)
What is IDLE time and IDLE time transfers
McASP primarily interfaces to a DAC / ADC, these DAC/ADC would require continuous streams of clock (fixed period) and data. In order to maintain this constant stream, applications will have to provide data to be transmitted (or buffers to store the received data, in case of a receiver) in an un-interrupted context.
Typically an application would require to process audio data (raw data) before data can be sent out to a DAC. This processing of data or system loads could limit applications from meeting the real time needs of McASP. (Example If DAC & McASP is configured to operate Bit Clock at 3MHz, McASP would require 2929.6875 Kilobits per second. (~366 Kilobytes). )
This could result in glitches/noise/re-programming of DAC/ADC, etc…, in this writeup these breaks in audio stream are referred as IDLE time.
In these conditions, McASP driver would send out know pattern of data. (could be NULL tone), referred as IDLE time transfer in this writeup . (In case of a receiver, the received data would be stored in buffers)
The data to be transmitted is referred as loopJobBuffer and its length is referred as loopJobLength. In case of a receiver, the buffer that would used to hold the received data is referred as loopJobBuffer and its length as loopJobLength.
Configuring loopJobBuffer and loopJobLength
McASP would use driver internal buffer as loopJobBuffer and its length as 4 bytes in case TDM/DSP and 8 in case of DIT mode of operation.
Application could configure the loopJobBuffer and its length, during creation of McASP driver. McASP would use the specified buffer and its length for IDLE time transfers.
The minimum number of bytes used for IDLE Time transfer is defined by loopJobLength.
Assume that specified length is 4 bytes and application could not supply data for 40 bytes time, the EDMA would be programmed to move 4 bytes (to or from loopJobBuffer) and repeat this for 10 times.
Time Lines, Configurability and Need
Channel create time
On creation of McASP device driver, the High Clock, Bit Clock and Frame Sync signals are configured. On edge of the Frame Sync the EDMA events are generated. With every Frame Sync either data is to be written/read from, failing which under run/overrun error conditions are reported. The only way to recover from this error condition would be to re-set the peripheral.
The McASP driver configures the EDMA to service the events raised by McASP before configuring the peripheral. The data is moved from/into the loopJobBuffer.
On channel creation the IDLE transfer is started, which uses loopJobBuffer.
(In transmit IO Channel the contents of loopJobBuffer is transmitted and in receive channel the read contents are stored in loopJobBuffer)
In scenarios where the applications have queued up enough data/buffer to be transmitted / received into, the loopJobBuffer would not be employed. McASP would transmit / receive into application supplied buffer, on completion of last byte of data, if there are no more IO requests from the applications, the loopJobBuffer would be employed.
McASP driver allocates loopJobBuffer for scenario where 1 serializer with one slot is used and wordwidth is assumed to be 32 bit. Depending on the DAC/ADC employed, application might require to specify loopJobBuffer of different length. The sections below discuss in detail the procedure to calculate length of loopJobBuffer and side effects of wrong configuration.
McASP transmits 0x00000000 as idle time data (in case of reception the data is received into loopJobBuffer), application that would require to send different data during idle time would configure McASP to use application specific data patterns.
The applications could choose to specify the buffer to be used as loopJobBuffer. This could be configured during creation of IO channel. Use channel creation parameter PSP_mcaspChanParams.userLoopJobBuffer and PSP_mcaspChanParams.userLoopJobLength . Please refer McASP device driver user guide for details (mcasp_bios_driver_users_guide.doc would be delivered as part of PSP package).
- Buffer that should be used as loopJobBuffer
- Length of loopJobBuffer
- Separate loopJobBuffer, length for receive section and transmit section.
- In case of transmitters, the pattern to be sent out during IDLE Time
Incorrect configurations of loopJobBuffer could lead undesired results, the sections below capture the mis-configurations that resulted different behavior. Please note that following points assume that all other configurations were correct and this list of undesired results is not comprehensive.
Swapped Channels – Static (Swapped once and stay that way)
Assume McASP is configured to use one serializer with two slots and wordwidth is 32 bits. Assuming this serializer is interfaced with a DAC which interprets first slot as Left Channel & Second Slot as Right Channels further application supplied data would contain data for left channel followed by data for right channel.
If the applications were use McASP default loopJobBuffer, on creation the loopJobBuffer is deployed and on a transmit request from the application, McASP would program the EDMA to move the application supplied data to serializer.
McASP driver can switch to application supplied buffer only on completion of length of loopJobBuffer (4 bytes in this case). Since the length of the slot is 4 bytes
Channels would not be swapped when the loopJobBuffer is used even times and swapped when loopJobBuffer is used odd times.
If loopJobBuffer is used ODD number of times and applications could provide sufficient data, the loopJobBuffer would never be scheduled. This way the channels are swapped once and remain swapped.
If the loopJobBuffer was configured as 8 bytes, this scenario would never occur.
Swapped Channels – Run Time (Swaps occasionally or after some time)
In the above example, if applications could not meet the real-time needs of McASP loopJobBuffer is scheduled. In a situation where application would randomly / periodically miss the real time needs, there is possibility of channels being swapped.
If the loopJobBuffer was configured as 8 bytes, this scenario would never occur.
Computing Length (loopJobLength)
In general the loopJobBuffer length should be long enough to satisfy all enabled slots in a serializer and all serializers. Computing the length is described under following sections.
Single serializer with single slot
Consider a scenario where the word length is 3 byte and default loopJobLength is used (i.e. 4 bytes). When application fails to meet the needs of McASP, loopJobBuffer is used. This would transmit data for 1 slot and 1st byte of 2nd slot. The net effect could be corrupted audio (or noise). By specifying loopJobBuffer length as 3 bytes, we ensure that loopJobBuffer completes on word boundary.
Recommended loopJobBuffer length is Configured Word Width
Multi serializers 1 slot each
Consider a scenario where word width is 4 bytes and 3 serializers are used. When application fails to meet the needs of McASP, loopJobBuffer is used. This would transmit data for first two serializers. At this point, if applications was to request transmit, the data of serializer 1 would be sent out on serializer 3, resulting in swapped channels.
By specifying loopJobBuffer length as 12 bytes, we ensure that we always begin with first serializer.
Recommended loopJobBuffer length is Product of (Configured Word Width * Number of Serializers Used)
Single serializer with multiple slots
Consider a scenario where word width is 4 bytes and 3 slots are used. When application fails to meet the needs of McASP, loopJobBuffer is used. This would transmit data for first two slots. At this point if applications was to requests transmit, the data of slot1 would be sent out on slot 3, resulting in swapped channels. By specifying loopJobBuffer length as 12 bytes, we ensure that we always begin with first slot 1.
Recommended loopJobBuffer length is Product of (Configured Word Width * Number of Slots Used)
Multiple serializers with multiple slots in each
Consider a scenario where word width is 4 bytes, 2 slots and 2 serializers are used. When application fails to meet the needs of McASP, loopJobBuffer is used. This would transmit data for first slot of first serializer. At this point if applications was to request transmit, the data of slot1-serializer1 would be sent out on slot 1 - serializer2, resulting in swapped channels.
By specifying loopJobBuffer length as 16 (4*2*2) bytes, we ensure that we always begin with first slot 1 of first serializer.
Recommended loopJobBuffer length is Product of (Configured Word Width * Number of Slots Used * Number of Serializers Used)