Преглед на файлове

Switch to I2C_Master_poll from 'STM8 optimized I2C examples'.

Vladimir N. Shilov преди 1 година
родител
ревизия
c826355575
променени са 5 файла, в които са добавени 387 реда и са изтрити 7 реда
  1. 1 1
      Makefile
  2. 1 1
      inc/stm8s_conf.h
  3. 12 5
      lib/htu21.c
  4. 329 0
      lib/i2c_master_poll.c
  5. 44 0
      lib/i2c_master_poll.h

+ 1 - 1
Makefile

@@ -58,7 +58,7 @@ PERIPH_OBJECTS += stm8s_clk.o
 PERIPH_OBJECTS += stm8s_exti.o
 #PERIPH_OBJECTS += stm8s_flash.o
 PERIPH_OBJECTS += stm8s_gpio.o
-PERIPH_OBJECTS += stm8s_i2c.o
+#PERIPH_OBJECTS += stm8s_i2c.o
 PERIPH_OBJECTS += stm8s_itc.o
 #PERIPH_OBJECTS += stm8s_iwdg.o
 #PERIPH_OBJECTS += stm8s_rst.o

+ 1 - 1
inc/stm8s_conf.h

@@ -50,7 +50,7 @@
 #include "stm8s_exti.h"
 #include "stm8s_flash.h"
 #include "stm8s_gpio.h"
-#include "stm8s_i2c.h"
+//#include "stm8s_i2c.h"
 #include "stm8s_itc.h"
 #include "stm8s_iwdg.h"
 #include "stm8s_rst.h"

+ 12 - 5
lib/htu21.c

@@ -1,6 +1,7 @@
 #include "stm8s.h"
 #include "htu21.h"
-#include "i2c.h"
+//#include "i2c.h"
+#include "i2c_master_poll.h"
 #include "delay.h"
 
 #define HTU_T_MEASURE 0xF3
@@ -8,13 +9,16 @@
 
 static uint8_t buf[3];
 static const uint8_t addr = 0x40;
-static t_i2c_status i2cs;
+//static t_i2c_status i2cs;
+static uint8_t i2cs;
 static uint32_t val;
 
 static uint8_t CalcSht21Crc(uint8_t *data, uint8_t nbrOfBytes);
 
 htu_err_t htu_GetTemperature(int16_t * temperature) {
-  i2cs = i2c_wr_reg(addr, HTU_T_MEASURE);
+  i2cs = 0;//i2c_wr_reg(addr, HTU_T_MEASURE);
+  buf[0] = HTU_T_MEASURE;
+  I2C_WriteBytes(addr, 1, buf);
   if (i2cs == 0) {
     Delay(90);
     i2c_rd_reg(addr, buf);
@@ -40,10 +44,13 @@ htu_err_t htu_GetTemperature(int16_t * temperature) {
 }
 
 htu_err_t htu_GetHumidity(uint16_t * humidity) {
-  i2cs = i2c_wr_reg(addr, HTU_H_MEASURE);
+  i2cs = 0;//i2c_wr_reg(addr, HTU_H_MEASURE);
+  buf[0] = HTU_H_MEASURE;
+  I2C_WriteBytes(addr, 1, buf);
   if (i2cs == 0) {
     Delay(60);
-    i2c_rd_reg(addr, buf);
+    //i2c_rd_reg(addr, buf);
+    I2C_ReadBytes(addr, 3, buf);
 //    if(buf[2] == CalcSht21Crc(buf,2)) {
       val = buf[0];
       val <<= 8;

+ 329 - 0
lib/i2c_master_poll.c

@@ -0,0 +1,329 @@
+/**
+  ******************************************************************************
+  * @file    i2c_master_poll.c
+  * @author  MCD Application Team
+  * @version V0.0.3
+  * @date    Oct 2010
+  * @brief   This file contains optimized drivers for I2C master
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
+  */ 
+
+#include "i2c_master_poll.h"
+
+/* Таймаут ожидания события I2C */
+extern __IO uint8_t I2C_timeout;
+
+/* flag clearing sequence - uncoment next for peripheral clock under 2MHz */
+#define dead_time() { /* _asm("nop"); _asm("nop"); */ }
+#define tout()            (I2C_timeout)
+#define set_tout_ms(a)    { I2C_timeout = a; }
+
+/******************************************************************************
+* Function name : I2C_Init
+* Description 	: Initialize I2C peripheral
+* Input param 	: None
+* Return 		    : None
+* See also 		  : None
+*******************************************************************************/
+void I2C_Init(void) {
+  //define SDA, SCL outputs, HiZ, Open drain, Fast
+  GPIOB->ODR |= (GPIO_PIN_4 | GPIO_PIN_5);
+  GPIOB->DDR |= (GPIO_PIN_4 | GPIO_PIN_5);
+  GPIOB->CR2 |= (GPIO_PIN_4 | GPIO_PIN_5);
+
+#ifdef FAST_I2C_MODE
+  I2C->FREQR = 16;               // input clock to I2C - 16MHz 
+  I2C->CCRL = 15;                // 900/62.5= 15, (SCLhi must be at least 600+300=900ns!)
+  I2C->CCRH = 0x80;              // fast mode, duty 2/1 (bus speed 62.5*3*15~356kHz)
+  I2C->TRISER = 5;               // 300/62.5 + 1= 5  (maximum 300ns)
+#else
+  I2C->FREQR = 8;                // input clock to I2C - 8MHz
+  I2C->CCRL = 40;                // CCR= 40 - (SCLhi must be at least 4000+1000=5000ns!)
+  I2C->CCRH = 0;                 // standard mode, duty 1/1 bus speed 100kHz
+  I2C->TRISER = 9;               // 1000ns/(125ns) + 1  (maximum 1000ns)
+#endif
+  I2C->OARL = 0xA0;              // own address A0;
+  I2C->OARH |= 0x40;
+  I2C->ITR = 1;                  // enable error interrupts
+  I2C->CR2 |= 0x04;              // ACK=1, Ack enable
+  I2C->CR1 |= 0x01;              // PE=1
+}
+
+/******************************************************************************
+* Function name : I2C_ReadRegister
+* Description 	: Read defined number bytes from slave memory starting with defined offset
+* Input param 	: offset in slave memory, number of bytes to read, starting address to store received data
+* Return 		    : None
+* See also 		  : None
+*******************************************************************************/
+void I2C_ReadRegister(u8 u8_regAddr, u8 u8_NumByteToRead, u8 *ReadBuffer)
+{
+  /*--------------- BUSY? -> STOP request ---------------------*/
+	while(I2C->SR3 & I2C_SR3_BUSY && tout())	  				// Wait while the bus is busy
+  {
+		I2C->CR2 |= I2C_CR2_STOP;                   				// Generate stop here (STOP=1)
+    while(I2C->CR2 & I2C_CR2_STOP && tout()); 				// Wait until stop is performed
+	}
+  I2C->CR2 |= I2C_CR2_ACK;                      				// ACK=1, Ack enable
+  /*--------------- Start communication -----------------------*/  
+  I2C->CR2 |= I2C_CR2_START;                    				// START=1, generate start
+  while((I2C->SR1 & I2C_SR1_SB)==0 && tout());				// Wait for start bit detection (SB)
+  /*------------------ Address send ---------------------------*/      
+  if(tout())
+  {
+    I2C->DR = (u8)(SLAVE_ADDRESS << 1);   						// Send 7-bit device address & Write (R/W = 0)
+  }
+  while(!(I2C->SR1 & I2C_SR1_ADDR) &&  tout()); 				// test EV6 - wait for address ack (ADDR)
+  dead_time();                                  				// ADDR clearing sequence
+  I2C->SR3;
+  /*--------------- Register/Command send ----------------------*/
+  while(!(I2C->SR1 & I2C_SR1_TXE) &&  tout());  				// Wait for TxE
+  if(tout())
+  {  
+    I2C->DR = u8_regAddr;                         			// Send register address
+  }                                            					// Wait for TxE & BTF
+  while((I2C->SR1 & (I2C_SR1_TXE | I2C_SR1_BTF)) != (I2C_SR1_TXE | I2C_SR1_BTF) && tout()); 
+  dead_time();                                  				// clearing sequence
+  /*-------------- Stop/Restart communication -------------------*/  
+  #ifdef NO_RESTART																		// if 7bit address and NO_RESTART setted
+    I2C->CR2 |= I2C_CR2_STOP;                     		// STOP=1, generate stop
+    while(I2C->CR2 & I2C_CR2_STOP && tout());   		// wait until stop is performed
+  #endif // NO_RESTART
+  /*--------------- Restart communication ---------------------*/  
+  I2C->CR2 |= I2C_CR2_START;                     				// START=1, generate re-start
+  while((I2C->SR1 & I2C_SR1_SB)==0 && tout()); 				// Wait for start bit detection (SB)
+  /*------------------ Address send ---------------------------*/      
+  if(tout())
+  {
+    I2C->DR = (u8)(SLAVE_ADDRESS << 1) | 1;         	// Send 7-bit device address & Write (R/W = 1)
+  }
+  while(!(I2C->SR1 & I2C_SR1_ADDR) && tout());  			// Wait for address ack (ADDR)
+  /*------------------- Data Receive --------------------------*/
+  if (u8_NumByteToRead > 2)                 						// *** more than 2 bytes are received? ***
+  {
+    I2C->SR3;                                     			// ADDR clearing sequence    
+    while(u8_NumByteToRead > 3 && tout())       			// not last three bytes?
+    {
+      while(!(I2C->SR1 & I2C_SR1_BTF) && tout()); 				// Wait for BTF
+			*ReadBuffer++ = I2C->DR;                   				// Reading next data byte
+      --u8_NumByteToRead;																		// Decrease Numbyte to reade by 1
+    }
+																												//last three bytes should be read
+    while(!(I2C->SR1 & I2C_SR1_BTF) && tout()); 			// Wait for BTF
+    I2C->CR2 &=~I2C_CR2_ACK;                      			// Clear ACK
+    disableInterrupts();                          			// Errata workaround (Disable interrupt)
+    *ReadBuffer++ = I2C->DR;                     		// Read 1st byte
+    I2C->CR2 |= I2C_CR2_STOP;                       		// Generate stop here (STOP=1)
+    *ReadBuffer++ = I2C->DR;                     		// Read 2nd byte
+    enableInterrupts();																	// Errata workaround (Enable interrupt)
+    while(!(I2C->SR1 & I2C_SR1_RXNE) && tout());			// Wait for RXNE
+    *ReadBuffer++ = I2C->DR;                   			// Read 3rd Data byte
+  }
+  else
+  {
+   if(u8_NumByteToRead == 2)                						// *** just two bytes are received? ***
+    {
+      I2C->CR2 |= I2C_CR2_POS;                      		// Set POS bit (NACK at next received byte)
+      disableInterrupts();                          		// Errata workaround (Disable interrupt)
+      I2C->SR3;                                       	// Clear ADDR Flag
+      I2C->CR2 &=~I2C_CR2_ACK;                        	// Clear ACK 
+      enableInterrupts();																// Errata workaround (Enable interrupt)
+      while(!(I2C->SR1 & I2C_SR1_BTF) && tout()); 		// Wait for BTF
+      disableInterrupts();                          		// Errata workaround (Disable interrupt)
+      I2C->CR2 |= I2C_CR2_STOP;                       	// Generate stop here (STOP=1)
+      *ReadBuffer++ = I2C->DR;                     	// Read 1st Data byte
+      enableInterrupts();																// Errata workaround (Enable interrupt)
+			*ReadBuffer = I2C->DR;													// Read 2nd Data byte
+    }
+    else                                      					// *** only one byte is received ***
+    {
+      I2C->CR2 &=~I2C_CR2_ACK;;                     		// Clear ACK 
+      disableInterrupts();                          		// Errata workaround (Disable interrupt)
+      I2C->SR3;                                       	// Clear ADDR Flag   
+      I2C->CR2 |= I2C_CR2_STOP;                       	// generate stop here (STOP=1)
+      enableInterrupts();																// Errata workaround (Enable interrupt)
+      while(!(I2C->SR1 & I2C_SR1_RXNE) && tout()); 		// test EV7, wait for RxNE
+      *ReadBuffer = I2C->DR;                     		// Read Data byte
+    }
+  }
+  /*--------------- All Data Received -----------------------*/
+  while((I2C->CR2 & I2C_CR2_STOP) && tout());     		// Wait until stop is performed (STOPF = 1)
+  I2C->CR2 &=~I2C_CR2_POS;                          		// return POS to default state (POS=0)
+}
+
+/******************************************************************************
+* Function name : I2C_WriteRegister
+* Description 	: write defined number bytes to slave memory starting with defined offset
+* Input param 	: offset in slave memory, number of bytes to write, starting address to send
+* Return 		    : None.
+* See also 		  : None.
+*******************************************************************************/
+void I2C_WriteRegister(u8 u8_regAddr, u8 u8_NumByteToWrite, u8 *ReadBuffer)
+{
+  while((I2C->SR3 & 2) && tout())       									// Wait while the bus is busy
+  {
+    I2C->CR2 |= 2;                        								// STOP=1, generate stop
+    while((I2C->CR2 & 2) && tout());      								// wait until stop is performed
+  }
+  
+  I2C->CR2 |= 1;                        									// START=1, generate start
+  while(((I2C->SR1 & 1)==0) && tout()); 									// Wait for start bit detection (SB)
+  dead_time();                          									// SB clearing sequence
+  if(tout())
+  {
+    I2C->DR = (u8)(SLAVE_ADDRESS << 1);   							// Send 7-bit device address & Write (R/W = 0)
+  }
+  while(!(I2C->SR1 & 2) && tout());     									// Wait for address ack (ADDR)
+  dead_time();                          									// ADDR clearing sequence
+  I2C->SR3;
+  while(!(I2C->SR1 & 0x80) && tout());  									// Wait for TxE
+  if(tout())
+  {
+    I2C->DR = u8_regAddr;                 								// send Offset command
+  }
+  if(u8_NumByteToWrite)
+  {
+    while(u8_NumByteToWrite--)          									
+    {																											// write data loop start
+      while(!(I2C->SR1 & 0x80) && tout());  								// test EV8 - wait for TxE
+      I2C->DR = *ReadBuffer++;           								// send next data byte
+    }																											// write data loop end
+  }
+  while(((I2C->SR1 & 0x84) != 0x84) && tout()); 					// Wait for TxE & BTF
+  dead_time();                          									// clearing sequence
+  
+  I2C->CR2 |= 2;                        									// generate stop here (STOP=1)
+  while((I2C->CR2 & 2) && tout());      									// wait until stop is performed  
+}
+
+/**
+ * @brief 
+ * 
+ * @param NumByteToRead 
+ * @param ReadBuffer 
+ */
+void I2C_ReadBytes(const u8 Addr, const u8 NumByteToRead, u8 *ReadBuffer) {
+  u8 adr = Addr << 1;
+  u8 n = NumByteToRead;
+  set_tout_ms(10);
+
+  /*--------------- BUSY? -> STOP request ---------------------*/
+	while(I2C->SR3 & I2C_SR3_BUSY && tout())	  			// Wait while the bus is busy
+  {
+		I2C->CR2 |= I2C_CR2_STOP;                   		// Generate stop here (STOP=1)
+    while(I2C->CR2 & I2C_CR2_STOP && tout()); 			// Wait until stop is performed
+	}
+  I2C->CR2 |= I2C_CR2_ACK;                      		// ACK=1, Ack enable
+  /*--------------- Start communication -----------------------*/  
+  I2C->CR2 |= I2C_CR2_START;                    		// START=1, generate start
+  while((I2C->SR1 & I2C_SR1_SB)==0 && tout());			// Wait for start bit detection (SB)
+  /*------------------ Address send ---------------------------*/      
+  if(tout())
+  {
+    I2C->DR = (adr | 1);         	                  // Send 7-bit device address & Write (R/W = 1)
+  }
+  while(!(I2C->SR1 & I2C_SR1_ADDR) && tout());  		// Wait for address ack (ADDR)
+  /*------------------- Data Receive --------------------------*/
+  if (n > 2)                 						            // *** more than 2 bytes are received? ***
+  {
+    I2C->SR3;                                     	// ADDR clearing sequence    
+    while(n > 3 && tout())       			              // not last three bytes?
+    {
+      while(!(I2C->SR1 & I2C_SR1_BTF) && tout()); 	// Wait for BTF
+			*ReadBuffer++ = I2C->DR;                   		// Reading next data byte
+      --n;																		      // Decrease Numbyte to reade by 1
+    }
+																										//last three bytes should be read
+    while(!(I2C->SR1 & I2C_SR1_BTF) && tout()); 		// Wait for BTF
+    I2C->CR2 &=~I2C_CR2_ACK;                      	// Clear ACK
+    disableInterrupts();                          	// Errata workaround (Disable interrupt)
+    *ReadBuffer++ = I2C->DR;                     		// Read 1st byte
+    I2C->CR2 |= I2C_CR2_STOP;                       // Generate stop here (STOP=1)
+    *ReadBuffer++ = I2C->DR;                     		// Read 2nd byte
+    enableInterrupts();															// Errata workaround (Enable interrupt)
+    while(!(I2C->SR1 & I2C_SR1_RXNE) && tout());		// Wait for RXNE
+    *ReadBuffer++ = I2C->DR;                   			// Read 3rd Data byte
+  }
+  else
+  {
+   if(n == 2)                						            // *** just two bytes are received? ***
+    {
+      I2C->CR2 |= I2C_CR2_POS;                      // Set POS bit (NACK at next received byte)
+      disableInterrupts();                          // Errata workaround (Disable interrupt)
+      I2C->SR3;                                     // Clear ADDR Flag
+      I2C->CR2 &=~I2C_CR2_ACK;                      // Clear ACK 
+      enableInterrupts();														// Errata workaround (Enable interrupt)
+      while(!(I2C->SR1 & I2C_SR1_BTF) && tout()); 	// Wait for BTF
+      disableInterrupts();                          // Errata workaround (Disable interrupt)
+      I2C->CR2 |= I2C_CR2_STOP;                     // Generate stop here (STOP=1)
+      *ReadBuffer++ = I2C->DR;                     	// Read 1st Data byte
+      enableInterrupts();														// Errata workaround (Enable interrupt)
+			*ReadBuffer = I2C->DR;												// Read 2nd Data byte
+    }
+    else                                      			// *** only one byte is received ***
+    {
+      I2C->CR2 &=~I2C_CR2_ACK;;                     // Clear ACK 
+      disableInterrupts();                          // Errata workaround (Disable interrupt)
+      I2C->SR3;                                     // Clear ADDR Flag   
+      I2C->CR2 |= I2C_CR2_STOP;                     // generate stop here (STOP=1)
+      enableInterrupts();														// Errata workaround (Enable interrupt)
+      while(!(I2C->SR1 & I2C_SR1_RXNE) && tout());  // test EV7, wait for RxNE
+      *ReadBuffer = I2C->DR;                     		// Read Data byte
+    }
+  }
+  /*--------------- All Data Received -----------------------*/
+  while((I2C->CR2 & I2C_CR2_STOP) && tout());     	// Wait until stop is performed (STOPF = 1)
+  I2C->CR2 &= ~I2C_CR2_POS;                         // return POS to default state (POS=0)
+}
+/**
+ * @brief write defined number bytes to slave device
+ * 
+ * @param Addr 
+ * @param NumByteToWrite 
+ * @param DataBuffer 
+ */
+void I2C_WriteBytes(const u8 Addr, const u8 NumByteToWrite, u8 *DataBuffer) {
+  u8 adr = Addr << 1;
+  u8 n = NumByteToWrite;
+  set_tout_ms(10);
+
+  while((I2C->SR3 & 2) && tout())       				// Wait while the bus is busy
+  {
+    I2C->CR2 |= 2;                        			// STOP=1, generate stop
+    while((I2C->CR2 & 2) && tout());      			// wait until stop is performed
+  }
+  
+  I2C->CR2 |= 1;                        				// START=1, generate start
+  while(((I2C->SR1 & 1)==0) && tout()); 				// Wait for start bit detection (SB)
+  dead_time();                          				// SB clearing sequence
+  if(tout())
+  {
+    I2C->DR = adr;   							              // Send 7-bit device address & Write (R/W = 0)
+  }
+  while(!(I2C->SR1 & 2) && tout());     				// Wait for address ack (ADDR)
+  dead_time();                          				// ADDR clearing sequence
+  I2C->SR3;
+  if(n)
+  {
+    while(n--)          									
+    {																						// write data loop start
+      while(!(I2C->SR1 & 0x80) && tout());  		// test EV8 - wait for TxE
+      I2C->DR = *DataBuffer++;           				// send next data byte
+    }																						// write data loop end
+  }
+  while(((I2C->SR1 & 0x84) != 0x84) && tout()); // Wait for TxE & BTF
+  dead_time();                          				// clearing sequence
+  
+  I2C->CR2 |= 2;                        				// generate stop here (STOP=1)
+  while((I2C->CR2 & 2) && tout());      				// wait until stop is performed  
+}

+ 44 - 0
lib/i2c_master_poll.h

@@ -0,0 +1,44 @@
+/**
+  ******************************************************************************
+  * @file    i2c_opt.h
+  * @author  MCD Application Team
+  * @version V0.0.3
+  * @date    Feb 2010
+  * @brief   This file contains definitions for optimized I2C software
+  ******************************************************************************
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  *                     COPYRIGHT 2009 STMicroelectronics  
+  */ 
+
+/* Define to prevent recursive inclusion */
+#ifndef __I2C_OPT_H
+#define __I2C_OPT_H
+
+#include "stm8s.h"
+
+// ************************** I2C Configuration Variables **************************
+/* definition of fast or default standard mode (bus speed up to 400 or 100 kHz) */
+#define FAST_I2C_MODE
+
+/* uncomment next line when stop request is required between device address sent and read data */
+//#define NO_RESTART
+
+#define SLAVE_ADDRESS  0x40
+
+// ************************* Function Declaration ***************************
+void I2C_Init(void);
+void I2C_ReadRegister(u8 u8_regAddr, u8 u8_NumByteToRead, u8 *u8_ReadBuffer);
+void I2C_WriteRegister(u8 u8_regAddr, u8 u8_NumByteToWrite, u8 *u8_DataBuffer);
+void I2C_ReadBytes(u8 Addr, u8 NumByteToRead, u8 *ReadBuffer);
+void I2C_WriteBytes(u8 Addr, u8 NumByteToWrite, u8 *DataBuffer);
+
+#endif /* __I2C_OPT_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/