What is Serial Paripheral Interface (SPI) • The Serial Peripheral Interface bus or SPI bus is a synchronous serial data link de facto standard, named by Motorola, that operates in full duplex mode. Devices communicate in master/slave mode where the master device initiates the data frame. Multiple slave devices are allowed with individual slave select lines. Sometimes SPI is called a four-wire serial bus, contrasting with three-, two-, and one-wire serial buses. SPI is often referred to as SSI (Synchronous Serial Interface). • The SPI bus specifies four logic signals: – – – – SCLK: serial clock (output from master); MOSI: master output, slave input (output from master); MISO: master input, slave output (output from slave); SS: slave select (active low, output from master). Operation • The SPI bus can operate with a single master device and with one or more slave devices. • If a single slave device is used, the SS pin may be fixed to logic low. • Most slave devices have tri-state outputs so their MISO signal becomes high impedance (logically disconnected) when the device is not selected. Devices without tri-state outputs can't share SPI bus segments with other devices; only one such slave could talk to the master, and only its chip select could be activated. Data Transmission • To begin a communication, the bus master first configures the clock, using a frequency less than or equal to the maximum frequency the slave device supports. Such frequencies are commonly in the range of 10 kHz–100 MHz. • The master then transmits the logic 0 for the desired chip over the chip select line. A logic 0 is transmitted because the chip select line is active low, meaning its off state is a logic 1; on is asserted with a logic 0. If a waiting period is required (such as for analog-to-digital conversion), then the master must wait for at least that period of time before starting to issue clock cycles. • During each SPI clock cycle, a full duplex data transmission occurs: – the master sends a bit on the MOSI line; the slave reads it from that same line – the slave sends a bit on the MISO line; the master reads it from that same line • Transmissions normally involve two shift registers of some given word size, such as eight bits, one in the master and one in the slave; they are connected in a ring. Data is usually shifted out with the most significant bit first, while shifting a new least significant bit into the same register. After that register has been shifted out, the master and slave have exchanged register values. • Transmissions may involve any number of clock cycles. When there is no more data to be transmitted, the master stops toggling its clock. Normally, it then deselects the slave • Transmissions often consist of 8-bit words, and a master can initiate multiple such transmissions if it wishes/needs. However, other word sizes are also common, such as 16-bit words for touchscreen controllers or audio codecs What is Inter Integrated Circuit (I2C) Interface • I2C is a multimaster serial single-ended computer bus invented by Philips used for attaching lowspeed peripherals to an embedded system. • I²C uses only two bidirectional open-drain lines, Serial Data Line (SDA) and Serial Clock (SCL), pulled up with resistors. Typical voltages used are +5 V or +3.3 V. • The I²C reference design has a 7-bit or a 10-bit (depending on the device used) address space. Common I²C bus speeds are the 100 kbit/s standard mode and the 10 kbit/s low-speed mode, but arbitrarily low clock frequencies are also allowed. • Recent revisions of I²C can host more nodes and run at faster speeds (400 kbit/s Fast mode, 1 Mbit/s Fast mode plus or Fm+, and 3.4 Mbit/s High Speed mode). These speeds are more widely used on embedded systems than on PCs. There are also other features, such as 16-bit addressing. Operation • Consider a bus with a clock (SCL) and data (SDA) lines with 7-bit addressing: The bus has two roles for nodes: master and slave: – Master node — node that generates the clock and initiates communication with slaves – Slave node — node that receives the clock and responds when addressed by the master – The bus is a multi-master bus which means any number of master nodes can be present. Additionally, master and slave roles may be changed between messages (after a STOP is sent). • There are four potential modes of operation for a given bus device, although most devices only use a single role and its two modes: – – – – – master transmit — master node is sending data to a slave master receive — master node is receiving data from a slave slave transmit — slave node is sending data to the master slave receive — slave node is receiving data from the master If the master wishes to read from the slave then it repeatedly receives a byte from the slave, the master sending an ACK bit after every byte but the last one. (In this situation, the master is in master receive mode and the slave is in slave transmit mode.) – The master then either ends transmission with a stop bit, or it may send another START bit if it wishes to retain control of the bus for another transfer (a "combined message"). • The master is initially in master transmit mode by sending a start bit followed by the 7-bit address of the slave it wishes to communicate with, which is finally followed by a single bit representing whether it wishes to write(0) to or read(1) from the slave. • If the slave exists on the bus then it will respond with an ACK bit (active low for acknowledged) for that address. The master then continues in either transmit or receive mode (according to the read/write bit it sent), and the slave continues in its complementary mode (receive or transmit, respectively). • The address and the data bytes are sent most significant bit first. The start bit is indicated by a high-to-low transition of SDA with SCL high; the stop bit is indicated by a low-to-high transition of SDA with SCL high. All other transitions of SDA take place with SCL low. • If the master wishes to write to the slave then it repeatedly sends a byte with the slave sending an ACK bit. (In this situation, the master is in master transmit mode and the slave is in slave receive mode.) Timing Diagram • Data transfer is initiated with the START bit (S) when SDA is pulled low while SCL stays high. Then, SDA sets the transferred bit while SCL is low (blue) and the data is sampled (received) when SCL rises (green). When the transfer is complete, a STOP bit (P) is sent by releasing the data line to allow it to be pulled up while SCL is constantly high. In order to avoid false marker detection, the level on SDA is changed on the falling edge and is captured on the rising edge of SCL. • • • • • • • • • • • • • • • • • • • SPI Adv/Disadv. +Full duplex communication +Not limited to 8-bit words +Arbitrary choice of message size, content, and purpose +Extremely simple hardware interfacing +Typically lower power requirements than I²C or SMBus due to less circuitry (including pull up resistors) +Slaves use the master's clock, and don't need precision oscillators +Slaves don't need a unique address — unlike I²C or GPIB or SCSI +Transceivers are not needed +Uses only four pins on IC packages, and wires in board layouts or connectors, much fewer than parallel interfaces +Not limited to any maximum clock speed, enabling potentially high throughput -Requires more pins on IC packages than I²C, even in the three-wire variant -No in-band addressing; out-of-band chip select signals are required on shared buses -No hardware flow control by the slave (but the master can delay the next clock edge to slow the transfer rate) -No hardware slave acknowledgment (the master could be transmitting to nowhere and not know it) -Supports only one master device -No error-checking protocol is defined -Generally prone to noise spikes causing faulty communication -Only handles short distances compared to RS-232, RS-485, or CAN-bus -SPI does not support hot plugging (dynamically adding nodes) Serial Communication Modules SPI port pins SPI1 SPI2 SPI3 NSS PA4,PA15 PB9,PB12,PI0 PA15,PA4 SCK PA5,PB3 PB10,PB13,PI1 PB3,PC10 MISO PA6,PB4 PC2,PB14,PI2 PB4,PC11 MOSI PA7,PB5 PC3,PB15,PI3 PC12,PB5 Initializing SPI • • • • • • • • • SPI_Direction: Unidirectional or bidirectional. SPI_Mode: Master or Slave SPI_DataSize: You can send 8 Bits and 16 Bits SPI_CPOL: Clock polarity – High/Low SPI_CPHA: Defines the edge for bit capture – 1st,2nd edge. SPI_NSS: Chip select hardware/sofware. Slave Selection SPI_BaudRatePrescaler: Defines the clock speed of our SPI SPI_FirstBit: Starting with MSB or LSB ? SPI_CRCPolynomial: Polynomial for CRC calculation • SPI_Direction: We need bidirectional here for read and write. • SPI_Mode: the stm32f4 should be the master here! • SPI_DataSize: We use 8 Bits. • SPI_CPOL: We set this to High, as it is in the read&write protocol in LIS302DL datasheet. • SPI_CPHA: We use 2nd edge. • SPI_NSS: I set this so software. • SPI_BaudRatePrescaler: set it to maximum here (Prescaler 2) • SPI_FirstBit: LIS302DL datasheet -> its MSB ! • SPI_CRCPolynomial: we don't use it in this example. SPI Init • RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); • SPI_InitTypeDef SPI_InitTypeDefStruct; • • SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; • SPI_InitTypeDefStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; • SPI_InitTypeDefStruct.SPI_Mode = SPI_Mode_Master; • SPI_InitTypeDefStruct.SPI_DataSize = SPI_DataSize_8b; • SPI_InitTypeDefStruct.SPI_NSS = SPI_NSS_Soft; • SPI_InitTypeDefStruct.SPI_FirstBit = SPI_FirstBit_MSB; • SPI_InitTypeDefStruct.SPI_CPOL = SPI_CPOL_High; • SPI_InitTypeDefStruct.SPI_CPHA = SPI_CPHA_2Edge; • • SPI_Init(SPI1, &SPI_InitTypeDefStruct); Auxiliary Function&GPIO Adj. • RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE , ENABLE); • • • • • • GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_6; GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitTypeDefStruct); • • • • • • GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_3; GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOE, &GPIO_InitTypeDefStruct); • • • GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); • GPIO_SetBits(GPIOE, GPIO_Pin_3); SPI TX_RX routines • uint8_t mySPI_GetData(uint8_t adress){ • GPIO_ResetBits(GPIOE, GPIO_Pin_3); • adress = 0x80 | adress; • while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); //transmit buffer empty? • SPI_I2S_SendData(SPI1, adress); • while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); //data received? • SPI_I2S_ReceiveData(SPI1); //Clear RXNE bit • • • • • • while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); //transmit buffer empty? SPI_I2S_SendData(SPI1, 0x00); //Dummy byte to generate clock while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); //data received? GPIO_SetBits(GPIOE, GPIO_Pin_3); return SPI_I2S_ReceiveData(SPI1); //return reveiced data } • void mySPI_SendData(uint8_t adress, uint8_t data){ • GPIO_ResetBits(GPIOE, GPIO_Pin_3); • while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); //transmit buffer empty? • SPI_I2S_SendData(SPI1, adress); • while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); //data received? • SPI_I2S_ReceiveData(SPI1); • while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); //transmit buffer empty? • SPI_I2S_SendData(SPI1, data); • while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); //data received? • SPI_I2S_ReceiveData(SPI1); • • • • • • • • • • • • • • • • • • • • • • int main(void) { int i=0; mySPI_Init(); //mySPI_SendData(0x20, 0xC0); //LIS302D Config mySPI_SendData(0x20, 0x47); // Data Rate=100Hz, Full Scale=2g, Activate, x,y,z enable while(!(mySPI_GetData(0x27)&1)); dataX=mySPI_GetData(0x29); while(!(mySPI_GetData(0x27)&2)); dataY=mySPI_GetData(0x2B); while(1) { status=mySPI_GetData(0x27); // Statusu ogrenelim. Kim hazir kim degil? while (status && 0x08){ if (status&&0x80) i=80;// okuma hizi ivme degisiminden dusuk overrun sorunu dataX = mySPI_GetData(0x29); dataY = mySPI_GetData(0x2B); dataZ = mySPI_GetData(0x2D); i=0; } } Main Output Data