/*

                         \\\|///
                       \\  - -  //
                        (  @ @  )
+---------------------oOOo-(_)-oOOo-------------------------+
|                 智林STM32开发板试验程序                   |
|                 Timer2 PWM 输出方式试验                   |
|                 刘笑然 by Xiaoran Liu                     |
|                        2008.4.16                          |
|                                                           |
|           智林测控技术研究所 ZERO research group          |
|                      www.the0.net                         |
|                             Oooo                          |
+-----------------------oooO--(   )-------------------------+
                       (   )   ) /
                        \ (   (_/
                         \_)     

*/
/*----------------------------------------------------------*\
 |  引入相关芯片的头文件                                    |
\*----------------------------------------------------------*/
#include <stdio.h>

#include <stm32f10x_lib.h>    // STM32F10x Library Definitions
#include "STM32_Init.h"       // STM32 Initialization
#include "TFT018.h"
/*----------------------------------------------------------*\
 | HARDWARE DEFINE                                          |
\*----------------------------------------------------------*/
#define LED             ( 1 << 5 )              // PB5: LED D2
/*----------------------------------------------------------*\
 | SOFTWARE DATA                                            |
\*----------------------------------------------------------*/
#define I2C_Speed    100000
#define I2C_OwnAddr  0xA0

I2C_InitTypeDef i = {
	I2C_Mode_I2C,
	I2C_DutyCycle_2,
	I2C_OwnAddr,
	I2C_Ack_Enable,
	I2C_AcknowledgedAddress_7bit,
	I2C_Speed
	};
/*----------------------------------------------------------*\
 | I2C Initialisation                                       |
\*----------------------------------------------------------*/
void I2C_Initialisation( void ) {
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//  RCC->APB2ENR |= (1<<0);                      /* enable periperal clock for AFIO      */
  /* Enable I2C1 clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  I2C_DeInit(I2C1);
  I2C_Init(I2C1, &i);

  I2C_Cmd (I2C1, ENABLE);
  }
u32 waitForEvent(u32 event) {
  int i;
  for(i = 2000000; i > 0; i--) {
    u32 s = I2C1->SR1;
	//if (s & (I2C_FLAG_TIMEOUT | I2C_FLAG_PECERR | I2C_FLAG_OVR | I2C_FLAG_AF | I2C_FLAG_ARLO | I2C_FLAG_BERR | I2C_FLAG_STOPF));
    if (s & event) return s;
  	}
  return 0;
  }
void sendStart(void) {
	I2C_GenerateSTART(I2C1, ENABLE);							// send start when bus becomes available
	waitForEvent(I2C_FLAG_SB);
	I2C1->DR = I2C_OwnAddr;										// send slave address for transmission
	waitForEvent(I2C_FLAG_ADDR);
	I2C1->SR2;												// clear event
  }
void sendData(u8 data){
  //waitForEvent(I2C_FLAG_TXE);
  waitForEvent(I2C_FLAG_BTF);
  I2C1->DR = data;											// send byte
  }
void sendStop(void) {
  waitForEvent(I2C_FLAG_TXE);
  I2C_GenerateSTOP(I2C1, ENABLE);							// send stop after current byte
  }
u8 receiveByte(void) {
  I2C_GenerateSTART(I2C1, ENABLE);							// send start when bus becomes available
  waitForEvent(I2C_FLAG_SB);
  I2C_AcknowledgeConfig(I2C1, DISABLE);					// only one byte will be read
  I2C1->DR = I2C_OwnAddr | 0x01;								// send slave address for reception
  waitForEvent(I2C_FLAG_ADDR);
  I2C1->SR2;												// clear event

  waitForEvent(I2C_FLAG_RXNE);
  I2C_GenerateSTOP(I2C1, ENABLE);							// send stop after current byte
  return I2C1->DR;											// receive byte
  }
/*----------------------------------------------------------*\
 | I2C Write Byte                                           |
\*----------------------------------------------------------*/
void WriteByte(u16 addr, u8 data) {
  /* Enable I2C1 acknowledgement if it is already disabled by other function */
  //I2C_AcknowledgeConfig(I2C1, ENABLE);
  //I2C_AcknowledgeConfig(I2C1, DISABLE);					// only one byte will be read

  sendStart();
  sendData( addr & 0xFF );
  //I2C_AcknowledgeConfig(I2C1, DISABLE);					// only one byte will be read
  sendData( data );
  waitForEvent(I2C_FLAG_BTF);
  sendStop();
  }
/*----------------------------------------------------------*\
 | I2C Read Byte                                            |
\*----------------------------------------------------------*/
u8 ReadByte(u16 addr) {
  /* Enable I2C1 acknowledgement if it is already disabled by other function */
  //I2C_AcknowledgeConfig(I2C1, ENABLE);

  sendStart();
  sendData( addr & 0xFF );
  //sendStart();
  //sendStop();
  return receiveByte();
  }
/*----------------------------------------------------------*\
 |  Delay                                                   |
 |  延时 Inserts a delay time.                              |
 |  nCount: 延时时间                                        |
 |  nCount: specifies the delay time length.                |
\*----------------------------------------------------------*/
void Delay(vu32 nCount) {
  for(; nCount != 0; nCount--);
  }
/*----------------------------------------------------------*\
 | MIAN ENTRY                                               |
\*----------------------------------------------------------*/
int main (void) {
  char s[20];

  stm32_Init ();                                // STM32 setup
  LCD_Init();

  LCD_Clear_Screen(Blue);
  Font = 0;
  LCD_PutString(30,0,"STM32F 开发板",Cyan,Blue);
  LCD_PutString(10,113,"智林测控技术研究所",Yellow,Blue);
  LCD_PutString(40,20,"I2C Test",Blue,Cyan);
  LCD_PutString(5,38,"24C02 Address 0x00",Cyan,Blue);

  I2C_Initialisation();

  LCD_PutString(4,62,"Write:0x55",Red,Yellow);
  WriteByte(0x00, 0x55);
  Delay(40000);
  sprintf(s, "Read:0x%2X", ReadByte(0x00) );
  LCD_PutString(4,82,s,Red,Yellow);

  for(;;) {
    GPIOB->ODR &= ~LED;                         // switch on LED
	Delay(2000000);
    GPIOB->ODR |=  LED;                         // switch off LED
	Delay(2000000);
    }
  }
/*******************************************************************************
* Function Name  : assert_failed
* Description    : Reports the name of the source file and the source line number
*                  where the assert error has occurred.
* Input          : - file: pointer to the source file name
*                  - line: assert error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
/*----------------------------------------------------------*\
 | END OF FILE                                              |
\*----------------------------------------------------------*/
