"bit bang" SPI pins STM32F1

Post here first, or if you can't find a relevant section!
User avatar
Pito
Posts: 1593
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: "bit bang" SPI pins STM32F1

Post by Pito » Mon Oct 09, 2017 3:15 pm

Comment out all delays if you need more speed (bitBangedSPI.cpp):

Code: Select all

    // clock high
    digitalWrite (sck_, HIGH);
 
    // delay between rise and fall of clock
    delayMicroseconds (delayUs_);
 
    // clock low
    digitalWrite (sck_, LOW);

    // delay between rise and fall of clock
    delayMicroseconds (delayUs_);
} // end of for loop, for each bit
First try to use this code, when you gather more experience with stm32 you may replace the digitalWrite()..
Pukao Hats Cleaning Services Ltd.

dannyf
Posts: 147
Joined: Wed May 11, 2016 4:29 pm

Re: "bit bang" SPI pins STM32F1

Post by dannyf » Mon Oct 09, 2017 3:34 pm

the following:

Code: Select all

//transmission on sck's rising edge
void spi1_write(unsigned char data_t) {
	unsigned char mask = 0x80;				//start with the most signifcant bit

#if defined(SPI1_MOSI)
	IO_OUT(SPI1_DDR, SPI1_MOSI);			//mosi as output
#endif
	IO_CLR(SPI1_PORT, SPI1_SCK);		//default state of sck: low
	while (mask) {
		IO_CLR(SPI1_PORT, SPI1_SCK);		//clear spi_sck

#if defined(SPI1_MOSI)
		if (data_t & mask) IO_SET(SPI1_PORT, SPI1_MOSI);	//send the data
		else IO_CLR(SPI1_PORT, SPI1_MOSI);
#endif
		IO_SET(SPI1_PORT, SPI1_SCK);		//send on the rising edge
		SPI1_DELAY(SPI1_DLY);				//insert some delays to generate 50% dc
		mask = mask >> 1;					//next bit
	}
	//IO_CLR(SPI1_PORT, SPI1_MOSI);		//clear mosi
	//IO_CLR(SPI1_PORT, SPI1_SCK);			//clear sck
}
took less than 500 clock cycles on a STM32F100.

At 72Mhz, that equates to <7us per byte transmitted. or 1+Mbps.

alexandros
Posts: 24
Joined: Mon Oct 02, 2017 6:51 pm

Re: "bit bang" SPI pins STM32F1

Post by alexandros » Mon Oct 09, 2017 6:19 pm

Pito wrote:
Mon Oct 09, 2017 3:15 pm
Comment out all delays if you need more speed (bitBangedSPI.cpp):

First try to use this code, when you gather more experience with stm32 you may replace the digitalWrite()..
I just tried it , i do see some speed but , this isnt the issue though.


i suspect that i am making something wrong , and i guess its the intrerupt that i am not taking care of , so i will post my code in order to get things straigh,

So my normal code before the bit bang is

Code: Select all

........
 dma_init(SPIDMA_1);
 dma_attach_interrupt(SPIDMA_1, DMA_CH3, &DMA1_CH3_handler);
 spi_tx_dma_enable(SPI_Class->dev());  
  .......
  
// Interrupt handler for DMA (clear data output)
void DMA1_CH3_handler()
 {
   while(SPI_Class->dev()->regs->SR & SPI_SR_BSY);
  SPI_Class->dev()->regs->DR = 0;
  }
  
  
///SEND DATA 
void SPI_dmaSend(uint8_t *transmitBuffer, uint16_t length) {
   //DATA SEND INTO PA7 MOSI1
   dma_setup_transfer( 
    SPIDMA_1, DMA_CH3,       // DMA channel specification for SPI 1
    &SPI_Class->dev()->regs->DR, // destination address: specify the SPI data register
    DMA_SIZE_8BITS,              // ​​Destination data size: 1 byte
    transmitBuffer,                 // source address: SRAM address
    DMA_SIZE_8BITS,              // ​​Destination data size: 1 byte
    DMA_MINC_MODE|               // flag: cyclic
    DMA_FROM_MEM |               // Peripheral from memory, transfer complete interrupted
    DMA_TRNS_CMPLT               // Transfer complete Interrupted calling * /
  );
  dma_set_num_transfers(SPIDMA_1, DMA_CH3, length); 
  dma_enable(SPIDMA_1, DMA_CH3);  
}
after the bit bang mod

Code: Select all

 #include <bitBangedSPI.h>
bitBangedSPI bbSPI ( PA6, -1 , PA5);  // MOSI, MISO, SCK
const byte mySS =  PA4;  // slave select
.......
 bbSPI.begin ();
 pinMode (mySS, OUTPUT);
 dma_init(SPIDMA_1);
 dma_attach_interrupt(SPIDMA_1, DMA_CH3, &DMA1_CH3_handler);
 spi_tx_dma_enable(SPI_Class->dev());  
  .......
  
// Interrupt handler for DMA (clear data output)
void DMA1_CH3_handler()
 {
   while(SPI_Class->dev()->regs->SR & SPI_SR_BSY);
  SPI_Class->dev()->regs->DR = 0;
  }
  
  
///SEND DATA 
void SPI_dmaSend(uint8_t *transmitBuffer, uint16_t length) {
   //DATA SEND INTO PA6 MISO1 
   
   for (uint16_t j = 0; j <=length; j++) 	
   {
 		 digitalWrite(mySS, LOW); 
		bbSPI.transfer (transmitBuffer[j]);
		// disable Slave Select
		 digitalWrite(mySS, HIGH);
   }   
}

stevestrong
Posts: 1748
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: "bit bang" SPI pins STM32F1

Post by stevestrong » Mon Oct 09, 2017 7:32 pm

Why do you "reinvent the wheel"?
We have already an hardware SPI library which supports DMA: https://github.com/rogerclarkmelbourne/ ... raries/SPI

As far as I know, the software (bit-bang) SPI cannot work with DMA.

You still haven't mentioned in clear text what is your issue.
"It does not work" is not enough information.

alexandros
Posts: 24
Joined: Mon Oct 02, 2017 6:51 pm

Re: "bit bang" SPI pins STM32F1

Post by alexandros » Mon Oct 09, 2017 8:27 pm

Ok , i am with you, can i use the https://github.com/rogerclarkmelbourne/ ... raries/SPI
and make the MISO of SPI1(PA6)act as a MOSI?
Because my microscope and solder station is ready to solder over the MCU the damn PA7 :? :?

User avatar
RogerClark
Posts: 7171
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: "bit bang" SPI pins STM32F1

Post by RogerClark » Mon Oct 09, 2017 8:54 pm

Is your MCU acting as the Master or the Slave?

You are implying that you want the MCU to use the slave connections.

Did you build the hardware yourself?

If not... There must be a good reason for the manufacturer to use a non standard pin configuration

alexandros
Posts: 24
Joined: Mon Oct 02, 2017 6:51 pm

Re: "bit bang" SPI pins STM32F1

Post by alexandros » Mon Oct 09, 2017 9:17 pm

RogerClark wrote:
Mon Oct 09, 2017 8:54 pm
Is your MCU acting as the Master or the Slave?

You are implying that you want the MCU to use the slave connections.

Did you build the hardware yourself?

If not... There must be a good reason for the manufacturer to use a non standard pin configuration
if i understand the question corectly , Yes my MCU acting as the Master,
i already manage to use the alternate pins of SPI1 pb5 ,pb4 ,pb3 etc

Code: Select all

afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // release PB3 and PB5
afio_remap(AFIO_REMAP_SPI1); // remap SPI1
gpio_set_mode(GPIOB, 5, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOB, 3, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOB, 4, GPIO_INPUT_FLOATING);
gpio_set_mode(GPIOB, 3, GPIO_AF_OUTPUT_PP); 
but again are not exposed , my only solution is to use MISO of SPI1(PA6)act as a MOSI
the hardware is not made by me , the manufactor have no idea why he didnt use non standard pin configuration he just cloned it copied i dont know, :)

User avatar
RogerClark
Posts: 7171
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: "bit bang" SPI pins STM32F1

Post by RogerClark » Mon Oct 09, 2017 9:38 pm

OK.

What is the hardware ?

alexandros
Posts: 24
Joined: Mon Oct 02, 2017 6:51 pm

Re: "bit bang" SPI pins STM32F1

Post by alexandros » Mon Oct 09, 2017 9:51 pm

a chinese controller for 3d printer

User avatar
RogerClark
Posts: 7171
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: "bit bang" SPI pins STM32F1

Post by RogerClark » Mon Oct 09, 2017 11:37 pm

OK

Post Reply