Author Topic: STM32F1 Spi Slave select with DMA  (Read 3943 times)

0 Members and 1 Guest are viewing this topic.

Offline tn88testTopic starter

  • Newbie
  • Posts: 1
STM32F1 Spi Slave select with DMA
« on: November 19, 2014, 03:08:14 am »
I am unable to deselect the slave. The MISO pin of the slave is still output the data its received from the master even when the NSS pin high.

The datasheet says:
Quote
Slave select (NSS) pin management
Hardware or software slave select management can be set using the SSM bit in the
SPI_CR1 register.
• Software NSS management (SSM = 1)
The slave select information is driven internally by the value of the SSI bit in the
SPI_CR1 register. The external NSS pin remains free for other application uses.
• Hardware NSS management (SSM = 0)
Two configurations are possible depending on the NSS output configuration (SSOE bit
in register SPI_CR2).
– NSS output enabled (SSM = 0, SSOE = 1)
This configuration is used only when the device operates in master mode. The
NSS signal is driven low when the master starts the communication and is kept
low until the SPI is disabled.
– NSS output disabled (SSM = 0, SSOE = 0)
This configuration allows multimaster capability for devices operating in master
mode. For devices set as slave, the NSS pin acts as a classical NSS input: the
slave is selected when NSS is low and deselected when NSS high.

Code: [Select]
#include "stm32f10x.h"

/* DEFINE */
#define BUFFSIZE 32

/* GLOBAL VARIABLE */
static volatile uint8_t spi_tx_buff[BUFFSIZE] = {0},
spi_rx_buff[BUFFSIZE] = {0};

/* FUNCTION PROTOTYPES */
void RCC_Config(void);
void GPIO_Config(void);
void NVIC_Config(void);
void SPI1_Config(void);
void DMA1_SPI1_TX_Config(void);
void DMA1_SPI1_RX_Config(void);


int main(void){
/* Config */
RCC_Config();
GPIO_Config();
NVIC_Config();
SPI1_Config();
DMA1_SPI1_TX_Config();
DMA1_SPI1_RX_Config();

/* SysTick 1ms */
SysTick_Config(SystemCoreClock / 1000);

while(1){

}
}

/* FUNCTION -------------------------------------------------------------------*/


/* CONFIG ---------------------------------------------------------------------*/
void RCC_Config(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

void GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;

/* GPIO Alternate function */

/* SPI1: PA4 -> NSS */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* SPI1: PA5 -> SCK */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* SPI1: PA6 -> MISO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* SPI1: PA7 -> MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void NVIC_Config(void){
NVIC_InitTypeDef NVIC_InitStructure;

/* DMA1_Channel2_IRQn */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

void SPI1_Config(void){
SPI_InitTypeDef  SPI_InitStructure;

SPI_I2S_DeInit(SPI1);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);

SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
}

void DMA1_SPI1_TX_Config(void){
DMA_InitTypeDef  DMA_InitStructure;

DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)spi_rx_buff;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = BUFFSIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel3, ENABLE);
}

void DMA1_SPI1_RX_Config(void){
DMA_InitTypeDef  DMA_InitStructure;

DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)spi_rx_buff;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BUFFSIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel2, ENABLE);
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
}



/* INTERRUPT ------------------------------------------------------------------*/
void SysTick_Handler(void){

}

void DMA1_Channel2_IRQHandler(void){
/* SPI1: RX */
if(DMA_GetITStatus(DMA1_IT_TC2) != RESET){
DMA_ClearITPendingBit(DMA1_FLAG_GL2);
}
}

« Last Edit: November 19, 2014, 04:33:54 am by tn88test »
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: STM32F1 Spi Slave select with DMA
« Reply #1 on: November 19, 2014, 07:46:49 pm »
The hardware documentation does not actually state that the slave transmitter is disabled when the NSS pin is deasserted. You may have to do it manually in software.


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf