SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: ARM Cortex-M0 SPI outputting 16bit not 8bit
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

ARM Cortex-M0 SPI outputting 16bit not 8bit

Eileen David
Last updated: September 14, 2023 12:29 pm
Eileen David 8 Min Read
Share
SHARE

When configuring the SPI (Serial Peripheral Interface) on an ARM Cortex-M0 chip to communicate with an external device, a common issue that arises is the SPI outputting 16-bit data instead of 8-bit as expected. This can occur if the SPI is not properly initialized and configured in the software. In this article, we will explore the root causes of this issue and walk through the steps to resolve it.

Contents
Common Causes of 16-bit SPI Output1. SPI Data Register Width2. External Device Expects 16-bit3. SPI Frame Format Configuration4. 16-bit Transmit Data BufferSolutionsConfigure Data Register WidthSet Frame Format to 8-bitUse 8-bit Transmit BufferExample CodeOther Tips for SPI on Cortex-M0Conclusion

Common Causes of 16-bit SPI Output

There are a few key reasons why the Cortex-M0 SPI may output 16 bits per transfer instead of 8 bits:

  • The SPI data register width is incorrectly set to 16-bit in the initialization
  • The external device expects 16-bit data frames
  • The SPI frame format register is configured for 16-bit frames
  • The data type for the transmit buffer is 16-bit (uint16_t)

Understanding the root cause is important to determine the proper solution. Let’s examine each of these in more detail.

1. SPI Data Register Width

One of the first things to check is the initialization of the SPI peripheral. Many Cortex-M0 MCUs have configurable data register widths – commonly 8-bit or 16-bit. For example, on an STM32L0 chip the SPI_CR1 register contains a DFF bit to select 8 or 16-bit data frames.

If this width setting is incorrectly configured for 16-bit, then any data loaded into the transmit buffer will be sent out as 16-bit frames. Double-check this data register width setting against your expected 8-bit peripheral.

2. External Device Expects 16-bit

In some cases, the external SPI device you are interfacing with actually expects 16-bit data instead of 8-bit. This could be a 16-bit ADC or DAC, for example. Make sure to verify the SPI frame size expected by the external component matches your software configuration.

Reading the device datasheet and any sample code can provide insight into the expected frame format. If the device uses 16-bit data, you will need to adjust the software accordingly.

3. SPI Frame Format Configuration

Related to the data register width setting, many Cortex-M0 chips also have SPI frame format registers to configure the length. For STM32L0, this is the SPI_CR2 register which contains a FRF[2:0] field to set the frame format.

If this is set to a 16-bit variant like Motorola mode, when 8-bit data is written to the buffer it will be packed into 16-bit frames for transmission. Verify this frame format matches your expected setting.

4. 16-bit Transmit Data Buffer

Lastly, the data type of the transmit buffer itself can lead to 16-bit output. For example:


uint16_t tx_buffer[10]; 

// Load 8-bit data
tx_buffer[0] = 0xAB; 

// Transmit buffer 
SPI_Transmit(tx_buffer);

Even though the data written to tx_buffer is 8-bit, because the buffer was defined as uint16_t the SPI will transmit 16-bit values. Make sure the transmit buffer matches your 8-bit data requirement.

Solutions

Now that we’ve explored some common root causes of 16-bit SPI output, let’s discuss solutions to configure the SPI for 8-bit operation.

Configure Data Register Width

First, set the SPI data register width appropriately for 8-bit communication. For STM32L0 this would be:


SPI1->CR1 &= ~SPI_CR1_DFF; // Clear DFF bit for 8-bit

Refer to your MCU reference manual for the corresponding control bit.

Set Frame Format to 8-bit

Next, configure the frame format register for 8-bit operation. Continuing the STM32L0 example:

 
SPI1->CR2 &= ~SPI_CR2_FRF; // Set FRF for 8-bit MOTOROLA mode

The frame format must match your peripheral requirement.

Use 8-bit Transmit Buffer

Finally, make sure your transmit buffer matches the 8-bit data you want to send:


uint8_t tx_buffer[10];

tx_buffer[0] = 0xAB; 

SPI_Transmit(tx_buffer);

With these three steps – configuring the data register width, frame format, and buffer type for 8-bit – the SPI should now transmit 8-bit data as expected.

Example Code

Here is an example initialization sequence for 8-bit SPI on an STM32L0 MCU:


void SPI1_Init(void)
{
  // Enable clock for SPI1
  RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; 

  // Configure pins for SPI1 alternate function
  GPIOA->MODER |= (2 << 2*5) | (2 << 2*6) | (2 << 2*7);

  // Set up SPI1 registers
  SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM;
  SPI1->CR1 &= ~SPI_CR1_DFF; // 8-bit data frame format
  SPI1->CR2 = SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0; 
  SPI1->CR2 &= ~SPI_CR2_FRF; // 8-bit MOTOROLA frame format

  // Enable SPI1
  SPI1->CR1 |= SPI_CR1_SPE; 
}

// Transmit Data
void SPI1_Transmit(uint8_t *data, uint16_t size) 
{
  for(int i=0; i<size; i++) {
    // Wait for TX buffer empty
    while(!(SPI1->SR & SPI_SR_TXE));
    // Write byte to TX buffer  
    SPI1->DR = data[i];
  }
}

This example demonstrates the key steps of configuring the SPI1 peripheral on an STM32L0 Cortex-M0 chip for 8-bit communication. The data register width and frame format are explicitly set for 8-bit. And the transmit buffer is uint8_t to match the 8-bit data.

Following these good SPI initialization practices will ensure you avoid errant 16-bit output when trying to interface Cortex-M0 chips with 8-bit peripherals.

Other Tips for SPI on Cortex-M0

Beyond the issue of 16-bit vs 8-bit data, there are some other best practices worth covering for SPI on Cortex-M0 platforms:

  • Use DMA if available – SPI transfers will be more efficient
  • Implement SPI delay if needed between transfers
  • Use SPI FIFOs on more advanced MCUs like STM32G0
  • Keep SPI SCK below the maximum rated frequency of your peripheral
  • Use multiple chip selects if communicating with multiple external devices

Additionally, be sure to utilize oscilloscope measurements during development. Probing the SPI MOSI, MISO, and SCK signals can give invaluable insight into the actual data transactions.

Conclusion

Configuring SPI on the ARM Cortex-M0 can certainly be tricky. Hopefully this article provided some helpful troubleshooting tips if you run into issues with unexpected 16-bit output. The key takeaways are:

  • Verify correct configuration of the data register width for 8-bit frames
  • Set the SPI frame format to match your peripheral requirement
  • Use uint8_t transmit buffers for 8-bit data
  • Follow best practices like utilizing DMA and SPI FIFOs when possible

With attention to these software settings and hardware interfaces, you should be able to resolve 16-bit SPI output problems and successfully utilize the Cortex-M0 SPI to add communication capabilities to your embedded systems.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article How to start ARM Cortex programming using embedded C?
Next Article Are there any practical differences between the Arm M0 and M3 for the C programmer?
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

What is ARM Cortex-M35P?

The ARM Cortex-M35P is a 32-bit processor core designed for…

7 Min Read

Is Arm The Future Of Gaming?

Arm-based processors have the potential to transform the gaming industry.…

6 Min Read

ARM Cortex-M4 Opcodes

The ARM Cortex-M4 is a powerful 32-bit processor optimized for…

7 Min Read

Arm Sleep Instruction

Falling asleep and staying asleep can be a challenge for…

8 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account